> 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/pl/artykuly-szczegolowe/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md).

# Jak działa \expandafter: od podstawowych zasad do analizy kodu źródłowego TeX-a

[Część 1](/latex/pl/artykuly-szczegolowe/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md) [Część 2](/latex/pl/artykuly-szczegolowe/22-how-does-expandafter-work-the-meaning-of-expansion.md) [Część 3](/latex/pl/artykuly-szczegolowe/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md) [Część 4](/latex/pl/artykuly-szczegolowe/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md) [Część 5](/latex/pl/artykuly-szczegolowe/17-how-does-expandafter-work-a-detailed-macro-case-study.md) [Część 6](/latex/pl/artykuly-szczegolowe/18-how-does-expandafter-work-a-detailed-study-of-consecutive-expandafter-commands.md)

## Wstęp

Omówiliśmy już teraz zagadnienia wprowadzające niezbędne do pełnego omówienia `\expandafter`:

* podstawy tokenów TeX-a i sposobu ich obliczania;
* zasady stojące za procesem ekspansji TeX-a;
* używanie/tworzenie przez TeX tymczasowych list tokenów podczas przetwarzania dokumentu;
* jak TeX korzysta z wielu źródeł wejściowych i nimi „żongluje” (w tym tymczasowymi listami tokenów).

W tym artykule połączymy te zagadnienia/koncepcje, aby wyjaśnić mechanizmy stojące za `\expandafter` poleceniem: krótko mówiąc, jak działa.

## A zatem, do \expandafter

Idea stojąca za `\expandafter` polega na wymuszeniu rozwinięcia polecenia (tokenu) zanim TeX normalnie by to zrobił. Mając dwa tokeny, $$\mathrm{T\_1}$$ i $$\mathrm{T\_2}$$ działanie `\expandafter` $$\mathrm{T\_1T\_2}$$ powoduje, że TeX przetwarza $$\mathrm{T\_1}\text{<}$$rozwinięcie $$\mathrm{T\_2}\text{>}$$, gdzie $$\text{<}\dots\text{>}$$ oznacza listę tokenów. TeX rozwija $$\mathrm{T\_2}$$ z wyprzedzeniem, tak aby token $$\mathrm{T\_1}$$ (np. prymityw lub makro) mógł zobaczyć lub wykorzystać tokeny powstałe w wyniku rozwinięcia $$\mathrm{T\_2}$$. Jeśli token $$\mathrm{T\_2}$$ oznacza element nierozwijalny, taki jak nieaktywny znak lub (większość) prymitywów, działanie `\expandafter` niczego nie zmienia: TeX kontynuowałby przetwarzanie tokenów $$\mathrm{T\_1T\_2}$$ w zwykły sposób.

### Wprowadzenie do używania \expandafter

Jeśli nie używałeś `\expandafter`, oto przykład użycia go z prymitywem `\uppercase{...}`. Załóżmy, że chcielibyśmy złożyć nazwę naszego głównego `.tex` pliku wejściowego, ale wielkimi literami. Możemy znać następujące prymitywne polecenia TeX-a:

* `\uppercase`: robi to, co sugeruje nazwa: zamienia tokeny znakowe na ich odpowiedniki wielkimi literami (tam, gdzie to istnieje);
* `\jobname`: jak już widzieliśmy, rozwija się do nazwy głównego `.tex` pliku.

Zakładając, że nasz plik TeX nazywa się `mycode.tex` moglibyśmy zasadnie oczekiwać `\uppercase{\jobname}` że zostanie złożone jako `MYCODE`. Ale nie, składa jako `mycode` małymi literami. Co poszło „nie tak”?

Jeśli zapiszemy ogólne użycie `\uppercase` jako

```
\uppercase{<token list>}
```

