> 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/54-what-is-a-tex-token-list.md).

# Що таке список токенів TeX

## Отже, що ж таке «список токенів TeX»?

У [попередня стаття](/latex/uk/dokladni-statti/53-what-is-a-tex-token.md)—також частина цього [циклу про низькорівневі технічні тонкощі TeX](/latex/uk/dokladni-statti/01-a-new-series-of-articles-tex-tokens-and-related-concepts-but-why-and-how.md)—ми дослідили процеси, через які TeX сканує ваш `.tex` файл, щоб згенерувати нові токени: ми розглянули фундаментальну природу токена TeX і те, як TeX їх створює (див. [Що таке «TeX-токен»?](/latex/uk/dokladni-statti/53-what-is-a-tex-token.md)).

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

Списки токенів відіграють ключову роль у внутрішній роботі TeX, часто в дещо несподіваний спосіб, наприклад у внутрішній роботі таких команд, як `\uppercase` та `\lowercase`. Один із особливо важливих способів використання списків токенів — зберігання та виконання макросів; цю тему ми детально розглянемо в майбутній статті цього циклу.

### TeX отримує вхідні дані з файлів і списків токенів

Рушії TeX мають три джерела вхідних даних — два з них вам, можливо, відомі:

* фізичні текстові файли, збережені на диску;
* текст, який користувач вводить у термінал (командний рядок);

але є ще третій спосіб читання/отримання вхідних даних: списки токенів!

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

Для швидкого прикладу низькорівнева (примітив TeX) `\toks` команда дає змогу створити список токенів, який TeX зберігає в пам’яті для подальшого повторного використання:

```latex
\toks100={Hello}
```

Щоб отримати ці токени (тобто наказати TeX поводитися з ними як із наступним джерелом вхідних даних), ви б подали команду на кшталт

```latex
\the\toks100
```

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

Крім того, списки токенів можуть бути внутрішньо згенеровані «на льоту» низкою команд TeX. Один приклад — команда `\jobname` яка генерує серію символьних токенів — по одному токену для кожного символа в назві головного файла, який обробляє TeX. Інший приклад — команда `\string` ; наприклад

```latex
\string\mymacro
```

