> 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/uk/inshi-temi/21-how-tex-macros-actually-work-part-3.md).

# Як насправді працюють макроси TeX: частина 3

[Частина 1](/latex/uk/inshi-temi/19-how-tex-macros-actually-work-part-1.md) [Частина 2](/latex/uk/inshi-temi/20-how-tex-macros-actually-work-part-2.md) [Частина 3](/latex/uk/inshi-temi/21-how-tex-macros-actually-work-part-3.md) [Частина 4](/latex/uk/inshi-temi/22-how-tex-macros-actually-work-part-4.md) [Частина 5](/latex/uk/inshi-temi/23-how-tex-macros-actually-work-part-5.md) [Частина 6](/latex/uk/inshi-temi/24-how-tex-macros-actually-work-part-6.md)

## Час зробити паузу!

Перш ніж переходити до наступної частини цієї історії, нам потрібно коротко повторити: нагадати собі, куди ми прямуємо, і зібрати думки, щоб переконатися, що всі ключові ідеї на місці. Нагадаємо, наш розглянутий приклад ґрунтується на припущенні, що TeX прочитав рядок тексту, що містить `Привіт, світ \jobname` і що TeX набирає це, щоб побудувати абзац.

### Кінцева мета

Наша мета — розвинути краще (глибше) розуміння природи макросів TeX і того, як вони працюють. Однак, щоб дійти до цього, спершу нам потрібно зрозуміти, як TeX читає вхідний файл і обробляє символи в ньому. Ось короткий підсумок тем, розглянутих дотепер.

* TeX читає (сканує) кожен символ у вашому вхідному тексті, і для кожного символу TeX має дві частини інформації:
* **код символу**: ціле число, що використовується для ідентифікації цього символу, наприклад, коли він зберігається у вхідному файлі .tex;
* **код категорії**: ще одне ціле число, внутрішнє для TeX, яке він використовує, щоб призначати значення кожному символу, прочитаному з вхідних даних.
* Щойно TeX читає символ, категорійний код кожного символу стає *остаточно* пов’язаним із цим окремим символом через створення символьного токена:
* TeX використовує просту формулу, щоб «упакувати» код символу та відповідний йому категорійний код в ціле число, яке називається символьним токеном.
* Ви можете змінити значення будь-якого символу, який TeX ще *ще не прочитав* призначивши інший категорійний код будь-якому символу, поведінку якого ви хочете змінити, тобто змінити спосіб, у який TeX обробляє цей символ.
* Перевизначення (перепризначення) категорійних кодів досягається за допомогою примітива TeX `\catcode` команду.
* Коли TeX бачить категорійний код 0, він переходить у спеціальний режим сканування і починає шукати команду: або (потенційно) багатолітерне *керівне слово* або односимвольне *керівний символ*.

Дотепер ми розглядали процес сканування вхідних даних TeX, коли він ідентифікує окремі символи та використовує категорійний код кожного символу, щоб визначити, що робити далі. Деякі символи — це просто звичайні елементи тексту для набору (наприклад, категорійний код 11), але ми також бачили пробільні символи (категорійний код 10) та символи екранування (категорійний код 0). Є й інші категорійні коди, які, з міркувань стислості, ми не розглядали — наприклад, категорійний код 1 («початок групи», напр., `{`), категорійний код 2 («кінець групи», напр., `}`) та інші. Кожен категорійний код відіграє свою власну роль у скануванні вхідних даних TeX і подальшій обробці програмними процесами/алгоритмами всередині TeX.

### Токени: короткий огляд

Поняття «токенів» є центральним для того, як працює TeX: ви побачите згадки про «токени» або посилання на них у книгах, статтях і онлайн-спільнотах, пов’язаних із TeX, тож варто коротко повторити цю тему — докладніше можна знайти в раніше опублікованій статті [Що таке «TeX-токен»?](/latex/uk/dokladni-statti/53-what-is-a-tex-token.md)

Ми вже бачили, що TeX перетворює вхідні символи на токени, поєднуючи код символу та категорійний код в одне складене ціле число. TeX робить дещо подібне і для команд: використовуючи назву команди, він обчислює ціле число, яке називається *токеном команди* (ми розглянемо це докладніше). Як орієнтир, можна вважати токени способом TeX «упаковувати» елементи, які він прочитав із вхідних даних, готуючи їх до передавання на наступний етап обробки TeX. Те, що всі елементи (символи або команди) акуратно загорнуті в єдине числове представлення, полегшує їхню подальшу обробку далі по ланцюжку. Наприклад, коли TeX хоче зберегти частину ваших вхідних даних для подальшого використання, наприклад визначення макросу, TeX просто потрібно зберегти ваше визначення макросу, яким би складним воно не було, як послідовність цілих чисел, де кожне ціле число є токеном, що представляє символ або команду, яка є частиною (міститься в) визначення вашого макросу.

