> 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/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md).

# Как работает \\\expandafter: введение в токены TeX

[Часть 1](/latex/ru/podrobnye-stati/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md) [Часть 2](/latex/ru/podrobnye-stati/22-how-does-expandafter-work-the-meaning-of-expansion.md) [Часть 3](/latex/ru/podrobnye-stati/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md) [Часть 4](/latex/ru/podrobnye-stati/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md) [Часть 5](/latex/ru/podrobnye-stati/17-how-does-expandafter-work-a-detailed-macro-case-study.md) [Часть 6](/latex/ru/podrobnye-stati/18-how-does-expandafter-work-a-detailed-study-of-consecutive-expandafter-commands.md)

## Справочная информация для \expandafter: токены TeX и списки токенов

В качестве первого шага к пониманию того, как `\expandafter` на самом деле работает, мы рассмотрим два компонента TeX, которые являются фундаментальными для работы `\expandafter`: токены TeX (целые числа) и списки токенов (списки целых чисел). Читателям, которые хотели бы изучить эти темы гораздо подробнее, может быть интересно прочитать следующие статьи, опубликованные Overleaf:

* [Что такое токен TeX?](/latex/ru/podrobnye-stati/53-what-is-a-tex-token.md)
* [Что такое список токенов TeX?](/latex/ru/podrobnye-stati/54-what-is-a-tex-token-list.md)-[Как на самом деле работают макросы TeX?](/latex/ru/drugie-temy/01-a-six-part-series-how-do-tex-macros-actually-work.md)

### Откуда взяты данные о токенах?

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

## Токены TeX 101 (и понятие расширения)

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

## Как TeX вычисляет значения токенов

Здесь мы рассматриваем вычисление токенов, используемое в оригинальном TeX Кнута, e-TeX и pdfTeX; для других движков TeX, особенно XeTeX и LuaTeX, вычисления токенов должны быть немного иными, чтобы учесть использование Unicode, но методы вычисления схожи с описанными ниже.

### Токены символов (неактивные символы)

Вычисление значений токенов для неактивных символов простое:

$$\text{character token} = 256\times \text{(category code)} + \text{character (ASCII) code}$$

**Пример**: Буква A с [код категории](/latex/ru/drugie-temy/43-table-of-tex-category-codes.md) 11, код символа 65 представляется TeX как значение токена символа $$256\times 11 + 65 = 2881$$.

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

### Токены команд

Обработка ввода и генерация токенов TeX распознают два типа команд:

* команды, составленные из одного или нескольких символов с кодом категории 11;
* односимвольные команды, у которых код категории этого символа не равен 11, например `\$` или `\#`.

В обоих случаях TeX исключает начальный `\` символ и использует код символа каждого оставшегося символа для вычисления целого числа, которое TeX называет `curcs` (**cur**rent **c**ontrol **последовательности**последовательностью). Затем TeX использует значение `curcs` для вычисления значения токена для команды.

#### Команды, составленные из символов с кодом категории 11

Предположим, что наша команда (без начального `\` символа) состоит из последовательности символов: $$\mathrm{C\_1C\_2C\_3...C\_N}$$ где $$\mathrm{C}\_i$$ — это код символа каждого символа, например код символа A равен 65. TeX использует все коды символов $$\mathrm{C}\_i$$ для вычисления целого числа `curcs` (с использованием [хэш-функции](https://en.wikipedia.org/wiki/Hash_function)). После того как TeX вычислил значение `curcs` он просто прибавляет к этому значению 4095, чтобы получить значение токена:

$$\text{command token} = \text{curcs + 4095}$$

Заметьте, что переменная `curcs` играет чрезвычайно важную роль во внутренних процессах TeX.

#### Односимвольные команды

Токены, представляющие такие команды, как `\$`, `\#` и т. д., вычисляются немного иначе: целое число `curcs` теперь вычисляется проще:

$$\text{curcs} = 257 + \text{character (ASCII) code}$$

Например, при `\$`, $$\text{curcs}=257 + 36 = 293$$. TeX снова прибавляет 4095 к этому значению (используя $$\text{command token} = \text{curcs} + 4095$$), в результате чего `\$` получает значение токена $$293 + 4095 = 4388$$.

По сравнению с командами, составленными из символов с кодом категории 11, здесь единственное отличие состоит в том, как TeX вычисляет значение для `curcs`.

**Примечание**: целое число `curcs` не вычисляется для токенов символов: при создании или обработке токенов символов TeX всегда устанавливает его в 0.

#### Токены активных символов

В TeX есть понятие так называемых *активных символов*: любого символа, которому присвоен код категории 13. Токены для этого особого класса символов вычисляются иначе, чем для обычных символов.