генерує серію символьних токенів для кожної літери в назві `\mymacro`— включно з початковим `\` символом. Наприкінці цієї статті ми докладніше розглянемо деякі «команди, що генерують токени».

## Список токенів: пояснення через аналогію

Якщо у вас немає досвіду програмування та/або певних знань із комп’ютерних наук, «списки токенів» можуть здаватися дещо туманним і, можливо, трохи заплутаним поняттям. Однак, якщо ви хочете навчитися добре писати макроси TeX/LaTeX, то гарне розуміння таких тем, як токени TeX, списки токенів і коди категорій (`\catcode`) виявиться надзвичайно корисним.

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

### Списки токенів: аналогія (уявний експеримент)

Ми проведемо «уявний експеримент», щоб створити основу для розуміння списків токенів TeX. Уявімо, що ви маєте доступ до великого набору контейнерів, наприклад сотень бляшанок — ми не можемо вживати термін «коробка» для опису контейнерів у цьому уявному експерименті, бо, звісно, «box» має дуже конкретне значення в TeX, цілком не пов’язане з нашою теперішньою розмовою. Тож ми назвемо наші контейнери «бляшанками», де кожна Бляшанка:

* має надрукований на зовнішньому боці унікальний ідентифікаційний номер;
* (внутрішньо) поділена на два відділення.

Ці два відділення спроєктовано так:

* ліве відділення містить предмет, який ви хочете покласти в Бляшанку;
* праве відділення призначене для аркуша паперу, на якому ви можете написати одне число: номер, що ідентифікує іншу Бляшанку.

![тест](/files/3bc1580cb7e7ff4092506d440a0a33ef143b8e1d)

Припустімо, що у вас є набір, скажімо, з 5 предметів і ви хочете зберегти цей набір у цих Бляшанках; але, на жаль, кожна Бляшанка може вмістити лише 1 предмет потрібного вам типу.

Для простоти припустімо, що ми хочемо зберігати 5 кольорових кіл:

![{{{alt}}}](/files/128721602265bc4cb8a04ac593bfb34ac4761164)

Крім того, коли ви потім повертаєтеся, щоб дістати ці предмети зі своєї системи зберігання (Бляшанок), ці предмети *необхідно* можуть бути отримані/знайдені в певному порядку — у тому порядку, в якому вони були збережені: цю послідовність треба зберегти. Як цього досягти?

Ми можемо скористатися тим фактом, що кожна Бляшанка:

* має прикріплений зовні унікальний ідентифікаційний номер;
* має 2 відділення — лише одне з них ми використаємо для предмета, а в іншому міститиметься аркуш паперу з написаним на ньому номером іншої Бляшанки.

Ми припустимо, що кожна Бляшанка порожня — але ніщо не заважає вам відкрити будь-яку Бляшанку й перевірити, чи вона порожня; якщо ні, спробуйте наступну, доки не знайдете порожню Бляшанку.

Що ми могли б зробити, так це ось що. Покласти наш перший предмет (темно-зелене коло) в одну з наших Бляшанок (наприклад, Бляшанку 124) і записати номер цієї першої Бляшанки — не має значення, який саме номер має та перша Бляшанка; важливо лише, щоб ми записали його десь і зберегли для подальшого використання.

![{{{alt}}}](/files/a068d755dfd1030bafd275373bb9a891f298a238)

Знайдіть другу Бляшанку — будь-яку Бляшанку з номером (наприклад, Бляшанку 432) — і запишіть її номер. Напишіть номер цієї другої Бляшанки (432) на аркуші паперу й покладіть цю записку *у першу Бляшанку* (Бляшанку 124). Ми кладемо наш другий предмет (світло-зелене коло) у другу Бляшанку. Отже, наразі маємо таку ситуацію:

* письмову записку — не збережену в Бляшанці — що перша Бляшанка має номер 124 (у ній міститься наш перший предмет);
* у Бляшанці 124 ми додали ще одну записку, де сказано, що наступний предмет треба шукати в Бляшанці 432.

По суті, ми *зв’язали* перші дві Бляшанки: ми знаємо, з чого почати (Бляшанка 124), і що записка в Бляшанці 124 каже нам, яка Бляшанка містить наступний предмет (Бляшанка 432).

![{{{alt}}}](/files/b890a667263aadbe672b282d2b25144be962c1eb)

Потім ми знаходимо третю Бляшанку, записуємо її номер (наприклад, Бляшанка 543) на аркуші паперу й кладемо його в *другу* Бляшанку (номер 432). Потім кладемо наш третій предмет (червоне коло) у третю Бляшанку.

Тепер ми зв’язали три Бляшанки в послідовність: наша стартова точка, Бляшанка 124 (темно-зелене коло) → Бляшанка 432 (світло-зелене коло)→ Бляшанка 543 (червоне коло) →…

![{{{alt}}}](/files/b5585e71f89ed5391062d84c1b138de6a7ea6fa7)

Повторіть цей процес для двох останніх предметів (світло-блакитного та темно-блакитного кіл), використовуючи Бляшанку 213 (світло-блакитне коло) і Бляшанку 102 (темно-блакитне коло).

![{{{alt}}}](/files/77806857cad539301c628d8a78736434873c27cc)

Тепер ми маємо всі 5 Бляшанок, зв’язаних разом (за допомогою числового ідентифікатора кожної Бляшанки), і можемо дістати всі наші збережені предмети — у правильному порядку — просто послідовно відвідуючи кожну Бляшанку, забираючи наш предмет і дивлячись на записку, яка каже нам, у якій Бляшанці міститься наш наступний предмет.

### А що щодо останнього предмета в нашому списку (Бляшанка 102)?

Чому ми маємо перейматися саме цим? Поки що ми зберігали кожен предмет у Бляшанці разом із запискою про те, в якій Бляшанці міститься наступний предмет: що має бути написано в такій записці для останнього предмета в нашому списку — адже наступної Бляшанки немає.

Коли ми дістаємося до останнього предмета (Бляшанки), має бути очевидно, що ця Бляшанка (яка містить останній предмет) є останнім предметом у нашому списку — нам не потрібно шукати іншу Бляшанку, бо її немає. Один зі способів це зробити — покласти всередину нашої останньої Бляшанки (102) «особливий» номер Бляшанки. Ми можемо використати будь-який номер, який захочемо, за умови, що виберемо унікальний номер, який не є номером жодної реальної Бляшанки — наприклад, «Бляшанка -1», «Бляшанка 0»: це не має значення, аби ми знали, що «Бляшанка -1» або «Бляшанка 0» тощо негайно підказує нам зупинитися: нам не потрібно шукати ще Бляшанки, бо це остання, а отже більше немає предметів для отримання.

### Від «предметів» і «Бляшанок» до токенів і TeX

Тепер нам треба перейти від нашої аналогії до опису, ближчого до реальності TeX. По-перше, замість зберігати по-різному кольорові кола в наших уявних Бляшанках, має бути зрозуміло, що ми можемо уявляти ці Бляшанки як сховище токенів TeX: простих цілих чисел. Це легша частина перенесення нашої аналогії у сферу програмного забезпечення (TeX). Але яким може бути програмний еквівалент наших фізичних пронумерованих Бляшанок із «відділеннями»?

Ми не хочемо надто заглиблюватися в поняття програмування, але ви можете уявляти наші «Бляшанки» як кілька байтів комп’ютерної пам’яті, які було «упаковано» в зручну одиницю зберігання. Використання числового ідентифікатора для кожної Бляшанки в нашій аналогії можна вважати місцем у комп’ютерній пам’яті, де розташований кожен маленький пакет пам’яті. Усередині самого TeX такі маленькі пакети сховища називаються «словами пам’яті» — терміном, що відображає час/епоху, коли було створено TeX (1970-ті). Ці «слова пам’яті» є фундаментальним будівельним блоком, що використовується в TeX, але нам не потрібно розглядати їх тут докладніше — усі, хто хоче більше деталей, можуть звернутися до статті в [особистому блозі автора](http://www.readytext.co.uk/?p=3537).

У термінах комп’ютерного програмування те, про що ми говорили, називається [*зв'язаний список*](https://en.wikipedia.org/wiki/Linked_list): список токенів TeX — це зв’язаний список, побудований із контейнерів зберігання TeX, які називаються *словами пам’яті* де кожне слово пам’яті може використовуватися для зберігання:

* a *значення*: значення токена (ціле число);
* a *зв’язок*: розташування в пам’яті наступного слова пам’яті, що містить наступний токен у нашому списку.

## Де TeX використовує списки токенів?

Скрізь! Це так, тому що визначення макросу TeX/LaTeX (наприклад, команди LaTeX) зберігається у (дещо спеціалізованій) формі списку токенів — спеціалізованій у тому сенсі, що воно містить токени, яких ви не бачите в «стандартних» списках токенів (пов’язані з зіставленням параметрів макроса тощо). Не хвилюйтеся через це, бо ми розглянемо ці деталі в майбутній статті.

### Приклад макроса

Макрос можна уявити як такий, що складається з трьох частин:

```
\def\<назва макроса><текст параметрів>{<текст заміни>}
```

Зауважте, що замість `\def` ви могли б використати `\edef`, `\gdef` або `\xdef`.

**Примітка для користувачів LaTeX**: Тут ми визначаємо макроси за допомогою сирих, низькорівневих команд TeX (які називаються *примітивів*). Користувачам LaTeX буде більш знайоме створення макросів через `\newcommand` (який сам є макросом).

Коли ви просите TeX створити (визначити) макрос, він створить токен, який представляє `<macro name>` і *списки токенів* який представляє поєднаний `<parameter text>` та `<replacement text>`. TeX уважно збереже все так, щоб токен, що представляє `<macro name>` було пов’язано зі списком токенів, який представляє його визначення (`<parameter text>` та `<replacement text>`).

Наприклад, якщо ми визначимо `\mymacro` ось так:

```latex
\def\mymacro abc #1 defz{I typed \"#1\"!}
```

Ми бачимо, що його складові частини такі:

* `<macro name>` = `mymacro`
* `<parameter text>` = `abc #1 defz`
* `<replacement text>` = `I typed \"#1\"!`