## Отже, що далі?

У заключному розділі Частини 2 ми бачили, як символ екранування (категорійний код 0) перемикає TeX у спеціальний режим обробки, де він шукає назву команди. У нашому прикладі TeX виявив рядок символів `jobname` і ми завершили Частину 2 на етапі, коли TeX збирався «щось зробити» з цим рядком символів (назвою команди). У цій частині ми детально розглянемо, що TeX робить далі.

Після того як TeX визначив, що певна послідовність символів у вашому вхідному файлі є назвою команди (тут, `jobname`) *буде*, у цій ситуації, потрібно виконати `\jobname`.

### Від рядка символів до виконання команди: як?

По-перше, давайте повернемося до Графіки 5b з Частини 2, де TeX визначив, що певний рядок символів у вхідних даних становить назву команди: `jobname`. Графіка 5b показує, що TeX має «перевірити внутрішні таблиці...». Що це *насправді означає*?

![TeX шукає назву команди](/files/afe8abaf0d87f68642a58a9556277d8182ebc7fe)

Інший, більш детальний, опис того, як TeX «перевіряє внутрішні таблиці», щоб перейти від наявності рядка символів ( `jobname`) до з’ясування, що саме це за команда і що вона означає, можна знайти в попередній статті [Що таке «TeX-токен»?](/latex/uk/dokladni-statti/53-what-is-a-tex-token.md) Тут ми підсумуємо ключові ідеї, намагаючись уникнути надмірних повторів.

Почнімо з аналогії. Припустімо, що ви читаєте книгу й натрапляєте на незнайоме слово: що ви робите? Сьогодні це майже напевно означало б «звернутися до Google», але припустімо, що ви надаєте перевагу старішому методу: берете словник, який перелічує слова й подає їхні значення. TeX має аналогічний механізм: внутрішній «словник», який перелічує всі команди, наразі відомі TeX, і «значення» цих команд. Під «значенням» мається на увазі, до якого типу належить команда: що вона робить, а також будь-яка інша інформація, яка може знадобитися TeX для виконання цієї команди. Зауважте також, що термін «команда» охоплює будь-які макроси TeX/LaTeX, написані користувачами/програмістами TeX, і [сотні вбудованих примітивних команд](/latex/uk/inshi-temi/46-tex-primitives-listed-by-tex-engine.md).

Продовжуючи нашу аналогію зі словником. Коли нам, як читачам, потрібно знайти значення слова, ми шукаємо його в словнику, користуючись алфавітним переліком слів, який подає словник, але, звісно, TeX працює не зовсім так. Повертаючись до нашого початкового `jobname` прикладу, як TeX знаходить у своєму «словнику» «значення» `jobname`—і що саме це «значення» насправді надає TeX?

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