możemy powiedzieć, że `\uppercase` przegląda `<token list>` i będzie działać (zmieniać wielkość liter) tylko na *tokenach znakowych* które wykryje w obrębie `<token list>`: wszystkie tokeny niebędące znakami są *ignorowane* ponieważ `\uppercase` nie będzie „zagłębiać się” (rozwijać) w tokeny nieznakowe, aby zobaczyć, co zawierają lub co reprezentują. Ponieważ token jest po prostu wartością całkowitą, wszystko, co `\uppercase` musi zrobić, to przejrzeć listę tokenów i sprawdzić, czy wartość numeryczna każdego tokenu w `<token list>` mieści się w zakresie wartości oznaczających token znakowy. Nawiasem mówiąc, `\uppercase` będzie także *zmieniać wielkość liter znaków aktywnych* aby utworzyć aktywny znak wielkimi literami, który, ponieważ nadal jest aktywny, również musi być zdefiniowany, w przeciwnym razie TeX wygeneruje błąd: `Niezdefiniowana sekwencja sterująca`, ale odbiegamy od tematu...

Na przykład, nawet jeśli zdefiniujemy makro, które jest tylko tekstem

```
\def\foo{some lower-case text}
```

to `\uppercase{\foo}` nadal składa `jakiś tekst małymi literami` a nie `SOME LOWER-CASE TEXT` jak byśmy oczekiwali, po prostu dlatego, że działanie `\uppercase` nie próbuje ustalić, co `\foo` oznacza: widzi `\foo` jako token polecenia i ignoruje go, tak jak zrobił to z `\jobname`.

### Jak możemy to naprawić? Z pomocą przychodzi \expandafter

Aby złożyć wersję wielkimi literami nazwy pliku, musimy zmodyfikować `\uppercase{\jobname}` przez wymuszenie, aby TeX zastąpił `\jobname` jego rozwinięciem (sekwencją tokenów znakowych) *zanim* `\uppercase` zacznie działać. Po raz kolejny rozwinięcie służy do usunięcia `\jobname` tokenu (polecenia) i zastąpienia go wynikiem jego rozwinięcia (listą tokenów zawierającą tokeny znakowe). Zatem, jeśli zapiszemy

```
\uppercase\expandafter{\jobname}
```

to działa: `MYCODE` zostałoby złożone. Dzieje się tak, że TeX zaczyna przetwarzać `\uppercase` i natychmiast sprawdza obowiązkowy znak otwierającego nawiasu klamrowego (`{`); jednak TeX wykrywa `\expandafter` polecenie, które powoduje, że tymczasowo „odwraca uwagę” i przetwarza `\expandafter{\jobname}`.

Jeśli porównamy

`\expandafter` $$\mathrm{T\_1T\_2}$$

z naszym przykładem

`\expandafter{\jobname}`

możemy zobaczyć

* $$\mathrm{T\_1} =\space$$`{`<sub>token</sub>
* $$\mathrm{T\_2} =\space$$`\jobname`<sub>token</sub>

Gdzie `{`<sub>token</sub> i `\jobname`<sub>token</sub> odnoszą się do wartości tokenów obliczanych przez TeX — zapis indeksowy <sub>token</sub> jest używany, by przypomnieć sobie, że TeX działa w świecie całkowitych tokenów.

Zapisanie `\uppercase\expandafter{\jobname}` działa, ponieważ w zarysie (szczegóły poniżej), `\expandafter` powoduje, że TeX wykonuje następujące zadania:

1. odczytaj i zapisz otwierający `{`<sub>token</sub>;
2. odczytaj następny token: `\jobname`<sub>token</sub>. TeX rozpoznaje, że `\jobname`<sub>token</sub> oznacza polecenie rozwijalne i rozwija je. `\jobname`<sub>token</sub> zostaje zastąpiony jego rozwinięciem — serią tokenów znakowych;
3. po rozwinięciu `\jobname` polecenia, TeX wkłada `{`$$\_\mathrm{token}$$ „z powrotem do wejścia” i używa listy tokenów powstałej z rozwinięcia `\jobname` tak, aby TeX odczytał `\uppercase{`<sub>token</sub>`<expansion of \jobname>`<sub>lista tokenów (znaki)</sub>`}`, a to daje pożądany rezultat.

Poniższy diagram pokazuje, jak TeX przetwarza `\uppercase\expandafter{\jobname}`— czytaj grafikę od dołu i przesuwaj się w górę, aby śledzić przebieg procesu.