Наприклад, ви можете викликати `\mymacro` ось так:

```latex
\mymacro abc THIS TEXT defz
```

що дає результат `I typed \"THIS TEXT\"!` набраним — `abc` та `defz` є *не* виводяться. `abc` та `defz` є послідовностями символьних токенів, які використовуються для *відокремлення* параметра макроса `#1` і поглинаються та відкидаються, коли ваш виклик макроса успішно обробляється TeX.

Коли ви визначили `\mymacro`, шаблон токенів, що міститься в збереженому, діє як «шаблон», який TeX може використати, щоб визначити:

* які токени у вашому вхідному тексті є токенами-розділювачами;
* які токени у вашому вхідному тексті фактично формують параметр(и) вашого макроса (тут, те, що ви використовуєте для `#1` у своєму виклику `\mymacro`).

Ви маєте викликати `\mymacro` на `<parameter text>` який містить розділювачі, ідентичні тим, що використовувалися для його визначення — це включає використання символьних розділювачів з ідентичними кодами категорій. Якщо розділювачі в `<parameter text>` використаному для виклику `\mymacro` відрізняються від тих, що використовувалися для його визначення (від «шаблону», збереженого в пам’яті), тоді TeX може неабияк заплутатися — коли він намагатиметься обробити `\mymacro` він не зможе зіставити «шаблон», який зберіг у своїй пам’яті.

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

