> 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/21-how-does-expandafter-work-tex-uses-temporary-token-lists.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)

## Расширение и внутренние списки токенов

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

`\jobname` — это расширяемый примитив TeX, расширение которого порождает последовательность символьных токенов, представляющих имя основного входного `.tex` файла. Например, предположим, что у нас есть следующий текст в составе `.tex` файл с именем `mycode.tex`:

```
    Имя моего файла — \jobname .tex %Обратите внимание на пробел после \jobname
```

Это было бы набрано

```
    Имя моего файла — mycode.tex
```

Когда мы используем `\jobname` команду, получаемые в результате набранные символы не считываются из вашего физического `.tex` файла, так откуда же они берутся: где TeX хранит/читает эти токены? Невидимый для пользователя (то есть глубоко внутри самого TeX) процесс расширения для `\jobname` создаёт временный список токенов, сформированный из последовательности символьных токенов, представляющих имя вашего файла. Как только `\jobname` создал этот список токенов, TeX временно «переключает свой взгляд» с текущего источника ввода (здесь это наш `.tex` файл), чтобы читать токены (символьные токены) из этого временного списка токенов. Когда TeX нужен ещё один токен ввода, он читает следующий токен из этого внутреннего списка и продолжает делать это, пока не достигнет конца списка; после этого TeX возобновляет чтение токенов из своего предыдущего источника ввода, которым здесь был бы текст, прочитанный из нашего `.tex` входного файла.

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

Изучая следующую иллюстрацию, читайте снизу вверх, чтобы проследить ход процесса.

![Как TeX расширяет \jobname](/files/43e7e99e113261d0ee985ed88223b84a8954c7d8)

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

Расширяемые команды (такие как `\jobname`) — не единственные примитивы TeX, которые «тайно» создают и используют списки токенов для достижения своего эффекта. Например, команды `\uppercase` и `\lowercase` обе создают внутренние списки токенов, чтобы изменить регистр своего аргумента. Когда работа по изменению регистра завершена, TeX переключается на чтение символьных токенов из списков токенов, созданных этими командами. Списки токенов — единственный механизм TeX для «хранения токенных данных» — если не считать записи данных во физический файл на диске.

### Источники токенов: TeX — мастер жонглирования

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

Предположим, мы хотим простую макрокоманду, которая наберёт имя нашего `.tex` файл:

```
    \def\myfile{Имя моего файла — \jobname .tex}
```

Позже, в какой-то момент в нашем `.tex` файле мы вызываем макрокоманду `\myfile`: временно TeX переключается с создания/чтения токенов через текст в вашем текстовом (`.tex`) файле на чтение токенов из `\myfile` определения (списка токенов), хранящегося в его памяти. Когда TeX выполняет `\myfile` макрокоманду (обрабатывает её токены), он обнаружит токен, представляющий `\jobname` команду, расширение которой создаёт ещё один, временный, список токенов, из которого TeX должен читать токены. Даже в этом простом сценарии TeX должен управлять тремя источниками ввода:

1. окружения `.tex` текстовым файлом, содержащим `\myfile` макрокоманду;
2. списком токенов, в котором хранится определение `\myfile` макрокоманду;
3. списком токенов, созданным `\jobname` командой внутри `\myfile` макрокоманды.

По мере обработки документа TeX постоянно переключается между источниками ввода: физическими файлами и списками токенов, так как же TeX отслеживает это? Ответ в том, что внутри движки TeX поддерживают так называемый [стек ввода](https://en.wikipedia.org/wiki/Stack_\(abstract_data_type\)) который действует как своего рода «память», позволяющая TeX помнить, что он делал (откуда читал), когда переключался между источниками ввода.

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

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

## Более глубокое погружение (необязательное чтение)

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

### Настоящие списки токенов

Следующая иллюстрация была создана с помощью пользовательской сборки TeX Кнута в Overleaf, которая предоставляет доступ к внутренним данным и структурам данных TeX. Эта иллюстрация списка токенов основана на упрощённой версии, представленной выше, и включает дополнительные данные, например показывает символы, порождённые `\jobname` имеют код категории 12, а не обычный код категории 11. На этой диаграмме «узел» — это просто название единицы памяти, используемой TeX.

![Внутри списка токенов TeX](/files/a4acb493362a6bcfa0c8bc03ff94c8cdcf4db993)

### Как TeX читает и обрабатывает \jobname

Также, для полноты картины, вот обзор «мыслительных процессов» TeX при обнаружении `\jobname` в нашем вводе `.tex` файле. На этой иллюстрации мы видим, как TeX обнаруживает символ экранирования (`\` с кодом категории 0), обрабатывает последовательность символов `jobname`, создаёт токен и ищет значение `\jobname` команды, при этом TeX обнаружит, что у неё код команды > 100, что указывает на то, что это расширяемая команда.

![Как TeX сканирует и обрабатывает \jobname](/files/2054fe620f737c6369b542c60d6362045021a479)

[Часть 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/21-how-does-expandafter-work-tex-uses-temporary-token-lists.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.