Механизм активных символов позволяет TeX создавать, по сути, односимвольные макросы, которые можно использовать *без* без необходимости ставить перед активным символом escape-символ (обычно `\`): отдельный символ будет вызывать поведение своего макроса. Классический пример — символ тильды (\~), который TeX/LaTeX используют для неразрывных пробелов и который можно определить/включить следующим образом:

```
\catcode`~=13 % присвоить символу ~ код категории 13
\def~{\penalty100000\ } % определить ~ как макрос
```

Когда TeX впоследствии считывает `~` символ, он обнаружит, что его код категории равен 13, и обработает его как «мини-макрос». Чтобы вычислить токен, представляющий активный символ, TeX применяет ещё один вариант вычисления `curcs`:

$$\begin{align\*} \text{curcs} &= \text{character code} + 1\ \text{active character token} &= \text{curcs} + 4095\ \end{align\*}$$

Например, символ \~ имеет код символа 126, поэтому его значение токена активного символа вычисляется следующим образом:

$$\begin{align\*} \text{curcs} &= 126 + 1\ \text{active character token} &= 127 + 4095\ &=4222\ \end{align\*}$$

Заметьте, что, как и токены команд, токены, представляющие активные символы, > 4095.

### Следствия/примечания

* Любой токен, значение которого превышает 4095, сразу же можно определить как токен команды — поэтому TeX может очень легко определить, представляет ли конкретный токен символ или команду.
* Для любого значения токена TeX при необходимости может «распаковать» этот токен, чтобы выявить символ (и его код категории) или команду, изначально присутствовавшие в вашем `.tex` файле, хранящиеся в определении макроса или содержащиеся в каком-либо другом списке токенов.
* Промежуточная величина, называемая `curcs`— которую TeX использует для вычисления значений токенов команд — играет важную роль в низкоуровневой обработке TeX. `curcs` служит «значением индекса», которое TeX использует для хранения/поиска текущего значения команды. Для любого токена команды $$\mathrm{T}$$, TeX просто вычитает 4095, чтобы получить доступ к значению `curcs`: $$\text{curcs} = \mathrm{T}-4095$$

Кстати, TeX действительно хранит человекочитаемую строку символов, из которой генерируется токен команды — это необходимо для сообщений об ошибках и других команд, таких как `\string` расширение которых представляет собой человекочитаемую версию значения токена. Однако эти человекочитаемые строки символов, хранящиеся внутри TeX, используются/выводятся только по запросу: во всей остальной обработке используется целочисленное значение токена.

## Рассмотрим несколько реальных токенов

Чтобы понятие токенов стало чуть менее туманным, определим следующий простой макрос и посмотрим на токены, которые создаёт TeX:

```
\def\hello{Greetings, from \TeX. \hskip 10pt}
```

Для `\hello` макроса TeX использует символы `h`, `e`, `l`, `l`, `или` для вычисления значения 3745 для `curcs`; затем TeX прибавляет 4095, чтобы создать значение токена $$3745 + 4095 = 7840$$ (для TeX Кнута, e-TeX или pdfTeX).

После создания токена, представляющего `\hello`, `\def` команда заставляет TeX прочитать последующие токены и использовать их для создания списка токенов, который хранится как *определением* из `\hello` команда. Это сохранённое определение (список токенов) затем можно получить всякий раз, когда вы указываете TeX использовать `\hello` команды.

В следующей таблице перечислены фактические значения токенов, созданные для каждого элемента (символа, макроса или примитива), содержащегося в `\hello` определении макроса — этот список токенов (целых чисел) и есть то, что TeX хранит в своей памяти (как структуру данных, известную как [связный список](https://en.wikipedia.org/wiki/Linked_list)). Читателям, желающим подробнее разобраться со списками токенов, рекомендуется статья Overleaf [Что такое список токенов TeX?](/latex/ru/podrobnye-stati/54-what-is-a-tex-token-list.md)

|                         |                            |
| ----------------------- | -------------------------- |
| **Значение токена TeX** | **Представляемый элемент** |
| 2887                    | G                          |
| 2930                    | r                          |
| 2917                    | e                          |
| 2917                    | e                          |
| 2932                    | t                          |
| 2921                    | i                          |
| 2926                    | n                          |
| 2919                    | g                          |
| 2931                    | последовательности         |
| 3116                    | ,                          |
| 2592                    |                            |
| 2918                    | f                          |
| 2930                    | r                          |
| 2927                    | или                        |
| 2925                    | m                          |
| 2592                    |                            |
| 5235                    | \TeX                       |
| 3118                    | .                          |
| 2592                    |                            |
| 7943                    | \hskip                     |
| 3121                    | 1                          |
| 3120                    | 0                          |
| 2928                    | p                          |
| 2932                    | t                          |

В приведённом выше списке токенов символы имеют коды категории 10, 11 или 12. Например:

* символы имеют код категории 10 и код символа 32, что даёт значение токена $$256\times 10 + 32 = 2592$$
* `,` и `.` имеют код категории 12 и коды символов 44 и 46 соответственно, что даёт токены:
* токен для `,` $$= 256 \times 12 + 44 = 3116$$
* токен для `.` $$= 256\times 12+ 46 = 3118$$

Всякий раз, когда TeX впоследствии встречает значение токена 7840 (представляющее `\hello`), он может, если требуется, «распаковать» этот токен, чтобы извлечь `curcs` с помощью простого вычисления $$\text{curcs} = \text{token value} - 4095$$ (см. выше). Используя значение `curcs` TeX может обратиться к своим внутренним таблицам данных, чтобы определить, что токен команды 7840 представляет макрокоманду. Кроме того, снова через `curcs`, TeX также может найти и извлечь сохранённое определение `\hello`.

Когда TeX нужно полностью обработать токен 7840, то есть выполнить `\hello` макрос, токен 7840 ему больше не нужен: этот токен *выполнил свою задачу*— то есть он заставил TeX выполнить макрос `\hello`. Теперь TeX может отбросить токен 7840 и извлечь токены, представляющие определение (список токенов), хранящееся в памяти. По сути, `\hello` команда макроса (токен 7840) была *удалена* из текущего источника ввода TeX и *заменена* токенами, содержащимися в определении `\hello`. Что мы только что описали, — это одна из форм *расширения токенов*.

Это `\TeX` команда (значение токена 5235, указанное выше), используемая в `\hello` сама является макросом, построенным из большего числа токенов — поэтому её определение также хранится как список токенов:

|                         |                            |
| ----------------------- | -------------------------- |
| **Значение токена TeX** | **Представляемый элемент** |
| 2900                    | T                          |
| 19598                   | \kern                      |
| 3117                    | -                          |
| 3118                    | .                          |
| 3121                    | 1                          |
| 3126                    | 6                          |
| 3126                    | 6                          |
| 3127                    | 7                          |
| 2917                    | e                          |
| 2925                    | m                          |
| 19597                   | \lower                     |
| 3118                    | .                          |
| 3125                    | 5                          |
| 2917                    | e                          |
| 2936                    | x                          |
| 6175                    | \hbox                      |
| 379                     | {                          |
| 2885                    | E                          |
| 637                     | }                          |
| 19598                   | \kern                      |
| 3117                    | -                          |
| 3118                    | .                          |
| 3121                    | 1                          |
| 3122                    | 2                          |
| 3125                    | 5                          |
| 2917                    | e                          |
| 2925                    | m                          |
| 2904                    | X                          |

Если бы мы заменили `\hello` команду полным списком токенов, из которых она состоит, включая `\TeX` макрос, это был бы довольно длинный список — то есть если бы мы также *развернули* окружения `\TeX` макрос, мы бы увидели:

![Список токенов, хранящийся в макросе TeX](/files/1f14b881c19bd4eaa8ee6e7e5e1e41d51b847f4a)

По сути, единственное значение токена 7840 (для `\hello`) при полном раскрытии даст в общей сложности 51 токен (целое число), представляющий символы и примитивные команды. В следующем списке символ или команда, представленные каждым токеном, заключены в скобки “(...)” — они не хранятся непосредственно в списках токенов TeX и приведены для удобства читателя:

```
2887 (G), 2930 (r), 2917 (e), 2917 (e), 2932 (t), 2921 (i), 2926 (n), 2919 (g), 2931 (s), 3116 (,), 2592 (<space>), 2918 (f), 2930 (r), 2927 (o), 2925 (m), 2592 (<space>),  2900 (T), 19598 (\kern), 3117 (-), 3118 (.), 3121 (1), 3126 (6), 3126 (6), 3127 (7), 2917 (e), 2925 (m), 19597 (\lower), 3118 (.), 3125 (5), 2917 (e), 2936 (x), 6175 (\hbox), 379 ({), 2885 (E), 637 (}), 19598 (\kern), 3117 (-), 3118 (.), 3121 (1), 3122 (2), 3125 (5), 2917 (e), 2925 (m), 2904 (X), 3118 (.), 2592 (<space>), 7943 (\hskip), 3121 (1), 3120 (0), 2928 (p), 2932 (t)
```

Для человека это всего лишь последовательность целых чисел, но для TeX она кодирует огромное количество информации.

## Считывайте токены сейчас и сохраняйте их на потом

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

Мы уже видели примеры списков токенов — `\hello` и `\TeX` макросы, перечисленные выше: определения этих макросов хранятся в памяти TeX как списки токенов. TeX будет обрабатывать (выполнять) такие списки токенов только тогда, когда вы решите вызвать эти макросы. Также помните, что каждый токен (целочисленное значение) содержит достаточно информации, чтобы TeX мог легко определить, представляет ли каждый токен, хранящийся в определении макроса, символ или команду.

### Сохранение токенов с помощью регистров токенов

Ещё один пример хранения токенов — явное создание списков токенов, которые сохраняются в так называемых *регистрах токенов*: выделенных внутренних областях хранения, которые TeX предоставляет пользователям для хранения списков токенов. Примитив TeX `\toksdef` — один из способов использовать регистры токенов; например, чтобы использовать регистр токенов `100` и обращаться к нему с помощью команды `\mylist`:

```
        \toksdef\mylist=100
        \mylist={несколько \TeX{} токенов здесь}
```

`\mylist` по сути, просто имя, которое вы присваиваете списку токенов, хранящемуся в позиции регистра `100`. `\mylist` содержит следующий список токенов:

|                         |                            |
| ----------------------- | -------------------------- |
| **Значение токена TeX** | **Представляемый элемент** |
| 2931                    | последовательности         |
| 2927                    | или                        |
| 2925                    | m                          |
| 2917                    | e                          |
| 2592                    |                            |
| 5235                    | \TeX                       |
| 379                     | {                          |
| 637                     | }                          |
| 2592                    |                            |
| 2932                    | t                          |
| 2927                    | или                        |
| 2923                    | к                          |
| 2917                    | e                          |
| 2926                    | n                          |
| 2931                    | последовательности         |
| 2592                    |                            |
| 2920                    | h                          |
| 2917                    | e                          |
| 2930                    | r                          |
| 2917                    | e                          |

**Примечание**: чтобы завершить `\TeX` макрос и не дать ему поглотить следующий `<space>` символ, мы использовали пару фигурных скобок `{}` сразу после `\TeX`— токены для `{` (379) и `}` (637) хранятся в списке токенов. Другой вариант — использовать токен «управляющий пробел» `\<space>` который появится в списке токенов, как показано ниже (жирным шрифтом):

|                         |                            |
| ----------------------- | -------------------------- |
| **Значение токена TeX** | **Представляемый элемент** |
| 2931                    | последовательности         |
| 2927                    | или                        |
| 2925                    | m                          |
| 2917                    | e                          |
| 2592                    |                            |
| 5235                    | \TeX                       |
| **4384**                | **\\**                     |
| 2932                    | t                          |
| 2927                    | или                        |
| 2923                    | к                          |
| 2917                    | e                          |
| 2926                    | n                          |
| 2931                    | последовательности         |
| 2592                    |                            |
| 2920                    | h                          |
| 2917                    | e                          |
| 2930                    | r                          |
| 2917                    | e                          |

Обратите внимание, что `<space>` символ представляется как *символьным токеном* со значением $$256\times 10 + 32 = 2592$$ но `\<space>` обрабатывается как односимвольный *токеном команды* (значение 4384), которое вычисляется по приведённым выше формулам:

\begin{align\*} \text{curcs} & = 257 + \text{код символа (ASCII)}\\\ & = 257 + 32\\\ &=289\\\ \text{токен команды для} \left<\text{\space}\right> & = \text{curcs + 4095}\\\ & = 289+4095\\\ &=4384\\\ \end{align\*}

По сути `\mylist={несколько \TeX{} токенов здесь}` говорит TeX: пожалуйста, просканируй мой входной файл, чтобы преобразовать следующие символы/команды в токены и сохранить их для последующего использования. TeX выполнит это и сохранит эти токены в области памяти, к которой можно обратиться, написав `\the\mylist`, давая TeX указание вставить копию токенов, содержащихся в регистре токенов `\mylist`. Движки TeX включают ряд примитивных команд, которые явно создают и сохраняют списки токенов — например `\everyjob`, `\everypar`, `\mark`, и многие другие.

[Часть 1](/latex/ru/podrobnye-stati/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md) [Часть 2](/latex/ru/podrobnye-stati/22-how-does-expandafter-work-the-meaning-of-expansion.md) [Часть 3](/latex/ru/podrobnye-stati/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md) [Часть 4](/latex/ru/podrobnye-stati/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md) [Часть 5](/latex/ru/podrobnye-stati/17-how-does-expandafter-work-a-detailed-macro-case-study.md) [Часть 6](/latex/ru/podrobnye-stati/18-how-does-expandafter-work-a-detailed-study-of-consecutive-expandafter-commands.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://overleaf-pro.ayaka.space/latex/ru/podrobnye-stati/19-how-does-expandafter-work-an-introduction-to-tex-tokens.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.