Щоразу, коли TeX виявляє команду, використану у вашому вхідному тексті, і йому потрібно щось знати про цю команду, він перетворює послідовність символів у назві команди на «еквівалентне» ціле число і використовує це число для пошуку команди у своєму «великому словнику». Тим із вас, хто програмує, може бути цікаво дізнатися, що TeX використовує форму [хеш-функції](https://en.wikipedia.org/wiki/Hash_function) для виконання цього перетворення.

![Діаграма хеш-функції](/files/a06ce2460760f444f86cff2ca3bdfc3ef25b3da8)

### Графіка 6: Від символів до значення команди

Наведена нижче графіка показує шлях, який проходить команда, коли TeX перетворює рядок символів на еквівалентне ціле число, яке називається **curcs**, і використовує це число для пошуку значення команди у «великому словнику» TeX. Результатом такого пошуку є дві частини інформації: два цілі числа, що називаються **curcmd** та **curchr**, які TeX може використовувати, щоб точно з’ясувати, що робить команда і як згодом її виконати.

![TeX перетворює рядок символів на еквівалентне ціле число, щоб знайти значення команди](/files/3ff052ae5b4b4845a9555fd8e1a62a170ede5d15)

Внутрішньо TeX підтримує змінну під назвою **curcs** (**поточ**ний **c**послідов **ність**послідовності), яка використовується для зберігання цілого значення команди, над якою TeX наразі працює, тобто **curcs** зберігає ціле число, обчислене з назви команди. Це ще не вся історія, бо є ще одна деталь: якщо TeX щойно прочитав/обробив символ, а не команду, він встановить **curcs** значення 0, щоб пам’ятати, що останнім прочитаним елементом був символ, а не команда.

### Що означають команди для TeX

Якщо ми подивимося на набір [вбудованих команд, які надають рушії TeX](/latex/uk/inshi-temi/46-tex-primitives-listed-by-tex-engine.md) ми можемо побачити, що деякі з цих команд тісно пов’язані: вони виконують схожі завдання; наприклад, є 4 примітивні команди, які всі рушії TeX використовують для визначення (створення) макросів: `\def`, `\gdef`, `\edef`, `\xdef`. Усі ці 4 команди визначають макроси, але, звісно, кожна робить це трохи по-іншому. Якщо подумати про це з програмістської точки зору: маємо 4 команди визначення макросів, які загалом роблять одне й те саме, але нам потрібно вибирати між ними, щоб врахувати їхню індивідуальну поведінку.

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

* **кодом команди**: свого роду «загальну класифікацію», що вказує, до якого «типу» належить команда, — наприклад, команда «визначення макросу» (одна з `\def`, `\gdef`, `\edef`, `\xdef`); команда «створення коробки» (одна з `\hbox`, `\vbox` або `\vcenter`) і так далі для сотень команд, які підтримують рушії TeX. Макросам (користувацьким командам) також призначається код команди.
* **модифікатор команди**: це допоміжна інформація, яка надає TeX конкретні відомості про команду. Макросам (користувацьким командам) також призначається модифікатор команди — хоча для макросів модифікатор команди відіграє дещо іншу роль, ніж для примітивів (для макросів модифікатор команди вказує, де в пам’яті зберігається визначення макросу).

У сукупності код команди та модифікатор команди однозначно ідентифікують кожну команду. Ось коди команд і модифікатори команд для команд визначення макросів, як їх використовувало оригінальне програмне забезпечення TeX Кнута — зауважте, що інші рушії TeX можуть використовувати інші значення, але вони дотримуються того самого принципу:

|             |                                                         |                                                                 |
| ----------- | ------------------------------------------------------- | --------------------------------------------------------------- |
| **Команда** | <p><strong>Команда</strong><br><strong>код</strong></p> | <p><strong>Команда</strong><br><strong>модифікатор</strong></p> |
| `\def`      | 97                                                      | 0                                                               |
| `\gdef`     | 97                                                      | 1                                                               |
| `\edef`     | 97                                                      | 2                                                               |
| `\xdef`     | 97                                                      | 3                                                               |

### Підсумок: як розібратися з усіма цими змінними/значеннями

На цьому етапі нас уже переповнює багато інформації про значення, змінні, значення команд і різні деталі — це швидко може заплутати, тож давайте підсумуємо, що ми знаємо. Коли TeX читає щось із ваших вхідних даних, це або символ, або команда. Щоразу, коли TeX читає щось із вхідного тексту, йому потрібно зберегти інформацію про те, що він щойно прочитав (просканував):

* Для **символи**: йому потрібно записати код символу та категорійний код. Також потрібно створити й зберегти значення токена, яке TeX обчислює, використовуючи ці значення.
* Для **команди**: TeX потрібно знати числовий еквівалент, **curcs**, яке він обчислив із назви команди. Також може знадобитися зберегти «значення», отримане під час пошуку команди в «словнику» TeX: код команди та модифікатор команди. Окрім цього, TeX також має обчислити значення токена, що представляє цю команду.

Так, це заплутано: навколо багато змінних і ідей про токени, тож спробуймо в цьому розібратися.

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

* **curcmd**: (поточна команда) ціла змінна. Вона використовується для зберігання *поточної команди* значення для команди, що обробляється *або* вона зберігає поточний *код категорії* символа, що обробляється;
* **curchr**: (поточний символ) ціла змінна, але те, що вона зберігає, залежить від того, що TeX щойно прочитав зі своїх вхідних даних:
* **символа**: Якщо найостаннішим прочитаним елементом є символ, **curchr** зберігає поточний *код символу*.
* **команду**: Якщо найостаннішим прочитаним елементом є команда, **curchr** зберігає *модифікатор команди*: додаткова інформація, яку TeX використовує для підтримки/уточнення **curcmd**—бо, як ми бачили вище, деякі команди мають однакове значення **curcmd**
* **curcs**: (поточна керівна послідовність) ціла змінна, яка зберігає значення, обчислене з рядка символів у назві команди. **curcs** = 0, якщо останнім прочитаним елементом був окремий символ, а не назва керівної послідовності (назва команди);
* **curtok**: (поточний токен) ціла змінна, яка містить значення поточного токена — тобто або токена команди, або символьного токена.

Наведену вище інформацію подано в таблиці:

|                                                          |                                                                                                                                                                                                                         |                                                                                                                                                                                                                                                                      |
| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Глобальна змінна, що використовується всередині TeX:** | **Коли TeX сканує символ:**                                                                                                                                                                                             | **Коли TeX сканує команду:**                                                                                                                                                                                                                                         |
| **curcmd**                                               | Зберігає категорійний код поточного символу                                                                                                                                                                             | Зберігає *кодом команди*—що визначає «тип» поточної команди                                                                                                                                                                                                          |
| **curchr**                                               | Зберігає код поточного символу                                                                                                                                                                                          | Зберігає додаткові дані (так звані *модифікатор команди*), які надають додаткову інформацію про поточну команду                                                                                                                                                      |
| **curcs**                                                | 0                                                                                                                                                                                                                       | Додатне ненульове ціле число, яке обчислюється (за допомогою хеш-функції) з рядка символів, що міститься в назві команди. Воно використовується для доступу до «словника» TeX, щоб знайти поточне значення команди — отримати її код команди та модифікатор команди. |
| **curtok**                                               | Для 8-бітних рушіїв TeX *символьним токеном* обчислюється за формулою: $$\text{curtok}=256\times \text{curcmd} + \text{curchr}$$ де $$\text{curcmd}$$ є категорійним кодом символу, а $$\text{curchr}$$ є кодом символу | Для 8-бітних рушіїв TeX *токеном команди* обчислюється за формулою: $$\text{curtok}=4095 + \text{curcs}$$                                                                                                                                                            |

### Додаткові примітки щодо поточного токена

Для символів максимальне можливе значення токена отримують, використовуючи найбільший категорійний код (15) і найбільший код символу, який для 8-бітних рушіїв TeX дорівнює 255. Теоретично (для 8-бітних рушіїв TeX) максимальне значення символьного токена, $$\text{curtok}\_{\text{max}}$$, становить:

$$\text{curtok}\_{\text{max}}= 256\times 15 + 255 = 4095$$

Ми зауважуємо «теоретично», тому що категорійний код 15 використовується для позначення «недійсного символу», який спричиняє помилку в TeX: недійсний символ ніколи не пройде через процес сканування вхідних даних TeX, тож ніколи не стане символьним токеном.

Для команд поточний токен ($$\text{curtok}$$) обчислюється з $$\text{curtok}=4095 + \text{curcs}$$ але для команд $$\text{curcs}$$ є *завжди* є ненульовим, тож TeX може легко визначити, що представляє токен:

* Якщо $$\text{curtok} > 4095$$ тоді це токен команди;
* Якщо $$\text{curtok} < 4095$$ це символьний токен.

Фактично TeX використовує токени — просте ціле значення — щоб «упакувати» всю інформацію, яку йому потрібно знати про елемент, прочитаний із вхідних даних.

## Частина 4

У Частині 4 ми досліджуємо низку прикладів макросів, щоб продемонструвати роль і призначення `<parameter text>` розділу макросу як «шаблону токенів», який можна побудувати за допомогою токенів-розділювачів.

[Частина 1](/latex/uk/inshi-temi/19-how-tex-macros-actually-work-part-1.md) [Частина 2](/latex/uk/inshi-temi/20-how-tex-macros-actually-work-part-2.md) [Частина 3](/latex/uk/inshi-temi/21-how-tex-macros-actually-work-part-3.md) [Частина 4](/latex/uk/inshi-temi/22-how-tex-macros-actually-work-part-4.md) [Частина 5](/latex/uk/inshi-temi/23-how-tex-macros-actually-work-part-5.md) [Частина 6](/latex/uk/inshi-temi/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/uk/inshi-temi/21-how-tex-macros-actually-work-part-3.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.
