> 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/uk/dokladni-statti/18-how-does-expandafter-work-a-detailed-study-of-consecutive-expandafter-commands.md).

# Як працює \expandafter: детальне дослідження послідовних команд \expandafter

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

## Практичний приклад: розуміння \expandafter\expandafter\expandafter...

Розширені макроси, такі як ті, що трапляються в пакетах LaTeX, часто широко використовують кілька послідовних `\expandafter` команд для виконання складного «жонглювання» токенами. Для більшості з нас такі макроси можуть бути важкими для розуміння або лячними для написання. У цьому розділі ми розглянемо механіку, що лежить в основі обробки TeX послідовних `\expandafter` команд:

```
\expandafter\expandafter\expandafter...
```

Щоб допомогти нашому поясненню, ми додамо нижні індекси до кожної `\expandafter`— щоб вказати, про яку саме йдеться:

```
        \expandafter1\expandafter2\expandafter3...
```

Крім того, ми розширимо позначення для токенів, оброблюваних кожною `\expandafter` так, щоб використовувати $$\mathrm{T^i\_1}$$ та $$\mathrm{T^i\_2}$$ для позначення токенів $$\mathrm{T\_1}$$ та $$\mathrm{T\_2}$$ зчитаних `\expandafter` з нижнім індексом `i`: `\expandafter`<sub>i</sub> $$\mathrm{T^i\_1T^i\_2}$$. Ми також припустимо, що два токени $$\mathrm{T\_X}$$ та $$\mathrm{T\_Y}$$ йдуть після `\expandafter<sub>3</sub>` так, що наш вхід виглядає так: `\expandafter<sub>1</sub>\expandafter<sub>2</sub>\expandafter<sub>3</sub>` $$\mathrm{T\_{X}T\_{Y}}$$.

Коли TeX починає обробляти цей вхід, для `\expandafter<sub>1</sub>` він побачить

* $$\mathrm{T^1\_1} =$$`\expandafter<sub>2</sub>` який зберігається для подальшої *повторної вставки* назад у вхід
* $$\mathrm{T^1\_2} =$$`\expandafter<sub>3</sub>`, який розгортається

Якщо ми повернемося до нашого попереднього обговорення [коду всередині TeX](/latex/uk/dokladni-statti/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md) який реалізує `\expandafter`, саме під час розгортання `\expandafter<sub>3</sub>` ми бачимо, як відбувається рекурсія. Щоб обробити `\expandafter<sub>1</sub>` TeX уже викликав свою внутрішню функцію `expand()`, тож для обробки (розгортання) `\expandafter<sub>3</sub>` TeX робить *другий* виклик `expand()`— ізсередини `expand()` самої функції.

Для `\expandafter<sub>3</sub>` ми маємо

* $$\mathrm{T^3\_1 = T\_X}$$, який зберігається для подальшої *повторної вставки* назад у вхід
* $$\mathrm{T^3\_2 = T\_Y}$$, який, припустимо, є розгортуваним

Давайте далі припустимо, що розгортання $$\mathrm{T\_Y}$$ дає таку послідовність токенів: $$\mathrm{{T^1\_Y}{T^2\_Y}{T^3\_Y}}\cdots\mathrm{T^N\_Y}$$. Тепер ми досягли кінця процесу розгортання, розпочатого послідовністю команд `\expandafter<sub>1</sub>\expandafter<sub>2</sub>\expandafter<sub>3</sub>` $$\mathrm{T\_{X}T\_{Y}}$$ і TeX переходить до «розмотування» процесу рекурсії, який почався з `\expandafter<sub>1</sub>`.

Після обробки `\expandafter<sub>3</sub>` TeX має в пам’яті список токенів, що містить токени з розгортання $$\mathrm{T\_Y\text{: }{T^1\_Y}{T^2\_Y}{T^3\_Y}}\cdots\mathrm{T^N\_Y}$$. TeX тепер починає повторно вставляти токени, які він зберіг під час обробки `\expandafter` команд:

1. TeX починає з повторної вставки токена $$\mathrm{T\_X}$$ збереженого `\expandafter<sub>3</sub>`. $$\mathrm{T\_X}$$ повторно вставляється *перед* розгортання $$\mathrm{T\_Y}$$, що призводить до такої послідовності токенів: $$\mathrm{{{T\_X}T^1\_Y}{T^2\_Y}{T^3\_Y}}\cdots\mathrm{T^N\_Y}$$.
2. Однак нам ще потрібно завершити процес, розпочатий `\expandafter<sub>1</sub>` який зберіг токен, що представляє `\expandafter<sub>2</sub>`
3. Кінцева послідовність токенів, зібрана TeX і готова до зчитування на наступному етапі обробки TeX, є `\expandafter<sub>2 (token)</sub>` $$\mathrm{T\_{X}T^1\_{Y}T^2\_{Y}T^3\_{Y}\cdots T^N\_Y}$$
4. TeX тепер завершив «перший раунд» обробки й переходить до зчитування послідовності списків токенів, яку він згенерував,— ця послідовність починається з `\expandafter<sub>2 (token)</sub>` яку TeX продовжує обробляти. Для `\expandafter<sub>2</sub>` ми маємо
   * $$\mathrm{T^2\_1} =\ \mathrm{T\_X}$$ який зберігається для подальшої *повторної вставки* назад у вхід
   * $$\mathrm{T^2\_2} = \mathrm{T^1\_Y}$$ який є першим токеном, що виникає внаслідок розгортання $$\mathrm{T\_Y}$$; якщо він розгортуваний, його розгортають
5. Якщо ми припустимо, що токен $$\mathrm{T^1\_Y}$$перший токен з розгортання $$\mathrm{T\_Y}$$, розгортається у $$\mathrm{{T^A\_{Y1}}{T^B\_{Y1}}{T^C\_{Y1}}}$$ тоді, після того як TeX повторно вставив $$\mathrm{T\_X}$$, отримана послідовність токенів, яку TeX має повторно обробити, буде такою: $$\mathrm{{T\_X}{T^A\_{Y1}}{T^B\_{Y1}}{T^C\_{Y1}}{T^2\_Y}{T^3\_Y}\cdots{T^N\_Y}}$$

   що ми можемо переформулювати як

   $$\mathrm{T\_X}\text{\<expansion of the first token in }\mathrm{T\_Y}\text{>\<remaining tokens in }\mathrm{T\_Y}\text{>}$$

Наступна діаграма ілюструє списки токенів, створені кодом TeX

```
    \expandafter1\expandafter2\expandafter3TXTY
```

![Зображення, що показує обробку TeX кількох команд \expandafter](/files/ac5d4effe9c2b3a17e3bf3c21a946b5e6d00ab83)

### Від теорії до практики

Як приклад, ми визначимо такі макроси, які слугуватимуть як $$\mathrm{T\_X}$$ та $$\mathrm{T\_Y}$$

* $$\mathrm{T\_X}=$$`\foo` де ми визначаємо `\foo` як `\def\foo#1{\textbf{#1}}`
* $$\mathrm{T\_Y}=$$`\bar` де спочатку визначаємо `\def\abc{Hello}`, `\def\xyz{, World!}` а потім `\def\bar{\abc\xyz}`

Ми використаємо такий фрагмент коду, щоб продемонструвати наш попередній аналіз:

\expandafter\expandafter\expandafter\foo\bar

Із нашого обговорення випливає, що результат `\expandafter<sub>1</sub>\expandafter<sub>2</sub>\expandafter<sub>3</sub>` $$\mathrm{T\_X}\mathrm{T\_Y}$$ створює послідовність токенів такого вигляду:

$$\mathrm{T\_X}\text{\<expansion of the first token in }\mathrm{T\_Y}\text{>\<remaining tokens in }\mathrm{T\_Y}\text{>}$$

де точна послідовність залежить від природи токена $$\mathrm{T\_Y}$$. Якщо ми підставимо наші прикладні команди, використовуючи $$\mathrm{T\_X}=$$`\foo` та $$\mathrm{T\_Y}=$$`\bar`, який визначено як `\def\bar{\abc\xyz}`, ми побачимо:

* перший токен у $$\mathrm{T\_Y}$$ є `\abc` і його розгортання — це послідовність символьних токенів: `Hello`
* решта токенів у $$\mathrm{T\_Y}$$ є єдиним токеном, що представляє `\xyz`.

Якщо ми підставимо цю інформацію в наш «аналіз», отримаємо

$$\begin{align\*} &\mathrm{T\_X}\text{\<expansion of the first token in }\mathrm{T\_Y}\text{>\<remaining tokens in }\mathrm{T\_Y}\text{>}\ &=\text{foo}*{\text{token}}\text{\<expansion of \abc>}*\text{token list (characters)}\text{xyx}*\text{token}\ &=\text{foo}*\text{token}\text{Hello}*\text{token list (characters)}\text{xyx}*\text{token}\\\[10pt] \end{align\*}$$