TeX дуже прискіпливий — пам’ятайте, що символьні токени є поєднанням коду символа та коду категорії: якщо змінити код категорії символа, ви отримаєте інше значення токена, що походить від цього символа.

Припустімо, ми змінили код категорії `z` на, скажімо, 12 — зазвичай це 11 — і спробуємо викликати наш макрос так:

```latex
\catcode`z=12
\mymacro abc THIS TEXT defz more text here...
```

Цього разу не спрацює, бо код категорії `z` було змінено. Ви побачите таку помилку:

```latex
Аргумент утік?
THIS TEXT defz
! Абзац закінчився до того, як \mymacro було завершено.
<читати ще раз>
\par
l.22
```

Коли TeX читає та сканує `z` % `defz` він не може розпізнати його як таке, що утворює кінець `\mymacro`’s `<parameter text>` використаного у вашому вхідному файлі. До того як TeX побачив цю помилкову `z` TeX правильно зіставив перші 3 символи `def` але це `z` (з кодом категорії 12) збиває сканування TeX. Якщо припустити, `z` мав код категорії 11, коли ми *визначили* `\mymacro`: це призвело б до збереження значення токена 256×11 + 122 = 2938 як частини `\mymacro`визначення (тобто як частини збереженого «шаблону»). Однак із кодом категорії 12, `z` тепер створить значення токена 256×12 + 122 = 3194. Оскільки значення токена (для `z`) прочитане з вашого входу (значення 3194) не збігається з `z`-токеном, що міститься в збереженому `<parameter text>` шаблоні списку токенів (значення 2938), TeX продовжить сканування вашого вхідного тексту. TeX і далі скануватиме текст, що йде після вашого макроса (*ще текст тут* ...) щоб шукати додаткові токени — намагаючись зіставити збережений шаблон із токенами, які він знаходить у вашому вході. Найімовірніше, він не знайде правильну послідовність токенів, і виникнуть помилки, коли TeX «перестрибне» ваш вхід і помилково прочитає зайвий текст, щоб створити додаткові токени — ці додаткові токени не мали б бути прочитані на цьому етапі й майже напевно згенерують помилку.

Ми розглянемо це докладніше в майбутній статті.

## Інші способи використання списків токенів

До інших команд, які використовуються для створення/збереження списків токенів, належать:

```latex
\toks<n>={...}
\everypar={...}
\everymath={...}
\everydisplay={...}
\everyhbox={...}
\everyvbox={...}
\output={...}
\everyjob={...}
\everycr={...}
\errhelp={...}
```

Кожна з цих команд створює список токенів із символів і команд усередині дужок ‘{...}’, і цей список токенів призначено для повторного використання за певних обставин. Наприклад, `\everypar={...}` створює та зберігає набір токенів (список токенів), який TeX вставляє у вхід перед тим, як розпочати новий абзац.

## Приховані способи використання списків токенів: приклади

У цьому завершальному розділі ми розглянемо кілька практичних прикладів використання списків токенів так, як ви, можливо, не очікуєте.

### Приклад 1: \uppercase{...} і \lowercase{....} — тимчасові списки токенів

Окрім явних команд на створення списків токенів, є ситуації, коли TeX створює прихований і тимчасовий внутрішній список токенів, щоб виконати певну спеціальну обробку. Пам’ятайте, що коли TeX читає/обробляє ваші вхідні символи/команди, вони перетворюються на токени: фундаментальні будівельні блоки, з якими працюють рушії TeX.

Хороший приклад — команди `\uppercase{...}` або `\lowercase{...}` бо їхня робота на перший погляд може бути досить заплутаною. Коли ви зрозумієте, що вони роблять — глибоко всередині TeX і невидимо для користувача — їхня робота стане набагато легшою для розуміння.

Припустімо, у вас є проста послідовність літер, яку ви хочете зробити великою — наприклад, abcde — і перетворити її на ABCDE. Що ж, із TeX-командою `\uppercase` команди:

```latex
\uppercase{abcde}
```

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

```latex
\toks100={abcde}
\def\mychars{abcde}
```

Потім, у якийсь момент, ви можете вирішити, що хочете повторно використати вашу послідовність літер, але цього разу у верхньому регістрі; тож ви пробуєте

```latex
\uppercase{\the\toks100}
```

та

```latex
\uppercase{\mychars}
```

Але, на жаль, жоден із цих варіантів не працює. Чому так?

### Таємні списки токенів!

Щоб зрозуміти, як насправді працюють команди `\uppercase{...}` `\lowercase{...}` мені довелося зазирнути всередину внутрішнього механізму TeX, тож пояснення нижче ґрунтується саме на цьому.

Коли TeX виявляє або `\uppercase{<material>}` або `\lowercase{<material>}` у вашому вході, перше, що робить TeX, — створює (тимчасовий) внутрішній список токенів із `<material>` , укладеного між ‘{’ і ‘}’, які йдуть після `\uppercase{...}` або `\lowercase{...}` команд — цей тимчасовий список токенів є внутрішнім для TeX.

Критично важливий момент, центральний для розуміння того, як `\uppercase{<material>}` та `\lowercase{<material>}` насправді працюють, полягає в тому, що будь-які команди або макроси, що містяться в `<material>` , не *розгорнуто*: усе, що робить TeX, — це генерує токени із символів і команд, розміщених між `{...}`. Під час роботи `\uppercase{<material>}` або `\lowercase{<material>}` нічого між дужками не виконується: воно просто перетворюється на токени.

Після `<material>` всередині `{...}` було перетворено на (тимчасовий) список токенів, TeX потім знову переглядає кожен токен у цьому списку й перевіряє, чи це *символа* символьний токен або *команду* токен команди (використовуючи числове значення токена). Якщо TeX виявляє символьний токен, він змінює цей токен, щоб скоригувати регістр символа (залежно від того, `\uppercase` або `\lowercase` обробляється). TeX просто ігнорує будь-які токени команд і не «заглядає» всередину жодного токена команди, щоб побачити, що вони представляють або містять (наприклад, макрос, що містить символи) — він просто пропускає їх: під час операцій зміни регістру фактично обробляються/змінюються лише символьні токени.

Тож, наприклад, якщо ми подаємо команду TeX, таку як `\uppercase{abcde}` TeX створить список токенів із `abcde` що містить лише символьні токени: усі вони коригуються, щоб створити серію змінених токенів, що представляють A, B, C, D і E. Ці змінені токени повертаються у вхідний процесор TeX, унаслідок чого `ABCDE` виводиться. *Однак якщо ми зберегли наші символи*у макросі `\def\mychars{abcde}`— наприклад

```latex
\uppercase{\mychars}
```

— і спробуємо перетворити їх на великі так: `\toks0={abcde}` і зробимо `\uppercase{\the\toks0}` то, знову ж таки, `\uppercase` не спрацює, бо список токенів буде складатися цілком із токенів, на які не впливає `\uppercase`.

Візьмімо як приклад наш макрос, `\mychars`, після того як TeX виявляє `\uppercase` у вхідному тексті, TeX визначає значення `\uppercase` і виконує його, створюючи тимчасовий список токенів із `{\mychars}`. Очевидно, цей тимчасовий список токенів містить лише один токен, який не є символьним токеном, а є тим, що представляє нашу команду макроса `\mychars`: отже, для цілей виконання `\uppercase`, цей токен ігнорується —`\mychars` не є символьним токеном. Однак, як зазначено вище, після того як `\uppercase` зробив свою роботу, тимчасовий список токенів (створений дією `\uppercase`) повертається в повний механізм обробки вхідних даних (сканування) TeX. Коли TeX повторно читає цей список токенів, він виявляє токен, що представляє наш `\mychars` макрос, який TeX виконує (розгортає) і генерує серію символів для набору abcde — усе ще в нижньому регістрі, бо вони були «запаковані» всередину макроса й тому невидимі для дії `\uppercase`.

Після того як TeX повторно переглянув тимчасовий список токенів, створений для `\uppercase{...}` або `\lowercase{...}`, і обробив будь-які символьні токени, він переходить до використання цього тимчасового списку токенів як джерела вхідних даних: набору символів (оброблених символьних токенів) і виконання команд та макросів.

### Як це можна виправити?

Оскільки `\uppercase{...}` або `\lowercase{...}` працюватиме лише з символьними токенами, нам потрібен спосіб «примусово розпакувати» символи, що містяться в нашому макросі `\mychars` (або містяться в `\toks` регістрі) перед тим, як `\uppercase{...}` або `\lowercase{...}` почне діяти на нього. Під «розпакуванням» ми насправді маємо на увазі процес TeX, який *розширення*:

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

#### Низькорівнева магія: scantoks(..., ...)

Тут ми справді заглядаємо в деякі темніші закутки внутрішнього механізму TeX, тож можете ігнорувати цей розділ, якщо вам не подобаються деталі…

Після того як TeX виявляє `\uppercase` або `\lowercase` у потоці вхідних даних, він виконує внутрішню функцію під назвою `scantoks(..., ...)` , завдання якої — згенерувати список токенів, використовуючи елементи між відкривальною ‘{’ і закривальною ‘}’ — як уже згадувалося, цей список токенів потім аналізується, щоб виявити (а потім скоригувати) будь-які символьні токени для зміни регістру символів за потреби. Уважно зауважте, що ми маємо на увазі `scantoks(..., ...)` як внутрішню функцію, вбудовану в вихідний код рушіїв TeX — тут це не назва керувальної послідовності.

У межах своєї роботи `scantoks(..., ...)` можна вказати, чи розгортати, чи не розгортати список токенів, який вона будує, а для `\uppercase` і (`\lowercase`) вона не розгортає токени: вона просто створює їх і поміщає в список токенів.

Одна з перших речей, які `scantoks(..., ...)` має зробити, — це перевірити наявність відкривальної ‘{’ (або будь-якого символа з `\catcode` 1) тому що треба переконатися, що користувач не припустився синтаксичної помилки й не забув відкривальну ‘{’ (або будь-який символ із кодом категорії 1) — адже символ із кодом категорії 1 потрібен, щоб позначити початок списку елементів, які потрібно токенізувати.

І ось у чому фокус: завдання пошуку відкривальної ‘{’ запускає `scantoks(..., ...)` для виконання процесу розгортання TeX, а це означає, що такі приклади працюватимуть:

```latex
\let\ob={
\uppercase\ob abcde}
\def\obb{\ob}
\uppercase\obb xyz}
```

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

Отже, якщо ви визначите:

```latex
\toks0={abcde}
\def\mychars{abcde}
```

А зробите так:

```latex
\uppercase\expandafter{\mychars}
\uppercase\expandafter{\the\toks0}
```

в обох випадках ви тепер побачите набраним ABCDE, бо `\expandafter` спричиняє «розпакування» (розгортання) `\mychars` та `\the\toks0`— обидва варіанти дають `\uppercase` потік символьних токенів, який вони можуть обробити для зміни регістру.

### Приклад 2: \string — ще більше тимчасових списків токенів

Внутрішньо TeX класифікує `\string` Це `\string` команда призначена для перетворення токена на текстову версію, зрозумілу для людини — тобто верстати зрозумілий для людини рядок символів, з яких цей токен було спочатку створено.

Наприклад `\string\hello` створює тимчасовий список токенів, який містить символи \\, h, e, l, l, o — так, навіть включно з початковим ‘\’. Після того як цей список токенів створено, TeX знову зчитує його, і текст команди “`\hello`” верстається — так, включно з ‘\’, якщо ви виберете правильний шрифт…

Ви можете дивуватися, як/чому TeX може верстати символ екранування, коли його зазвичай використовують, щоб змусити сканер TeX створити токен команди: чому тут він так не робить? Відповідь пов’язана з кодами категорій: зазвичай символ ‘\’ має catcode 0 (символ екранування), але коли `\string` генерує свій внутрішній список токенів, він робить дещо інакше. Коли він створює список токенів-символів, він присвоює категорійний код 12 усім символам, окрім пробільного символу, якому присвоюється catcode 10 — згадайте, що токени-символи обчислюються як 256 x catcode + значення ASCII. Отже, коли TeX зчитує (входить) тимчасовий список токенів, який `\string` згенеровано з `\hello`, TeX *не бачить символу екранування* оскільки токен для ‘\’ було обчислено з catcode 12, а не 0: TeX просто сприймає ‘\’ як звичайний символ і верстає його.

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

### Технічна примітка

Команда під назвою `\showtokens{...}` (впроваджена рушієм e-TeX) може показувати списки токенів (у файлі журналу). Із довідника e-TeX:

> Команда `\showtokens{<token list>}` відображає список токенів і дозволяє показувати величини, які не можна відобразити за допомогою `\show` або `\showthe`, наприклад:
>
> ```latex
> \showtokens\expandafter{\jobname}
> ```

## На завершення

У розділі 291 вихідного коду TeX (див. сторінку 122 з [TeX: Програма](https://www.amazon.co.uk/Computers-Typesetting-TeX-Program-TEX/dp/0201134373)) Кнут описує список токенів так:

> «Список токенів — це однозв’язний список вузлів по одному слову в mem, де кожне слово містить токен і посилання. Визначення макросів, визначення процедур виводу, позначки, `\write` тексти та кілька інших речей TeX запам’ятовує у формі списків токенів, зазвичай із вузлом перед ними з лічильником посилань у полі “token\_ref\_count”.»

З першого прочитання це, можливо, було нелегко зрозуміти, але, сподіваємося, тепер це може трохи більше мати сенс.


---

# 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/54-what-is-a-tex-token-list.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.