![Jak działa \expandafter](/files/4a37a1bc94ee9177303c19967f6c0c030b9d6205)

Poniższe uwagi wyjaśniają poszczególne etapy przetwarzania.

1. TeX zaczyna przetwarzać `\uppercase` i sprawdza obowiązkowy znak otwierającego nawiasu klamrowego (`{`) lecz wykrywa `\expandafter` polecenie.
2. Jeśli porównamy `\expandafter` $$\mathrm{T\_1T\_2}$$ w naszym wejściu dla `\expandafter{\jobname}` możemy zobaczyć $$\mathrm{T\_1} =$$`{`<sub>token</sub> i $$\mathrm{T\_2} =$$`\jobname`<sub>token</sub>. Zauważ, że tutaj użyjemy indeksu <sub>token</sub> aby wskazać, że TeX przetwarza całkowite wartości tokenów.
3. `\expandafter` odczytuje, a następnie tymczasowo zapisuje `{`<sub>token</sub> przechowując tę całkowitą wartość tokenu w zmiennej wewnętrznej. Później TeX wstawi ten token z powrotem do wejścia, po przetworzeniu `\jobname` polecenie.
4. `\expandafter` odczytuje następny token, `\jobname`<sub>token</sub>, i rozwija `\jobname` polecenie.
5. Rozwinięcie `\jobname` tworzy tymczasową listę tokenów, która zawiera sekwencję tokenów znakowych reprezentujących `.tex` nazwę pliku. Zauważ, że wszystkie tokeny znakowe generowane przez `\jobname` są obliczane z użyciem kodu kategorii 12.
6. Gdy `\jobname` zostanie rozwinięty, TeX ponownie wstawia token zapisany w kroku 3 (`{`<sub>token</sub>) i wkłada go z powrotem do wejścia. TeX robi to, tworząc kolejną listę tokenów zawierającą *pojedynczy* `{`<sub>token</sub>
7. TeX zakończył teraz przetwarzanie `\expandafter`, co skutkuje dwiema listami tokenów gotowymi do użycia jako źródła wejścia TeX-a. TeX wraca teraz do przetwarzania `\uppercase` ale skonfigurował swoje wejście tak, że dwie listy tokenów utworzone przez `\expandafter` stają się źródłem tokenów dla `\uppercase`— który teraz widzi `\uppercase{`<sub>token</sub>`<expansion of \jobname>`<sub>lista tokenów (znaki)</sub>`}`. `\uppercase` teraz widzi sekwencję tokenów znakowych i może uzyskać pożądany rezultat.
8. Po odczytaniu wszystkich tokenów znakowych wygenerowanych przez `\jobname`, TeX wraca do pobierania tokenów z poprzedniego źródła wejścia (naszego `.tex` pliku), skąd odczyta następny token: zamykający `}` wymagany do zakończenia listy tokenów przetwarzanej przez `\uppercase`.

### \expandafter i wewnętrzne listy tokenów

Tymczasowe listy tokenów są *kluczowym* elementem `\expandafter`zachowania przetwarzania: zrozumienie użycia i istnienia tych list tokenów może pomóc wyjaśnić, jak `\expandafter` osiąga swoje rezultaty, szczególnie gdy próbujemy pisać lub rozumieć makra, które korzystają z wielu kolejnych `\expandafter` poleceń, aby osiągnąć bardziej złożone formy przetwarzania tokenów: `\expandafter\expandafter\expandafter...`

Innym kluczowym elementem `\expandafter`zachowania, zwłaszcza przy wielu kolejnych `\expandafter` poleceniach, jest użycie *rekurencji* (wewnątrz samego oprogramowania TeX-a) — tematu, który omówimy później w tym artykule.

Aby jeszcze bardziej pomóc w zrozumieniu tymczasowych list tokenów, przyjrzymy się jeszcze jednemu przykładzie `\expandafter`, tym razem z `\the` polecenie.

#### \expandafter i wewnętrzne listy tokenów: przykład 2

W tym przykładzie zobaczymy, jak `\expandafter` można użyć do wpływania na tokeny przechowywane w rejestrze tokenów za pomocą `\toks` polecenia. Oto prymitywy TeX-a, z których będziemy korzystać:

* `**\count** *rejestr*=*liczba*`: prymityw TeX-a używany do przechowywania wartości `*liczba*` w lokalizacji TeX-a `*rejestr*`;
* `**\toks** *rejestr*={*lista tokenów*}`: prymityw TeX-a używany do przechowywania `*lista tokenów*` w lokalizacji rejestru tokenów `*rejestr*`— zapisując sekwencję tokenów do późniejszego użycia;
* `**\the** *token*`: rozwijalne prymitywne polecenie TeX-a, które przetwarza `*token*`, choć dokładne wyniki zależą od natury `*token*` przetwarzanego tokenu. `\the` ma wiele zastosowań: jednym z nich jest składanie wartości przechowywanej w parametrze lub zmiennej TeX-a (np. rejestrze). Inne zastosowania `\the` obejmują wstawienie kopii tokenów przechowywanych w rejestrze tokenów. Tutaj użyjemy `\the` do złożenia wartości zapisanej w `\count` rejestrze.

Zaczniemy od następującego kodu TeX-a, aby zapisać wartość `12345` w `\count` rejestrze `99`:

```
\count99=12345
```

Jeśli chcemy złożyć wartość przechowywaną w `\count99` możemy użyć `\the\count99` (lub `\number\count99`).

Następnie użyjemy `\toks` polecenia, aby przechować pewne tokeny w rejestrze tokenów `99`:

```
\toks99={\the\count99 }
```

Lista tokenów przechowywana w rejestrze tokenów `99` zawierałaby następujące elementy:

|                          |                                                                                                      |
| ------------------------ | ---------------------------------------------------------------------------------------------------- |
| **Wartość tokenu TeX-a** | **Reprezentowany element**                                                                           |
| 5382                     | `\the`                                                                                               |
| 7885                     | `\count`                                                                                             |
| 3129                     | `9` (kod znaku 57 z kodem kategorii 12), co daje wartość tokenu $$256 \times 12 + 57 = 3129$$        |
| 3129                     | `9` (kod znaku 57 z kodem kategorii 12), co daje wartość tokenu $$256 \times 12 + 57 = 3129$$        |
| 2592                     | `<spacja>` (kod znaku 32 z kodem kategorii 10), co daje wartość tokenu $$256 \times 10 + 32 = 2592$$ |

Zauważ, że lista tokenów utworzona przez `\toks99` nie *nie* zawiera rzeczywistej wartości danych przechowywanej w `\count99` ponieważ `\toks` polecenie nie wykonuje rozwinięcia: po prostu tworzy tokeny i je przechowuje. W naszym przykładzie, `\the` nie jest rozwijane, więc nie przetwarza `\count99`; tutaj `\the` jest jedynie zamieniane w token (wartość 5382) i przechowywane na liście tokenów.

Jeśli chcemy, aby `\toks99` lista tokenów zawierała tokeny reprezentujące dane przechowywane w `\count99` potrzebujemy jakiegoś sposobu, aby utworzyć te tokeny (udostępnić je), tak by `\toks` polecenie mogło uzyskać do nich dostęp. I oczywiście `\expandafter` może zrobić to za nas. Jeśli zapiszemy:

```
        \toks99=\expandafter{\the\count99 }
```

działanie/przetwarzanie `\toks` polecenia zostanie „wstrzymane”, podczas gdy `\expandafter` powoduje (wymusza) rozwinięcie `\the` które z kolei działa na `\count` aby wygenerować tymczasową listę tokenów zawierającą tokeny znakowe reprezentujące dane przechowywane w `\count99`. Małą, ale ważną kwestią jest `<spacja>` znak po cyfrach `99`: ten `<spacja>` znak służy do zakończenia procesu skanowania TeX-a, gdy szuka on wartości numerycznej.

Tutaj działanie `\expandafter` jest bardzo podobne do `\jobname` przykładu.