Зверніть увагу, що нижні індекси <sub>токен</sub> та <sub>список токенів (символи)</sub> використовуються, щоб підкреслити (нагадати нам), що TeX зчитує *цілі значення токенів*, а не *текстові символи*, тож немає потреби показувати будь-які пробіли чи інші роздільники після `\foo`: такі роздільники вже давно оброблено або відкинуто; тут ми міцно перебуваємо у внутрішньому світі TeX зі списками токенів та цілими значеннями токенів.

Коли TeX обробляє послідовність списків токенів, створену нашими `\expandafter` командами, він набере `**H**ello, World!`— лише `H` набирається жирним. Ми могли б досягти того самого результату, написавши еквівалентний код TeX `\foo Hello\xyz`. Зверніть увагу, що визначення `\foo` використовувало один параметр; отже, `\foo` поглинає єдиний `H` символьний токен для свого аргументу, залишаючи решту символьних токенів (`ello`) без змін.

**Примітки:**

* написання `\foo\bar` дає зовсім інший результат: токен для `\bar` використовувався б як аргумент для `\foo` що призводить до набору **`Hello, World`**— усе набирається жирним.
* написання `\expandafter\foo\bar` спричиняє `\bar` розгортання, що створює два токени: $$\text{abc}*\text{token}\text{xyz}*\text{token}$$. Потім, після того як $$\text{foo}*\text{token}$$ повторно вставляється `\expandafter` TeX обробляє послідовність токенів $$\text{foo}*\text{token}\text{abc}*\text{token}\text{xyz}*\text{token}$$ що набирає `**Hello**, World`— лише **`Hello`** набирається жирним. Тут єдиний токен $$\text{abc}*\text{token}$$ обробляється як аргумент для токена макросу $$\text{foo}*\text{token}$$, залишаючи токен $$\text{xyz}\_\text{token}$$ без змін, а його вміст набирається поточним шрифтом.

## Примітка про \expandafter і макроси з аргументами

Під час використання `\expandafter` щоб примусово розгортати макроси, варто знати, як працює розгортання макросів — особливо для макросів, що приймають аргументи. Перш ніж TeX зможе виконати макрос — тобто зчитати й обробити токени, що містяться у визначенні макросу — TeX потрібно «підготувати до виконання» макрос, виконавши початковий процес розгортання макроса. Якщо визначення макросу містить використання параметрів (`#1`, `#2`, ... `#9`); частина процесу розгортання макроса вимагає від TeX просканувати вхід, шукаючи токени, що складають аргумент(и), надані користувачем: ці токени аргументів поглинаються (видаляються) з входу. Під час розгортання макроса TeX зчитує й поглинає токени з входу, щоб створити міні-списки токенів, по одному списку на кожен аргумент; згодом ці списки токенів буде вставлено у відповідне місце всередині тіла макроса — коли TeX виконуватиме його. Останній крок у розгортанні макроса полягає в тому, що TeX знаходить визначення макроса, збережене в пам’яті, і налаштовує цю ділянку як джерело, з якого TeX зчитуватиме свій наступний набір вхідних токенів. Виконання макроса починається, коли TeX починає зчитувати й обробляти ці токени, підставляючи списки токенів, попередньо створені для збереження аргументів.

### Токени-роздільники також поглинаються

Якщо початкове визначення макроса також використовувало токени, що виконують роль роздільників, TeX також потрібно було б порівняти початкове визначення макроса з використанням (викликом) цього макроса користувачем, щоб знайти й зіставити токени-роздільники. Після того як їх зіставлено/знайдено, токени-роздільники надалі ігноруються, оскільки їхня єдина мета — служити «пунктуацією», допомагаючи TeX виокремити та ідентифікувати справжні токени, призначені для формування кожного аргументу.

&#x20;[Частина 1](/latex/uk/dokladni-statti/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md)   [Частина 2](/latex/uk/dokladni-statti/22-how-does-expandafter-work-the-meaning-of-expansion.md)   [Частина 3](/latex/uk/dokladni-statti/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md)   [Частина 4](/latex/uk/dokladni-statti/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md)   [Частина 5](/latex/uk/dokladni-statti/17-how-does-expandafter-work-a-detailed-macro-case-study.md)   [Частина 6](/latex/uk/dokladni-statti/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/uk/dokladni-statti/18-how-does-expandafter-work-a-detailed-study-of-consecutive-expandafter-commands.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.
