> 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/ru/podrobnye-stati/15-how-do-tex-engines-typeset-tables-2.md).

# Как движки TeX верстают таблицы 2

## Как движки TeX верстают таблицы 2

## Движки TeX называют таблицы выравниваниями

В [документация исходного кода TeX](https://www.overleaf.com/latex/examples/typeset-the-source-code-documentation-for-tex-e-tex-or-pdftex/qkgfgyspnhcv) Кнут не обсуждает способность TeX «верстать таблицы», а вместо этого описывает алгоритмы TeX для построения так называемых *выравниваний*. Верстка таблиц в TeX, по сути, представляет собой автоматизированный процесс выравнивания коробок: размещение коробок (ячеек, строк и столбцов таблицы) для получения приятной прямоугольной сетки или массива — хотя, конечно, в TeX есть *множеством* нюансы в этом процессе.

Термин «выравнивание» отражается и в названиях двух команд верстки таблиц, встроенных во все движки TeX:

* `\halign` (горизонтальное выравнивание), и
* `\valign` (вертикальное выравнивание).

Мы рассмотрим обе команды в течение этой серии статей, начав с более формального обзора формата/структуры `\halign` и `\valign` команд, чтобы заложить основу для более поздних, подробных, статей в этой серии.

### Таблицы TeX — это коробки и пробелы

Отдельные ячейки таблицы обычно содержат разный контент, например строки текста, формулы или графику, что приводит к набору ячеек таблицы, имеющих различную ширину, высоту или глубину набранного материала. TeX каким-то образом должен работать с этими ячейками, различающимися по размерам содержимого, чтобы построить итоговую таблицу, где каждая строка имеет определенную высоту, а каждый столбец — определенную ширину. TeX должен вывести подходящие значения высоты каждой строки и ширины каждого столбца из набора ячеек таблицы переменного размера.

Однако TeX не может узнать истинный размер содержимого каждой ячейки, пока это содержимое не будет набрано; следовательно, TeX проходит по всей таблице, набирая каждую ячейку, чтобы получить данные о размерах, необходимые для завершения макета таблицы. На основе этих данных о размере TeX может определить правильную высоту каждой строки и ширину каждого столбца. TeX также может столкнуться с пустыми ячейками или ячейками, которые пользователь хочет растянуть на несколько столбцов или несколько строк, и все это TeX должен тщательно учитывать в своих вычислениях. После «фильтрации» этого разнородного набора данных о размерах ячеек (коробок) только тогда TeX способен определить итоговые значения ширины столбцов в `\halign`, или высоты строк для `\valign` и использует эти значения на заключительных этапах своих алгоритмов верстки таблиц.

На практике и «под капотом» верстка таблиц в TeX состоит из нескольких шагов. В общих чертах TeX сначала набирает «черновую» или «неполную» версию таблицы, одновременно собирая и обрабатывая данные о размерах ячеек — а также данные о любых `\span` командах, используемых в таблице. На финальных этапах TeX повторно обрабатывает эту «неполную» версию таблицы, чтобы окончательно определить `\halign` ширину столбцов или `\valign` высоту строк и получить завершенный макет — все это мы рассмотрим в этой серии статей.

## \halign и \valign: два способа строить таблицы

Все движки TeX предоставляют две *встроенная* команды (примитивы), предназначенные для верстки таблиц (выравниваний): `\halign` и `\valign`, которые имеют много общих основных свойств, но также и фундаментально отличаются друг от друга. Ключевое различие между `\halign` и `\valign` заключается в том, как они строят соответствующие таблицы: построчно или по столбцам:

* `\halign`: верстает таблицы построчно, создавая отдельные строки, которые складываются вертикально и образуют столбцы таблицы
* `\valign`: верстает таблицы по столбцам, создавая отдельные столбцы, которые складываются горизонтально и образуют строки таблицы

### \halign

Следующая диаграмма показывает построение таблицы, созданной с помощью `\halign`. Таблица набирается построчно, при этом отдельные строки складываются вертикально. Некоторые следствия этого таковы:

* столбцы таблицы возникают из вертикального сложения строк таблицы
* разрывы страниц могут происходить между строками таблицы
* между строками можно вставлять нетабличный материал (с помощью `\nolign`, который мы рассмотрим позже)

![](/files/10a48161d16cc2d80b972c57cbc8bb666df02d68)

### \valign

Следующая диаграмма показывает построение таблицы, созданной с помощью `\valign`. Таблица набирается по столбцам, при этом отдельные столбцы складываются горизонтально (рядом друг с другом). Некоторые следствия этого таковы:

* строки таблицы возникают из горизонтального сложения столбцов таблицы
* разрывы строк могут происходить между столбцами таблицы
* между столбцами можно вставлять нетабличный материал (с помощью `\noalign`, который мы рассмотрим позже)

![](/files/597e6eae038460b5ed094452d817f4aac1a29739)

### Примеры

Следующий пример призван подчеркнуть построчный *против*постолбцовый подход \halign и \valign.

```latex
\documentclass{article}
\begin{document}
\pagestyle{empty}
% Плотно прилегающие границы коробок
\setlength{\fboxsep}{0pt}

Вот таблица \verb|\valign|:
\begingroup
% \hsize управляет \valign
% шириной столбцов. Мы также устанавливаем
% \parindent в меньшее значение
\hsize=30pt
\parindent=10pt
\fbox{\valign{
#&#&#\cr % Преамбула: будет рассмотрена позже (очень подробно!)
A&B&C\cr % Первый СТОЛБЕЦ этой таблицы \valign
D&E&F\cr
G&H&I\cr
}}
\endgroup

% Примечание: по причинам, объясняемым позже
% \halign нужно поместить в \vbox
Вот таблица \verb|\halign|: \fbox{%
\vbox{\halign{
#&#&#\cr % Преамбула: будет рассмотрена позже (очень подробно!)
A&B&C\cr % Первая СТРОКА этой таблицы \halign
D&E&F\cr
G&H&I\cr
}}}
\end{document}
```

[Откройте этот пример в 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)

Этот пример выдаёт следующий результат: ![](/files/c25d955e880ac89547b99d39e1a34b87f872671d)

Следующая графика показывает аннотированную версию таблиц, созданных кодом выше. Позже в этой серии статей мы рассмотрим такие темы, как:

* что такое преамбулы таблиц?
* почему мы задаем `\hsize` и `\parindent` для `\valign` таблицы?

Для наших текущих целей просто отметим построчный vs. постолбцовый подход `\halign` *против*. `\valign` к построению таблиц:

![](/files/1f1d10f4987e277a8163dccdc5d9ceccb418cb75)

## Общий вид \halign и \valign

Для начала мы рассмотрим основные свойства и общий формат `\halign` и `\valign` но пока не будем вдаваться в какие-либо реальные подробности. [Как уже отмечалось](#intro), мы принимаем немного более формальный обзор формы/структуры `\halign` и `\valign` команд, чтобы заложить основу для последующих статей в этой серии.

Наиболее общий вид `\halign` и `\valign` команд можно записать так:

`\halign` $$\langle$$⁠`необязательное указание`⁠$$\rangle$$ { $$\langle$$⁠`преамбуле`⁠$$\rangle$$ $$\langle$$⁠`тело`⁠$$\rangle$$ }

`\valign` $$\langle$$⁠`необязательное указание`⁠$$\rangle$$ { $$\langle$$⁠`преамбуле`⁠$$\rangle$$ $$\langle$$⁠`тело`⁠$$\rangle$$ }

Как видите, обе `\halign` и `\valign` состоят из трех основных разделов:

* [$$\langle$$⁠`необязательное указание`⁠$$\rangle$$](#optspec)
* [$$\langle$$⁠`преамбуле`⁠$$\rangle$$](#preamble)
* [$$\langle$$⁠`тело`⁠$$\rangle$$](#body)

## Это $$\langle$$⁠необязательное указание⁠$$\rangle$$

Размер таблицы по умолчанию, так называемый «естественный размер», определяется ее содержимым — уточним, под размером/протяженностью мы имеем в виду

* окружения *ширина* таблицы, создаваемой с помощью `\halign`, или
* окружения *высота* таблицы, создаваемой с помощью `\valign`

Дополнение $$\langle$$⁠`необязательное указание`⁠$$\rangle$$ может использоваться для «переопределения» естественного размера таблицы и принимает одну из двух форм:

* **`на`** $$\langle$$**⁠`размер`⁠**$$\rangle$$
* **`spread`** $$\langle$$**⁠`размер`⁠**$$\rangle$$

где

* $$\langle$$**⁠`размер`⁠**$$\rangle$$ — это длина, заданная в единицах, понятных TeX, например pt, mm или cm; длина также может быть указана как команда, разворачивающаяся в значение, заданное в подходящих единицах;
* **`на`** и **`spread`** — это ключевые слова TeX, указывающие тип «переопределения» естественного размера:
  * **`на`**: задает размер таблицы равным указанной $$\langle$$⁠`размер`⁠$$\rangle$$ значения
  * **`spread`**: добавляет указанное $$\langle$$⁠`размер`⁠$$\rangle$$ значение к естественному размеру таблицы

Эффект $$\langle$$⁠`необязательное указание`⁠$$\rangle$$ зависит от типа верстаемой таблицы: он будет корректировать `\halign` естественную *ширина*, или `\valign` естественную *высота*.

Вот несколько примеров:

* `\halign **to 100pt**{...}`: задает `\halign` ширину таблицы равной `100pt`
* `\valign **to 50pt**{...}`: задает `\valign` высоту таблицы равной `30pt`
* `\halign **spread 30pt**{...}`: добавляет 30pt к `\halign` естественной ширине таблицы. И наоборот, запись **spread -30pt** уменьшила бы ширину таблицы на 30pt.
* `\valign **spread 20pt**{...}`: добавляет 20pt к `\valign` естественной высоте таблицы. И наоборот, запись **spread -20pt** уменьшила бы высоту таблицы на 20pt.

Следующий код повторно использует приведенные выше примеры таблиц, но применяет $$\langle$$⁠`необязательное указание`⁠$$\rangle$$ к `\valign` и `\halign` таблице:

```latex
\documentclass{article}
\begin{document}
\pagestyle{empty}
% Плотно прилегающие границы коробок
\setlength{\fboxsep}{0pt}

Вот таблица \verb|\valign|:
\begingroup
\hsize=30pt
\parindent=10pt
\fbox{\valign to 50pt{
#&#&#\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}}
\endgroup

Вот таблица \verb|\halign|:
\fbox{%
\vbox{\halign to 100pt{
#&#&#\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}}}
\end{document}
```

[Откройте этот пример в 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)

Этот пример дает результат, показанный ниже:

![](/files/840d628cbb0e8056da0cf2de1c3ec3ebbdcb59cb)

—но обратите внимание, как содержимое обеих таблиц «сбивается в кучу». Причина в отсутствии гибкого пробела (glue), который TeX может использовать, чтобы растянуть содержимое и заполнить дополнительное пространство, предоставленное **`на`** $$\langle$$**⁠`размер`⁠**$$\rangle$$. Здесь мы забежим вперед, чтобы упомянуть `\tabskip` команды.

#### Первое знакомство с командой \tabskip

Эстетика макета таблицы может требовать корректировки интервалов между ее строками или столбцами, так что, неудивительно, движки TeX предоставляют команду под названием `\tabskip` которая позволяет это делать. `\tabskip` используется для задания (и изменения) величины гибкого пространства («glue»), которое TeX помещает между столбцами `\halign` или строками `\valign`. Позднее статьи рассмотрят `\tabskip` гораздо подробнее.

В качестве вводного примера следующий код использует настройку для `\tabskip` которая заставляет TeX вставлять некоторое (очень) гибкое пространство между строками `\valign` таблицы. Это гибкое пространство позволяет строкам таблицы раздвинуться и заполнить дополнительное пространство, созданное $$\langle$$⁠`необязательное указание`⁠$$\rangle$$ для **`до 50pt`**:

```latex
\documentclass{article}
\setlength{\fboxsep}{0pt}
\setlength{\parindent}{0pt}
\newcommand{\optspec}{\(\langle \texttt{необязательное указание} \rangle\)}
\begin{document}
\pagestyle{empty}
Вот таблица \verb|\valign|:
\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}

Вот та же таблица \verb|\valign|, но с \optspec{} равным «\texttt{to 50pt}». Обратите внимание, как строки «сбиваются в кучу», потому что между ними нет доступного «растяжимого клея»:

\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}

Мы будем использовать таблицу \verb|\valign| с \optspec{} равным «\texttt{to 50pt}», но обеспечим «гибкий интервал» с помощью команды \verb|\tabskip|. Здесь \verb|\tabskip| предоставляет достаточно «клея», чтобы позволить строкам \verb|\valign| «растянуться» и заполнить любое доступное дополнительное пространство. Вот «растянутая» таблица \verb|\valign|:

\tabskip=0pt plus1fil % Это задает \tabskip как очень гибкий 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}
```

[Откройте этот пример в 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)

Этот пример выдаёт следующий результат:

![](/files/15d874d900b66d487e80bfc6f7f6d4e7aa79c9f3)

## Введение в $$\langle$$⁠преамбулу⁠$$\rangle$$ и $$\langle$$⁠тело⁠$$\rangle$$

Этот раздел содержит введение в $$\langle$$⁠`преамбуле`⁠$$\rangle$$, и *кратко* затрагивает $$\langle$$⁠`тело`⁠$$\rangle$$ которое затем [рассматривается подробнее](#bodydetails).

Позднее статьи этой серии будут рассматривать $$\langle$$⁠`преамбуле`⁠$$\rangle$$ и $$\langle$$⁠`тело`⁠$$\rangle$$ подробнее, особенно использование и обработку TeX $$\langle$$⁠`преамбуле`⁠$$\rangle$$.

Как уже отмечалось выше, наиболее общий формат `\halign` или `\valign` таблиц можно записать так:

`\halign` $$\langle$$⁠`необязательное указание`⁠$$\rangle$$ { $$\langle$$⁠`преамбуле`⁠$$\rangle$$ $$\langle$$⁠`тело`⁠$$\rangle$$ }

`\valign` $$\langle$$⁠`необязательное указание`⁠$$\rangle$$ { $$\langle$$⁠`преамбуле`⁠$$\rangle$$ $$\langle$$⁠`тело`⁠$$\rangle$$ }

### Это $$\langle$$⁠преамбулу⁠$$\rangle$$

Это $$\langle$$⁠`преамбуле`⁠$$\rangle$$ раздел содержит одну $$\langle$$⁠`строку преамбулы`⁠$$\rangle$$ который *заканчивающуюся* командой `\cr` ; следовательно, $$\langle$$⁠`преамбуле`⁠$$\rangle$$ можно переписать так:

$$\langle$$⁠`преамбуле`⁠$$\rangle$$=$$\langle$$⁠`строку преамбулы`⁠$$\rangle$$**`\cr`**

### Это $$\langle$$⁠тело⁠$$\rangle$$

Аналогично, $$\langle$$⁠тело⁠$$\rangle$$ раздел можно дополнительно разбить на одну или несколько составляющих «строк», но здесь для каждой строки есть два варианта:

* строку, состоящую из набора ячеек, образующих `\halign` строку или `\valign` столбец; или
* один `\noalign` команду, которая «вставляет» материал между `\halign`строками или `\valign`столбцами.

Для текущих целей мы проигнорируем команду `\noalign` \nolign [позже в статье](#noalign)) (см. $$\langle$$⁠тело⁠$$\rangle$$ и будем считать, что каждая строка *заканчивающуюся* преамбулы является данными для набора ячеек и `\cr` команды.

Игнорируя `\noalign`, $$\langle$$⁠`тело`⁠$$\rangle$$ раздел тела, который представляет содержимое пользователя, содержит последовательность строк, каждую из которых мы будем называть $$\langle$$⁠`строкой тела`⁠$$\rangle$$ , которая *заканчивающуюся* сопровождается своим `\cr` команды.

Это $$\langle$$⁠`тело`⁠$$\rangle$$ можно переписать так:

$$\langle$$⁠строкой тела$${}\_1$$⁠$$\rangle$$\cr $$\langle$$⁠строкой тела$${}\_2$$⁠$$\rangle$$\cr $$\langle$$⁠строкой тела$${}*3$$⁠$$\rangle$$\cr ... $$\langle$$⁠строкой тела$${}*\mathrm{N}$$⁠$$\rangle$$\cr

Собрав все вместе, мы можем переписать общий формат `\halign` и `\valign` как:

`\halign` $$\langle$$⁠`необязательное указание`⁠$$\rangle$$ { $$\langle$$⁠`строку преамбулы`⁠$$\rangle$$\cr $$\langle$$⁠строкой тела$${}\_1$$⁠$$\rangle$$\cr $$\langle$$⁠строкой тела$${}\_2$$⁠$$\rangle$$\cr $$\langle$$⁠строкой тела$${}*3$$⁠$$\rangle$$\cr ... $$\langle$$⁠строкой тела$${}*\mathrm{N}$$⁠$$\rangle$$\cr }

`\valign` $$\langle$$⁠`необязательное указание`⁠$$\rangle$$ { $$\langle$$⁠`строку преамбулы`⁠$$\rangle$$\cr $$\langle$$⁠строкой тела$${}\_1$$⁠$$\rangle$$\cr $$\langle$$⁠строкой тела$${}\_2$$⁠$$\rangle$$\cr $$\langle$$⁠строкой тела$${}*3$$⁠$$\rangle$$\cr ... $$\langle$$⁠строкой тела$${}*\mathrm{N}$$⁠$$\rangle$$\cr }

По причинам, которые будут рассмотрены в более поздних статьях, $$\langle$$⁠`преамбуле`⁠$$\rangle$$, просто одна $$\langle$$⁠`строку преамбулы`⁠$$\rangle$$, имеет формат, отличный от всех строк в таблице $$\langle$$⁠`тело`⁠$$\rangle$$. Мы также [вернемся к `\noalign` команда](#noalign) которую также можно использовать внутри таблицы $$\langle$$⁠`тело`⁠$$\rangle$$.

### Это $$\langle$$⁠строка преамбулы⁠$$\rangle$$

Это $$\langle$$⁠`строку преамбулы`⁠$$\rangle$$ играет *жизненно* важную`\halign` роль в верстке таблиц, потому что она предоставляет своего рода «чертеж», используемый для набора содержимого — `\valign` строк или $$\langle$$⁠`тело`⁠$$\rangle$$. $$\langle$$⁠`строку преамбулы`⁠$$\rangle$$ столбцов — содержащихся в таблице `\halign` может также содержать шаблоны ячеек, используемые для построения строк `\valign`или столбцов

— тема, которая будет подробно рассмотрена. $$\langle$$⁠`строку преамбулы`⁠$$\rangle$$ Назначение

* двойное: *максимум* оно определяет `\halign` количество ячеек в строке `\valign`.
* или в столбце *хранит* шаблоны ячеек $$\langle$$⁠`тело`⁠$$\rangle$$. Шаблоны ячеек необязательны и могут быть «пустыми», либо вы можете включить символы или команды, которые TeX автоматически вставит до и/или после фактического содержимого конкретных ячеек в вашей таблице. Это избавляет вас от утомительной необходимости вручную писать/включать эти символы или команды в каждую ячейку, к которой вы хотите их применять.

**Примечание**: `\halign` строку или `\valign` столбец может содержать меньше ячеек, чем максимум, указанный $$\langle$$⁠`строку преамбулы`⁠$$\rangle$$ но не может содержать больше этого максимума, иначе TeX выдаст ошибку. Для текущих целей мы опускаем подробности *циклических* преамбул.

Продолжая наши структурные диаграммы, таблица $$\langle$$⁠`строку преамбулы`⁠$$\rangle$$ для

* изображение `\halign` с максимальным количеством $$\mathrm{K}$$ ячеек на *строки*, или
* один `\valign` с максимальным количеством $$\mathrm{K}$$ ячеек на *столбец*

может быть записана так:

$$\langle$$⁠шаблон$${}\_1$$⁠$$\rangle$$&$$\langle$$⁠шаблон$${}\_2$$⁠$$\rangle$$&$$\langle$$⁠шаблон$${}*3$$⁠$$\rangle$$ $$\cdots$$ &$$\langle$$⁠шаблон$${}*\mathrm{K}$$⁠$$\rangle$$

где `&` — это *символ выравнивания* который обозначает конец одной ячейки и начало следующей. Традиционно амперсанд (`&`) используется как символ выравнивания, но вместо него можно использовать любой символ с [код категории](/latex/ru/drugie-temy/43-table-of-tex-category-codes.md) 4.

Напомним, что $$\langle$$⁠`преамбуле`⁠$$\rangle$$ можно записать $$\langle$$⁠`преамбуле`⁠$$\rangle$$=$$\langle$$⁠`строку преамбулы`⁠$$\rangle$$**`\cr`**, или, эквивалентно,

$$\langle$$⁠`преамбуле`⁠$$\rangle$$=$$\langle$$⁠шаблон$${}\_1$$⁠$$\rangle$$&$$\langle$$⁠шаблон$${}\_2$$⁠$$\rangle$$&$$\langle$$⁠шаблон$${}*3$$⁠$$\rangle$$ $$\cdots$$ &$$\langle$$⁠шаблон$${}*\mathrm{K}$$⁠$$\rangle$$**`\cr`**

#### Структура каждой ячейки $$\langle$$⁠шаблон⁠$$\rangle$$

Каждая ячейка $$\langle$$⁠шаблон$${}\_i$$⁠$$\rangle$$ может быть записана так:

$$\langle$$⁠$$\texttt{U}\_i$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_i$$⁠$$\rangle$$ где:

* $$\langle$$⁠$$\texttt{U}\_i$$⁠$$\rangle$$ — это набор символов или команд (токенов), которые TeX автоматически вставит *до* содержимое ячейки, предоставленное пользователем $$i$$;
* $$\texttt{#}$$ — это заполнитель, показывающий, где в ячейке должно появиться содержимое, предоставленное пользователем $$i$$. Опять же, `#` символ — это всего лишь *традиция*, вместо него можно использовать любой символ с [код категории](/latex/ru/drugie-temy/43-table-of-tex-category-codes.md) 6. Обратите внимание, что код категории 6 используется для параметров макросов;
* $$\langle$$⁠$$\texttt{V}\_i$$⁠$$\rangle$$ — это набор символов или команд (токенов), которые TeX автоматически вставит *после* содержимое ячейки, предоставленное пользователем $$i$$.

Обратите внимание, что все $$\langle$$⁠$$\texttt{U}\_i$$⁠$$\rangle$$ и $$\langle$$⁠$$\texttt{V}\_i$$⁠$$\rangle$$ вошли *необязательный*: вам не обязательно использовать какие-либо символы или команды до или после содержимого ячейки.

**Завершение** $$\langle$$**⁠преамбулу⁠**$$\rangle$$

Наконец, используя обозначения выше, $$\langle$$⁠`преамбуле`⁠$$\rangle$$ для

* изображение `\halign` с максимальным количеством $$\mathrm{K}$$ ячеек на *строки*, или
* один `\valign` с максимальным количеством $$\mathrm{K}$$ ячеек на *столбец*

может быть записана так:

$$\langle$$⁠`преамбуле`⁠$$\rangle$$=$$\langle$$⁠`строку преамбулы`⁠$$\rangle$$`**\cr**`

или

$$\langle$$⁠`преамбуле`⁠$$\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**`

**Это** $$\langle$$**⁠преамбулу⁠**$$\rangle$$ **и подсчет строк и столбцов**

Дополнение **`\halign`** таблицу с $$\langle$$⁠`преамбуле`⁠$$\rangle$$ задающей $$\mathrm{K}$$ ячеек и $$\langle$$⁠`тело`⁠$$\rangle$$ содержащей $$\mathrm{N}$$ $$\langle$$⁠`строки тела`⁠$$\rangle$$ создаст таблицу с $$\mathrm{K}$$ *столбцами* и $$\mathrm{N}$$ *строками*, как показано на следующей диаграмме:

![](/files/f1ce267944392d317f499be30dfca6a51b8bcc6a)

Один **`\valign`** таблицу с $$\langle$$⁠`преамбуле`⁠$$\rangle$$ задающей $$\mathrm{K}$$ ячеек и $$\langle$$⁠`тело`⁠$$\rangle$$ содержащей $$\mathrm{N}$$ $$\langle$$⁠`строки тела`⁠$$\rangle$$ создаст таблицу с $$\mathrm{K}$$ *строками* и $$\mathrm{N}$$ *столбцами*, как показано на следующей диаграмме:

![](/files/8aa53413b76c201912b2a6952022542685996853)

### Хватит теории, немного примеров!

Как мы позже подробно увидим, когда TeX обрабатывает содержимое таблицы — ячейки таблицы, содержащиеся в [$$\langle$$⁠`тело`⁠$$\rangle$$](#body)— он проверяет наличие шаблонов ячеек, которые были определены в $$\langle$$⁠`преамбуле`⁠$$\rangle$$, потому что TeX ищет любые токены шаблона, которые нужно вставить до и/или после содержимого пользователя. Следующие, минимальные, примеры демонстрируют использование шаблонов ячеек $$\langle$$⁠$$\texttt{U}\_i$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_i$$⁠$$\rangle$$ в `\halign` и `\valign` файла, чтобы сгенерировать SVG-графику набранной

#### Таблица \halign с использованием шаблонов ячеек

Следующий пример демонстрирует `\halign` таблицу, которая использует шаблон ячейки для автоматического добавления двойных кавычек вокруг содержимого первой ячейки в каждой строке: то есть шаблон, который влияет на каждую ячейку в первом столбце:

```latex
\documentclass{article}
\usepackage{parskip} % Установить \parindent в 0pt
% Выберите удобно маленький размер страницы
\usepackage[paperheight=10cm,paperwidth=12cm,textwidth=8cm]{geometry}
\setlength{\tabskip}{20pt} % Раздвинуть столбцы \halign
\begin{document}
\pagestyle{empty}

Вот таблица \verb|\halign| без шаблонов ячеек:

\halign{
% Ничего до или после каждого '#' в <преамбуле>
#&#&#\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}

Вот та же таблица \verb|\halign|, но с автоматически добавляемыми двойными кавычками к первой ячейке каждой строки; то есть это влияет на каждую ячейку в первом столбце:

\halign{
% Шаблоны кавычек в преамбуле:
«#»&#&#\cr % Двойные кавычки до и после первого #
A&B&C\cr
D&E&F\cr
G&H&I\cr
}
\end{document}
```

[Откройте этот пример в 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)

Этот пример выдаёт следующий результат:

![](/files/a841ef7f4924e035fab13eb362d0a2b9f4315bc5)

Следующая графика — это аннотированная версия `\halign` таблицы, полученной по приведенному выше примеру; здесь мы сравниваем «формальную» структуру трехъячеечной $$\langle$$⁠`преамбуле`⁠$$\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**`

с фактической $$\langle$$⁠`преамбуле`⁠$$\rangle$$ для `«#»&#&#**\cr**`, подчеркивая наличие или отсутствие шаблонов ячеек:

![](/files/fc4c54c0b76ed1f8f27e2cc62db9a402b21fb82b)

#### Таблица \valign с использованием шаблонов ячеек

Следующий пример демонстрирует `\valign` таблицу, которая использует шаблон для каждой ячейки, чтобы автоматически вставлять цифры, окружающие содержимое пользователя.

```latex
\documentclass{article}
\usepackage{parskip} % Установить \parindent в 0pt
% Выберите удобно маленький размер страницы
\usepackage[paperheight=14cm,paperwidth=12cm,textwidth=10cm]{geometry}
\setlength{\tabskip}{8pt} % Раздвинуть строки \valign
\begin{document}
\pagestyle{empty}

Вот таблица \verb|\valign| без шаблонов ячеек:

\begingroup
\hsize=25pt
\valign{
% Ничего до или после каждого '#' в
% <пreamble>
#&#&#\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}
\endgroup

Вот та же таблица \verb|\valign|, но с использованием шаблонов ячеек для автоматического вставления цифр в каждую ячейку:

\begingroup
\hsize=25pt
\valign{
% Цифры вставляются до и после каждого '#' в
% <пreamble>
1#2&3#4&5#6\cr
A&B&C\cr
D&E&F\cr
G&H&I\cr
}
\endgroup
\end{document}
```

[Откройте этот пример в 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)

Этот пример выдаёт следующий результат:

![](/files/90e834396408e02c0fe76d6a8fbd69e3bbdb9c87)

Следующая графика — это аннотированная версия `\valign` таблицы, полученной по приведенному выше примеру; здесь мы сравниваем «формальную» структуру трехъячеечной $$\langle$$⁠`преамбуле`⁠$$\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**`

с фактической $$\langle$$⁠`преамбуле`⁠$$\rangle$$ для `1#2&3#4&5#6**\cr**`, подчеркивая использование шаблонов ячеек $$\langle$$⁠$$\texttt{U}\_i$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_i$$⁠$$\rangle$$:

![](/files/1f3cfd8da682b7bc8c67d8f2c60a4cb9b3521b0d)

Обратите внимание, как шаблон для ячейки $$i$$ ($$\langle$$⁠$$\texttt{U}\_i$$⁠$$\rangle$$$$\texttt{#}$$$$\langle$$⁠$$\texttt{V}\_i$$⁠$$\rangle$$) применяется к $$i$$первой ячейке в каждом `\valign` столбце, в результате чего все ячейки $$i$$этого *строки* столбца оказываются затронутыми.

#### Стилизация текста с помощью шаблонов ячеек

В следующем примере используются следующие $$\langle$$⁠`преамбуле`⁠$$\rangle$$ (шаблоны ячеек) для стилизации текста, содержащегося в каждой строке или столбце:

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

Если мы сравним эту $$\langle$$⁠`преамбуле`⁠$$\rangle$$ с нашей «формальной» структурой трехъячеечной $$\langle$$⁠`преамбуле`⁠$$\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**`

мы видим, что:

$$\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$$=`}`

Обратите внимание, как эти шаблоны ячеек, такие как `\textbf{#}` напоминают макросы с одним параметром (содержимым ячейки).

```latex
Таблица \verb|\valign| с текстом, оформленным с помощью шаблонов ячеек:

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

Таблица \verb|\halign| с текстом, оформленным с помощью шаблонов ячеек:

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

[Откройте этот пример в 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)

Этот пример выдаёт следующий результат:

![](/files/097098e081a0e503935e30f61e24e3dc532339ed)

## Подробнее о таблице $$\langle$$⁠тело⁠$$\rangle$$

В разделе [Введение в $$\langle$$⁠`преамбуле`⁠$$\rangle$$ и $$\langle$$⁠`тело`⁠$$\rangle$$](#preamble) мы увидели, как, если временно игнорировать `\noalign`, $$\langle$$⁠`тело`⁠$$\rangle$$ у `\halign` или `\valign` таблицы состоит из нескольких строк, каждая из которых обозначена $$\langle$$⁠строкой тела$${}\_j$$⁠$$\rangle$$, где:

* каждая $$\langle$$⁠строкой тела$${}\_j$$⁠$$\rangle$$ заканчивается `\cr` команда
* каждая $$\langle$$⁠строкой тела$${}\_j$$⁠$$\rangle$$ у `\halign` — это строка таблицы
* каждая $$\langle$$⁠строкой тела$${}\_j$$⁠$$\rangle$$ у `\valign` — это столбец таблицы

Последовательность строк, $$\langle$$⁠строкой тела$${}\_j$$⁠$$\rangle$$, где $$j=1\ldots\mathrm{N}$$, порождает $$\mathrm{N}$$ строки `\halign` или $$\mathrm{N}$$ столбцы для `\valign`. Как показано в следующей схеме, общий $$\langle$$⁠`преамбуле`⁠$$\rangle$$ такой как

$$\langle$$⁠`преамбуле`⁠$$\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**`

задает шаблоны ячеек максимум для $$\mathrm{K}$$ ячеек в каждой из $$\mathrm{N}$$ $$\langle$$⁠`строкой тела`⁠$$\rangle$$ записей в $$\langle$$⁠`тело`⁠$$\rangle$$:

![](/files/7c0e149679c05b6ea094bf063bae29982dcbe9c4)

### Структура каждой $$\langle$$⁠строкой тела$${}\_j$$⁠$$\rangle$$

Каждая строка $$\langle$$⁠строкой тела$${}\_j$$⁠$$\rangle$$ таблицы $$\langle$$⁠тело⁠$$\rangle$$ содержит содержимое для до $$\mathrm{K}$$ ячеек — в зависимости от таблицы $$\langle$$⁠преамбулу⁠$$\rangle$$— и имеет общий вид:

$$\langle$$⁠строкой тела$${}\_j$$⁠$$\rangle$$=$$\langle$$⁠Ячейка$${}\_1$$⁠$$\rangle$$$$\texttt{&}$$$$\langle$$⁠Ячейка$${}\_2$$⁠$$\rangle$$$$\texttt{&}$$$$\langle$$⁠Ячейка$${}*3$$⁠$$\rangle$$$$\texttt{&}$$$$\cdots$$$$\texttt{&}$$$$\langle$$⁠Ячейка$${}*\mathrm{K}$$⁠$$\rangle$$`**\cr**`

где:

* $$\langle$$⁠Ячейка$${}\_i$$⁠$$\rangle$$ представляет пользовательское содержимое для $$i$$й ячейки в некоторой $$\langle$$⁠строкой тела$${}\_j$$⁠$$\rangle$$
* окружения **`&`** символ называется *табуляцией выравнивания* (тот же, что используется в $$\langle$$⁠преамбулу⁠$$\rangle$$), который сигнализирует об окончании одной ячейки и начале следующей. И снова использование **`&`** — это лишь традиция (соглашение), поскольку любой символ с [код категории](/latex/ru/drugie-temy/43-table-of-tex-category-codes.md) 4.

Хотя каждая $$\langle$$⁠строкой тела$${}\_j$$⁠$$\rangle$$ может содержать максимум $$\mathrm{K}$$ ячеек (определяемое $$\langle$$⁠преамбулу⁠$$\rangle$$) они могут содержать *меньше* чем $$\mathrm{K}$$ ячеек, и любая $$\langle$$⁠Ячейка$${}\_i$$⁠$$\rangle$$ в $$\langle$$⁠строкой тела$${}\_j$$⁠$$\rangle$$ может быть пустой.

Следующий пример демонстрирует $$\langle$$⁠преамбулу⁠$$\rangle$$ для `#&#&#&#&#\cr` что обеспечивает максимум 5 ячеек на $$\langle$$⁠строку тела⁠$$\rangle$$; однако в набранных таблицах есть строки с менее чем 5 ячейками:

```latex
Таблица \verb|\valign| с 1–5 ячейками на \textit{столбец}:

\begingroup
% \hsize управляет шириной столбцов \valign (размером набранных строк).
\hsize=40pt
\fbox{\valign{
% Используйте преамбулу, допускающую 5 ячеек на столбец
% Большинство столбцов не содержат данных для 5 ячеек
#&#&#&#&#\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

% Примечание: по причинам, объясняемым позже
% \halign нужно поместить в \vbox
Таблица \verb|\halign| с 1–5 ячейками на \textit{строку}:

\fbox{%
\vbox{\halign{
% Используйте преамбулу, допускающую 5 ячеек на строку
% Большинство строк не содержат данных для 5 ячеек
#&#&#&#&#\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
}}}
```

[Откройте этот пример в Overleaf](/latex/ru/podrobnye-stati/15-how-do-tex-engines-typeset-tables-2.md)

Этот пример выдаёт следующий результат:

![](/files/20539cdbd5c77b19f5409e0af4a1724d60a28a54)

Следующий `\halign` пример демонстрирует переменное число ячеек в строке и возможность пустых ячеек — обратите внимание, как пустые ячейки создаются последовательными **`&`** символами в таблице:

```latex
Таблица \verb|\halign| с некоторыми пустыми ячейками — обратите внимание, что в таблице \(\langle\texttt{body}\rangle\) есть последовательные символы \texttt{\&}:

\fbox{%
\vbox{\halign{
% Используйте преамбулу, допускающую 5 ячеек на строку
% Большинство строк не содержат данных для 5 ячеек
#&#&#&#&#\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
}}}
```

[Откройте этот пример в 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)

Этот пример выдаёт следующий результат:

![](/files/a7086c6371b0b524a0ac350dc9add18a4315a6cd)

### В верстке таблиц нет ничего особенного в символах & и \#

Использование TeX символов `&` и `#` при верстке `\halign`- или `\valign`-основанных таблиц — это традиция, восходящая к исходным макросам plain TeX Кнута. Вполне можно использовать символы, отличные от `&` и `#` задав соответствующие коды категорий для выбранных вами заменителей, как показывает следующий пример:

* заменяет `&` с `@` задав `@` коду категории 4
* заменяет `#` с `|` задав `|` коду категории 6 (который используется для параметров макросов)

Изменения категории остаются локальными благодаря использованию `\begingroup` и `\endgroup`:

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

[Откройте этот пример в 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)

## Снова вводим команду \noalign

Движки TeX предоставляют встроенную (примитивную) `\noalign` команду:

`\noalign{`$$\langle$$⁠`токены`⁠$$\rangle$$`}`

где $$\langle$$⁠`токены`⁠$$\rangle$$ — это символы и/или команды TeX/LaTeX. Команда `\noalign` предназначена исключительно для использования внутри `\halign` или `\valign` таблицы: использование ее вне их вызовет ошибку.

Назначение `\noalign` — позволить «вставку» текста и команд TeX/LaTeX *между* строками `\halign` таблицы или столбцами `\valign` таблицы. Наиболее распространенное применение `\noalign` — создание линий таблицы:

* *горизонтальных* линий между `\halign` строками таблицы
* *вертикальных* линий между `\valign` столбцами таблицы

Обратите внимание на следующее:

* окружения `\noalign` команды таков ***не заканчивается на\*\*\*\*****&#x20;****`\cr`****&#x20;****\*\*\*\*команду***
* набор команд, допустимых внутри `\noalign{...}` зависит от того, используется ли он в $$\langle$$⁠`тело`⁠$$\rangle$$ у `\halign` или `\valign` таблице (то есть в вертикальном или горизонтальном режиме).

Теперь можно сказать, что таблица $$\langle$$⁠`тело`⁠$$\rangle$$ для `\halign` или `\valign` может состоять из отдельных строк $$\langle$$⁠строкой тела$${}\_i$$⁠$$\rangle$$`\cr` перемежающихся с `\noalign` командами; одной из множества возможных комбинаций может быть:

`\noalign{`$$\langle$$⁠`токены`⁠$$\rangle$$`}` $$\langle$$⁠строкой тела$${}\_1$$⁠$$\rangle$$\cr $$\langle$$⁠строкой тела$${}\_2$$⁠$$\rangle$$\cr `\noalign{`$$\langle$$⁠`дополнительные токены`⁠$$\rangle$$`}` $$\langle$$⁠строкой тела$${}*3$$⁠$$\rangle$$\cr ... $$\langle$$⁠строкой тела$${}*\mathrm{N}$$⁠$$\rangle$$\cr `\noalign{`$$\langle$$⁠`другие токены`⁠$$\rangle$$`}`

### Пример использования \noalign

Другие случаи использования мы рассмотрим позже в этой серии статей, а здесь приведем базовый пример, демонстрирующий создание линий таблицы с помощью `\noalign`:

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

Использование \verb|\noalign| для размещения горизонтальных линий между строками таблицы \verb|\halign|:
\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}
}

Использование \verb|\noalign| для размещения вертикальных линий между столбцами таблицы \verb|\valign|:
\vspace{6pt}

\begingroup % сохраняем изменения \parindent и \hsize локальными
\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
```

[Откройте этот пример в 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)

Этот пример выдаёт следующий результат:

![](/files/660bd7d2994da11911f78467a3a82f14cf46f0b2)

## Снова о \tabskip

Мы подробнее рассмотрим `\tabskip` команду, опираясь на [введение в предыдущем разделе](#tabskip).

Это `\tabskip` команда задает значение особой формы «пробела» (glue), используемой *исключительно* при верстке таблиц: ее назначение — обеспечивать промежутки между строками или столбцами таблицы:

* для `\halign` таблиц: `\tabskip` glue вставляется до и после таблицы (то есть слева и справа), а также между столбцами таблицы
* для `\valign` таблиц: `\tabskip` glue вставляется до и после таблицы (то есть сверху и снизу), а также между строками таблицы

Значение `\tabskip` можно задать с помощью LaTeX `\setlength` команду:

`\setlength{\tabskip}{`$$\langle$$⁠`значения glue`⁠$$\rangle$$`}`

где $$\langle$$⁠`значения glue`⁠$$\rangle$$ может быть:

* фиксированной длиной, например `5pt`, `3mm`, или
* конечным гибким glue, например `3pt plus 2pt minus 1pt`, или
* бесконечно гибким glue, например `0pt plus1fill`.

Вы также можете напрямую задать `\tabskip` (обходя `\setlength`) записав

`\tabskip`=$$\langle$$⁠`значения glue`⁠$$\rangle$$

Однако любое изменение значения `\tabskip` glue будет влиять на интервалы таблицы только если это изменение:

* сделано *до* окружения `\halign` или `\valign` командой, подлежащей обработке, или
* сделано внутри таблицы $$\langle$$⁠`преамбуле`⁠$$\rangle$$

Попытки задать `\tabskip` значения внутри содержимого таблицы (ячейки в таблице $$\langle$$⁠`тело`⁠$$\rangle$$) *не будет* не изменяют интервалы `\halign` столбцов таблицы или `\valign` строк таблицы. Причина такого поведения `\tabskip` связана с ролью, которую играет $$\langle$$⁠`преамбуле`⁠$$\rangle$$ при верстке таблиц — процессы, которые мы позже подробно рассмотрим.

### Лучше один раз увидеть

Чтобы наглядно показать наличие различных типов интервалов/glue, используемых при верстке таблиц, особенно

* `\tabskip` клей
* `\baselineskip` клей
* ручного кернинга (`\kern`)

Overleaf подготовил проект на базе LuaTeX для цветового выделения компонентов таблицы. LuaTeX был выбран, потому что он позволяет выполнять низкоуровневую повторную обработку внутренних данных/структур набранных таблиц, но здесь мы не будем подробно рассматривать эти детали.

Вот несколько примеров, показывающих различные применения `\tabskip`. Для каждого примера мы покажем фактический вывод и цветную версию, созданную LuaTeX.

### Пример 1 с \tabskip

Рассмотрим использование `\tabskip` в `\halign` и `\valign` таблицы. Мы покажем реальные набранные таблицы с рамкой, чтобы визуализировать их размер и интервалы, а также аннотированные изображения с цветными версиями, которые наглядно показывают размеры различных glue/интервалов в каждой таблице.

Сначала, `\halign`:

```latex
% Чтобы визуализировать размеры таблицы, мы поместим вокруг нее рамку
\setlength{\fboxsep}{0pt} % Используем плотно прилегающие рамки

% Здесь мы задаем \tabskip «напрямую»
\tabskip5pt % Устанавливаем начальное значение \tabskip вне таблицы

% Чтобы поместить рамку вокруг таблицы, ее нужно сохранить в TeX-ящик.
% \halign должен быть помещен в \vbox, потому что \halign должен быть
% обработан в «вертикальном режиме»: \hbox не подойдет, потому что
% он обрабатывается в «горизонтальном режиме»

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

[Откройте этот пример в 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)

Этот пример выдаёт следующий результат:

![](/files/a3ef29edd88ae6e948e0830f91272500d2ece419)

Следующая иллюстрация — это более крупная, цветная и аннотированная версия таблицы, полученной в предыдущем примере:

![](/files/9883716f46a200cbc37834fa4b5b4667c169681e)

Встречаются 4 экземпляра `\tabskip` команды, и каждый соответствует определенному месту интервала в таблице:

1. `\tabskip5pt` используется вне таблицы и задает `\tabskip` значение, применяемое перед (слева от) первой ячейки в каждой строке.
2. `\tabskip10pt` задается в первом шаблоне ячейки $$\langle$$⁠`преамбуле`⁠$$\rangle$$ что влияет на промежуток между $$\langle$$⁠Ячейка$${}\_1$$⁠$$\rangle$$ и $$\langle$$⁠Ячейка$${}\_2$$⁠$$\rangle$$ в каждой строке.
3. `\tabskip15pt` задается во втором шаблоне ячейки $$\langle$$⁠`преамбуле`⁠$$\rangle$$ что влияет на промежуток между $$\langle$$⁠Ячейка$${}\_2$$⁠$$\rangle$$ и $$\langle$$⁠Ячейка$${}\_3$$⁠$$\rangle$$ в каждой строке.
4. `\tabskip20pt` задается в третьем и последнем шаблоне ячейки $$\langle$$⁠`преамбуле`⁠$$\rangle$$ что влияет на пространство, добавляемое после $$\langle$$⁠Ячейка$${}\_3$$⁠$$\rangle$$, последней ячейки каждой строки.

Далее, `\valign`

```latex
\setlength{\fboxsep}{0pt} % Используем плотно прилегающие рамки
\tabskip5pt % Устанавливаем начальное значение \tabskip вне таблицы

% Оставляем изменения \hsize локальными (в группе)
\begingroup
% \hsize определяет ширину столбцов \valign
\setlength{\hsize}{50pt}
% Поскольку \valign можно поместить в \vbox или \hbox, мы можем использовать
% \fbox напрямую
\fbox{\valign{
\tabskip10pt#&
\tabskip15pt#&
\tabskip20pt#\cr
A&B&C\cr
E&E&F\cr
G&H&I\cr
}}
\endgroup
```

[Откройте этот пример в 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)

Этот пример выдаёт следующий результат:

![](/files/ffc243cce7bf771201eff50e6b68ec8bc8227d3e)

Снова, следующая иллюстрация — это более крупная, цветная и аннотированная версия таблицы, полученной в предыдущем примере:

![](/files/a8eb87d9fc88595449739064dc38cbb7ee78137f)

Как и в `\halign` примере, встречаются 4 экземпляра `\tabskip` команды. Однако в `\valign` таблице `\tabskip` вставляется между строками таблицы:

1. `\tabskip5pt` используется вне таблицы и задает `\tabskip` значение, применяемое перед (над) первой ячейкой в каждом столбце.
2. `\tabskip10pt` задается в первом шаблоне ячейки $$\langle$$⁠`преамбуле`⁠$$\rangle$$ что влияет на промежуток между $$\langle$$⁠Ячейка$${}\_1$$⁠$$\rangle$$ и $$\langle$$⁠Ячейка$${}\_2$$⁠$$\rangle$$ каждого столбца.
3. `\tabskip15pt` задается во втором шаблоне ячейки $$\langle$$⁠`преамбуле`⁠$$\rangle$$ что влияет на промежуток между $$\langle$$⁠Ячейка$${}\_2$$⁠$$\rangle$$ и $$\langle$$⁠Ячейка$${}\_3$$⁠$$\rangle$$ каждого столбца.
4. `\tabskip20pt` задается в третьем и последнем шаблоне ячейки $$\langle$$⁠`преамбуле`⁠$$\rangle$$ что влияет на пространство, добавляемое после $$\langle$$⁠Ячейка$${}\_3$$⁠$$\rangle$$, последней ячейки каждого столбца.

**Итоги/выводы**

* В `\halign` таблице `\tabskip` glue размещается слева и справа от каждой ячейки в строке, тем самым увеличивая интервалы между столбцами таблицы.
* В одной `\valign` таблице `\tabskip` glue размещается над и под каждой ячейкой в столбце, тем самым увеличивая интервалы между строками таблицы.

### \tabskip и \noalign

#### Использование \halign

Следующий `\halign` пример использует `\tabskip` glue и также демонстрирует `\noalign` команду, используя ее для размещения линий с интервалами над и под строками `\halign` таблицы. Эти линии набираются с помощью `\hrule` (примитивной) команды вместе с интервалом, созданным `\kern`:

```latex
\setlength{\tabskip}{5pt} % Задаем \tabskip вне таблицы

\halign{
#&#&#&#&#\cr % The <preamble>
\noalign{\hrule\kern2pt} % Линия с интервалом перед строкой 1
1&2&3&4&5\cr % Строка 1
\noalign{\kern2pt\hrule\kern2pt} % Линия с интервалом между строками 1/2
6&7&8&9&10\cr % Строка 2
\noalign{\kern2pt\hrule\kern2pt} % Линия с интервалом между строками 2/3
11&12&13&14&15\cr % Строка 3
16&17&18&19&20\cr % Строка 4 — без линий между строками 3/4
\noalign{\kern2pt\hrule} % Линия с интервалом в конце таблицы
}
```

[Откройте этот пример в 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)

Этот пример создает таблицу, показанную ниже, которая дополнительно аннотирована, чтобы воспроизвести код (La)TeX и номера (1)–(4) для перечисления `\noalign` команд, содержащих линии и керны, вместе с соответствующим набранным результатом:

![](/files/0f5062018ea155f1ca87c5df92ea8996d3d0beff)

Следующая иллюстрация показывает цветную версию таблицы с метками, показывающими различные интервалы/glue в таблице:

![](/files/a00a8b749a1e692bef02505c18f638a91e62ce8e)

Обратите внимание на следующее:

* использование `\noalign` для вставки линий между определенными строками и ручное использование `\kern` значений, чтобы добавить немного пространства до/после линий. Движки TeX не вставляют `\baselineskip` glue после набранной линии, поэтому пространство вставляется вручную с помощью `\kern` (можно было бы использовать и другие команды интервалов);
* `\baselineskip` glue автоматически был вставлен между строками 3 и 4.

#### Использование \valign

Следующий `\valign` пример использует те же данные, что и предыдущий `\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
```

[Откройте этот пример в 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)

Этот пример создает таблицу, показанную ниже, которая дополнительно аннотирована, чтобы воспроизвести код (La)TeX и номера (1)–(4) для перечисления `\noalign` команд, содержащих линии и керны, вместе с соответствующим набранным результатом:

![](/files/f569c9e9ed892a466c7706738a936bb2d5ec2110)

![](/files/c29ea18eb2c89a4770b50ce4b3b51df992a6b783)

### Таблица \valign со строками текста

Следующий пример

```latex
\setlength{\tabskip}{5pt}
\begingroup % Сохраняем изменения \parindent и \hsize локальными
\setlength{\parindent}{10pt}
\setlength{\hsize}{75pt}
\valign{
#&#&#\cr
\noalign{\vrule\kern5pt}
\TeX{} может верстать очень сложные
таблицы.&Вот немного дополнительного
текста.&И, наконец, дополнительная строка
в этом столбце.\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
```

[Откройте этот пример в 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)

Этот пример выдаёт следующий результат:

## Задание ширины строк и высоты столбцов

## Еще о таблице $$\langle$$⁠преамбулу⁠$$\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/ru/podrobnye-stati/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.
