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

# Jak działa \expandafter: szczegółowe badanie kolejnych poleceń \expandafter

&#x20;[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)&#x20;

## Studium przypadku: Zrozumienie \expandafter\expandafter\expandafter...

Zaawansowane makra, takie jak te spotykane w pakietach LaTeX, często w dużym stopniu wykorzystują wiele kolejnych `\expandafter` poleceń, aby wykonywać zaawansowaną „żonglerkę” tokenami. Dla większości z nas takie makra mogą być trudne do zrozumienia lub zniechęcające do napisania. W tej sekcji omówimy mechanizmy leżące u podstaw przetwarzania przez TeX kolejnych `\expandafter` poleceń:

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

Aby pomóc w wyjaśnieniu, dodamy indeksy dolne do każdego `\expandafter`— aby wskazać, do którego się odnosimy:

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

Ponadto rozszerzymy notację dla tokenów przetwarzanych przez każdy `\expandafter` na użycie $$\mathrm{T^i\_1}$$ i $$\mathrm{T^i\_2}$$ reprezentujących tokeny $$\mathrm{T\_1}$$ i $$\mathrm{T\_2}$$ wczytywane przez `\expandafter` z indeksem dolnym `i`: `\expandafter`<sub>i</sub> $$\mathrm{T^i\_1T^i\_2}$$. Przyjmiemy też, że dwa tokeny $$\mathrm{T\_X}$$ i $$\mathrm{T\_Y}$$ następują po `\expandafter<sub>3</sub>` tak, aby nasze wejście wyglądało tak: `\expandafter<sub>1</sub>\expandafter<sub>2</sub>\expandafter<sub>3</sub>` $$\mathrm{T\_{X}T\_{Y}}$$.

Gdy TeX zaczyna przetwarzać to wejście, dla `\expandafter<sub>1</sub>` zobaczy

* $$\mathrm{T^1\_1} =$$`\expandafter<sub>2</sub>` który zostaje zachowany na później *ponownego wstawienia* z powrotem do wejścia
* $$\mathrm{T^1\_2} =$$`\expandafter<sub>3</sub>`, który jest rozwijany

Jeśli odwołamy się do naszej wcześniejszej dyskusji o [kodzie wewnątrz TeX-a](/latex/pl/artykuly-szczegolowe/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md) który implementuje `\expandafter`, to właśnie przy rozwijaniu `\expandafter<sub>3</sub>` widzimy, że zachodzi rekurencja. Aby przetworzyć `\expandafter<sub>1</sub>` TeX wywołał już swoją wewnętrzną funkcję `expand()`, więc aby przetworzyć (rozwinąć) `\expandafter<sub>3</sub>` TeX wykonuje *drugie* wywołanie `expand()`— z wnętrza `expand()` samej funkcji.

Dla `\expandafter<sub>3</sub>` mamy

* $$\mathrm{T^3\_1 = T\_X}$$, który zostaje zachowany na później *ponownego wstawienia* z powrotem do wejścia
* $$\mathrm{T^3\_2 = T\_Y}$$, co do którego założymy, że można go rozwinąć

Załóżmy dalej, że rozwinięcie $$\mathrm{T\_Y}$$ daje następującą sekwencję tokenów: $$\mathrm{{T^1\_Y}{T^2\_Y}{T^3\_Y}}\cdots\mathrm{T^N\_Y}$$. Dotarliśmy teraz do końca procesu rozwijania rozpoczętego przez sekwencję poleceń `\expandafter<sub>1</sub>\expandafter<sub>2</sub>\expandafter<sub>3</sub>` $$\mathrm{T\_{X}T\_{Y}}$$ a TeX przystępuje do „odwijania” procesu rekurencji, który rozpoczął się od `\expandafter<sub>1</sub>`.

Po przetworzeniu `\expandafter<sub>3</sub>` TeX ma w swojej pamięci listę tokenów zawierającą tokeny z rozwinięcia $$\mathrm{T\_Y\text{: }{T^1\_Y}{T^2\_Y}{T^3\_Y}}\cdots\mathrm{T^N\_Y}$$. TeX teraz zaczyna ponownie wstawiać tokeny, które zachował podczas przetwarzania `\expandafter` poleceń:

1. TeX zaczyna od ponownego wstawienia tokenu $$\mathrm{T\_X}$$ zachowanego przez `\expandafter<sub>3</sub>`. $$\mathrm{T\_X}$$ jest ponownie wstawiany *przed* rozwinięciem $$\mathrm{T\_Y}$$, co daje sekwencję tokenów: $$\mathrm{{{T\_X}T^1\_Y}{T^2\_Y}{T^3\_Y}}\cdots\mathrm{T^N\_Y}$$.
2. Musimy jednak jeszcze dokończyć proces rozpoczęty przez `\expandafter<sub>1</sub>` który zachował token reprezentujący `\expandafter<sub>2</sub>`
3. Ostateczna sekwencja tokenów złożona przez TeX-a, gotowa do odczytu w następnym etapie przetwarzania TeX-a, to `\expandafter<sub>2 (token)</sub>` $$\mathrm{T\_{X}T^1\_{Y}T^2\_{Y}T^3\_{Y}\cdots T^N\_Y}$$
4. TeX zakończył teraz „pierwszą rundę” przetwarzania i przechodzi do odczytywania sekwencji list tokenów, które wygenerował — ta sekwencja zaczyna się od `\expandafter<sub>2 (token)</sub>` którą TeX zaczyna przetwarzać. Dla `\expandafter<sub>2</sub>` mamy
   * $$\mathrm{T^2\_1} =\ \mathrm{T\_X}$$ który zostaje zachowany na później *ponownego wstawienia* z powrotem do wejścia
   * $$\mathrm{T^2\_2} = \mathrm{T^1\_Y}$$ który jest pierwszym tokenem powstałym z rozwinięcia $$\mathrm{T\_Y}$$; jeśli można go rozwinąć, zostaje rozwinięty
5. Jeśli założymy, że token $$\mathrm{T^1\_Y}$$, pierwszy token z rozwinięcia $$\mathrm{T\_Y}$$, rozwija się do $$\mathrm{{T^A\_{Y1}}{T^B\_{Y1}}{T^C\_{Y1}}}$$ to po tym, jak TeX ponownie wstawił $$\mathrm{T\_X}$$, wynikowa sekwencja tokenów do ponownego przetworzenia przez TeX byłaby: $$\mathrm{{T\_X}{T^A\_{Y1}}{T^B\_{Y1}}{T^C\_{Y1}}{T^2\_Y}{T^3\_Y}\cdots{T^N\_Y}}$$

   co możemy zapisać ponownie jako

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

Poniższy diagram ilustruje listy tokenów utworzone przez kod TeX-a

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

![Obraz pokazujący przetwarzanie wielu poleceń \expandafter przez TeX](/files/39b9eb72f26750bc71d2f3c655b1d0ca788634e9)

### Teoria w praktyce

Jako przykład zdefiniujemy następujące makra, które będą służyć jako $$\mathrm{T\_X}$$ i $$\mathrm{T\_Y}$$

* $$\mathrm{T\_X}=$$`\foo` gdzie definiujemy `\foo` jako `\def\foo#1{\textbf{#1}}`
* $$\mathrm{T\_Y}=$$`\bar` gdzie najpierw definiujemy `\def\abc{Hello}`, `\def\xyz{, World!}` a następnie `\def\bar{\abc\xyz}`

Użyjemy następującego fragmentu kodu, aby zademonstrować naszą wcześniejszą analizę:

\expandafter\expandafter\expandafter\foo\bar

Z naszej dyskusji wynika, że wynik `\expandafter<sub>1</sub>\expandafter<sub>2</sub>\expandafter<sub>3</sub>` $$\mathrm{T\_X}\mathrm{T\_Y}$$ generuje sekwencję tokenów w postaci:

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

gdzie dokładna sekwencja zależy od natury tokenu $$\mathrm{T\_Y}$$. Jeśli wstawimy nasze przykładowe polecenia używając $$\mathrm{T\_X}=$$`\foo` i $$\mathrm{T\_Y}=$$`\bar`, który jest zdefiniowany jako `\def\bar{\abc\xyz}`, widzimy:

* pierwszy token w $$\mathrm{T\_Y}$$ to `\abc` i jego rozwinięcie to sekwencja tokenów znakowych: `Hello`
* pozostałe tokeny w $$\mathrm{T\_Y}$$ to pojedynczy token reprezentujący `\xyz`.

Jeśli wstawimy te informacje do naszej „analizy”, otrzymamy

$$\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\*}$$