1. Odczytaj i zapisz otwierający `{`<sub>token</sub>.
2. Odczytaj następny token, `\the`<sub>token</sub>, który reprezentuje polecenie rozwijalne, więc TeX je rozwija. `\expandafter` wymusza rozwinięcie `\the` które następnie działa na `\count99` aby przekształcić dane przechowywane w `\count` rejestrze `99` (liczbę 12345) w tymczasową listę tokenów. Lista ta będzie zawierać tokeny znakowe reprezentujące cyfry `1`, `2`, `3`, `4` i `5`— tokeny znakowe z kodem kategorii 12.
3. Po rozwinięciu i przetworzeniu `\the`, TeX wkłada `{`<sub>token</sub> „z powrotem do wejścia” i używa listy tokenów powstałej z `\the\count99` tak, aby TeX odczytał `\toks99={`<sub>token</sub>`<expansion of \the\count99>`<sub>lista tokenów (znaki)</sub>`}` a to daje pożądany rezultat.

Ta sekwencja zdarzeń jest podsumowana na poniższym diagramie — czytaj grafikę od dołu i przesuwaj się w górę, aby śledzić przebieg procesu.

![Jak działa \expandafter](/files/5bf460dd3be6451d15dd6b4cb88aeec0e19370f3)

1. TeX zaczyna przetwarzać `\toks`; widzi opcjonalny `=` znak, a następnie sprawdza obowiązkowy znak otwierającego nawiasu klamrowego (`{`, lub dowolny znak z kodem kategorii 1) używany do wskazania początku listy tokenów. Jednak TeX wykrywa `\expandafter` polecenie i zamiast tego przystępuje do jego wykonania.
2. Jeśli porównamy `\expandafter` $$\mathrm{T\_1T\_2}$$ w naszym wejściu dla `\expandafter{\the\count99 }` możemy zobaczyć $$\mathrm{T\_1} =$$ `{`<sub>token</sub> i $$\mathrm{T\_2} =$$ `\the<sub>token</sub>`.
3. `\expandafter` odczytuje, a następnie tymczasowo zapisuje `{`<sub>token</sub> (TeX tymczasowo przechowuje tę całkowitą wartość tokenu w zmiennej wewnętrznej). Później TeX ponownie wstawi ten token do wejścia, po przetworzeniu `\the`
4. `\expandafter` odczytuje następny token, `\the`<sub>token</sub> i rozwija go.
5. Rozwinięcie `\the` tworzy tymczasową listę tokenów z przetwarzania `\count99`— ta lista tokenów zawiera sekwencję tokenów znakowych, które reprezentują wartość danych przechowywaną w `\count` rejestrze `99`.
6. Gdy `\the` zostanie rozwinięty, TeX ponownie wstawia token zapisany w kroku 3 (`{`<sub>token</sub>) i wkłada ten token z powrotem do wejścia. TeX robi to, tworząc kolejną listę tokenów zawierającą *pojedynczy* token `{`<sub>token</sub>.
7. TeX zakończył teraz przetwarzanie `\expandafter` i utworzył dwie listy tokenów gotowe do użycia jako kolejne źródła wejścia. TeX wraca do przetwarzania `\toks99=` ale teraz TeX skonfigurował swoje wejście tak, że dwie listy tokenów utworzone przez `\expandafter` stają się źródłem tokenów dla `\toks`— który teraz widzi `{`<sub>token</sub>`<expansion of \the\count99>`<sub>lista tokenów (znaki)</sub>`}`. `\toks` może teraz uzyskać dostęp do sekwencji 5 tokenów znakowych, które reprezentują wartość danych (`12345`) przechowywaną w `\count99`: nasz pożądany rezultat.
8. Po odczytaniu wszystkich tokenów znakowych wygenerowanych przez `\the\count99`, TeX wraca do pobierania tokenów z poprzedniego źródła wejścia (naszego `.tex` pliku), skąd odczyta następny token: zamykający `}` wymaganego do zakończenia listy tokenów, która ma zostać zapisana przez `\toks99={...}`.

## Jak naprawdę działa \expandafter

W tej sekcji zajrzymy „nisko poziomowo” do samego TeX-a: zbadamy kod źródłowy/funkcje w TeX-ie, które implementują zachowanie `\expandafter`. Szczegóły zapisano w pseudokodzie C, ale powinny być zrozumiałe dla każdego, kto zna inne języki programowania.

