> For the complete documentation index, see [llms.txt](https://overleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://overleaf-pro.ayaka.space/latex/in-depth-articles/15-how-do-tex-engines-typeset-tables-2.md).

# How do TeX engines typeset tables 2

## How do TeX engines typeset tables 2

## TeX engines refer to tables as alignments

Within the [documentation of TeX’s source code](https://www.overleaf.com/latex/examples/typeset-the-source-code-documentation-for-tex-e-tex-or-pdftex/qkgfgyspnhcv) Knuth doesn't discuss TeX’s ability to “typeset tables” but, instead, he describes TeX’s algorithms for constructing so-called *alignments*. TeX’s typesetting of tables is, in effect, an automated box-alignment process: arranging boxes (table cells, rows and columns) to achieve a pleasing rectangular grid or array—though, of course, being TeX there are *many* nuances in that process.

The term “alignment” is also reflected in the names of the two table typesetting commands built into all TeX engines:

* `\halign` (horizontal alignment), and
* `\valign` (vertical alignment).

We’ll explore both commands throughout this article series, starting with a more formal overview of the format/structure of the `\halign` and `\valign` commands to lay foundations for later, in-depth, articles in this series.

### TeX’s tables are boxes and spacing

Individual table cells typically contain a variety of content such as lines of text, mathematics or graphics, which produces a set of table cells that have different widths, heights or depths of typeset material. Somehow, TeX needs to work with those cells, of varying content dimensions, to construct the final table where each row has a certain height and each column a particular width. TeX needs to deduce appropriate values for the heights of each row and widths of each column from the collection of variable-size table cells.

However, TeX cannot know the true size of each cell's content until that content is typeset; consequently, TeX works through the entire table, typesetting each cell, to obtain sizing data required to complete the table layout. From that size data, TeX can determine the correct height for each row and width for each column. TeX may also encounter empty cells or cells that the user wants to span across multiple columns or multiple rows, all of which TeX has to carefully factor into its calculations. After “filtering” this disparate collection of cell (box) size data, only then is TeX able to determine the final values for column widths in an `\halign`, or row heights for `\valign` and uses those values in the final stages of its table-layout algorithms.

In practice, and “under the hood”, TeX’s table typesetting consists of several steps. In outline, TeX first typesets a “draft” or “incomplete” version of the table whilst it captures and processes the cell size data—and data on any `\span` commands used in the table. In the final steps TeX reprocesses that “incomplete” version of the table, to finalise `\halign` column widths or `\valign` row heights and achieve the completed layout—all of which we’ll explore in this article series.

## \halign and \valign: two ways to construct tables

All TeX engines provide two *built-in* commands (primitives) designed for typesetting tables (alignments): `\halign` and `\valign`, which share many core features but also differ in some fundamental ways. The key difference between `\halign` and `\valign` is how they construct their respective tables: row-by-row or column-by-column:

* `\halign`: typesets tables on a row-by-row basis to create individual rows which are stacked vertically to produce the table’s columns
* `\valign`: typesets tables on a column-by-column basis to create individual columns which are stacked horizontally to produce the table’s rows

### \halign

The following diagram depicts construction of a table created by `\halign`. The table is typeset row-by-row with individual rows stacked vertically. Some consequences of this include:

* the table columns arise from vertical stacking of table rows
* page breaks can take place between the table rows
* non-tabular material can be inserted between rows (via `\nolign`, which we'll look at later)

![](/files/8DYywK4L2aLY0yZfmmc7)

### \valign

The following diagram depicts construction of a table created by `\valign`. The table is typeset column-by-column with individual columns stacked horizontally (side-by-side). Some consequences of this include:

* the table rows arise from horizontal stacking of table columns
* line breaks can take place between the table columns
* non-tabular material can be inserted between columns (via `\noalign`, which we'll look at later)

![](/files/Ww0K678Foo70IFeAEvMA)

### Examples

The following example is intended to highlight the row *vs*. column approach of \halign and \valign.

```latex
\documentclass{article}
\begin{document}
\pagestyle{empty}
% Close-fitting box borders
\setlength{\fboxsep}{0pt}

Here is a \verb|\valign| table:
\begingroup
% \hsize controls the \valign
% column widths. We also set
% \parindent to a smaller value
\hsize=30pt
\parindent=10pt
\fbox{\valign{
#&#&#\cr % The preamble: covered later (in great detail!)
A&B&C\cr % The first COLUMN of this \valign table
D&E&F\cr
G&H&I\cr
}}
\endgroup

% Note: for reasons explained later
% the \halign has to be put in a \vbox
Here is an \verb|\halign| table: \fbox{%
\vbox{\halign{
#&#&#\cr % The preamble: covered later (in great detail!)
A&B&C\cr % The first ROW of this \halign table
D&E&F\cr
G&H&I\cr
}}}
\end{document}
```

[Open this example in Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Basic+table+example\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bempty%7D%0A%25+Close-fitting+box+borders+%0A%5Csetlength%7B%5Cfboxsep%7D%7B0pt%7D%0A%0AHere+is+a+%5Cverb%7C%5Cvalign%7C+table%3A+%0A%5Cbegingroup%0A%25+%5Chsize+controls+the+%5Cvalign+%0A%25+column+widths.+We+also+set+%0A%25+%5Cparindent+to+a+smaller+value%0A%5Chsize%3D30pt+%0A%5Cparindent%3D10pt%0A%5Cfbox%7B%5Cvalign%7B%0A%23%26%23%26%23%5Ccr+%25+The+preamble%3A+covered+later+%28in+great+detail%21%29%0AA%26B%26C%5Ccr+%25+The+first+COLUMN+of+this+%5Cvalign+table%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%7D%0A%5Cendgroup%0A%0A%25+Note%3A+for+reasons+explained+later%0A%25+the+%5Chalign+has+to+be+put+in+a+%5Cvbox%0AHere+is+an+%5Cverb%7C%5Chalign%7C+table%3A+%5Cfbox%7B%25%0A%5Cvbox%7B%5Chalign%7B%0A%23%26%23%26%23%5Ccr+%25+The+preamble%3A+covered+later+%28in+great+detail%21%29%0AA%26B%26C%5Ccr+%25+The+first+ROW+of+this+%5Chalign+table%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%7D%7D%0A%5Cend%7Bdocument%7D)

This example produces the following output: ![](/files/jWNXK8Lv9tY7Bp2iDcnD)

The following graphic shows an annotated version of the tables produced by the code above. Later in this article series we will address topics such as:

* what are table preambles?
* why do we set `\hsize` and `\parindent` for `\valign` tables?

For present purposes, just note the row vs. column approach of `\halign` *vs*. `\valign` table construction:

![](/files/1JNoBT3lwI8xJgF93WaI)

## General form of \halign and \valign

To start with we’ll review the basic properties and general format of `\halign` and `\valign` but not (yet) delve into any real detail. [As noted](#intro), we adopt a slightly formal overview of the form/structure of the `\halign` and `\valign` commands to lay foundations for subsequent articles in this series.

The most general form of the `\halign` and `\valign` commands can be written as follows:

`\halign` $$\langle$$⁠`optional specification`⁠$$\rangle$$ { $$\langle$$⁠`preamble`⁠$$\rangle$$ $$\langle$$⁠`body`⁠$$\rangle$$ }

`\valign` $$\langle$$⁠`optional specification`⁠$$\rangle$$ { $$\langle$$⁠`preamble`⁠$$\rangle$$ $$\langle$$⁠`body`⁠$$\rangle$$ }

As you can see, both `\halign` and `\valign` comprise three main sections:

* [$$\langle$$⁠`optional specification`⁠$$\rangle$$](#optspec)
* [$$\langle$$⁠`preamble`⁠$$\rangle$$](#preamble)
* [$$\langle$$⁠`body`⁠$$\rangle$$](#body)

## The $$\langle$$⁠optional specification⁠$$\rangle$$

The default size/extent of a table, its so-called "natural size", is determined by its content—just to clarify, by size/extent we are referring to is

* the *width* of a table produced by `\halign`, or
* the *height* of a table produced by `\valign`

An $$\langle$$⁠`optional specification`⁠$$\rangle$$ can be used to "override" the natural size of the table and takes one of two forms:

* **`to`** $$\langle$$**⁠`dimension`⁠**$$\rangle$$
* **`spread`** $$\langle$$**⁠`dimension`⁠**$$\rangle$$

where

* $$\langle$$**⁠`dimension`⁠**$$\rangle$$ is a length given in units TeX understands, such as pt, mm or cm—the length can also be specified as a command that expands to a value specified in appropriate units;
* **`to`** and **`spread`** are TeX keywords specifying the type of natural size "override":
  * **`to`**: sets the table's size to the specified $$\langle$$⁠`dimension`⁠$$\rangle$$ value
  * **`spread`**: adds the specified $$\langle$$⁠`dimension`⁠$$\rangle$$ value to the table's natural size

The effect of an $$\langle$$⁠`optional specification`⁠$$\rangle$$ depends on the type of table being typeset: it will adjust an `\halign` table's natural *width*, or a `\valign` table's natural *height*.

Here are some examples:

* `\halign **to 100pt**{...}`: sets the `\halign` table's width to `100pt`
* `\valign **to 50pt**{...}`: sets the `\valign` table's height to `30pt`
* `\halign **spread 30pt**{...}`: adds 30pt to the `\halign` table's natural width. Conversely, writing **spread -30pt** would reduce the table's width by 30pt.
* `\valign **spread 20pt**{...}`: adds 20pt to the `\valign` table's natural height. Conversely, writing **spread -20pt** would reduce the table's height by 20pt.

The following code re-uses the table examples above but applies an $$\langle$$⁠`optional specification`⁠$$\rangle$$ to a `\valign` and `\halign` table:

```latex
\documentclass{article}
\begin{document}
\pagestyle{empty}
% Close-fitting box borders
\setlength{\fboxsep}{0pt}

Here is a \verb|\valign| table:
\begingroup
\hsize=30pt
\parindent=10pt
\fbox{\valign to 50pt{
#&#&#\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}}
\endgroup

Here is an \verb|\halign| table:
\fbox{%
\vbox{\halign to 100pt{
#&#&#\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}}}
\end{document}
```

[Open this example in Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Basic+table+example\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bempty%7D%0A%25+Close-fitting+box+borders+%0A%5Csetlength%7B%5Cfboxsep%7D%7B0pt%7D%0A%0AHere+is+a+%5Cverb%7C%5Cvalign%7C+table%3A+%0A%5Cbegingroup%0A%5Chsize%3D30pt+%0A%5Cparindent%3D10pt%0A%5Cfbox%7B%5Cvalign+to+50pt%7B%0A%23%26%23%26%23%5Ccr%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%7D%0A%5Cendgroup%0A%0AHere+is+an+%5Cverb%7C%5Chalign%7C+table%3A%0A%5Cfbox%7B%25%0A%5Cvbox%7B%5Chalign+to+100pt%7B%0A%23%26%23%26%23%5Ccr%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%7D%7D%0A%5Cend%7Bdocument%7D)

This example produces the output shown below:

![](/files/vIGFFsRa4VSLdz3i6Xvm)

—but note how both table's content is “bunched together”. The reason for that is an absence of flexible spacing (glue) that TeX can use to stretch out the content to fill the additional space provided by **`to`** $$\langle$$**⁠`dimension`⁠**$$\rangle$$. Here we'll jump ahead to mention the `\tabskip` command.

#### An initial introduction to the \tabskip command

The aesthetics of a table’s layout might require adjustment to spacing between its rows or columns so, not surprisingly, TeX engines provide a command called `\tabskip` which lets you do that. `\tabskip` is used to set (and vary) the amount of flexible space (“glue”) that TeX places between columns of an `\halign` or the rows of a `\valign`. Later articles will explore `\tabskip` in much more detail.

As an introductory example, the following code uses a setting for `\tabskip` which causes TeX to insert some (very) flexible space between the rows of a `\valign` table. That flexible space allows the table rows to spread out and fill the additional space created by the $$\langle$$⁠`optional specification`⁠$$\rangle$$ of **`to 50pt`**:

```latex
\documentclass{article}
\setlength{\fboxsep}{0pt}
\setlength{\parindent}{0pt}
\newcommand{\optspec}{\(\langle \texttt{optional specification} \rangle\)}
\begin{document}
\pagestyle{empty}
Here is a \verb|\valign| table:
\vspace{6pt}

\begingroup
\hsize=30pt
\parindent=10pt
\fbox{\valign{
#&#&#\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}}
\endgroup
\vspace{6pt}

Here is the same \verb|\valign| table but with an \optspec{} of ``\texttt{to 50pt}''. Note how the rows are ``bunched up'' because there's no available ``stretchable glue'' between the rows:

\vspace{6pt}
\begingroup
\hsize=30pt
\parindent=10pt
\fbox{\valign to 50pt{
#&#&#\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}}
\endgroup
\vspace{6pt}

We'll use the \verb|\valign| table with \optspec{} of ``\texttt{to 50pt}'', but provide ``flexible spacing'' via the \verb|\tabskip| command. Here, \verb|\tabskip| is providing enough ``glue'' to enable the  \verb|\valign| rows to  ``stretch out'' and fill any available extra space. Here is the ``stretched out'' \verb|\valign| table:

\tabskip=0pt plus1fil % This sets \tabskip to a very flexible glue
\vspace{6pt}

\def\mylen{50pt}
\begingroup
\hsize=30pt
\parindent=10pt
\fbox{\valign to \mylen{
#&#&#\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}}
\endgroup
\end{document}
```

[Open this example in Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Basic+example+using+tabskip+glue\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Csetlength%7B%5Cfboxsep%7D%7B0pt%7D%0A%5Csetlength%7B%5Cparindent%7D%7B0pt%7D%0A%5Cnewcommand%7B%5Coptspec%7D%7B%5C%28%5Clangle+%5Ctexttt%7Boptional+specification%7D+%5Crangle%5C%29%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bempty%7D%0AHere+is+a+%5Cverb%7C%5Cvalign%7C+table%3A%0A%5Cvspace%7B6pt%7D%0A%0A%5Cbegingroup%0A%5Chsize%3D30pt+%0A%5Cparindent%3D10pt%0A%5Cfbox%7B%5Cvalign%7B%0A%23%26%23%26%23%5Ccr%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%7D%0A%5Cendgroup%0A%5Cvspace%7B6pt%7D%0A%0AHere+is+the+same+%5Cverb%7C%5Cvalign%7C+table+but+with+an+%5Coptspec%7B%7D+of+%60%60%5Ctexttt%7Bto+50pt%7D%27%27.+Note+how+the+rows+are+%60%60bunched+up%27%27+because+there%27s+no+available+%60%60stretchable+glue%27%27+between+the+rows%3A+%0A%0A%5Cvspace%7B6pt%7D%0A%5Cbegingroup%0A%5Chsize%3D30pt+%0A%5Cparindent%3D10pt%0A%5Cfbox%7B%5Cvalign+to+50pt%7B%0A%23%26%23%26%23%5Ccr%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%7D%0A%5Cendgroup%0A%5Cvspace%7B6pt%7D%0A%0AWe%27ll+use+the+%5Cverb%7C%5Cvalign%7C+table+with+%5Coptspec%7B%7D+of+%60%60%5Ctexttt%7Bto+50pt%7D%27%27%2C+but+provide+%60%60flexible+spacing%27%27+via+the+%5Cverb%7C%5Ctabskip%7C+command.+Here%2C+%5Cverb%7C%5Ctabskip%7C+is+providing+enough+%60%60glue%27%27+to+enable+the++%5Cverb%7C%5Cvalign%7C+rows+to++%60%60stretch+out%27%27+and+fill+any+available+extra+space.+Here+is+the+%60%60stretched+out%27%27+%5Cverb%7C%5Cvalign%7C+table%3A%0A%0A%5Ctabskip%3D0pt+plus1fil+%25+This+sets+%5Ctabskip+to+a+very+flexible+glue%0A%5Cvspace%7B6pt%7D%0A%0A%5Cdef%5Cmylen%7B50pt%7D%0A%5Cbegingroup%0A%5Chsize%3D30pt+%0A%5Cparindent%3D10pt%0A%5Cfbox%7B%5Cvalign+to+%5Cmylen%7B%0A%23%26%23%26%23%5Ccr%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%7D%0A%5Cendgroup%0A%5Cend%7Bdocument%7D)

This example produces the following output:

![](/files/MnWawwPvFRNBlCjOr7Bz)

## Introducing the table $$\langle$$⁠preamble⁠$$\rangle$$ and $$\langle$$⁠body⁠$$\rangle$$

This section provides an introduction to the table $$\langle$$⁠`preamble`⁠$$\rangle$$, and *briefly* touches on the table $$\langle$$⁠`body`⁠$$\rangle$$ which is subsequently [explored in more detail](#bodydetails).

Later articles in this series will explore the $$\langle$$⁠`preamble`⁠$$\rangle$$ and $$\langle$$⁠`body`⁠$$\rangle$$ in more detail, particularly TeX's use and processing of the table $$\langle$$⁠`preamble`⁠$$\rangle$$.

As noted above, the most general format of `\halign` or `\valign` tables can be written as:

`\halign` $$\langle$$⁠`optional specification`⁠$$\rangle$$ { $$\langle$$⁠`preamble`⁠$$\rangle$$ $$\langle$$⁠`body`⁠$$\rangle$$ }

`\valign` $$\langle$$⁠`optional specification`⁠$$\rangle$$ { $$\langle$$⁠`preamble`⁠$$\rangle$$ $$\langle$$⁠`body`⁠$$\rangle$$ }

### The $$\langle$$⁠preamble⁠$$\rangle$$

The $$\langle$$⁠`preamble`⁠$$\rangle$$ section contains a single $$\langle$$⁠`preamble line`⁠$$\rangle$$ which is *terminated* by the `\cr` command; consequently, the $$\langle$$⁠`preamble`⁠$$\rangle$$ can be rewritten as:

$$\langle$$⁠`preamble`⁠$$\rangle$$=$$\langle$$⁠`preamble line`⁠$$\rangle$$**`\cr`**

### The $$\langle$$⁠body⁠$$\rangle$$

Similarly, the $$\langle$$⁠body⁠$$\rangle$$ section can be further broken down into one or more constituent "lines", but here there are two options for each line:

* a line consisting of set of cells which form an `\halign` row or `\valign` column; or
* a `\noalign` command which "injects" material between an `\halign`'s rows or `\valign`'s columns.

For present purposes we'll ignore the `\noalign` command (see [later in the article](#noalign)) and assume each line of the $$\langle$$⁠body⁠$$\rangle$$ is data for a set of cells and *terminated* by `\cr` command.

Ignoring `\noalign`, the $$\langle$$⁠`body`⁠$$\rangle$$ section, which represents the user's content, contains a sequence of lines, each of which we'll refer to as a $$\langle$$⁠`body line`⁠$$\rangle$$ that is *terminated* by its accompanying `\cr` command.

The $$\langle$$⁠`body`⁠$$\rangle$$ can be rewritten as:

$$\langle$$⁠body line$${}\_1$$⁠$$\rangle$$\cr $$\langle$$⁠body line$${}\_2$$⁠$$\rangle$$\cr $$\langle$$⁠body line$${}*3$$⁠$$\rangle$$\cr ... $$\langle$$⁠body line$${}*\mathrm{N}$$⁠$$\rangle$$\cr

Putting this together, we can rewrite the general format of `\halign` and `\valign` as:

`\halign` $$\langle$$⁠`optional specification`⁠$$\rangle$$ { $$\langle$$⁠`preamble line`⁠$$\rangle$$\cr $$\langle$$⁠body line$${}\_1$$⁠$$\rangle$$\cr $$\langle$$⁠body line$${}\_2$$⁠$$\rangle$$\cr $$\langle$$⁠body line$${}*3$$⁠$$\rangle$$\cr ... $$\langle$$⁠body line$${}*\mathrm{N}$$⁠$$\rangle$$\cr }

`\valign` $$\langle$$⁠`optional specification`⁠$$\rangle$$ { $$\langle$$⁠`preamble line`⁠$$\rangle$$\cr $$\langle$$⁠body line$${}\_1$$⁠$$\rangle$$\cr $$\langle$$⁠body line$${}\_2$$⁠$$\rangle$$\cr $$\langle$$⁠body line$${}*3$$⁠$$\rangle$$\cr ... $$\langle$$⁠body line$${}*\mathrm{N}$$⁠$$\rangle$$\cr }

For reasons that will addressed in later articles, the $$\langle$$⁠`preamble`⁠$$\rangle$$, just a single $$\langle$$⁠`preamble line`⁠$$\rangle$$, has a different format to all lines in the table $$\langle$$⁠`body`⁠$$\rangle$$. We'll also [re-visit the `\noalign` command](#noalign) which can also be used within the table $$\langle$$⁠`body`⁠$$\rangle$$.

### The $$\langle$$⁠preamble line⁠$$\rangle$$

The $$\langle$$⁠`preamble line`⁠$$\rangle$$ plays a *vital* role in typesetting tables because it provides a sort of “blueprint” used to typeset the content—`\halign` rows or `\valign` columns—contained in the table $$\langle$$⁠`body`⁠$$\rangle$$. The $$\langle$$⁠`preamble line`⁠$$\rangle$$ can also contain cell “templates” used to construct the rows of an `\halign` or columns of a `\valign`—a topic that will be explored in detail.

The purpose of the $$\langle$$⁠`preamble line`⁠$$\rangle$$ is two-fold:

* it determines the *maximum* number of cells per row of an `\halign` or per column of a `\valign`.
* it stores *cell templates* which can be used to automate formatting or content-inclusion within cells contained in the table $$\langle$$⁠`body`⁠$$\rangle$$. Cell templates are optional and can be "empty", or you can include characters or commands that TeX will automatically insert before and/or after the actual content of specific cells in your table. This saves you the tedium of having to manually write/include those characters or commands in every cell you want them to apply to.

**Note**: an `\halign` row or `\valign` column can contain fewer cells than the maximum specified by the $$\langle$$⁠`preamble line`⁠$$\rangle$$ but cannot contain more than that maximum, otherwise TeX generates an error. For present purposes we are omitting details of *cyclic* preambles.

Continuing with our structure diagrams, the $$\langle$$⁠`preamble line`⁠$$\rangle$$ for

* an `\halign` table with a maximum of $$\mathrm{K}$$ cells per *row*, or
* a `\valign` table with a maximum of $$\mathrm{K}$$ cells per *column*

can be written as:

$$\langle$$⁠template$${}\_1$$⁠$$\rangle$$&$$\langle$$⁠template$${}\_2$$⁠$$\rangle$$&$$\langle$$⁠template$${}*3$$⁠$$\rangle$$ $$\cdots$$ &$$\langle$$⁠template$${}*\mathrm{K}$$⁠$$\rangle$$

where `&` is the *alignment tab character* which indicates the end of one cell and the start of the next. Traditionally, the ampersand character (`&`) is used as the alignment tab but any character with [category code](/latex/more-topics/43-table-of-tex-category-codes.md) 4 could be used instead.

Just as a reminder, the $$\langle$$⁠`preamble`⁠$$\rangle$$ can be written $$\langle$$⁠`preamble`⁠$$\rangle$$=$$\langle$$⁠`preamble line`⁠$$\rangle$$**`\cr`**, or equivalently

$$\langle$$⁠`preamble`⁠$$\rangle$$=$$\langle$$⁠template$${}\_1$$⁠$$\rangle$$&$$\langle$$⁠template$${}\_2$$⁠$$\rangle$$&$$\langle$$⁠template$${}*3$$⁠$$\rangle$$ $$\cdots$$ &$$\langle$$⁠template$${}*\mathrm{K}$$⁠$$\rangle$$**`\cr`**

#### Structure of each cell $$\langle$$⁠template⁠$$\rangle$$

Each cell $$\langle$$⁠template$${}\_i$$⁠$$\rangle$$ can be written as:

$$\langle$$⁠$$\texttt{U}\_i$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_i$$⁠$$\rangle$$ where:

* $$\langle$$⁠$$\texttt{U}\_i$$⁠$$\rangle$$ is a set of characters or commands (tokens) that TeX will insert automatically *before* user-supplied content for cell $$i$$;
* $$\texttt{#}$$ is a placeholder, showing where user-supplied content is to appear in cell $$i$$. Again, the `#` character is just a *tradition*, any character with [category code](/latex/more-topics/43-table-of-tex-category-codes.md) 6 could be used instead. Note that category code 6 is used for macro parameters;
* $$\langle$$⁠$$\texttt{V}\_i$$⁠$$\rangle$$ is a set of characters or commands (tokens) that TeX will insert automatically *after* user-supplied content for cell $$i$$.

Note that all $$\langle$$⁠$$\texttt{U}\_i$$⁠$$\rangle$$ and $$\langle$$⁠$$\texttt{V}\_i$$⁠$$\rangle$$ are *optional*: you do not have to use any characters or commands before or after the cell's content.

**Completing the** $$\langle$$**⁠preamble⁠**$$\rangle$$

Finally, using the notation above, the $$\langle$$⁠`preamble`⁠$$\rangle$$ for

* an `\halign` table with a maximum of $$\mathrm{K}$$ cells per *row*, or
* a `\valign` table with a maximum of $$\mathrm{K}$$ cells per *column*

can be written as:

$$\langle$$⁠`preamble`⁠$$\rangle$$=$$\langle$$⁠`preamble line`⁠$$\rangle$$`**\cr**`

or

$$\langle$$⁠`preamble`⁠$$\rangle$$=$$\langle$$⁠$$\texttt{U}\_1$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_1$$⁠$$\rangle$$&$$\langle$$⁠$$\texttt{U}\_2$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_2$$⁠$$\rangle$$&$$\langle$$⁠$$\texttt{U}*3$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}*3$$⁠$$\rangle$$$$\cdots$$$$\langle$$⁠$$\texttt{U}*\mathrm{K}$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}*\mathrm{K}$$⁠$$\rangle$$`**\cr**`

**The** $$\langle$$**⁠preamble⁠**$$\rangle$$ **and counting of rows and columns**

An **`\halign`** table with a $$\langle$$⁠`preamble`⁠$$\rangle$$ specifying $$\mathrm{K}$$ cells and a $$\langle$$⁠`body`⁠$$\rangle$$ containing $$\mathrm{N}$$ $$\langle$$⁠`body lines`⁠$$\rangle$$ will produce a table with $$\mathrm{K}$$ *columns* and $$\mathrm{N}$$ *rows*, as shown in the following diagram:

![](/files/Dg4EqIgqjOe7rHauCjHE)

A **`\valign`** table with a $$\langle$$⁠`preamble`⁠$$\rangle$$ specifying $$\mathrm{K}$$ cells and a $$\langle$$⁠`body`⁠$$\rangle$$ containing $$\mathrm{N}$$ $$\langle$$⁠`body lines`⁠$$\rangle$$ will produce a table with $$\mathrm{K}$$ *rows* and $$\mathrm{N}$$ *columns*, as shown in the following diagram:

![](/files/K2lOekpM6JYc2lIl1DFE)

### Enough theory, some examples!

As we will later see in some detail, when TeX processes a table's content—table cells contained in the [$$\langle$$⁠`body`⁠$$\rangle$$](#body)—it checks for the presence of cell templates, which were defined in the $$\langle$$⁠`preamble`⁠$$\rangle$$, because TeX is looking for any template tokens to be inserted before and/or after the user's content. The following, minimal, examples demonstrate the use of cell templates $$\langle$$⁠$$\texttt{U}\_i$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_i$$⁠$$\rangle$$ in an `\halign` and `\valign` table.

#### An \halign table using cell templates

The following example demonstrates an `\halign` table which uses a cell template to automatically insert double quotes around the content of the first cell in every row: i.e., a template which affects every cell in the first column:

```latex
\documentclass{article}
\usepackage{parskip} % Set \parindent to 0pt
% Choose a conveniently small page size
\usepackage[paperheight=10cm,paperwidth=12cm,textwidth=8cm]{geometry}
\setlength{\tabskip}{20pt} % Space out the \halign columns
\begin{document}
\pagestyle{empty}

Here is an \verb|\halign| table \textit{without} cell templates:

\halign{
% Nothing before or after each '#' in the <preamble>
#&#&#\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}

Here is the same \verb|\halign| table but with double quotes automatically added to the first cell in each row; i.e., it affects every cell in the first column:

\halign{
% Quotation templates in the preamble:
``#''&#&#\cr % Double quote marks before and after first #
A&B&C\cr
D&E&F\cr
G&H&I\cr
}
\end{document}
```

[Open this example in Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=halign+example+of+cell+templates\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%7Bparskip%7D+%25+Set+%5Cparindent+to+0pt%0A%25+Choose+a+conveniently+small+page+size%0A%5Cusepackage%5Bpaperheight%3D10cm%2Cpaperwidth%3D12cm%2Ctextwidth%3D8cm%5D%7Bgeometry%7D%0A%5Csetlength%7B%5Ctabskip%7D%7B20pt%7D+%25+Space+out+the+%5Chalign+columns%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bempty%7D%0A%0AHere+is+an+%5Cverb%7C%5Chalign%7C+table+%5Ctextit%7Bwithout%7D+cell+templates%3A+%0A%0A%5Chalign%7B%0A%25+Nothing+before+or+after+each+%27%23%27+in+the+%3Cpreamble%3E%0A%23%26%23%26%23%5Ccr+%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%0A%0AHere+is+the+same+%5Cverb%7C%5Chalign%7C+table+but+with+double+quotes+automatically+added+to+the+first+cell+in+each+row%3B+i.e.%2C+it+affects+every+cell+in+the+first+column%3A+%0A%0A%5Chalign%7B%0A%25+Quotation+templates+in+the+preamble%3A%0A%60%60%23%27%27%26%23%26%23%5Ccr+%25+Double+quote+marks+before+and+after+first+%23%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%0A%5Cend%7Bdocument%7D)

This example produces the following output:

![](/files/0rNa45vhgGi7XhzqwoRw)

The following graphic is an annotated version of the `\halign` table produced by the example above; here, we compare the "formal" structure of a three-cell $$\langle$$⁠`preamble`⁠$$\rangle$$:

$$\langle$$⁠$$\texttt{U}\_1$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_1$$⁠$$\rangle$$&$$\langle$$⁠$$\texttt{U}\_2$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_2$$⁠$$\rangle$$&$$\langle$$⁠$$\texttt{U}\_3$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_3$$⁠$$\rangle$$`**\cr**`

with the actual $$\langle$$⁠`preamble`⁠$$\rangle$$ of ` ``#''&#&#**\cr** `, highlighting the presence, or absence, of cell templates:

![](/files/z86YUvDIVjwxqvEHV34n)

#### A \valign table using cell templates

The following example demonstrates a `\valign` table which uses a template for every cell to automatically insert digits surrounding the user's content.

```latex
\documentclass{article}
\usepackage{parskip} % Set \parindent to 0pt
% Choose a conveniently small page size
\usepackage[paperheight=14cm,paperwidth=12cm,textwidth=10cm]{geometry}
\setlength{\tabskip}{8pt} % Space out the \valign rows
\begin{document}
\pagestyle{empty}

Here is a \verb|\valign| table \textit{without} cell templates:

\begingroup
\hsize=25pt
\valign{
% Nothing before or after each '#' in
% the <preamble>
#&#&#\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}
\endgroup

Here is the same \verb|\valign| table but using cell templates to automatically insert digits into every cell:

\begingroup
\hsize=25pt
\valign{
% Digits inserted before and after every '#' in
% the <preamble>
1#2&3#4&5#6\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}
\endgroup
\end{document}
```

[Open this example in Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Example+of+valign+cell+templates\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%7Bparskip%7D+%25+Set+%5Cparindent+to+0pt%0A%25+Choose+a+conveniently+small+page+size%0A%5Cusepackage%5Bpaperheight%3D14cm%2Cpaperwidth%3D12cm%2Ctextwidth%3D10cm%5D%7Bgeometry%7D%0A%5Csetlength%7B%5Ctabskip%7D%7B8pt%7D+%25+Space+out+the+%5Cvalign+rows%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bempty%7D%0A%0AHere+is+a+%5Cverb%7C%5Cvalign%7C+table+%5Ctextit%7Bwithout%7D+cell+templates%3A%0A%0A%5Cbegingroup%0A%5Chsize%3D25pt%0A%5Cvalign%7B%0A%25+Nothing+before+or+after+each+%27%23%27+in+%0A%25+the+%3Cpreamble%3E%0A%23%26%23%26%23%5Ccr+%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%0A%5Cendgroup%0A%0AHere+is+the+same+%5Cverb%7C%5Cvalign%7C+table+but+using+cell+templates+to+automatically+insert+digits+into+every+cell%3A+%0A%0A%5Cbegingroup%0A%5Chsize%3D25pt%0A%5Cvalign%7B%0A%25+Digits+inserted+before+and+after+every+%27%23%27+in%0A%25+the+%3Cpreamble%3E%0A1%232%263%234%265%236%5Ccr+%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%0A%5Cendgroup%0A%5Cend%7Bdocument%7D)

This example produces the following output:

![](/files/9RrFyDwYq9NNov6OBcwZ)

The following graphic is an annotated version of the `\valign` table produced by the example above; here, we compare the "formal" structure of a three-cell $$\langle$$⁠`preamble`⁠$$\rangle$$:

$$\langle$$⁠$$\texttt{U}\_1$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_1$$⁠$$\rangle$$&$$\langle$$⁠$$\texttt{U}\_2$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_2$$⁠$$\rangle$$&$$\langle$$⁠$$\texttt{U}\_3$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_3$$⁠$$\rangle$$`**\cr**`

with the actual $$\langle$$⁠`preamble`⁠$$\rangle$$ of `1#2&3#4&5#6**\cr**`, highlighting the use of cell templates $$\langle$$⁠$$\texttt{U}\_i$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_i$$⁠$$\rangle$$:

![](/files/UbewJ8gpGTwR59icdbmD)

Note how the template for cell $$i$$ ($$\langle$$⁠$$\texttt{U}\_i$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_i$$⁠$$\rangle$$) is applied to the $$i$$th cell in every `\valign` column, resulting in all cells of the $$i$$th *row* being affected.

#### Styling text using cell templates

The next example uses the following $$\langle$$⁠`preamble`⁠$$\rangle$$ (cell templates) to style the text contained in each row or column:

`\textbf{#}&\textit{#}&\texttt{#}\cr`

If we compare this $$\langle$$⁠`preamble`⁠$$\rangle$$ to our "formal" structure of a three-cell $$\langle$$⁠`preamble`⁠$$\rangle$$:

$$\langle$$⁠$$\texttt{U}\_1$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_1$$⁠$$\rangle$$&$$\langle$$⁠$$\texttt{U}\_2$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_2$$⁠$$\rangle$$&$$\langle$$⁠$$\texttt{U}\_3$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_3$$⁠$$\rangle$$`**\cr**`

we can see that:

$$\langle$$⁠$$\texttt{U}\_1$$⁠$$\rangle$$=`\textbf{`

$$\langle$$⁠$$\texttt{V}\_1$$⁠$$\rangle$$=`}`

$$\langle$$⁠$$\texttt{U}\_2$$⁠$$\rangle$$=`\textit{`

$$\langle$$⁠$$\texttt{V}\_2$$⁠$$\rangle$$=`}`

$$\langle$$⁠$$\texttt{U}\_3$$⁠$$\rangle$$=`\texttt{`

$$\langle$$⁠$$\texttt{V}\_3$$⁠$$\rangle$$=`}`

Note how these cell templates, such as `\textbf{#}` resemble macros with a single parameter (the cell content).

```latex
A \verb|\valign| table with text styled using cell templates:

\begingroup
\hsize=25pt
\valign{
\textbf{#}&\textit{#}&\texttt{#}\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}
\endgroup

An \verb|\halign| table with text styled using cell templates:

\halign{
\textbf{#}&\textit{#}&\texttt{#}\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}
```

[Open this example in Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Styling+with+cell+templates\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%7Bparskip%7D+%25+Set+%5Cparindent+to+0pt%0A%25+Choose+a+conveniently+small+page+size%0A%5Cusepackage%5Bpaperheight%3D14cm%2Cpaperwidth%3D12cm%2Ctextwidth%3D6cm%5D%7Bgeometry%7D%0A%25+Space+out+the+%5Chalign+columns+or+%5Cvalign+rows%0A%5Csetlength%7B%5Ctabskip%7D%7B8pt%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bempty%7D%0AA+%5Cverb%7C%5Cvalign%7C+table+with+text+styled+using+cell+templates%3A%0A%0A%5Cbegingroup%0A%5Chsize%3D25pt%0A%5Cvalign%7B%0A%5Ctextbf%7B%23%7D%26%5Ctextit%7B%23%7D%26%5Ctexttt%7B%23%7D%5Ccr+%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%0A%5Cendgroup%0A%0AAn+%5Cverb%7C%5Chalign%7C+table+with+text+styled+using+cell+templates%3A%0A%0A%5Chalign%7B%0A%5Ctextbf%7B%23%7D%26%5Ctextit%7B%23%7D%26%5Ctexttt%7B%23%7D%5Ccr+%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%0A%5Cend%7Bdocument%7D)

This example produces the following output:

![](/files/J0O2VCLm875jAdykmg9z)

## More detail on the table $$\langle$$⁠body⁠$$\rangle$$

In the section [Introducing the table $$\langle$$⁠`preamble`⁠$$\rangle$$ and $$\langle$$⁠`body`⁠$$\rangle$$](#preamble) we saw how, if we temporarily ignore `\noalign`, the $$\langle$$⁠`body`⁠$$\rangle$$ of an `\halign` or `\valign` table consists of multiple lines, each designated $$\langle$$⁠body line$${}\_j$$⁠$$\rangle$$, where:

* each $$\langle$$⁠body line$${}\_j$$⁠$$\rangle$$ is terminated by the `\cr` command
* each $$\langle$$⁠body line$${}\_j$$⁠$$\rangle$$ of an `\halign` is a table row
* each $$\langle$$⁠body line$${}\_j$$⁠$$\rangle$$ of a `\valign` is a table column

The sequence of lines, $$\langle$$⁠body line$${}\_j$$⁠$$\rangle$$, where $$j=1\ldots\mathrm{N}$$, produces $$\mathrm{N}$$ rows of an `\halign` or $$\mathrm{N}$$ columns for a `\valign`. As summarized in the following diagram, a general $$\langle$$⁠`preamble`⁠$$\rangle$$ such as

$$\langle$$⁠`preamble`⁠$$\rangle$$=$$\langle$$⁠$$\texttt{U}\_1$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_1$$⁠$$\rangle$$&$$\langle$$⁠$$\texttt{U}\_2$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_2$$⁠$$\rangle$$&$$\langle$$⁠$$\texttt{U}*3$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}*3$$⁠$$\rangle$$$$\cdots$$$$\langle$$⁠$$\texttt{U}*\mathrm{K}$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}*\mathrm{K}$$⁠$$\rangle$$`**\cr**`

specifies cell templates for a maximum of $$\mathrm{K}$$ cells in each of the $$\mathrm{N}$$ $$\langle$$⁠`body line`⁠$$\rangle$$ entries in the $$\langle$$⁠`body`⁠$$\rangle$$:

![](/files/lNxqrNRKhzQYwi7BHxzj)

### The structure of each $$\langle$$⁠body line$${}\_j$$⁠$$\rangle$$

Each line $$\langle$$⁠body line$${}\_j$$⁠$$\rangle$$ of the table $$\langle$$⁠body⁠$$\rangle$$ contains content for up to $$\mathrm{K}$$ cells—as determined by the table $$\langle$$⁠preamble⁠$$\rangle$$—and has the general form:

$$\langle$$⁠body line$${}\_j$$⁠$$\rangle$$=$$\langle$$⁠Cell$${}\_1$$⁠$$\rangle$$$$\texttt{&}$$$$\langle$$⁠Cell$${}\_2$$⁠$$\rangle$$$$\texttt{&}$$$$\langle$$⁠Cell$${}*3$$⁠$$\rangle$$$$\texttt{&}$$$$\cdots$$$$\texttt{&}$$$$\langle$$⁠Cell$${}*\mathrm{K}$$⁠$$\rangle$$`**\cr**`

where:

* $$\langle$$⁠Cell$${}\_i$$⁠$$\rangle$$ represents the user's content for the $$i$$th cell in some $$\langle$$⁠body line$${}\_j$$⁠$$\rangle$$
* the **`&`** character is called the *alignment tab* (same as used in the $$\langle$$⁠preamble⁠$$\rangle$$) which signals the end of one cell and the start of the next. Once again, use of **`&`** is merely a tradition (convention) because any character with [category code](/latex/more-topics/43-table-of-tex-category-codes.md) 4 could be used instead.

Although each $$\langle$$⁠body line$${}\_j$$⁠$$\rangle$$ can contain a maximum $$\mathrm{K}$$ cells (determined by the $$\langle$$⁠preamble⁠$$\rangle$$) they can contain *fewer* than $$\mathrm{K}$$ cells and any $$\langle$$⁠Cell$${}\_i$$⁠$$\rangle$$ in $$\langle$$⁠body line$${}\_j$$⁠$$\rangle$$ can be empty.

The following example demonstrates a $$\langle$$⁠preamble⁠$$\rangle$$ of `#&#&#&#&#\cr` which provides for a maximum of 5 cells per $$\langle$$⁠body line⁠$$\rangle$$; however, the typeset tables contain lines with fewer than 5 cells:

```latex
A \verb|\valign| table with 1 to 5 cells per \textit{column}:

\begingroup
% \hsize controls the \valign column widths (size of typeset lines).
\hsize=40pt
\fbox{\valign{
% Use a preamble that allows for 5 cells per column
% Most columns don't provide content for 5 cells
#&#&#&#&#\cr% 5 cells per column
\(\mathrm{Cell}{}_1\)\cr
\(\mathrm{Cell}{}_1\)&\(\mathrm{Cell}{}_2\)\cr
\(\mathrm{Cell}{}_1\)&\(\mathrm{Cell}{}_2\)&\(\mathrm{Cell}{}_3\)\cr
\(\mathrm{Cell}{}_1\)&\(\mathrm{Cell}{}_2\)&\(\mathrm{Cell}{}_3\)&\(\mathrm{Cell}{}_4\)\cr
\(\mathrm{Cell}{}_1\)&\(\mathrm{Cell}{}_2\)&\(\mathrm{Cell}{}_3\)&\(\mathrm{Cell}{}_4\)&\(\mathrm{Cell}{}_5\)\cr
}}
\endgroup

% Note: for reasons explained later
% the \halign has to be put in a \vbox
An \verb|\halign| table with 1 to 5 cells per \textit{row}:

\fbox{%
\vbox{\halign{
% Use a preamble that allows for 5 cells per row
% Most rows don't provide content for 5 cells
#&#&#&#&#\cr % 5 cells per row
\(\mathrm{Cell}{}_1\)\cr
\(\mathrm{Cell}{}_1\)&\(\mathrm{Cell}{}_2\)\cr
\(\mathrm{Cell}{}_1\)&\(\mathrm{Cell}{}_2\)&\(\mathrm{Cell}{}_3\)\cr
\(\mathrm{Cell}{}_1\)&\(\mathrm{Cell}{}_2\)&\(\mathrm{Cell}{}_3\)&\(\mathrm{Cell}{}_4\)\cr
\(\mathrm{Cell}{}_1\)&\(\mathrm{Cell}{}_2\)&\(\mathrm{Cell}{}_3\)&\(\mathrm{Cell}{}_4\)&\(\mathrm{Cell}{}_5\)\cr
}}}
```

[Open this example in Overleaf](/latex/in-depth-articles/15-how-do-tex-engines-typeset-tables-2.md)

This example produces the following output:

![](/files/DXMMfMHIf053KrsOcd21)

The next `\halign` example demonstrates a varying number of cells per row and the ability for cells to be empty—note how empty cells are produced by consecutive **`&`** characters in the table:

```latex
An \verb|\halign| table with some empty cells---note there are consecutive \texttt{\&} characters in the table \(\langle\texttt{body}\rangle\):

\fbox{%
\vbox{\halign{
% Use a preamble that allows for 5 cells per row
% Most rows don't provide content for 5 cells
#&#&#&#&#\cr % 5 cells per row
\(\mathrm{Cell}{}_1\)\cr
\(\mathrm{Cell}{}_1\)&\(\mathrm{Cell}{}_2\)\cr
\(\mathrm{Cell}{}_1\)&&\(\mathrm{Cell}{}_3\)\cr
&\(\mathrm{Cell}{}_2\)&\(\mathrm{Cell}{}_3\)&\(\mathrm{Cell}{}_4\)\cr
\(\mathrm{Cell}{}_1\)&\(\mathrm{Cell}{}_2\)&&&\(\mathrm{Cell}{}_5\)\cr
}}}
```

[Open this example in Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Empty+cells+Number+of+cells+per+row\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%7Bparskip%7D+%25+Set+%5Cparindent+to+0pt%0A%25+Choose+a+conveniently+small+page+size%0A%5Cusepackage%5Bpaperheight%3D16cm%2Cpaperwidth%3D12cm%2Ctextwidth%3D8cm%5D%7Bgeometry%7D%0A%25+Space+out+the+%5Chalign+columns+and+%5Cvalign+rows%0A%5Csetlength%7B%5Ctabskip%7D%7B8pt%7D+%0A%25+Close-fitting+box+borders+%0A%5Csetlength%7B%5Cfboxsep%7D%7B0pt%7D%0A%5Cbegin%7Bdocument%7D%0AAn+%5Cverb%7C%5Chalign%7C+table+with+some+empty+cells---note+there+are+consecutive+%5Ctexttt%7B%5C%26%7D+characters+in+the+table+%5C%28%5Clangle%5Ctexttt%7Bbody%7D%5Crangle%5C%29%3A%0A%0A%5Cfbox%7B%25%0A%5Cvbox%7B%5Chalign%7B%0A%25+Use+a+preamble+that+allows+for+5+cells+per+row%0A%25+Most+rows+don%27t+provide+content+for+5+cells%0A%23%26%23%26%23%26%23%26%23%5Ccr+%25+5+cells+per+row%0A%5C%28%5Cmathrm%7BCell%7D%7B%7D_1%5C%29%5Ccr+%0A%5C%28%5Cmathrm%7BCell%7D%7B%7D_1%5C%29%26%5C%28%5Cmathrm%7BCell%7D%7B%7D_2%5C%29%5Ccr%0A%5C%28%5Cmathrm%7BCell%7D%7B%7D_1%5C%29%26%26%5C%28%5Cmathrm%7BCell%7D%7B%7D_3%5C%29%5Ccr%0A%26%5C%28%5Cmathrm%7BCell%7D%7B%7D_2%5C%29%26%5C%28%5Cmathrm%7BCell%7D%7B%7D_3%5C%29%26%5C%28%5Cmathrm%7BCell%7D%7B%7D_4%5C%29%5Ccr%0A%5C%28%5Cmathrm%7BCell%7D%7B%7D_1%5C%29%26%5C%28%5Cmathrm%7BCell%7D%7B%7D_2%5C%29%26%26%26%5C%28%5Cmathrm%7BCell%7D%7B%7D_5%5C%29%5Ccr%0A%7D%7D%7D%0A%5Cend%7Bdocument%7D)

This example produces the following output:

![](/files/KToXM4bVipd4SdHzIo4P)

### There’s nothing special about & and # in table typesetting

TeX’s use of the characters `&` and `#` within typesetting of `\halign`- or `\valign`-based tables is a tradition which originates from Knuth’s original plain TeX macros. It’s quite possible to use characters other than `&` and `#` by assigning the appropriate category codes to your preferred replacements, as the following example demonstrates:

* replacing `&` with `@` by assigning `@` to category code 4
* replacing `#` with `|` by assigning `|` to category code 6 (which is used for macro parameters)

Category changes are kept local by using `\begingroup` and `\endgroup`:

```latex
\documentclass{article}
\begin{document}
\begingroup
\catcode`@=4
\catcode`|=6
\halign{
|@|@|\cr
A@B@C\cr
D@E@F\cr
}
\endgroup
\end{document}
```

[Open this example in Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Tables+and+category+codes\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cbegingroup%0A%5Ccatcode%60%40%3D4%0A%5Ccatcode%60%7C%3D6%0A%5Chalign%7B%0A%7C%40%7C%40%7C%5Ccr%0AA%40B%40C%5Ccr%0AD%40E%40F%5Ccr%0A%7D%0A%5Cendgroup%0A%5Cend%7Bdocument%7D)

## Re-introducing the \noalign command

TeX engines provide the built-in (primitive) `\noalign` command:

`\noalign{`$$\langle$$⁠`tokens`⁠$$\rangle$$`}`

where $$\langle$$⁠`tokens`⁠$$\rangle$$ are characters and/or TeX/LaTeX commands. The `\noalign` command is exclusively for use within an `\halign` or `\valign` table: using it outside of these will generate an error.

The purpose of `\noalign` is to allow "insertion" of text and TeX/LaTeX commands *between* the rows of an `\halign` table or the columns of a `\valign` table. The most common use of `\noalign` is creation of table rules (lines):

* *horizontal* rules between `\halign` table rows
* *vertical* rules between `\valign` table columns

Note the following:

* the `\noalign` command is ***not terminated by the\*\*\*\*****&#x20;****`\cr`****&#x20;****\*\*\*\*command***
* the set of commands permitted within `\noalign{...}` is dependent on whether it is being used in the $$\langle$$⁠`body`⁠$$\rangle$$ of an `\halign` or `\valign` table (i.e., in a vertical or horizontal mode).

We can now say that the table $$\langle$$⁠`body`⁠$$\rangle$$ of `\halign` or `\valign` can consist of individual lines $$\langle$$⁠body line$${}\_i$$⁠$$\rangle$$`\cr` interspersed with `\noalign` commands; one of many possibilities/combinations could be:

`\noalign{`$$\langle$$⁠`tokens`⁠$$\rangle$$`}` $$\langle$$⁠body line$${}\_1$$⁠$$\rangle$$\cr $$\langle$$⁠body line$${}\_2$$⁠$$\rangle$$\cr `\noalign{`$$\langle$$⁠`more tokens`⁠$$\rangle$$`}` $$\langle$$⁠body line$${}*3$$⁠$$\rangle$$\cr ... $$\langle$$⁠body line$${}*\mathrm{N}$$⁠$$\rangle$$\cr `\noalign{`$$\langle$$⁠`other tokens`⁠$$\rangle$$`}`

### Example using \noalign

We will look at other use cases later in this article series but here is a basic example to demonstrate creating table rules via `\noalign`:

```latex
\setlength{\tabskip}{5pt}

Using \verb|\noalign| to place horizontal rules between rows of an \verb|\halign| table:
\vspace{6pt}

\halign{%
#&#&#&#&#\cr
\noalign{\hrule\kern2pt}
1&2&3&4&5\cr
\noalign{\kern2pt\hrule\kern2pt}
6&7&8&9&10\cr
\noalign{\kern2pt\hrule}
}

Using \verb|\noalign| to place vertical rules between columns of a \verb|\valign| table:
\vspace{6pt}

\begingroup % keep changes to \parindent and \hsize local
\parindent=0pt
\hsize=50pt
\valign{%
#&#&#&#&#\cr
\noalign{\vrule\kern2pt}
1&2&3&4&5\cr
\noalign{\kern2pt\vrule\kern2pt}
6&7&8&9&10\cr
\noalign{\kern2pt\vrule}
}
\endgroup
```

[Open this example in Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Example+of+the+noalign+command\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%5Bpaperheight%3D16cm%2Cpaperwidth%3D10cm%2Ctextwidth%3D6cm%5D%7Bgeometry%7D%0A%5Cusepackage%7Bverbatim%7D+%0A%5Cusepackage%7Bparskip%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bempty%7D%0A%5Csetlength%7B%5Ctabskip%7D%7B5pt%7D%0A%0AUsing+%5Cverb%7C%5Cnoalign%7C+to+place+horizontal+rules+between+rows+of+an+%5Cverb%7C%5Chalign%7C+table%3A%0A%5Cvspace%7B6pt%7D%0A%0A%5Chalign%7B%25%0A%23%26%23%26%23%26%23%26%23%5Ccr%0A%5Cnoalign%7B%5Chrule%5Ckern2pt%7D%0A1%262%263%264%265%5Ccr%0A%5Cnoalign%7B%5Ckern2pt%5Chrule%5Ckern2pt%7D%0A6%267%268%269%2610%5Ccr%0A%5Cnoalign%7B%5Ckern2pt%5Chrule%7D%0A%7D%0A%0AUsing+%5Cverb%7C%5Cnoalign%7C+to+place+vertical+rules+between+columns+of+a+%5Cverb%7C%5Cvalign%7C+table%3A%0A%5Cvspace%7B6pt%7D%0A%0A%5Cbegingroup+%25+keep+changes+to+%5Cparindent+and+%5Chsize+local%0A%5Cparindent%3D0pt%0A%5Chsize%3D50pt%0A%5Cvalign%7B%25%0A%23%26%23%26%23%26%23%26%23%5Ccr%0A%5Cnoalign%7B%5Cvrule%5Ckern2pt%7D%0A1%262%263%264%265%5Ccr%0A%5Cnoalign%7B%5Ckern2pt%5Cvrule%5Ckern2pt%7D%0A6%267%268%269%2610%5Ccr%0A%5Cnoalign%7B%5Ckern2pt%5Cvrule%7D%0A%7D%0A%5Cendgroup%0A%5Cend%7Bdocument%7D)

This example produces the following output:

![](/files/aIS0QBg9IExEWjpGSNCR)

## \tabskip revisited

We'll take a closer look at the `\tabskip` command, building on the [introduction in a previous section](#tabskip).

The `\tabskip` command sets the value of a special form of "spacing" (glue) used *exclusively* in typesetting tables: its purpose is to provide spacing between table rows or columns:

* for `\halign` tables: `\tabskip` glue is inserted before and after the table (i.e., to the left and right) and between the table columns
* for `\valign` tables: `\tabskip` glue is inserted before and after the table (i.e., above and below) and between the table rows

The value of `\tabskip` can be set using the LaTeX `\setlength` command:

`\setlength{\tabskip}{`$$\langle$$⁠`glue value`⁠$$\rangle$$`}`

where $$\langle$$⁠`glue value`⁠$$\rangle$$ can be:

* a fixed length such as `5pt`, `3mm`, or
* a finite flexible glue such as `3pt plus 2pt minus 1pt`, or
* an infinitely flexible glue such as `0pt plus1fill`.

You can also directly set `\tabskip` (bypassing `\setlength`) by writing

`\tabskip`=$$\langle$$⁠`glue value`⁠$$\rangle$$

However, any change to the value of `\tabskip` glue will only affect table spacing when that change is:

* made *before* the `\halign` or `\valign` command to be processed, or
* made within the table $$\langle$$⁠`preamble`⁠$$\rangle$$

Attempts to set `\tabskip` values inside the table content (cells in the table $$\langle$$⁠`body`⁠$$\rangle$$) *will not* change the spacing of `\halign` table columns or `\valign` table rows. The reason for this behaviour of `\tabskip` can be traced to the role played by the $$\langle$$⁠`preamble`⁠$$\rangle$$ during table typesetting—processes we'll later explore in some detail.

### Seeing is believing

To help visualize the presence of various types of spacing/glue used in typesetting tables, especially

* `\tabskip` glue
* `\baselineskip` glue
* manual kerning (`\kern`)

Overleaf prepared a LuaTeX-based project to colourize the components of a table. LuaTeX was chosen because it enables low-level re-processing of the internal data/structures of typeset tables but we won't explore those details here.

Here are some examples which show various applications of `\tabskip`. For each example we'll show the actual output and the colourized version produced by LuaTeX.

### \tabskip example 1

Let's examine the use of `\tabskip` in an `\halign` and `\valign` table. We'll show the actual typeset tables, with a border to visualize their size and spacing, together with annotated graphics containing colourized versions which clearly show the size of various glues/spacing in each table.

Firstly, the `\halign`:

```latex
% To visualize the table's extent we'll put a border around it
\setlength{\fboxsep}{0pt} % Use close-fitting borders

% Here we set \tabskip "directly"
\tabskip5pt % Set the initial \tabskip value outside the table

% To put a border around the table it has to be saved to a TeX box.
% An \halign has to be placed in a \vbox because \halign must be
% processed in a "vertical mode": an \hbox will not work because
% that is processed in a "horizontal mode"

\fbox{\vbox{\halign{
\tabskip10pt#&
\tabskip15pt#&
\tabskip20pt#\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}}}
```

[Open this example in Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Tabskip+glue+in+an+halign\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%5Bpaperheight%3D16cm%2Cpaperwidth%3D10cm%2Ctextwidth%3D6cm%5D%7Bgeometry%7D%0A%5Cusepackage%7Bverbatim%7D+%0A%5Cusepackage%7Bparskip%7D+%25+sets+%5Cparindent+to+0pt%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bempty%7D%0A%25+To+visualize+the+table%27s+extent+we%27ll+put+a+border+around+it+%0A%5Csetlength%7B%5Cfboxsep%7D%7B0pt%7D+%25+Use+close-fitting+borders%0A%0A%25+Here+we+set+%5Ctabskip+%22directly%22%0A%5Ctabskip5pt+%25+Set+the+initial+%5Ctabskip+value+outside+the+table%0A%0A%25+To+put+a+border+around+the+table+it+has+to+be+saved+to+a+TeX+box.%0A%25+An+%5Chalign+has+to+be+placed+in+a+%5Cvbox+because+%5Chalign+must+be+%0A%25+processed+in+a+%22vertical+mode%22%3A+an+%5Chbox+will+not+work+because%0A%25+that+is+processed+in+a+%22horizontal+mode%22%0A%0A%5Cfbox%7B%5Cvbox%7B%5Chalign%7B%0A%5Ctabskip10pt%23%26%0A%5Ctabskip15pt%23%26%0A%5Ctabskip20pt%23%5Ccr%0AA%26B%26C%5Ccr%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%7D%7D%0A%5Cend%7Bdocument%7D)

This example produces the following output:

![](/files/uFuVHIJAjxWebcoGfbD6)

The next graphic is a larger, colourized and annotated version of the table produced by the previous example:

![](/files/RGx8E7iVR68zt4Ayk1tv)

There are 4 instances of the `\tabskip` command, each one corresponds to a particular location of spacing within the table:

1. `\tabskip5pt` is used outside the table and sets the `\tabskip` value applied before (to the left of) the first cell in each row.
2. `\tabskip10pt` is set in the first cell template of the $$\langle$$⁠`preamble`⁠$$\rangle$$ which affects the space between $$\langle$$⁠Cell$${}\_1$$⁠$$\rangle$$ and $$\langle$$⁠Cell$${}\_2$$⁠$$\rangle$$ of every row.
3. `\tabskip15pt` is set in the second cell template of the $$\langle$$⁠`preamble`⁠$$\rangle$$ which affects the space between $$\langle$$⁠Cell$${}\_2$$⁠$$\rangle$$ and $$\langle$$⁠Cell$${}\_3$$⁠$$\rangle$$ of every row.
4. `\tabskip20pt` is set in the third, and final, cell template of the $$\langle$$⁠`preamble`⁠$$\rangle$$ which affects the space added after $$\langle$$⁠Cell$${}\_3$$⁠$$\rangle$$, the final cell of every row.

Next, the `\valign`

```latex
\setlength{\fboxsep}{0pt} % Use close-fitting borders
\tabskip5pt % Set the initial \tabskip value outside the table

% Keep changes to \hsize local (in a group)
\begingroup
% \hsize determines the \valign column widths
\setlength{\hsize}{50pt}
% Because \valign can be placed in a \vbox or \hbox we can use
% \fbox directly
\fbox{\valign{
\tabskip10pt#&
\tabskip15pt#&
\tabskip20pt#\cr
A&B&C\cr
E&E&F\cr
G&H&I\cr
}}
\endgroup
```

[Open this example in Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Example+halign\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%5Bpaperheight%3D16cm%2Cpaperwidth%3D10cm%2Ctextwidth%3D6cm%5D%7Bgeometry%7D%0A%5Cusepackage%7Bverbatim%7D+%0A%5Cusepackage%7Bparskip%7D+%25+sets+%5Cparindent+to+0pt%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bempty%7D%0A%5Csetlength%7B%5Cfboxsep%7D%7B0pt%7D+%25+Use+close-fitting+borders%0A%5Ctabskip5pt+%25+Set+the+initial+%5Ctabskip+value+outside+the+table%0A%0A%25+Keep+changes+to+%5Chsize+local+%28in+a+group%29%0A%5Cbegingroup%0A%25+%5Chsize+determines+the+%5Cvalign+column+widths%0A%5Csetlength%7B%5Chsize%7D%7B50pt%7D+%0A%25+Because+%5Cvalign+can+be+placed+in+a+%5Cvbox+or+%5Chbox+we+can+use+%0A%25+%5Cfbox+directly%0A%5Cfbox%7B%5Cvalign%7B%0A%5Ctabskip10pt%23%26%0A%5Ctabskip15pt%23%26%0A%5Ctabskip20pt%23%5Ccr%0AA%26B%26C%5Ccr%0AE%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%7D%7D%0A%5Cendgroup%0A%5Cend%7Bdocument%7D)

This example produces the following output:

![](/files/eaNKRR7mWM6Vairbopd5)

Again, the next graphic is a larger, colourized and annotated version of the table produced by the previous example:

![](/files/qgeRUslOjDiBI1P0U4pn)

As with the `\halign` example, there are 4 instances of the `\tabskip` command. However, with a `\valign` table the `\tabskip` is inserted between the table rows:

1. `\tabskip5pt` is used outside the table and sets the `\tabskip` value applied before (above) the first cell in each column.
2. `\tabskip10pt` is set in the first cell template of the $$\langle$$⁠`preamble`⁠$$\rangle$$ which affects the space between $$\langle$$⁠Cell$${}\_1$$⁠$$\rangle$$ and $$\langle$$⁠Cell$${}\_2$$⁠$$\rangle$$ of every column.
3. `\tabskip15pt` is set in the second cell template of the $$\langle$$⁠`preamble`⁠$$\rangle$$ which affects the space between $$\langle$$⁠Cell$${}\_2$$⁠$$\rangle$$ and $$\langle$$⁠Cell$${}\_3$$⁠$$\rangle$$ of every column.
4. `\tabskip20pt` is set in the third, and final, cell template of the $$\langle$$⁠`preamble`⁠$$\rangle$$ which affects the space added after $$\langle$$⁠Cell$${}\_3$$⁠$$\rangle$$, the final cell of every column.

**Summary/conclusions**

* In an `\halign` table the `\tabskip` glue is placed to the left and right of each cell in a row, thus spacing out the table columns.
* In a `\valign` table the `\tabskip` glue is placed above and below each cell in a column, thus spacing out the table rows.

### \tabskip and \noalign

#### Using an \halign

The following `\halign` example uses `\tabskip` glues and also demonstrates the `\noalign` command, using it to place spaced rules above and below the rows of an `\halign` table. Those rules are typeset using the `\hrule` (primitive) command together with space created by `\kern`:

```latex
\setlength{\tabskip}{5pt} % Set \tabskip outside of the table

\halign{
#&#&#&#&#\cr % The <preamble>
\noalign{\hrule\kern2pt} % Spaced rule before row 1
1&2&3&4&5\cr % Row 1
\noalign{\kern2pt\hrule\kern2pt} % Spaced rule between rows 1/2
6&7&8&9&10\cr % Row 2
\noalign{\kern2pt\hrule\kern2pt} % Spaced rule between rows 2/3
11&12&13&14&15\cr % Row 3
16&17&18&19&20\cr % Row 4---no rules between rows 3/4
\noalign{\kern2pt\hrule} % Space rule at table end
}
```

[Open this example in Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Example+halign\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%5Bpaperheight%3D16cm%2Cpaperwidth%3D10cm%2Ctextwidth%3D6cm%5D%7Bgeometry%7D%0A%5Cusepackage%7Bverbatim%7D+%0A%5Cusepackage%7Bparskip%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bempty%7D%0A%5Csetlength%7B%5Ctabskip%7D%7B5pt%7D+%25+Set+%5Ctabskip+outside+of+the+table%0A%0A%5Chalign%7B%0A%23%26%23%26%23%26%23%26%23%5Ccr+%25+The+%3Cpreamble%3E%0A%5Cnoalign%7B%5Chrule%5Ckern2pt%7D+%25+Spaced+rule+before+row+1%0A1%262%263%264%265%5Ccr+%25+Row+1%0A%5Cnoalign%7B%5Ckern2pt%5Chrule%5Ckern2pt%7D+%25+Spaced+rule+between+rows+1%2F2+%0A6%267%268%269%2610%5Ccr+%25+Row+2%0A%5Cnoalign%7B%5Ckern2pt%5Chrule%5Ckern2pt%7D+%25+Spaced+rule+between+rows+2%2F3+%0A11%2612%2613%2614%2615%5Ccr+%25+Row+3%0A16%2617%2618%2619%2620%5Ccr+%25+Row+4---no+rules+between+rows+3%2F4%0A%5Cnoalign%7B%5Ckern2pt%5Chrule%7D+%25+Space+rule+at+table+end%0A%7D%0A%5Cend%7Bdocument%7D)

This example produces the table shown below, which has been further annotated to reproduce the (La)TeX code and numbers (1) to (4) to enumerate the `\noalign` commands, containing rules and kerns, together with their corresponding typeset output:

![](/files/P3hdX2qyC4udwozgj5a4)

The following graphic shows a colourized version of the table labelled to show the various spacings/glues in the table:

![](/files/RS3Ix9lspyluNBxMdcrL)

Note the following:

* the use of `\noalign` to insert rules between certain rows and the manual use of `\kern` values to put some space before/after the rules. TeX engines do not insert `\baselineskip` glue following a typeset rule which why space is manually inserted using `\kern` (other spacing commands could be used);
* `\baselineskip` glue was automatically inserted between rows 3 and 4.

#### Using a \valign

The following `\valign` example uses the same data as the previous `\halign`:

```latex
\begingroup
\setlength{\parindent}{10pt}
\setlength{\hsize}{50pt}
\setlength{\tabskip}{5pt}
\valign{
#&#&#&#&#\cr
\noalign{\vrule\kern2pt}
1&2&3&4&5\cr
\noalign{\kern2pt\vrule\kern2pt}
6&7&8&9&10\cr
\noalign{\kern2pt\vrule\kern2pt}
11&12&13&14&15\cr
16&17&18&19&20\cr
\noalign{\kern2pt\vrule}
}
\endgroup
```

[Open this example in Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Example+halign\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%5Bpaperheight%3D16cm%2Cpaperwidth%3D12cm%2Ctextwidth%3D10cm%5D%7Bgeometry%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bempty%7D%0A%5Cbegingroup%0A%5Csetlength%7B%5Cparindent%7D%7B10pt%7D%0A%5Csetlength%7B%5Chsize%7D%7B50pt%7D%0A%5Csetlength%7B%5Ctabskip%7D%7B5pt%7D%0A%5Cvalign%7B%0A%23%26%23%26%23%26%23%26%23%5Ccr%0A%5Cnoalign%7B%5Cvrule%5Ckern2pt%7D%0A1%262%263%264%265%5Ccr%0A%5Cnoalign%7B%5Ckern2pt%5Cvrule%5Ckern2pt%7D%0A6%267%268%269%2610%5Ccr%0A%5Cnoalign%7B%5Ckern2pt%5Cvrule%5Ckern2pt%7D%0A11%2612%2613%2614%2615%5Ccr%0A16%2617%2618%2619%2620%5Ccr%0A%5Cnoalign%7B%5Ckern2pt%5Cvrule%7D%0A%7D%0A%5Cendgroup%0A%5Cend%7Bdocument%7D)

This example produces the table shown below, which has been further annotated to reproduce the (La)TeX code and numbers (1) to (4) to enumerate the `\noalign` commands, containing rules and kerns, together with their corresponding typeset output:

![](/files/Qcixq4RhECNAyUSInGOd)

![](/files/ReiHJgI7U1AwMC7YHaXs)

### A \valign table with lines of text

The next example

```latex
\setlength{\tabskip}{5pt}
\begingroup % Keep changes to \parindent and \hsize local
\setlength{\parindent}{10pt}
\setlength{\hsize}{75pt}
\valign{
#&#&#\cr
\noalign{\vrule\kern5pt}
\TeX{} can typeset very complex
tables.&Here's a bit of extra
text.&And, finally, an extra line
in this column.\cr
\noalign{\kern5pt\vrule\kern5pt}
A&B&C\cr
\noalign{\kern5pt\vrule\kern5pt}
D&E&F\cr
G&H&I\cr
\noalign{\kern5pt\vrule}
}
\endgroup
```

[Open this example in Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Example+valign+command\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%5Bpaperheight%3D16cm%2Cpaperwidth%3D16cm%2Ctextwidth%3D12cm%5D%7Bgeometry%7D%0A%5Cbegin%7Bdocument%7D%0A%5Csetlength%7B%5Ctabskip%7D%7B5pt%7D%0A%5Cbegingroup+%25+Keep+changes+to+%5Cparindent+and+%5Chsize+local%0A%5Csetlength%7B%5Cparindent%7D%7B10pt%7D%0A%5Csetlength%7B%5Chsize%7D%7B75pt%7D%0A%5Cvalign%7B%0A%23%26%23%26%23%5Ccr%0A%5Cnoalign%7B%5Cvrule%5Ckern5pt%7D%0A%5CTeX%7B%7D+can+typeset+very+complex%0Atables.%26Here%27s+a+bit+of+extra+%0Atext.%26And%2C+finally%2C+an+extra+line%0Ain+this+column.%5Ccr%0A%5Cnoalign%7B%5Ckern5pt%5Cvrule%5Ckern5pt%7D%0AA%26B%26C%5Ccr%0A%5Cnoalign%7B%5Ckern5pt%5Cvrule%5Ckern5pt%7D%0AD%26E%26F%5Ccr%0AG%26H%26I%5Ccr%0A%5Cnoalign%7B%5Ckern5pt%5Cvrule%7D%0A%7D%0A%5Cendgroup%0A%5Cend%7Bdocument%7D)

This example produces the following output:

## Setting row widths and column heights

## More on the table $$\langle$$⁠preamble⁠$$\rangle$$


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://overleaf-pro.ayaka.space/latex/in-depth-articles/15-how-do-tex-engines-typeset-tables-2.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
