> 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/14-how-do-tex-engines-typeset-tables.md).

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

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

## Введение: Что охватывает эта серия?

Создание эстетически приятных таблиц может отнимать много времени — независимо от того, используете ли вы визуальный инструмент верстки, LaTeX или язык разметки, например HTML или markdown. Для пользователей LaTeX, в частности, верстка таблиц занимает одно из первых мест в списке «болевых точек», о чём, возможно, свидетельствует то, что «таблицы» являются одной из самых [помечаемых тем на tex.stackexchange](https://tex.stackexchange.com/tags).

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

* У Overleaf [справочные страницы](https://www.overleaf.com/learn/latex/tables) и других сайтов, таких как [learnlatex.org](https://www.learnlatex.org/en/lesson-08)
* CTAN, Comprehensive TeX Network, перечисляет более [70 пакетов TeX/LaTeX](https://ctan.org/topic/table) связанных с созданием таблиц
* целую [книгу о верстке таблиц с помощью LaTeX](https://www.amazon.co.uk/Typesetting-Tables-LaTeX-Herbert-Voss/dp/1906860254)
* отличный [онлайн-генератор таблиц LaTeX](https://www.tablesgenerator.com/latex_tables)

Простой поиск в Google по запросу [LaTeX tables](https://www.google.com/search?q=latex+tables) дает огромное количество результатов, перечисляющих множество сайтов, предлагающих помощь, советы, примеры и объяснения.

### TeX, а не LaTeX

Учитывая богатство литературы, доступной по теме верстки таблиц с помощью LaTeX, есть ли ещё что писать о них — ещё больше примеров таблиц и перечисление/демонстрация команд пакетов? Есть ли способ подойти к теме верстки таблиц так, чтобы выделить или сосредоточиться на фундаментальных принципах и концепциях верстки таблиц? Есть, но для этого нужно снять слои луковицы LaTeX…

Мы решили подготовить серию статей, призванную дать читателям справочную информацию и объяснения лежащих в основе *механизмов* верстки таблиц на основе TeX. Вместо того чтобы сосредотачиваться на верстке таблиц с помощью конкретных макросов/пакетов LaTeX, мы рассмотрим *лежащие в основе особенности поведения* движков TeX: исследуя низкоуровневую машинерию верстки, которая служит основой, на которой строятся макрокоманды LaTeX. Конечная цель — выделить и объяснить основные методы и алгоритмы верстки таблиц на основе TeX — и, будем надеяться, помочь читателям/пользователям лучше понять, почему таблицы ведут себя так, как ведут. Неизбежным следствием такого подхода, снимающего защитные слои изоляции макросов LaTeX, является знакомство с грязными низкоуровневыми деталями, от которых пользователи обычно (и с радостью) ограждены слоями макрокода LaTeX.

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

### Изучение механики таблиц TeX: Как это можно сделать?

Чтобы исследовать и затем писать о процессах и механизмах низкого уровня, происходящих внутри движков TeX, таких как верстка таблиц, Overleaf создал (скомпилировал) «отладочные» версии движка TeX Кнута с использованием [процесса Web2W](https://w3-o.cs.hm.edu/users/ruckert/public_html/web2w/index.html).

Традиционно сборка TeX включает процесс, называемый Web2C, используемый в TeX Live, который генерирует код C, преобразуя исходный код TeX на Pascal в его эквивалент на C. Этот процесс создает код C, который никогда не предназначался для чтения людьми — только компиляторами C. Механически сгенерированный код C *чрезвычайно* трудно читать или изменять для экспериментальных целей.

Напротив, Web2W создает исходный код C (доступный [здесь](https://w3-o.cs.hm.edu/users/ruckert/public_html/web2w/ctex.c)) который *на порядки* читабельнее кода, создаваемого Web2C. Следовательно, исходный код C, полученный с помощью Web2W, гораздо удобнее для модификации в учебных/экспериментальных целях.

Web2W создает версию TeX («CTeX»), которая *чрезвычайно* близка к оригинальной программе Кнута: «CTeX» не включает многие изменения и улучшения, внесенные процессом Web2C, — такие как SyncTeX, обработка командной строки и поиск файлов через Kpathsea. Хотя вы лишаетесь этих ценных улучшений, получающийся (Web2W) код C относительно легко просматривать, используя опубликованный Кнутом исходный код TeX, хотя TeX был написан на Pascal.

* **Примечание о названиях:** Строго говоря, название «TeX» должно относиться только к оригинальному программному обеспечению, написанному и опубликованному Дональдом Кнутом. Любые изменения в его программе должны использовать другое имя для получившегося программного обеспечения для верстки на основе TeX. Здесь мы использовали процесс Web2W, чтобы собрать движок, который, по сути, по-прежнему является оригинальной программой Кнута. Однако, во избежание сомнений, мы будем использовать термин «CTeX» для обозначения конкретной версии, собранной с помощью Web2W, но также будем использовать «TeX» либо в значении оригинального движка Кнута, либо как общий термин для языка верстки, основанного на принципах TeX Кнута. Мы надеемся, что читатели простят любые редкие отступления от строгого применения/использования совершенно корректной терминологии: надеемся, что смысл/намерение передаются контекстом.

Отладочная версия CTeX запускалась с помощью [Eclipse IDE](https://www.eclipse.org/downloads/packages/)что позволило наблюдать обработку кода C в реальном времени, реализующего низкоуровневые примитивные (встроенные) команды TeX и алгоритмы, разработанные Кнутом для поддержки верстки таблиц.

Следующее короткое (примерно 90 секунд) видео демонстрирует работу движка CTeX внутри [Eclipse IDE](https://www.eclipse.org/downloads/packages/):

{% embed url="<https://videos.ctfassets.net/nrgyaltdicpt/7drdFwYR6h5xD88XnurDIH/36511f504755ab274f4da2e3f3fc1ce5/TeXtables.mp4>" %}

Помимо CTeX, мы также скомпилировали e-TeX, чтобы получить доступ к нескольким дополнительным примитивам, отсутствующим в оригинальном программном обеспечении Кнута. Хотя CTeX и e-TeX к настоящему времени являются старыми движками на базе TeX, они по-прежнему подходят в качестве основы для изучения механики верстки таблиц, поскольку эти лежащие в основе принципы применимы ко всем движкам верстки на базе TeX.

### Зачем использовать более старый движок TeX для изучения таблиц?

Во-первых, печатная книга [TeX:The Program](https://www.amazon.co.uk/Computers-Typesetting-TeX-Program-TEX/dp/0201134373), в которой перечисляется и объясняется исходный код TeX, по-прежнему остается чрезвычайно удобным путеводителем по мутным водам внутреннего устройства TeX, несмотря на то, что она была опубликована более 30 лет назад (1986). Разумеется, вы можете самостоятельно сверстать документацию по исходному коду TeX; например, см. проект Overleaf [Сверстать документацию по исходному коду TeX, e-TeX или pdfTeX](https://www.overleaf.com/latex/examples/typeset-the-source-code-documentation-for-tex-e-tex-or-pdftex/qkgfgyspnhcv). С момента публикации TeX:The Program в 1986 году появились новые движки TeX, включая pdfTeX, XeTeX и LuaTeX, каждый из которых ввел функции и команды, не описанные в TeX:The Program просто потому, что их не было в оригинальном программном обеспечении Кнута.

Для многих основных процессов, таких как верстка таблиц в TeX, код, документированный в TeX:The Program, по-прежнему актуален как основа для изучения — хотя исходный код TeX написан на Pascal. Кроме того, TeX Кнута сравнительно легко и быстро компилировать — особенно с помощью чрезвычайно полезного [Web2W](https://w3-o.cs.hm.edu/users/ruckert/public_html/web2w/index.html) процесса, разработанного Мартином Рюккертом. Простота/скорость компиляции делают намного удобнее внесение простых изменений в TeX — например, создание SVG-графики, используемой позже в этой серии статей.

### Понимание разницы между TeX и LaTeX

Многие читатели уже знают, что LaTeX на самом деле не является *исполняемой* программой верстки, а представляет собой большой набор команд (*макросов*) которые, в конечном счете, написаны на более низкоуровневом языке верстки/программирования, называемом TeX. Ваш код LaTeX дает сверстанный результат только после того, как он будет обработан исполняемой программой, называемой *движком TeX*— программным обеспечением, которое находится между вашим кодом LaTeX (документом) и сверстанным PDF. Сегодня пользователи могут выбирать между различными движками TeX для верстки своего кода LaTeX, включая pdfTeX, XeTeX и варианты LuaTeX.

Те, кто недавно познакомился с экосистемой TeX/LaTeX, часто и вполне понятно, озадачены множеством загадочно звучащих названий инструментов, с которыми они сталкиваются: TeX, LaTeX, pdfTeX, pdfLaTeX, XeTeX, XeLaTeX, LuaTeX и LuaLaTeX. Если вы чувствуете то же самое, помощь рядом — в статье Overleaf [Что в имени: руководство по множеству разновидностей TeX](/latex/ru/podrobnye-stati/55-what-s-in-a-name-a-guide-to-the-many-flavours-of-tex.md) в которой объясняется происхождение и значение всех этих терминов.

#### Диалекты и примитивы TeX

У каждого движка TeX есть набор встроенных команд, называемых *примитивов* которые в совокупности составляют «диалект» этого движка в языке верстки TeX, отражая возможности, встроенные в каждый движок. Здесь термин «примитив», используемый для описания встроенных команд движков TeX, не *не* означает, что эти команды простые или примитивные в бытовом смысле, а означает, что они фундаментальны и неделимы: не построены из других команд (в отличие от макросов). Все движки TeX используют большой общий набор примитивов, но некоторые содержат примитивы, специфичные для данного движка, — отсюда и возникает представление о «диалекте» TeX.

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

Чтобы избежать необходимости писать напрямую на языке TeX или постоянно заново вводить одну и ту же последовательность команд, движки TeX позволяют создавать «ярлыки», называемые *макросов*. Создавая макросы, вы определяете собственные команды, которые упаковывают потенциально длинные и сложные последовательности примитивов языка TeX (или других макросов) в одну «более высокоуровневую» команду. Программисты TeX могут писать очень сложные макросы, которые заключают в себе большой объем функциональности в одной команде — например, команды, предоставляемые LaTeX. Используя пакеты макросов, такие как LaTeX (или [ConTeXt](https://wiki.contextgarden.net/Main_Page)), авторы документов (в основном) защищены от многих утомительных деталей, что позволяет им сосредоточиться на написании и верстке, а не постоянно бороться со сложностями и нюансами языка TeX.

## В начале…

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

Однако движки TeX взимают плату за гибкость, которую предоставляют их возможности построения таблиц: множество тонкостей и нюансов в низкоуровневом поведении встроенных (примитивных) команд верстки таблиц, которых всего 9:

* **`\halign`**, **`\valign`**: основные команды построения таблиц
* **`\tabskip`**: клей, помещаемый между \halign columns или \valign rows
* **`\cr`**: обязательный терминатор «возврат каретки» для всех строк в таблице
* **`\noalign`**: вставляет материал между строками \halign или столбцами \valign
* **`\everycr`**: команды (регистровое значение токенов), считываемые после обнаружения \cr
* **`\span`**: команда двойного назначения: \span создает ячейки, охватывающие столбцы или строки, или разворачивает команды в преамбуле таблицы (мы рассмотрим это подробнее)
* **`\omit`**: пропускает шаблоны для конкретной ячейки
* **`\crcr`**: используется в макросах, чтобы избежать ошибок, если пользователи забудут обязательный \cr

Мы встретимся с этими командами на нашем пути по построению таблиц.

### Отдаленные отголоски этих трудностей

Скрыто в [исходном коде TeX](https://www.overleaf.com/latex/examples/typeset-the-source-code-documentation-for-tex-e-tex-or-pdftex/qkgfgyspnhcv) содержится несколько устрашающее введение в тему реализации низкоуровневых команд \halign и \valign, предназначенных для верстки таблиц:

> «Всякий раз, когда \halign и \valign работают, это своего рода чудо, потому что они пересекают столь многие структуры управления TeX. Поэтому, вероятно, эта страница — не лучшее место для новичка, с которого следует начать чтение этой программы; лучше сначала освоить всё остальное.»

Кнут продолжает:

> «Заметьте, что по мере обработки \halign мы бесстрашно передаем управление остальному TeX. В критические моменты вызывается процедура выравнивания, чтобы вмешаться и выполнить какое-то небольшое действие, но большую часть времени эти процедуры просто скрываются на заднем плане. Это что-то вроде постгипнотического внушения.»

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

Автор охотно подтверждает сложность кода и алгоритмов, лежащих в основе возможностей TeX по верстке таблиц, но также выражает восхищение тем огромным объемом возможностей, заключенным в относительно небольшом количестве, пусть и плотного, кода на Pascal (или C).


---

# 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/14-how-do-tex-engines-typeset-tables.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.