Poniższy opatrzony komentarzami diagram wyjaśnia, jak TeX implementuje `\expandafter` jako część większej funkcji o nazwie `expand()`— kluczowej funkcji, która steruje przetwarzaniem rozwinięć w TeX-ie. W części odpowiedzialnej za implementację `\expandafter` możemy zobaczyć [*rekurencyjnego* zachowania](https://en.wikipedia.org/wiki/Recursion) gdzie kolejne wywołanie `expand()` funkcji jest używane do przetworzenia drugiego odczytanego tokenu, $$\mathrm{T\_2}$$, w tych przypadkach, gdy $$\mathrm{T\_2}$$ jest rozwijalny.

Choć ten kod występuje w silniku TeX-a Knutha, podstawowe zasady przedstawione na tym diagramie mają zastosowanie do wszystkich silników TeX-a.

![Jak \expandafter działa wewnątrz TeX-a](/files/8ed35d0768c50dde48dd1d97d06b43b67d1b2e32)

Pierwszym zadaniem `expand()` jest ustalenie, czy polecenie do rozwinięcia jest makrem czy prymitywem, ponieważ makra mają wyspecjalizowany proces rozwijania, obsługiwany przez funkcję o nazwie `macrocall()`.

Jeśli polecenie do rozwinięcia jest prymitywem, funkcja `expand()` używa bieżącej wartości kodu polecenia (przechowywanej w zmiennej globalnej `curcmd`) aby określić, który konkretny prymityw należy przetworzyć. Możemy zobaczyć te szczegóły w pełniejszym zestawieniu `expand()`:

```
    void expand(void)
    {
    //curcmd to zmienna globalna
    if(curcmd != macro) // curcmd < 111
    {
      switch(curcmd)
      {
        przypadek \expandafter: // Przetwórz polecenie \expandafter T1T2
        {
            gettoken(); // Odczytaj token T1
            t = curtok; // Zapisz token T1 w lokalnej zmiennej t
            gettoken(); // Odczytaj token T2
            if(curcmd > 100) // Czy token T2 jest rozwijalny?
                expand();    // Tak! T2 jest rozwijalny:
                             // wykonaj rozwinięcie T2 przez
                             // wywołanie rekurencyjne funkcji expand()
            else
                backinput(); // T2 nie jest rozwijalny: włóż ten token
                             // z powrotem do wejścia, aby został odczytany ponownie (później)

            curtok = t ;  // Przywróć globalnej zmiennej curtok zapisaną wartość T1
            backinput() ; // Włóż token T1 z powrotem do wejścia
                          // przed tokenami wynikającymi z rozwinięcia T2
        }
        break;

        // Kod do przetwarzania innych rozwijalnych poleceń
        przypadek polecenia „konwertuj na tekst”: // Dowolne z \number, \string, \romannumeral,
                                        // \meaning, \fontname, \jobname
                                        // Mają tę samą wartość curcmd
        break;

        przypadek \noexpand: // Wstrzymaj rozwinięcie następnego tokenu
        ...
        break;

        przypadek \csname:  // Utwórz nazwę sekwencji kontrolnej.
        ...
        break;

        przypadek \the: // Wstaw kilka tokenów
        ....
        break;

        przypadek „\if... test command” : // Przetwórz jeden z warunków TeX-a:
                                      // \if, \ifcat, \ifnum, \ifdim, \ifodd, \ifvmode,
                                      // \ifhmode, \ifmmode, \ifinner, \ifvoid,
                                      // \ifhbox, \ifvbox, \ifx, \ifeof, \iftrue, \iffalse,
                                      // \ifcase, \ifdefined, \ifcsname, \iffontchar
        ...
        break;

        przypadek „\fi lub \else”: // Zakończ bieżący warunek
        ...
        break;

        // itd. dla innych rozwijalnych poleceń pierwotnych obsługiwanych przez
        // silnik TeX-a

        }

    }else // To nie jest rozwijalne polecenie pierwotne: to makro
        {
             macrocall()
        }
        //... usunięto więcej kodu
    }
```

### Miłość TeX-a do zmiennych globalnych

Być może odzwierciedlając swój wiek i epokę, w której został zaprojektowany, kod źródłowy TeX-a w dużym stopniu korzysta z tak zwanych [zmiennych globalnych](https://en.wikipedia.org/wiki/Global_variable)—w rzeczywistości są ich setki. Z samej swojej natury zmienne globalne mogą być zmieniane/modyfikowane z dowolnego miejsca w kodzie źródłowym TeX-a — a w przypadku TeX-a Knutha jest to pojedynczy monolityczny plik zawierający ponad 25 000 linii kodu i setki funkcji. Zrozumienie, jak działa TeX, nie zawsze jest łatwym zadaniem...

Aby przetworzyć `\expandafter`, TeX odczytuje tokeny ze swojego bieżącego wejścia, używając funkcji o nazwie `gettoken()` której działaniem jest utworzenie tokenu i ustawienie wartości kilku kluczowych zmiennych globalnych używanych w całym kodzie źródłowym TeX-a. Dwie takie zmienne, aktualizowane przez działanie `gettoken()`, są używane w implementacji `\expandafter`:

* `curtok`: (bieżący token) całkowita wartość właśnie odczytanego tokenu;
* `curcmd`: (bieżący kod polecenia) kod polecenia (lub znaku) reprezentowanego przez token `curtok`.

Podczas przetwarzania `\expandafter`$$\mathrm{T\_1T\_2}$$ TeX odczytuje token $$\mathrm{T\_1}$$ i tymczasowo zapisuje jego wartość (liczbę całkowitą) w lokalnej zmiennej o nazwie `t`. Następnie TeX odczytuje $$\mathrm{T\_2}$$ i sprawdza, czy ten token reprezentuje polecenie rozwijalne — sprawdzając, czy jego kod polecenia (`curcmd`) jest > 100. Jeśli tak, TeX musi rozwinąć polecenie reprezentowane przez $$\mathrm{T\_2}$$ i wykonuje kolejne wywołanie funkcji `expand()`: to jest przykład *rekurencji* ponieważ `expand()` funkcji wywołującej samą siebie. Świadomość rekurencyjnej natury rozwijania, zwłaszcza podczas używania `\expandafter`, może pomóc zrozumieć, jak wiele kolejnych `\expandafter` poleceń — tj. `\expandafter\expandafter\expandafter...` osiąga swoje skutki.

Jeśli token $$\mathrm{T\_2}$$ jest rozwijalny, rozwinięcie następuje i gdy rekurencyjne wywołanie `expand()` zwraca, kod w implementacji `\expandafter` ponownie wstawia token $$\mathrm{T\_1}$$ z powrotem do wejścia. Zmienna globalna `curtok` zostaje ponownie przypisana do wartości zapisanego tokenu — przechowywanej w lokalnej zmiennej `t`, która jest wartością tokenu $$\mathrm{T\_1}$$— i następuje wywołanie funkcji `backinput().`

#### Funkcja backinput()

Jak sugeruje nazwa, funkcja ta wkłada token „z powrotem do wejścia”. Aby to zrobić, TeX używa bieżącej wartości zmiennej globalnej `curtok` do utworzenia listy tokenów zawierającej pojedynczy token (którego wartość całkowitą podaje `curtok`). TeX także tak organizuje obsługę wejścia, aby ta lista z jednym tokenem została we właściwym czasie ponownie odczytana przez TeX-a jako część dalszego przetwarzania wejścia. Zwróć uwagę, że token $$\mathrm{T\_1}$$ jest ponownie wstawiany *po zakończeniu rozwinięcia*, co zapewnia, że TeX odczyta ten ponownie wstawiony token *zanim* gdy odczytuje tokeny wynikające z rozwinięcia $$\mathrm{T\_2}$$.

### Przetwarzanie makr: funkcja macrocall()

Jak już wcześniej omówiono, wszystkie makra, wraz z niektórymi poleceniami pierwotnymi, są rozwijalne, a całe przetwarzanie rozwijania przechodzi przez `expand()` funkcję. Jednakże `expand()` uważnie korzysta z `curcmd` (bieżące polecenie) wartości, aby odróżnić rozwijalne polecenia pierwotne od makr, ponieważ proces rozwijania makr obsługuje specjalna funkcja o nazwie `macrocall()`. Makra potrzebują specjalistycznego procesu rozwijania, ponieważ argumenty makr i tokeny rozdzielające muszą być wyszukiwane w bardzo określony i rygorystyczny sposób; w konsekwencji proces ten jest przekazywany funkcji zaprojektowanej właśnie do tego: `macrocall()`.

#### Rozwijanie makra a wykonanie makra

Makro *rozwijanie* nie jest tym samym procesem co *wykonanie*: rozwinięcie makra jest procesem poprzedzającym wykonanie, który TeX wykonuje, aby przygotować makro *do wykonania*. „Wykonanie” makra następuje, gdy TeX aktywnie odczytuje i przetwarza tokeny zawarte w definicji tego makra (tekście zastępczym) oraz jego argumentach (parametrach).

#### Rozwijanie makra

Aby rozwinąć makro, TeX najpierw sprawdza, czy makro przyjmuje argumenty; jeśli tak, `macrocall()` bardzo dokładnie skanuje wejście w poszukiwaniu tokenów przeznaczonych na argumenty makra. Proces ten obejmuje sprawdzanie wejścia użytkownika pod kątem tokenów rozdzielających użytych w oryginalnej definicji makra — wzorzec tokenów użyty w wywołaniu makra musi dokładnie odpowiadać wzorcowi tokenów zawartemu w zapisanej definicji. Jednak tokeny używane jako rozdzielacze są po prostu odrzucane przez TeX-a: w praktyce są tylko formą „interpunkcji”, której TeX używa do określenia rzeczywistych tokenów przeznaczonych na argumenty makra — tj. tokenów, które użytkownik zamierza przekazać do przetwarzania przez makro. Więcej informacji o tokenach rozdzielających zobacz [Jak naprawdę działają makra TeX-a](/latex/pl/wiecej-tematow/22-how-tex-macros-actually-work-part-4.md).

Dla każdego parametru (`#1, #2...#9`) występującego w oryginalnej definicji makra TeX skanuje rzeczywiste wywołanie makra, aby ustalić, które tokeny dostarczone przez użytkownika są przeznaczone dla każdego parametru (tj. tworzą argumenty makra). Proces ten tworzy jedną lub więcej małych list tokenów: po jednej dla każdego argumentu makra.

Po wykryciu argumentów makra i przygotowaniu ich list tokenów TeX pobiera definicję makra (tekst zastępczy) przechowywaną w pamięci i tak organizuje przetwarzanie wejścia, że gdy tylko TeX będzie gotowy odczytać/przetworzyć więcej tokenów, odczyta je z tekstu zastępczego makra, tym samym wykonując makro. W odpowiednim momencie, podczas wykonywania makra, listy tokenów reprezentujące argumenty makra zostaną wstawione we właściwe miejsce w tekście zastępczym makra.

Jeszcze raz: rozwinięcie polecenia makra oznacza *usunięcie* tego polecenia makra (tokenu) z wejścia oraz *zastąpienie* go listą tokenów zapisaną jako tekst zastępczy makra.

Aby uzyskać szczegółowe spojrzenie na przetwarzanie makr w TeX-ie, zobacz sześcioczęściowy cykl artykułów [Jak naprawdę działają makra TeX-a?](/latex/pl/wiecej-tematow/01-a-six-part-series-how-do-tex-macros-actually-work.md)

[Część 1](/latex/pl/artykuly-szczegolowe/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md) [Część 2](/latex/pl/artykuly-szczegolowe/22-how-does-expandafter-work-the-meaning-of-expansion.md) [Część 3](/latex/pl/artykuly-szczegolowe/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md) [Część 4](/latex/pl/artykuly-szczegolowe/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md) [Część 5](/latex/pl/artykuly-szczegolowe/17-how-does-expandafter-work-a-detailed-macro-case-study.md) [Część 6](/latex/pl/artykuly-szczegolowe/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/pl/artykuly-szczegolowe/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.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.
