> For the complete documentation index, see [llms.txt](https://ayakaleaf-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://ayakaleaf-pro.ayaka.space/latex/ru/drugie-temy/20-how-tex-macros-actually-work-part-2.md).

# Как на самом деле работают макросы TeX: часть 2

[Часть 1](/latex/ru/drugie-temy/19-how-tex-macros-actually-work-part-1.md) [Часть 2](/latex/ru/drugie-temy/20-how-tex-macros-actually-work-part-2.md) [Часть 3](/latex/ru/drugie-temy/21-how-tex-macros-actually-work-part-3.md) [Часть 4](/latex/ru/drugie-temy/22-how-tex-macros-actually-work-part-4.md) [Часть 5](/latex/ru/drugie-temy/23-how-tex-macros-actually-work-part-5.md) [Часть 6](/latex/ru/drugie-temy/24-how-tex-macros-actually-work-part-6.md)

## Введение: История в картинках

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

### Рисунок 1: Глаза готовы

Предположим, что TeX получил некоторый ввод из `.tex` файла и собирается обработать нашу строку символов `Hello World \jobname` содержащуюся в абзаце текста. Он будет по очереди проверять каждый символ и изучать его код категории.

![Глаза TeX, готовые сканировать строку текста](/files/8f1a0433567b1dc40fe3b667142c2e1ce90e11b5)

### Рисунок 2: Обработка кодов категории

На следующем рисунке мы в общих чертах видим (с дополнительными подробностями ниже), как TeX реагирует на несколько разных кодов категории. Заметьте, всего существует 16 кодов категории, но для простоты мы показываем использование только трёх: 11, 10 и 0. Другие коды символов становятся важными во время процессов верстки TeX, таких как построение таблиц, набор математических формул и распознавание параметров макросов.

![Реакция TeX на несколько разных кодов категории](/files/fe4b943633b14ea089c7dff2d1782d46ddc0f8a5)

#### Примечания к Рисунку 2

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

* **(зелёные глаза)** TeX увидит, что каждый из этих символов имеет код категории 11 («буква»), и передаст эти символы для набора как часть абзаца, который он строит. Однако TeX передаёт (использует) не только сам код символа, а, вместо этого, использует пару чисел (код символа, код категории), чтобы вычислить составное целое значение, называемое *символьным токеном* (см. ниже). Как только этот токен символа создаётся, он входит во внутренние процессы/алгоритмы набора TeX.
* **(синие глаза)** TeX видит пробел (ASCII 32) с кодом категории 10 («пробельные символы») — отметим, что, как обсуждалось, вполне возможно, что код категории пробела (ASCII 32) или любого символа был изменён на другое значение до того, как он был прочитан TeX.

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

* **(красные глаза)** Здесь TeX обнаружил символ с очень важным кодом категории: 0 (символ экранирования).

Символ экранирования —*любой* символ с кодом категории 0 — сообщает TeX переключиться в особый режим чтения и внимательно просканировать (прочитать) последующие символы, поскольку они обозначают имя *команда*, а не текст, предназначенный для набора. В литературе по TeX вы также увидите, что термин «command» обозначается как *управляющей последовательности*. После того как TeX видит символ экранирования, он проверяет код категории символа, который следует *сразу за ним*; это связано с тем, что TeX распознаёт два типа команд:

* многобуквенные команды, называемые *управляющих слов*: символ, непосредственно следующий за символом экранирования, имеет код категории 11. Все последующие символы с кодом категории 11 считаются частью имени команды. TeX перестанет искать символы, входящие в имя команды, когда обнаружит любой символ, который *не* не имеет кода категории 11 — например, пробельный символ с кодом категории 10.
* односимвольные команды, называемые *управляющими символами*: символ, непосредственно следующий за символом экранирования *не* не имеет кода категории 11.

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

### Рисунок 3: Обработка кода категории 11 («буквы»)

В Части 1 этой серии мы отмечали, что каждый символ, который TeX читает из своего ввода, описывается двумя целыми числами:

* код символа: целое число, определяющее числовое представление символа;
* код категории: значение от 0 до 15, которое TeX присваивает каждому символу, который может появиться во входных данных.

TeX использует эти два элемента информации на следующем этапе своей обработки: создании токенов символов.

Рисунок 3 развивает Рисунок 2, показывая, что делает TeX с этими входными символами, имеющими код категории 11 (буква): он создаёт *символьные токены*— целочисленные значения, которые TeX вычисляет, используя комбинацию кода категории этого символа и кода символа.

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

![TeX обрабатывает символы с кодом категории 11](/files/4d169645fddf6f0452d9a3267dc1ba5c6c53928f)

Рисунок 5 ниже покажет, что делает TeX, когда видит символ с кодом категории 0 (символ экранирования).

#### Примечания к Рисунку 3: Обработка кода категории 11 («буква»)

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

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

**Вычисление токенов символов**

Движки TeX используют простую формулу для вычисления токена символа, $$T$$, из символа с кодом категории $$C$$ и кодом символа $$A$$:

$$T = \text{constant} \times C + A$$

8-битные движки, такие как pdfTeX, используют:

$$T = 256\times C + A$$

Движки, поддерживающие Unicode, такие как XeTeX или LuaTeX, должны использовать другую формулу, потому что в Unicode коды символов могут быть намного больше максимума 255 в старом 8-битном мире кодировки ASCII. Например, XeTeX использует:

$$T= 2^{21}\times C + A \hskip5mm \text{(where } A \text{ is a Unicode character code value)}$$

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

### Рисунок 4: Обработка кода категории 10 («пробельный символ»)

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

![TeX обрабатывает символы с кодом категории 10](/files/2a12d469b3de17802a6e2a386a5eb9a7d82af28c)

Обработка пробелов в TeX может показаться довольно своеобразной, но хороший обзор можно найти в главах 1 и 2 [TeX по темам](http://www.eijkhout.net/texbytopic/texbytopic.html) книги Виктора Эйкхаута — вы можете [скачать бесплатную PDF-копию](https://bitbucket.org/VictorEijkhout/tex-by-topic) с его сайта.

Например, когда TeX видит символ с кодом категории 10, бывают случаи, когда TeX будет:

* пропускать (игнорировать) их все — например, когда TeX находится в вертикальном режиме;
* преобразовывать несколько пробельных символов в один — пропуская лишние пробелы, например при обработке абзаца;
* поглощать их — например, поглощать один пробел после имени команды;

Также отметим, что бывают случаи, когда TeX будет *генерировать* пробелы — преобразуя символы конца строки в пробел. Поведение/обработка пробельных символов (любого символа с кодом категории 10) — одна из «особенностей» TeX: чтобы освоиться с этим аспектом TeX, требуется время и практика.

### Рисунок 5а: Обработка кода категории 0 («символ экранирования»)

На этом рисунке TeX обработал все символы до `\` символа, который имеет код категории 0: «символа экранирования» — мы используем следующую последовательность рисунков, чтобы показать, как TeX обрабатывает символ экранирования и определяет имя команды.

![TeX обрабатывает символы с кодом категории 0](/files/3f3d833ca0dd759b47f1cb3c6fb5cd7f4b3a4a0b)

### Рисунок 5б: Поиск имени команды

На этом рисунке мы заглянем в раздел в красной пунктирной рамке (**Начать поиск команды**) чтобы увидеть, что делает TeX после того, как он увидел символ экранирования.

![TeX ищет имя команды](/files/e5b43b51cbbffcf8a15286cc4094d63bdcf6ab2c)

**Примечания к Рисунку 5б**

* После распознавания символ экранирования выполнил свою задачу: он сработал как переключатель и не участвует в дальнейшей обработке — точнее, он **не** преобразуется в токен символа.
* Для удобства повторим одну ранее упомянутую деталь. После того как TeX видит символ экранирования, он проверяет код категории символа, который следует *сразу за ним*; это связано с тем, что TeX распознаёт два типа команд:
* * многобуквенные команды, называемые *управляющих слов*: символ, непосредственно следующий за символом экранирования, имеет код категории 11. Все последующие символы с кодом категории 11 считаются составляющими имя команды (*управляющее слово*). TeX перестанет искать символы, входящие в имя команды, когда обнаружит любой символ, который *не* не имеет кода категории 11 — например, пробельный символ с кодом категории 10.
  * односимвольные команды, называемые *управляющими символами*: символ, непосредственно следующий за символом экранирования *не* не имеет кода категории 11.
* В нашем примере первый символ после `\` — это `j` (код категории 11), что говорит TeX искать команду, которая является (возможно) многобуквенной последовательностью символов с кодом категории 11.
* TeX продолжает проверять наличие следующих символов с кодом категории 11. Как только он обнаруживает символ с любым другим кодом категории, например пробел с кодом категории 10, TeX понимает, что достиг конца имени команды. Для подчёркивания: здесь конец команды «завершил» пробел (код категории 10), но это мог быть любой символ, который **не** не имеет кода категории 11.

## Часть 3

В Части 3 мы продолжим с Рисунка 5б, чтобы завершить эту часть истории — как TeX распознаёт команду — и перейдём к тому, что он делает дальше. Мы также глубже рассмотрим некоторые внутренние аспекты обработки TeX — некоторые из них можно пропустить при первом чтении, если только вы не любите детали.

[Часть 1](/latex/ru/drugie-temy/19-how-tex-macros-actually-work-part-1.md) [Часть 2](/latex/ru/drugie-temy/20-how-tex-macros-actually-work-part-2.md) [Часть 3](/latex/ru/drugie-temy/21-how-tex-macros-actually-work-part-3.md) [Часть 4](/latex/ru/drugie-temy/22-how-tex-macros-actually-work-part-4.md) [Часть 5](/latex/ru/drugie-temy/23-how-tex-macros-actually-work-part-5.md) [Часть 6](/latex/ru/drugie-temy/24-how-tex-macros-actually-work-part-6.md)


---

# 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://ayakaleaf-pro.ayaka.space/latex/ru/drugie-temy/20-how-tex-macros-actually-work-part-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.