Zwróć uwagę, że indeksy dolne <sub>token</sub> i <sub>lista tokenów (znaki)</sub> są używane, aby podkreślić (przypomnieć nam), że TeX odczytuje *wartości całkowite tokenów*, a nie *znaki tekstowe*, stąd nie ma potrzeby pokazywać po `\foo`: takie separatory zostały już dawno przetworzone lub odrzucone; tutaj znajdujemy się zdecydowanie w wewnętrznym świecie TeX-a list tokenów i całkowitych wartości tokenów.

Gdy TeX przetwarza sekwencję listy tokenów wygenerowaną przez nasze `\expandafter` polecenia, sformatuje `**H**ello, World!`— tylko `H` jest sformatowane pogrubieniem. Ten sam wynik moglibyśmy uzyskać, zapisując równoważny kod TeX `\foo Hello\xyz`. Zauważ, że definicja `\foo` używała jednego parametru; w konsekwencji `\foo` pochłania pojedynczy `H` token znakowy dla swojego argumentu, pozostawiając pozostałe tokeny znakowe (`ello`) nietknięte.

**Uwagi:**

* zapis `\foo\bar` daje zupełnie inny wynik: token dla `\bar` zostałby użyty jako argument dla `\foo` co skutkuje sformatowaniem **`Hello, World`**— wszystko jest sformatowane pogrubieniem.
* zapis `\expandafter\foo\bar` powoduje `\bar` zostanie rozwinięty, co daje dwa tokeny: $$\text{abc}*\text{token}\text{xyz}*\text{token}$$. Następnie, po tym jak $$\text{foo}*\text{token}$$ jest ponownie wstawiany przez `\expandafter` TeX przetwarza sekwencję tokenów $$\text{foo}*\text{token}\text{abc}*\text{token}\text{xyz}*\text{token}$$ która formatuje `**Hello**, World`— tylko **`Hello`** jest sformatowane pogrubieniem. Tutaj pojedynczy token $$\text{abc}*\text{token}$$ jest przetwarzany jako argument dla tokenu makra $$\text{foo}*\text{token}$$, pozostawiając token $$\text{xyz}\_\text{token}$$ nietknięty, a jego zawartość sformatowaną w bieżącej czcionce.

## Uwaga dotycząca \expandafter i makr z argumentami

Podczas używania `\expandafter` aby wymusić rozwijanie makr, warto wiedzieć, jak działa rozwijanie makr — zwłaszcza w przypadku makr, które przyjmują argumenty. Zanim TeX może uruchomić makro — tj. odczytać i przetworzyć tokeny zawarte w definicji makra — TeX musi „przygotować” makro do uruchomienia, wykonując początkowy proces rozwijania makra. Jeśli definicja makra zawiera użycie parametrów (`#1`, `#2`, ... `#9`), część procesu rozwijania makra wymaga od TeX-a przeszukania wejścia w poszukiwaniu tokenów składających się na argument(y) podane przez użytkownika: te tokeny argumentu są pochłaniane (usuwane) z wejścia. Podczas rozwijania makr TeX odczytuje i pochłania tokeny z wejścia, aby utworzyć mini listy tokenów, po jednej liście na każdy argument; te listy tokenów zostaną następnie wstawione we właściwe miejsce w treści makra — gdy TeX je wykona. Ostatni krok rozwijania makra polega na tym, że TeX lokalizuje definicję makra przechowywaną w pamięci i sprawia, że to miejsce staje się źródłem, z którego TeX odczyta następny zestaw tokenów wejściowych. Wykonanie makra rozpoczyna się, gdy TeX zaczyna odczytywać i przetwarzać te tokeny, wczytując listy tokenów utworzone wcześniej do przechowywania argumentów.

### Tokeny ograniczające są również pochłaniane

Jeśli oryginalna definicja makra używała również tokenów pełniących rolę ograniczników, TeX musiałby także porównać oryginalną definicję makra z użyciem (wywołaniem) tego makra przez użytkownika, szukając i dopasowując tokeny ograniczników. Po dopasowaniu/zlokalizowaniu tokeny ograniczników są następnie ignorowane, ponieważ ich jedynym celem jest pełnienie roli „interpunkcji”, pomagając TeX-owi wyszukać i zidentyfikować rzeczywiste tokeny przeznaczone do utworzenia każdego argumentu.

&#x20;[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/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.
