> 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/23-how-does-latex-typeset-headers-and-footers.md).

# Как LaTeX верстает колонтитулы?

## Как LaTeX верстает верхние и нижние колонтитулы?

### Введение

Если вы ищете руководство по изменению верхних и нижних колонтитулов, пожалуйста [посетите нашу страницу помощи](/latex/ru/formatirovanie/02-headers-and-footers.md) потому что эта статья посвящена объяснению механизмов низкого уровня, используемых движками TeX и LaTeX, для создания верхних и нижних колонтитулов.

* **Примечание (обновление)**: В этой статье рассматривается базовый механизм меток LaTeX, использовавшийся до июня 2022 года, когда была введена новая и более универсальная реализация обработки меток в LaTeX. См. [Обзор нового механизма меток в LaTeX](https://www.latex-project.org/help/documentation/ltmarks-doc.pdf) для получения более подробной информации. По соображениям обратной совместимости LaTeX продолжает поддерживать свой устаревший механизм меток. Материал статьи, посвящённый поведению движков TeX, не затронут этими изменениями в LaTeX.
* **Примечание**: в этих обсуждениях повсюду используются термины «LaTeX», «TeX» и «движок TeX», поэтому полезно понимать их значение — см. статью 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 обрабатывает ваш код LaTeX, чтобы получить набранный материал — например, абзацы, таблицы и математические формулы, — ему нужно временно хранить это содержимое в памяти того движка TeX, который используется для обработки вашего кода LaTeX. Для хранения набранного содержимого движки TeX используют последовательность так называемых *узлов*, которые можно представить как переменные по размеру «фрагменты» памяти компьютера (устройства), соединённые вместе в список (см. эту [статью Википедии о связанных структурах данных](https://en.wikipedia.org/wiki/Linked_data_structure)).

![Схематическое изображение того, как движки TeX хранят содержимое с помощью связанных узлов](/files/7b8b23ab930800cce5d39a85d9753d8ea1d5a1ac)

Чтобы представить основные элементы набора текста на основе TeX — такие как символы, клей, коробки, штрафы, керны и [*метки*](#why-were-here-understanding-mark-nodes) (и это лишь некоторые) — движки TeX используют разные *типам* типы узлов. Некоторые узлы, например узлы для коробок, должны хранить больше данных по сравнению с более простыми типами узлов, такими как узлы символов; следовательно, некоторые узлы больше других — для их хранения в памяти требуется больше байтов. При чтении о TeX вы можете встретить такие термины, как *узлы символов*, *узлы клея*, [*узлы меток*](#why-were-here-understanding-mark-nodes) и тому подобное: теперь вы знаете, что это всего лишь названия фрагментов памяти, выделенных для хранения данных, представляющих элемент набора текста TeX.

#### Почему мы здесь: понимание узлов меток

Из многих типов узлов тот, о котором нам нужно поговорить, называется *узлом метки* который создаётся командой `\mark` команду:

```latex
\mark{сохраняемые данные}
```

Это `\mark` команда не создаёт непосредственно никакого набранного содержимого: её аргумент `*сохраняемые данные*` сохраняется в памяти для последующего использования, и создаётся *узлом метки* чтобы содержать адрес памяти *сохраняемые данные*. Как мы увидим, команда `\mark` была создана *специально* для помощи в создании верхних и нижних колонтитулов.

Узлы меток, создаваемые `\mark` командами, «встраиваются» в содержимое страницы и готовы к использованию на заключительных этапах формирования страницы, когда движок TeX готов добавить верхние и нижние колонтитулы к набранной странице (основному тексту). Обычно `*сохраняемые данные*` будет содержать такие материалы, как номера страниц и заголовки/номера глав или разделов — строительные блоки верхних и нижних колонтитулов.

#### ε-TeX добавляет команду \marks

[Версия 2 ε-TeX](https://texdoc.org/serve/e-TeX/0), расширение оригинального TeX Кнута, была опубликована в 1998 году и предоставляет новые возможности вместе с улучшениями существующих функций. Сегодня большинство улучшений ε-TeX уже включены в основные движки TeX: pdfTeX, LuaTeX и XeTeX — см. [**`-etex`** параметр командной строки движков TeX](/latex/ru/drugie-temy/44-tex-engine-command-line-options-for-pdftex-xetex-and-luatex.md) который позволяет использовать расширения ε-TeX.

Оригинальное программное обеспечение TeX Кнута предоставляет команду \mark, которая создаёт только 1 «класс» или «тип» узла метки. Ваш документ может содержать множество команд \mark, но все они создают узлы меток одного и того же «типа» или «класса» — встроенного механизма для их группировки или классификации нет. Это ограничение было снято улучшением ε-TeX: командой \marks, которая поддерживается pdfTeX, LuaTeX и XeTeX:

```latex
\marks n {сохраняемые данные}
```

где `n` это целое число (`0` <= `n` < `32768`), которое определяет узел метки *классом*.

Примечания:

* запись `\marks 0` (то есть `n`=`0`) является синонимом использования оригинальной команды TeX `\mark` команда
* ε-TeX также ввёл переменные меток ([см. далее](#pre-output-checks-looking-for-mark-nodes)) для каждого класса (`n`) метки: `\firstmarks n`, `\topmarks n` и `\botmarks n`. Избранные классы переменных меток могут использоваться для предоставления данных меток для конкретных задач набора.
* LuaTeX увеличил максимальное значение `n` на `65535`, позволяя $$2^{16}$$ классы меток

### Причины использования меток в TeX

Чтобы понять *почему* (и как) движки TeX используют `\mark` (или `\marks`) команду для создания верхних и нижних колонтитулов, нам нужно оценить некоторые «особенности» механизмов движка TeX по формированию страниц — поиску разрывов страниц и выводу готовых страниц в PDF-файл. В действительности эти процессы формирования страницы сложны, но основные принципы/понятия можно упростить, чтобы дать достаточное пояснение и помочь нам понять метки.

По мере того как движок TeX завершает набор отдельных элементов содержимого, таких как абзацы, таблицы или математические формулы, он вызывает внутреннюю процедуру (функцию под названием `build_page(...)`), которая пытается добавить эти только что набранные элементы на страницу, которая в данный момент формируется в памяти. Когда этот новый материал добавляется на создаваемую страницу, TeX также проверяет, не стала ли эта только что добавленная содержимым текущая страница «достаточно заполненной». Если страница заполнена, TeX может создать *разрыв страницы*— отправив содержимое этой страницы на окончательную обработку («упаковку») и последующий вывод в PDF-файл.

Одной из ключевых особенностей заключительного этапа упаковки страницы (композиции) является то, что называется *процедурой вывода* которая, по сути, представляет собой определяемую пользователем последовательность команд, используемую для упаковки страницы содержимого, чтобы подготовить её к отправке в PDF-файл. Один из примеров действия по «упаковке» — добавление верхних и нижних колонтитулов, но существует множество способов использования процедур вывода — например, см. [эту статью в TUGboat](https://tug.org/TUGboat/tb11-1/tb27salomon.pdf). Процедуры вывода — довольно сложная область TeX, поэтому мы не будем вдаваться в подробности здесь: для наших целей достаточно помнить, что заключительный этап формирования страницы включает использование некоторой последовательности команд, заданной пользователем (в совокупности называемой *процедурой вывода*).

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

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

![Схематическое изображение абзаца, пересекающего разрыв страницы](/files/3e1d356a49384c8057d0fb3264358afc8bdc97d7)

Этот пример абзаца показывает, что движок TeX часто обрабатывает (набирает) *в полном объёме*, фрагменты содержимого, которые не могут поместиться на текущей странице — потому что это содержимое выходит за точку, в которой становится необходим разрыв страницы. Напомним, что движки TeX находят разрывы строк, вводя, а затем набирая, *целые абзацы* и, в отличие от некоторых приложений, не используют построчный подход к набору абзацев. Иными словами, TeX набирает *весь* абзац целиком, независимо от того, помещается он на текущей странице или нет (это определяется позже). Кстати, принцип «сначала набрать полностью, затем добавить на текущую страницу» верен и для других типов содержимого TeX, включая таблицы, которые полностью считываются из файла .tex и набираются целиком до любой попытки добавить их на текущую страницу.

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

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

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

![Схематическое изображение места в узлах, где TeX находит разрыв страницы, также показывающее содержимое, удерживаемое для следующей страницы](/files/8b14c8f3cbb20937a4be55db746c4989135d113f)

Напомним, что как только TeX получает «достаточно заполненную» страницу (основную часть), он передаёт это содержимое в то, что называется *процедурой вывода* которое представляет собой последовательность команд, задаваемых пользователем. Среди прочего, процедура вывода добавляет верхние и нижние колонтитулы к основному тексту страницы, завершая страницу и подготавливая её к отправке в PDF-файл.

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

Когда TeX начинает упаковывать текущую страницу, его «текущее внутреннее состояние» *не* определяется всем, что набрано вплоть до места разрыва страницы, поскольку TeX уже *перешёл за эту точку* в вашем файле и обработал дополнительный материал. Если рассматривать место в вашем файле, соответствующее тому, где происходит разрыв страницы, и место, до которого TeX фактически дошёл в вашем `.tex` файле, то два соответствующих внутренних состояния TeX, включая сохранённые данные и значения переменных, могут сильно различаться. Текущее состояние набора TeX обычно находится впереди места разрыва страницы; то есть действия набора TeX *не синхронизированы* с процессом вывода набранных страниц через процедуру вывода.

#### Гипотетический пример: как получить неправильные верхние и нижние колонтитулы

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

```latex
\newtoks\headertoks% новая переменная списка токенов для текста верхнего колонтитула
\newtoks\footertoks% новая переменная списка токенов для текста нижнего колонтитула
% Используйте \global, чтобы гарантировать, что сохранённые данные верхнего или нижнего колонтитула
% доступны везде, включая команды в
% процедуре вывода
\newcommand{\myheader}[1]{\global\headertoks={#1}}
\newcommand{\myfooter}[1]{\global\footertoks={#1}}
```

в которой `\headertoks` и `\footertoks` являются списками токенов, используемыми для хранения текста верхних и нижних колонтитулов.

Кроме того, в нашем гипотетическом примере есть также процедура вывода, которая получает текст верхнего и нижнего колонтитула из текущих значений `\myheader` и `\myfooter`. Как показано на диаграмме, внутри содержимого, предназначенного для текущей страницы, `\myheader` и `\myfooter` устанавливают соответствующие (правильные) значения. Однако `\myheader` и/или `\myfooter` могли бы быть вызваны `\myheader` и `\myfooter` снова, чтобы сбросить текст верхнего/нижнего колонтитула, сохранённый в «внутреннем состоянии TeX», создавая значения, которые не подходят для текущей страницы. Когда процедура вывода создаст верхний и нижний колонтитул, они будут содержать текст, предназначенный для следующей страницы.

![Графика, показывающая неправильные верхние и нижние колонтитулы, создаваемые, если процедура вывода использует только макросы TeX для извлечения текста верхнего и нижнего колонтитулов](/files/f7d446f18f0b545eb328a64c2cdc734639b64cfd)

#### Асинхронное поведение TeX: на помощь приходит команда \mark

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

В [Книга TeX](https://www.amazon.co.uk/TeXbook-Donald-Knuth/dp/0201134489), Дональд Кнут, создатель TeX, описывает эту ситуацию как

> ... процедура вывода TeX отстаёт от его действий по формированию страниц

Из-за этой несинхронизированной связи требуются «специальные средства» в виде *механизма меток*, применяемого через `\mark` (или `\marks n`) команду, чтобы верхние и нижние колонтитулы содержали материал, относящийся к фактической выводимой странице. Команда `\mark` встраивает узлы меток в содержимое страницы, сохраняя адрес памяти содержимого, которое может использоваться для верхнего и нижнего колонтитула данной страницы.

Автор известной и уважаемой книги [TeX по темам](https://www.eijkhout.net/tex/tex-by-topic.html) описывает `\mark` механизм как

> ... основной механизм, с помощью которого процедура вывода может получать информацию о содержимом текущей оборванной страницы, в частности о её верхе и низе.

Это `\mark` команда — это механизм, предназначенный для обхода асинхронной природы алгоритма разбиения на страницы и процедуры вывода в TeX.

![Схематическое изображение данных меток (узлов), встроенных в содержимое тела страницы](/files/a43b6162667143e9c83bdfa5c63cd1cb67b067ca)

### Проверки перед выводом: поиск узлов меток

После того как движок TeX определил место разрыва страницы, он вызывает внутреннюю процедуру (называемую `fire_up()`), которая выполняет множество предварительных обработок перед тем, как процедура вывода завершит формирование страницы и запишет готовую страницу в PDF-файл. Важной частью этих предварительных шагов является установка значений трёх *глобальных переменных меток*: `\botmark`, `\topmark` и `\firstmark` , которые используются для предоставления данных при построении верхних и нижних колонтитулов. Конечно, страница может содержать несколько узлов меток, но они фильтруются, чтобы получить три переменные меток, которые действуют следующим образом:

* **`\botmark`** является меткой, действующей в текущем разрыве страницы; то есть последней меткой, увиденной на *текущего* страницу
* **`\topmark`** является значением `\botmark` из *предыдущей* страницу
* **`\firstmark`** является первой меткой на *текущего* странице — первой меткой между `\topmark` и `\botmark`

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

![Схематическое изображение основных принципов, используемых для определения значений трёх глобальных переменных меток \botmark, \topmark и \firstmark](/files/49cd28bce0e65b3971db1343117cb137610ebae5)

В следующем разделе используются некоторые из приведённых выше пояснений, чтобы показать, как LaTeX набирает верхние и нижние колонтитулы.

### Классы LaTeX: стили страниц и верхние/нижние колонтитулы

Когда вы пишете `\documentclass{*класс*}` где `*класс*` может быть `статью`, `книга`, `отчёт` или `letter`, LaTeX загружает файл с именем `*класс*.cls`; например, `book.cls`, `article.cls` и тому подобное. Эти `.cls` файлы содержат код LaTeX для реализации зависящих от класса вариантов различных команд и функций, ожидаемых в каждом классе документа и предоставляемых им — поведений, общих для всех классов документов. Примеры могут включать зависящие от класса поля макета страницы вместе с зависящими от класса версиями команд, таких как `\section`, `\subsection` и так далее.

Другим важным элементом `.cls` файлов является зависящая от класса реализация стандартных стилей страниц, которые определяют верхние и нижние колонтитулы документов, создаваемых с использованием определённого класса и стиля страницы. Например:

* **`book.cls`** и **`article.cls`** каждый содержат реализации стилей страниц `headings` и `myheadings`
* **`letter.cls`** содержит определения стилей страниц `headings`, `пусто`, `plain` и один под названием `firstpage`
* **`report.cls`** содержит определения стилей страниц `headings` и `myheadings`

Реализации стилей страниц часто зависят от `twoside` опции `\documentclass`— односторонний или двусторонний документ — чтобы верхние и нижние колонтитулы были определены должным образом для левых (чётных) страниц и правых (нечётных) страниц.

Классы документов могут опираться на стандартные определения `plain` или `пусто` стилей страниц, предоставляемые в другом месте в LaTeX — вне `.cls` используемого файла.

#### Подробнее о стилях страниц

Когда вы меняете стиль страницы с помощью `\pagestyle{*какой-либо стиль*}` или `\thispagestyle{*какой-либо стиль*}` LaTeX ожидает найти внутреннюю команду с именем `ps@*какой-либо стиль*`— обычно предоставляемую файлом `.cls` класса документа или, возможно, пакетом, таким как `fancyhdr`. Кстати, под «внутренней командой» мы понимаем команду, являющуюся частью исходного кода LaTeX и имя которой содержит `@` символ [код категории](/latex/ru/drugie-temy/43-table-of-tex-category-codes.md)).

Определение `\ps@*какой-либо стиль*` отвечает за реализацию функций/поведений этого стиля страницы, что включает предоставление определений:

* команд, используемых на заключительных этапах формирования страницы (для добавления верхних и нижних колонтитулов, см. [позже в статье](#commands-for-the-output-routine)):
  * `\@oddhead`
  * `\@oddfoot`
  * `\@evenhead`
  * `\@evenfoot`
* команд для вставки данных меток, связанных с разделами, для использования при генерации верхних и нижних колонтитулов документа, которые содержат названия разделов, номера и тому подобное. Например, стиль `headings` страницы (внутри `book.cls`) определяет следующие команды, создающие метки:
  * `\chaptermark`
  * `\sectionmark`

Мы [дальше рассмотрим команды, генерирующие метки](#mark-commands-and-mark-data), такие как `\chaptermark`, но лишь в качестве примера: когда вы пишете `\chapter{название главы}` окружения `\chaptermark` команда также выполняется, чтобы вставить данные меток, связанные с главой, для последующего создания верхних колонтитулов страницы.

#### Анатомия команд верхнего и нижнего колонтитула, основанных на стиле страницы

Этот раздел рассматривает некоторые основные команды/процессы LaTeX, используемые для создания верхних и нижних колонтитулов, опираясь на объяснения или концепции, представленные ранее в этой статье.

**Модель верхних и нижних колонтитулов LaTeX**

Содержимое (стандартных) верхних и нижних колонтитулов LaTeX основано на двухуровневой иерархии разделов документа: раздел «более высокого уровня», содержащий несколько разделов «более низкого уровня». Для классов book и article это означает:

* `**book**` **классом**: разделы «более высокого уровня» создаются с помощью `\chapter` команд, а разделы «более низкого уровня» — с помощью `\section`, что отражает главы, содержащие множество разделов.
* `**article**` **классом** (при условии двухсторонних документов): разделы «более высокого уровня» создаются с помощью `\section` команд, а разделы «более низкого уровня» — с помощью `\subsection`, что отражает множество подразделов, появляющихся внутри одного и того же раздела.

LaTeX применяет свою «модель» верхних и нижних колонтитулов через свои команды разбиения на разделы, которые «вставляют» узлы меток (через `\mark` команду) для хранения данных, относящихся к создаваемому разделу документа. Например, каждый раз, когда вы пишете `\section{*название раздела*}` будет создан узел метки, содержащий данные, которые отражают `*название раздела*` и номер раздела.

LaTeX использует систему меток, содержащих данные вида `{left}{right}`, в конечном итоге генерируемых через `\mark` команды

```latex
\mark{{left}{right}}
```

, заключённую в слои макросов, предназначенных для того, чтобы скрыть от пользователей детали низкого уровня, которые рассматриваются в последующих разделах этой статьи.

#### Изучаем класс book

Когда `book.cls` файл загружается, одним из его последних действий является выполнение `\pagestyle{headings}` которое устанавливает стиль страницы по умолчанию `headings`, поэтому мы рассмотрим этот стиль страницы подробнее.

Как [было отмечено выше](#more-on-page-styles), функции/свойства `headings` стиля страницы, реализованного классом `книга` , будут определяться (внутренней) командой `\ps@headings` содержащейся в файле `book.cls`. Точное определение `\ps@headings` зависит от того, является ли документ односторонним или двусторонним (по умолчанию для класса `книга` ).

**«Команды меток» и «данные меток»**

Для двусторонних документов, созданных классом `книга` , определение `\ps@headings` создаёт (определяет) две «команды меток»: `\chaptermark` и `\sectionmark` которые создают «данные меток» в форме `{left}{right}`, для использования в верхних и нижних колонтитулах. Эти команды меток отражают модель верхних и нижних колонтитулов LaTeX — основанную на иерархии разделов документа:

* команда раздела «более высокого уровня» (здесь `\chapter`) используется для предоставления «данных меток» для заголовков левых (чётных) страниц. Когда вы начинаете новую главу, написав `\chapter{*название главы*}`, `\chaptermark` вызывается для создания «данных меток», которые отражают эту новую главу — содержащих её `*название главы*` и номер.
* команда раздела «более низкого уровня» (здесь `\section`) используется для предоставления «данных меток» для правых (нечётных) страниц. Когда вы пишете `\section{*section title*}` окружения `\sectionmark` команда будет вызвана для создания «данных меток», отражающих новый раздел — содержащих его `*section title*` и номер. Любые данные меток, предоставленные предыдущей `\chapter` не затрагиваются никакими последующими командами \section.

**\markboth и \markright**

Специфичные для разделов команды меток LaTeX, такие как `\chaptermark` и `\sectionmark`, используют ещё две команды под названием `\markboth` и `\markright` , которые предоставляют фактические данные меток для верхних и нижних колонтитулов. `\markboth` и/или `\markright` могут включать команды для оформления текста верхнего или нижнего колонтитула, например для перевода его в верхний регистр.

Для документов, создаваемых с использованием `книга` значения класса по умолчанию (двусторонний, `headings` оформления страницы), команды, генерирующие метки, работают следующим образом:

* `\chaptermark` генерирует данные метки с помощью `\markboth`
* `\sectionmark` генерирует данные метки `\markright`

`\markboth` и `\markright` являются макросами, которые в конечном счёте используют примитивную (встроенную, низкоуровневую) `\mark` команду для фактической вставки меток, сгенерированных внутри команд секционирования.

`\markboth` имеет вид

* **`\markboth{left}{right}`**: вставляет метку (узел), используя `\mark{{left}{right}}` в результате получается узел метки, содержащий пару значений в фигурных скобках `{left}{right}`.

`\markright` имеет вид

* **`\markright{newright}`**: вставляет метку (узел), используя `\mark{{currentleft}{newright}}`; то есть изменяет текущее значение `правый` на `newright` но текущее значение `левый` (то есть `currentleft`) не изменяется, в результате чего получается узел метки, содержащий пару значений в фигурных скобках `{currentleft}{newright}`.

Поведение `\markboth` и `\markright` поддерживают двухуровневую иерархию разделов, например документ, содержащий несколько разделов в каждой главе.

В качестве примеров для (двустороннего) `книга` класса документа (с использованием стиля страницы headings):

* `\chaptermark` использует `\markboth` для установки:
  * один `{left}` поле, которое набирает CHAPTER . прописными буквами.
  * поле {right}, которое пустое (`{}`)
* `\sectionmark` использует `\markright` для установки `{right}` поля метки для набора, также прописными буквами.

Чтобы понять почему `\sectionmark` использует `\markright` мы можем заметить, что каждая новая `\section` команда должна:

* вставлять новую метку, содержащую данные для этого `\section` (например, её заголовок и номер).
* но *не* влиять на значения данных метки для текущего `\chapter` в котором эта конкретная `\section` команда появляется

По этим причинам `\section` команда вызывает `\sectionmark` которая использует `\markright` для создания `\section`-связанной метки: она обновляет `{right}` поле данных метки, но не влияет на текущее `{left}` значение поля данных метки, которое было установлено текущей `\chapter`.

Примечание: исходный код LaTeX содержит предупреждение:

> Команды маркировки работают довольно хорошо для правых меток, «нумеруемых внутри» левых меток — например, левая метка изменяется командой \chapter, а правая метка изменяется командой \section. Однако это даёт несколько аномальные результаты, если на одной странице встречаются 2 \markboth.

**Команды для процедуры вывода**

Это `\ps@headings` команда реализует определения следующих команд

* `\@oddhead`
* `\@oddfoot`
* `\@evenhead`
* `\@evenfoot`

которые используются процедурой вывода для добавления верхних и нижних колонтитулов на завершающем этапе формирования страницы. Например, `book.cls` устанавливает `\@oddfoot` и `\@evenfoot` в значение `\@empty`, которое определено как `\def\@empty{}`, таким образом `\ps@headings` создаёт пустые нижние колонтитулы на нечётных и чётных страницах:

```latex
\let\@oddfoot\@empty
\let\@evenfoot\@empty
```

Верхние колонтитулы определяются так:

```latex
\def\@evenhead{\thepage\hfil\slshape\leftmark}%
\def\@oddhead{{\slshape\rightmark}\hfil\thepage}%
```

где

* `\leftmark` извлекает `{left}` значение из пары `{left}{right}` метки
* `\rightmark` извлекает `{right}` значение из пары `{left}{right}` метки
* \thepage выводит текущий номер страницы

По сути, эти реализации `\@evenhead` и `\@oddhead` дают следующие результаты:

* `\@evenhead`: номер страницы появляется слева в верхнем колонтитуле, а содержимое `\leftmark`, оформленное командой шрифта `\slshape`, выводится справа в верхнем колонтитуле — промежуточное пустое пространство обеспечивается очень гибкой `\hfil` клея.
* `\@oddhead`: содержимое `\rightmark`, оформленное командой шрифта `\slshape`, появляется слева в верхнем колонтитуле, а текущий номер страницы выводится справа в верхнем колонтитуле — и снова промежуточное пустое пространство обеспечивается `\hfil` клея.

Однако остаётся ключевой вопрос: *какая* `{left}{right}` пара метки используется `\leftmark` и `\rightmark`: другими словами, откуда они получают свои значения данных меток?

Как [было отмечено выше](#filtering) но [объясняется ниже](#explainfiltering), на завершающих этапах формирования страницы любые метки, содержащиеся на страницах документа, «фильтруются» и используются для установки значений трёх глобальных переменных меток: `\botmark`, `\topmark` и `\firstmark`. Из-за [структуры меток LaTeX](#latexs-model-of-headers-and-footers), каждая из этих трёх переменных меток в итоге будет содержать значение `{left}{right}` для некоторой пары значений `{left}` и `{right}` и именно они обеспечивают фактические `{left}{right}` пара меток (поля) для `\leftmark` и `\rightmark`:

* `\leftmark` извлекает `левый` значение из `{left}{right}` пары меток (полей), предоставляемой `\botmark`
* `\rightmark` извлекает `правый` значение из `{left}{right}` пары меток, предоставляемой `\firstmark`

Примечание `\markboth` и `\markright` может содержать команды для оформления текста верхнего и нижнего колонтитулов — например, для преобразования в прописные буквы.

### Примеры с использованием низкоуровневых команд LaTeX

Следующие примеры демонстрируют внесение изменений в стили страниц или верхние и нижние колонтитулы путём переопределения некоторых низкоуровневых (внутренних) команд LaTeX, обсуждаемых в этой статье (тех, которые содержат символ @). Мы не рекомендуем этот способ изменения верхних и нижних колонтитулов, но он доступен тем, кому он нужен (например, авторам пакетов). Предпочтительное решение для изменения верхних и нижних колонтитулов — использование [`fancyhdr` пакет](https://ctan.org/pkg/fancyhdr?lang=en), которое обсуждается в [справочной статье Overleaf](/latex/ru/formatirovanie/02-headers-and-footers.md).

#### Определение минимального стиля страницы

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

Пример начинается с изменения категории кода символа `@` до 11, чтобы его можно было использовать в именах макросов. Команда `\ps@demostyle` реализует наш минимальный стиль страницы, переопределяя команды, используемые (в процедуре вывода) для создания верхних и нижних колонтитулов: `\@oddhead`, `\@oddfoot`, `\@evenhead` и `\@evenfoot`. Обратите внимание на `twoside` параметр в нашем `\documentclass` объявлении — которое использует `статью` класс.

```latex
\documentclass[twoside]{article}
\catcode`@=11
\newcommand{\ps@demostyle}{%
\renewcommand\@oddfoot{\hfil Нижний колонтитул нечётной страницы\hfil}%
\renewcommand\@evenfoot{\hfil Нижний колонтитул чётной страницы\hfil}%
\renewcommand\@evenhead{\thepage\hfil Верхний колонтитул чётной страницы}%
\renewcommand\@oddhead{Верхний колонтитул нечётной страницы\hfil\thepage}}
\catcode`@=12
\title{Demonstrating a page style}
\author{Overleaf}
\date{Август 2022}
\begin{document}
\pagestyle{demostyle}
\maketitle
\newpage
\section{Introduction}
\newpage
\section{More material}
\end{document}
```

[Откройте этот пример в Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Creating+a+new+page+style\&snip=%5Cdocumentclass%5Btwoside%5D%7Barticle%7D%0A%5Ccatcode%60%40%3D11%0A%5Cnewcommand%7B%5Cps%40demostyle%7D%7B%25%0A%5Crenewcommand%5C%40oddfoot%7B%5Chfil+The+odd-page+footer%5Chfil%7D%25%0A%5Crenewcommand%5C%40evenfoot%7B%5Chfil+The+even-page+footer%5Chfil%7D%25%0A%5Crenewcommand%5C%40evenhead%7B%5Cthepage%5Chfil+The+even-page+header%7D%25%0A%5Crenewcommand%5C%40oddhead%7BThe+odd-page+header%5Chfil%5Cthepage%7D%7D%0A%5Ccatcode%60%40%3D12%0A%5Ctitle%7BDemonstrating+a+page+style%7D%0A%5Cauthor%7BOverleaf%7D%0A%5Cdate%7BAugust+2022%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cpagestyle%7Bdemostyle%7D%0A%5Cmaketitle%0A%5Cnewpage%0A%5Csection%7BIntroduction%7D%0A%5Cnewpage%0A%5Csection%7BMore+material%7D%0A%5Cend%7Bdocument%7D)

#### Изменение верхних колонтитулов для класса book

Следующий пример изменяет верхние колонтитулы для класса book путём переопределения `\@oddhead` и `\@evenhead` так, чтобы верхние колонтитулы на нечётных и чётных страницах содержали текущий номер страницы и заголовок главы. Обратите внимание, как вторая `\chapter` команда использует необязательный краткий заголовок главы `[Краткий заголовок]` который теперь используется в тексте колонтитула вместо полного заголовка.

`\section` команды не влияют на содержимое колонтитулов, потому что наши переопределения колонтитулов используют только `\leftmark` которая получает сведения о текущей главе. Чтобы получить сведения о текущем разделе, нам нужно было бы использовать `\rightmark` в определении `\@oddhead` и/или `\evenhead`.

```latex
\documentclass{book}
% NB: категория кода '@' временно изменена на 11
% чтобы разрешить его использование в именах команд
\catcode `@=11
% Сделать \@oddfoot и \evenfoot эквивалентными \@empty
% чтобы сделать их пустыми
\let\@oddfoot\empty\let\evenfoot\empty
% Переопределить \@oddhead и \@evenhead
\renewcommand{\@oddhead}{\leftmark\hfil\thepage}
\renewcommand{\@evenhead}{\thepage\hfil\leftmark}
\catcode `@=12
% Использовать удобно маленький размер страницы
\usepackage[paperheight=16cm,paperwidth=12cm,textwidth=10cm]{geometry}
\title{Мемуары пользователя \TeX{}}
\author{Overleaf}
\begin{document}
\frontmatter
\maketitle
Это вводная часть, в которой используются римские цифры.
\mainmatter
\chapter{Where do I start?}
Глава 1: Короткая глава.
\newpage
\section{В начале...}
Раздел.
\chapter[The short title]{A chapter with a very long title, making it unsuitable for headers}
\newpage
\section{Ещё один раздел}
С небольшим содержанием.
\newpage
\section{What, another section?}
Тоже с небольшим содержанием.
\end{document}
```

[Откройте этот пример в Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Changing+headers+for+the+book+class\&snip=%5Cdocumentclass%7Bbook%7D%0A%25+NB%3A+category+code+of+%27%40%27+temporarily+changed+to+11%0A%25+to+enable+its+use+in+command+names%0A%5Ccatcode+%60%40%3D11%0A%25+Let+%5C%40oddfoot+and+%5Cevenfoot+be+equivalent+to+%5C%40empty%0A%25+to+make+them+blank+%28empty%29%0A%5Clet%5C%40oddfoot%5Cempty%5Clet%5Cevenfoot%5Cempty%0A%25+Redefine+%5C%40oddhead+and+%5C%40evenhead%0A%5Crenewcommand%7B%5C%40oddhead%7D%7B%5Cleftmark%5Chfil%5Cthepage%7D%0A%5Crenewcommand%7B%5C%40evenhead%7D%7B%5Cthepage%5Chfil%5Cleftmark%7D%0A%5Ccatcode+%60%40%3D12%0A%25+Use+a+conveniently+small+page+size%0A%5Cusepackage%5Bpaperheight%3D16cm%2Cpaperwidth%3D12cm%2Ctextwidth%3D10cm%5D%7Bgeometry%7D%0A%5Ctitle%7BMemoirs+of+a+%5CTeX%7B%7D+user%7D%0A%5Cauthor%7BOverleaf%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cfrontmatter%0A%5Cmaketitle%0AThis+is+frontmatter+which+uses+Roman+numerals.%0A%5Cmainmatter%0A%5Cchapter%7BWhere+do+I+start%3F%7D%0AChapter+1%3A+A+short+chapter.%0A%5Cnewpage%0A%5Csection%7BIn+the+beginning...%7D%0AA+section.%0A%5Cchapter%5BThe+short+title%5D%7BA+chapter+with+a+very+long+title%2C+making+it+unsuitable+for+headers%7D%0A%5Cnewpage%0A%5Csection%7BAnother+section%7D%0AWith+little+content.%0A%5Cnewpage%0A%5Csection%7BWhat%2C+another+section%3F%7D%0AAlso+with+little+content.%0A%5Cend%7Bdocument%7D)

#### Использование расширенных команд меток ε-TeX

Это `книга` класс использует следующие определения `\@evenhead` и `\@oddhead` для создания верхних колонтитулов:

```latex
\def\@evenhead{\thepage\hfil\slshape\leftmark}
\def\@oddhead{{\slshape\rightmark}\hfil\thepage}
```

где команды `\leftmark` и `\rightmark` определяются как

```latex
\def\leftmark{\expandafter\@leftmark\botmark\@empty\@empty}
\def\rightmark{\expandafter\@rightmark\firstmark\@empty\@empty}
```

Используя расширенные команды ε-TeX и эквивалентность между классом меток 0 ε-TeX и исходными командами TeX, мы можем:

* переписать `\leftmark` чтобы заменить `\botmark` с помощью `\botmarks0` эквивалентной, а
* переписать `\rightmark` чтобы заменить `\firstmark` с помощью `\firstmarks0` эквивалентной

Эти переопределения дают

```latex
\renewcommand{\leftmark}{\expandafter\@leftmark\botmarks0\relax\@empty\@empty}
\renewcommand{\rightmark}{\expandafter\@rightmark\firstmarks0\relax\@empty\@empty}
```

Обратите внимание на использование `\relax` для прекращения поиска TeX дополнительных цифр — также можно заменить `\relax` на пробел, который будет выполнять роль разделителя.

Следующий пример выдаёт результат, идентичный исходным определениям `\leftmark` и `\rightmark`.

```latex
\documentclass{book}
% Переопределить \leftmark и \rightmark, чтобы использовать
% \botmarks0 и \firstmarks0 соответственно
% NB: категория кода '@' временно изменена на 11
% чтобы разрешить его использование в именах команд
\catcode `@=11
\renewcommand{\leftmark}{\expandafter\@leftmark\botmarks0\relax\@empty\@empty}
\renewcommand{\rightmark}{\expandafter\@rightmark\firstmarks0\relax\@empty\@empty}
\catcode `@=12
% Использовать удобно маленький размер страницы
\usepackage[paperheight=16cm,paperwidth=12cm,textwidth=10cm]{geometry}
\title{Мемуары пользователя \TeX{}}
\author{Overleaf}
\begin{document}
\frontmatter
\maketitle
Это вводная часть, в которой используются римские цифры.
\mainmatter
\chapter{Where do I start?}
Глава 1: Короткая глава.
\newpage
\section{В начале...}
Раздел.
\newpage
Ещё один раздел.
\end{document}
```

[Откройте этот пример в Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Using+%CE%B5-TeX%E2%80%99s+extended+marks+command\&snip=%5Cdocumentclass%7Bbook%7D%0A%25+Redefine+%5Cleftmark+and+%5Crightmark+to+use+%0A%25+%5Cbotmarks0+and+%5Cfirstmarks0+respectively%0A%25+NB%3A+category+code+of+%27%40%27+temporarily+changed+to+11%0A%25+to+enable+its+use+in+command+names%0A%5Ccatcode+%60%40%3D11%0A%5Crenewcommand%7B%5Cleftmark%7D%7B%5Cexpandafter%5C%40leftmark%5Cbotmarks0%5Crelax%5C%40empty%5C%40empty%7D%0A%5Crenewcommand%7B%5Crightmark%7D%7B%5Cexpandafter%5C%40rightmark%5Cfirstmarks0%5Crelax%5C%40empty%5C%40empty%7D%0A%5Ccatcode+%60%40%3D12%0A%25+Use+a+conveniently+small+page+size%0A%5Cusepackage%5Bpaperheight%3D16cm%2Cpaperwidth%3D12cm%2Ctextwidth%3D10cm%5D%7Bgeometry%7D%0A%5Ctitle%7BMemoirs+of+a+%5CTeX%7B%7D+user%7D%0A%5Cauthor%7BOverleaf%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cfrontmatter%0A%5Cmaketitle%0AThis+is+frontmatter+which+uses+Roman+numerals.%0A%5Cmainmatter%0A%5Cchapter%7BWhere+do+I+start%3F%7D%0AChapter+1%3A+A+short+chapter.%0A%5Cnewpage%0A%5Csection%7BIn+the+beginning...%7D%0AA+section.%0A%5Cnewpage%0AAnother+section.%0A%5Cend%7Bdocument%7D)

**Заметки об ε-TeX**

Как [как было отмечено выше](#etex), ε-TeX вводит `\marks` команду:

```latex
\marks n {сохраняемые данные}
```

который расширяет исходную `\mark` возможность движка TeX Кнута и доступен во всех трёх основных движках TeX: pdfTeX, LuaTeX и XeTeX.

Реализация ε-TeX также вводит новые глобальные переменные меток `\firstmarks n`, `\botmarks n` и `\topmarks n`: по одной для каждого класса `n`. Эти переменные меток, основанные на классах, определяются [с помощью описанных выше механизмов](#pre-output-checks-looking-for-mark-nodes), и все могут использоваться при формировании верхних и нижних колонтитулов.

Вы можете использовать любой из $$2^{15}$$ = 32768 классов меток, от 0 до 32767, в переопределениях `\leftmark` или `\rightmark`. Это предполагает, что вы предоставили (вставили) подходящие данные метки для выбранного вами класса меток, `n`, через `\marks n{{left}{right}}`.

Обратите внимание, что LuaTeX предоставляет $$2^{16}$$ = 65536 классов меток, при этом `n` их номера варьируются от 0 до 65535.

**Пример использования класса меток 10**

Этот пример демонстрирует использование класса меток 10 (выбранного случайно) для создания верхних колонтитулов документа. Образец документа набирает 6 страниц, содержащих последовательность меток, представленную в [разобранном примере в конце этой статьи](#a-worked-example-to-show-how-tex-engines-determine-values-for-botmark-topmark-and-firstmark). Изучение этого примера покажет, почему движок TeX выбрал определённую метку, $$\alpha$$, $$\beta$$, $$\gamma$$ и $$\delta$$, для использования в каждом из колонтитулов.

Мы начинаем с определения удобного макроса, `\domark`, который использует `\marks 10` для вставки данных метки, следующих соглашению LaTeX `{left}{right}` соглашению:

```latex
\newcommand{\domark}[2]{\marks 10{{#1}{#2}}}
```

Метки класса 10 становятся доступными механизму верхних и нижних колонтитулов LaTeX путём переопределения `\leftmark` и `\rightmark`— с добавлением небольшой дополнительной информации:

```latex
\renewcommand{\leftmark}{\expandafter\@leftmark\botmarks10 \@empty\@empty{} (via \texttt{\string\botmarks10})}
\renewcommand{\rightmark}{\expandafter\@rightmark\firstmarks10 \@empty\@empty{} (via \texttt{\string\firstmarks10})}
```

После вставки нескольких меток (класса 10) движок TeX (здесь pdfTeX) любезно создаёт глобальные переменные меток для класса 10 —`\botmarks10`, `\topmarks10` и `\firstsmarks10` какая `\leftmark` и `\rightmark` используются для создания верхних колонтитулов.

```latex
\documentclass{book}
% Короткая команда для использования меток класса 10
% и следующая структуре меток LaTeX {left}{right}
\newcommand{\domark}[2]{\marks 10{{#1}{#2}}}
% Переопределить \leftmark и \rightmark, чтобы использовать
% \botmarks10 и \firstmarks10 соответственно
\catcode`@=11
\renewcommand{\leftmark}{\expandafter\@leftmark\botmarks10 \@empty\@empty{} (via \texttt{\string\botmarks10})}
\renewcommand{\rightmark}{\expandafter\@rightmark\firstmarks10 \@empty\@empty{} (via \texttt{\string\firstmarks10})}
\catcode`@=12
\title{Demonstrating \(\varepsilon\)-\TeX’s enhanced marks}
\author{Overleaf}
\date{Август 2022}
\begin{document}

Страница 1: Метки не добавлены, поэтому все переменные меток остаются в инициализированном состоянии: пустые (NULL).

\newpage
Страница 2: На эту страницу добавлена метка $\alpha$ через

\verb|\domark{$\alpha$-left}{$\alpha$-right}|\domark{$\alpha$-left}{$\alpha$-right}

\newpage
Страница 3: На эту страницу не добавлено новых меток.

\newpage
Страница 4: На эту страницу через добавлены метка $\beta$, за которой следует метка $\gamma$

\verb|\domark{$\beta$-left}{$\beta$-right}|

\verb|\domark{$\gamma$-left}{$\gamma$-right}|.
\domark{$\beta$-left}{$\beta$-right}
\domark{$\gamma$-left}{$\gamma$-right}

\newpage
Страница 5: На эту страницу через добавлена метка $\delta$

\verb|\domark{$\delta$-left}{$\delta$-right}|
\domark{$\delta$-left}{$\delta$-right}

\newpage
Страница 6: На эту страницу не добавлено меток.
\end{document}
```

[Откройте этот пример в Overleaf](https://www.overleaf.com/docs?engine=pdflatex\&snip_name=Using+e-TeX+global+marks+variables\&snip=%5Cdocumentclass%7Bbook%7D%0A%25+A+short+command+to+use+marks+with+class+10%0A%25+and+following+LaTeX%27s+mark+structure+%7Bleft%7D%7Bright%7D%0A%5Cnewcommand%7B%5Cdomark%7D%5B2%5D%7B%5Cmarks+10%7B%7B%231%7D%7B%232%7D%7D%7D%0A%25+Redefine+%5Cleftmark+and+%5Crightmark+to+use+%0A%25+%5Cbotmarks10+and+%5Cfirstmarks10+respectively%0A%5Ccatcode%60%40%3D11%0A%5Crenewcommand%7B%5Cleftmark%7D%7B%5Cexpandafter%5C%40leftmark%5Cbotmarks10+%5C%40empty%5C%40empty%7B%7D+%28via+%5Ctexttt%7B%5Cstring%5Cbotmarks10%7D%29%7D%0A%5Crenewcommand%7B%5Crightmark%7D%7B%5Cexpandafter%5C%40rightmark%5Cfirstmarks10+%5C%40empty%5C%40empty%7B%7D+%28via+%5Ctexttt%7B%5Cstring%5Cfirstmarks10%7D%29%7D%0A%5Ccatcode%60%40%3D12%0A%5Ctitle%7BDemonstrating+%5C%28%5Cvarepsilon%5C%29-%5CTeX%E2%80%99s+enhanced+marks%7D%0A%5Cauthor%7BOverleaf%7D%0A%5Cdate%7BAugust+2022%7D%0A%5Cbegin%7Bdocument%7D%0A%0APage+1%3A+No+marks+added+so+all+mark+variables+remain+in+their+initialized+state%3A+empty+%28NULL%29.%0A%0A%5Cnewpage%0APage+2%3A+%24%5Calpha%24-mark+added+to+this+page+via%0A%0A%5Cverb%7C%5Cdomark%7B%24%5Calpha%24-left%7D%7B%24%5Calpha%24-right%7D%7C%5Cdomark%7B%24%5Calpha%24-left%7D%7B%24%5Calpha%24-right%7D%0A%0A%5Cnewpage%0APage+3%3A+No+new+marks+added+to+this+page.%0A%0A%5Cnewpage%0APage+4%3A+%24%5Cbeta%24-mark+followed+by+%24%5Cgamma%24-mark+added+to+this+page+via%0A%0A%5Cverb%7C%5Cdomark%7B%24%5Cbeta%24-left%7D%7B%24%5Cbeta%24-right%7D%7C%0A%0A%5Cverb%7C%5Cdomark%7B%24%5Cgamma%24-left%7D%7B%24%5Cgamma%24-right%7D%7C.%0A%5Cdomark%7B%24%5Cbeta%24-left%7D%7B%24%5Cbeta%24-right%7D%0A%5Cdomark%7B%24%5Cgamma%24-left%7D%7B%24%5Cgamma%24-right%7D%0A%0A%5Cnewpage%0APage+5%3A+%24%5Cdelta%24-mark+added+to+this+page+via%0A%0A%5Cverb%7C%5Cdomark%7B%24%5Cdelta%24-left%7D%7B%24%5Cdelta%24-right%7D%7C%0A%5Cdomark%7B%24%5Cdelta%24-left%7D%7B%24%5Cdelta%24-right%7D%0A%0A%5Cnewpage%0APage+6%3A+No+marks+added+to+this+page.%0A%5Cend%7Bdocument%7D)

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

![Изображение, показывающее вывод кода LaTeX с использованием расширенных команд меток ε-TeX](/files/f9a11a69cb8903d2c53c57a59bc96642c2098333)

* **Примечание**: Верхний колонтитул на странице 1 создаётся в тот момент, когда все три переменные меток для класса 10 —`\botmarks10`, `\topmarks10` и `\firstsmarks10`— пусты. В результате `\rightmark` (для страницы 1) вставляет только последний фрагмент колонтитула: `(через \texttt{\string\firstmarks10})`, как показано на иллюстрации выше.

## Разобранный пример, показывающий, как движки TeX определяют значения для \botmark, \topmark и \firstmark

![Db.gif](/files/f6ce6bab6ac321fea22890320c9da39c22307149)![Db.gif](/files/f6ce6bab6ac321fea22890320c9da39c22307149) Кажется уместным воспроизвести использование Кнутом двойных знаков «опасный поворот» (изображение любезно предоставлено [этот сайт](http://www.truetex.com/db.htm)) потому что материал довольно низкоуровневый и «заглядывает под капот» — хотя мы надеемся, что он может быть интересен смелым читателям, желающим разобраться в ещё нескольких деталях.

Следующее обсуждение тесно основано на последнем примере на странице 258 [Книга TeX](https://www.amazon.co.uk/TeXbook-Donald-Knuth/dp/0201134489). Здесь мы отредактировали и перенабрали этот пример для тех, у кого нет доступа к The TeXbook:

![Отредактированная и перенабранная версия примера со страницы 258 The TeXbook](/files/90e27a6e95a93dbe33563cce8c93fa5f8b7df5c4)

Таблица, представленная на этой иллюстрации, воспроизведена по таблице, предоставленной Кнутом, но, как и в оригинале, без объяснения того, как она была получена. Здесь мы разберём это, чтобы привести дополнительные сведения, показывающие, как были получены эти значения `\botmark`, `\topmark` и `\firstmark` были получены — для получения этих сведений потребовалось исследовать исходный код движка TeX!

Процесс установки значений для `\botmark`, `\topmark` и `\firstmark` можно кратко изложить в трёх коротких фрагментах псевдокода, как показано на следующей схеме и в последующих пояснениях:

1. Проверка перед содержимым
2. Цикл по содержимому
3. Проверка после содержимого

Примечание:

* Проверки на шаге 1 «Проверка перед содержимым» и шаге 3 «Проверка после содержимого» выполняются один раз на страницу.
* Шаг 2 «Цикл по содержимому» включает в себя просмотр TeX содержимого страницы в поисках узлов меток и использование их для установки значений переменных меток, как показано.

![Изображение, показывающее версии кода на псевдокоде, используемого для установки значений трёх глобальных переменных меток, применяемых движками TeX](/files/8589b8370d66abfad2e491a6f28c04f09a45bd8e)

Каждый раз, когда TeX находит подходящее разбиение страницы, он отправляет содержимое этой страницы на финальную обработку, выполняя эти (три) шага обработки меток для каждой страницы в вашем документе. Шаги обработки, обозначенные 1, 2 и 3, упоминаются в итоговой схеме в этом разделе.

Заметьте, что:

* до обработки первой страницы все три глобальные переменные меток `\botmark`, `\topmark` и `\firstmark` были инициализированы как пустые (NULL).
* итоговые значения `\botmark`, `\topmark` и `\firstmark` определённые в конце *предыдущей* страницы становятся (входными) значениями для обработки *текущего* страницы — той, которая обрабатывается.

Следующие фрагменты кода являются ***псевдокодом*** полученным (суммированным) из реального исходного кода движка TeX. Цель — дать краткое резюме кода, помогающее продемонстрировать ключевые принципы.

**Шаг 1: Проверка перед содержимым** Прежде чем TeX просматривает фактическое содержимое текущей страницы, он проверяет, является ли текущее `\botmark` значение — то есть полученное из *предыдущей* страницы — пустым (NULL):

```latex
if(\botmark != NULL)
{
   \topmark = \botmark;
   \firstmark= NULL;
}
```

В этой проверке, если `\botmark` (из *предыдущей* страницы) является *не* пустым:

* `\topmark` для *текущего* страницы устанавливается в *предыдущей* страничное `\botmark` значения
* `\firstmark`, для *текущего* страницы (которая обрабатывается) устанавливается в пустое значение (NULL): начинайте эту страницу, предполагая, что нет `\mark` узлов.

Обратите внимание, что эта проверка выполняется *один раз* для каждой обрабатываемой страницы.

**Шаг 2: Цикл по содержимому** Далее TeX проходит по содержимому страницы; часть этого цикла включает поиск `\mark` узлов:

```latex
if(type(node)==mark_node)
{
   if(\firstmark==NULL)
   {
      \firstmark=node(text);
   }
   \botmark= node(text);
}
```

Эта проверка применяется к каждому узлу метки, расположенному внутри (содержащемуся в) текущей страницы. Предыдущая проверка (шаг 1 выше) могла установить `\firstmark` в пустое значение, поэтому самая первая метка, найденная на текущей странице, становится значением `\firstmark` и `\botmark`. Любой *последующий* `\mark` узел, обнаруженный при выполнении этого цикла, не изменит значение `\firstmark`, потому что оно уже не пустое (NULL), но `\botmark` обновляется — потому что именно в этом состоит назначение `\botmark`: хранить последний увиденный `\mark` узел для этой страницы.

**Шаг 3: Проверка после содержимого** После прохождения по содержимому страницы TeX применяет следующую, финальную, проверку, которая также выполняется один раз на страницу:

```latex
if((\topmark != NULL)&&(\firstmark==NULL))
{
	\firstmark= \topmark;
}
```

* Если `\topmark` не пусто (NULL), мы знаем из шага 1, что `\botmark` для предыдущей страницы не было пустым (NULL).
* Если `\firstmark` всё ещё пусто, то мы не видели никаких `\mark` узлов, потому что проверка на шаге 2 не сработала; следовательно, `\firstmark` устанавливается в значение `\topmark` которое также является значением `\botmark` с предыдущей страницы.

После последовательного применения этих трёх шагов ко всем 6 страницам нашего примера значения `\botmark`, `\topmark` и `\firstmark` получаются с использованием переходов, показанных на диаграмме ниже, где:

* светло-синие скруглённые прямоугольники — это конечные значения маркерных переменных для каждой страницы
* светло-серые скруглённые квадраты представляют промежуточные значения, возникающие в ходе обработки
* помеченные стрелки обозначают изменения значений маркерных переменных согласно шагам 1, 2 или 3 на диаграмме выше — либо что значение не было изменено ни одним из шагов; помечено «без изменений».

Следующая диаграмма показывает, как три фрагмента псевдокода порождают конечные значения `\botmark`, `\topmark` и `\firstmark` перечисленные в таблице, содержащейся на странице 258 книги The TeXbook.

![Диаграмма переходов, сопровождающая пример со страницы 258 книги The TeXbook, показывающая внутренние переходы по мере того, как глобальным маркерным переменным присваиваются их значения](/files/b52a53cfca512cc2d0286c1ecc35878518fa2caa)


---

# 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/23-how-does-latex-typeset-headers-and-footers.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.
