> 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/cs/dalsi-temata/24-how-tex-macros-actually-work-part-6.md).

# Jak makra TeXu ve skutečnosti fungují: Část 6

[Část 1](/latex/cs/dalsi-temata/19-how-tex-macros-actually-work-part-1.md) [Část 2](/latex/cs/dalsi-temata/20-how-tex-macros-actually-work-part-2.md) [Část 3](/latex/cs/dalsi-temata/21-how-tex-macros-actually-work-part-3.md) [Část 4](/latex/cs/dalsi-temata/22-how-tex-macros-actually-work-part-4.md) [Část 5](/latex/cs/dalsi-temata/23-how-tex-macros-actually-work-part-5.md) [Část 6](/latex/cs/dalsi-temata/24-how-tex-macros-actually-work-part-6.md)

## Úvod a přehled: Dosavadní příběh

V předchozích 5 částech této série jsme viděli:

* jak TeX čte znaky v souboru se vstupem a používá kategoriální kódy k rozpoznání různých „tříd“ znaků a následně je převádí na znakové tokeny a příkazové tokeny;
* že makro je ve skutečnosti složeno ze čtyř částí:

```
<TeX makro primitivum><název makra><text parametrů>{<náhradní text>}
```

kde:

* `<TeX makro primitivum>` = jedna z možností `\def`, `\edef`, `\gdef` nebo `\xdef`;
* `<název makra>`= název vašeho makra, například `\foo`;
* `<parametrický text>` může být „prázdný“ (nepřítomný), nebo to může být řetězec oddělovacích tokenů a tokenů parametrů makra;
* `<náhradní text>` je skutečné tělo vašeho makra: část, která je při volání makra „provedena“ (rozvinuta).
* jak `<parametrický text>` část může obsahovat širokou škálu tokenů a že TeX používá tuto část jako „šablonu tokenů“, aby přiřadil volání makra k jeho původní definici a zjistil argumenty použité s makrem — a jak TeX očekává, že vaše použití makra bude odpovídat jeho původní definici;
* že uvnitř TeXu je definice makra uložena jako souvislá sekvence tokenů představujících `<parametrický text>` a `<náhradní text>` části.

Když použijete příkaz makra, TeX nejprve zkontroluje, zda bere nějaké parametry. Pokud ano, TeX pak musí identifikovat skutečné *argumenty* použité ve vašem volání makra. TeX musí vaše volání makra porovnat s uloženou definicí „šablony tokenů“. Konkrétně TeX používá svou interní (uloženou) definici vašeho makra `<parametrický text>` část jako šablonu, přes niž může vybrat *tokeny* které jsou skutečnými argumenty, a které *tokeny* jsou tam jen jako oddělovače.

## Význam rozvinutí makra

Nyní jsme konečně připraveni přejít k nejdůležitějšímu tématu: jak TeX zpracovává argumenty makra a makro skutečně vykonává: procesu, který TeX označuje jako *rozvinutí makra*.

### Ale nejprve krátký příklad: něco podivného?

Abychom „uvedli scénu“ pro vysvětlení mechanismu, kterým TeX zpracovává makra a jejich argumenty, použijeme krátký příklad, abychom naznačili problémy, které musíme zvážit.

#### Argumenty se nejprve převádějí na tokeny

Následující příklad je založen na jednom, o kterém se diskutuje na stranách 114–5 knihy [The Advanced TeXbook](https://www.amazon.co.uk/Advanced-Texbook-David-Salomon/dp/0387945563) napsané Davidem Salomonem. Je vybrán proto, že velmi pěkně shrnuje ústřední myšlenky v rámci velmi krátkého makra TeXu.

Při běžném provozu TeXu/LaTeXu, `$` znak má kategoriální kód 3 („math shift“), který přepíná TeX do/ze inline matematického režimu (`$...$`) nebo režimu zobrazené matematiky (`$$...$$`) — samozřejmě, LaTeX používá `\(..\)` a `\[..\]` ke stejnému účelu.

Předpokládejme, že chceme makro, které změní kategoriální kód `$` znaku na třeba 11, abychom jej mohli vysázet jako jakýkoli běžný znak. Můžeme použít primitivní příkaz TeXu `\catcode` a naším prvním pokusem o takové makro, `\docat`, by mohlo být

```
\def\docat #1{\catcode`\$=11 #1}
```

Když se ho však pokusíme použít, například takto

```
\begin{document}
\def\docat #1{\catcode`\$=11 #1}
Zaplatil jsem \docat{$90} za tu knihu.
\end{document}
```

očekávali bychom, že TeX vysází `Zaplatil jsem $90 za tu knihu.` ale skončí to chybovým hlášením:

```
! Vložen chybějící $.
<vložený text>
                $
<má být přečteno znovu>
                   \par
l.7
```

Z chyby se zdá, že `$` použitý v argumentu našeho makra stále spouští TeX k sazbě matematiky; je zjevné, že TeX *neprovedl* změnu kategoriálního kódu `$` použitého v argumentu našeho makra (`$90`). Otázka zní *proč* proč TeX nezměnil kategoriální kód `$` na 11 a nevysázel jej jako běžný znak? Stručná odpověď je, že TeX nejprve převádí argumenty makra na tokeny **dříve, než** a poté je předává do tokenového seznamu `<náhradní text>`— ale podkladové mechanismy si prohlédneme mnohem podrobněji.

Co si musíme pamatovat, je to, že naše představa, že TeX používá text/znaky, se vztahuje pouze na obsah souboru, který TeX čte: jakmile TeX načte jakékoli znaky, ocitáme se ve světě *tokeny*. TeXovská volání maker pracují s *tokeny*, nikoli s faktickou *psanou/textovou reprezentací* příkazů TeXu/LaTeXu — to bude jasnější, až projdeme příkladem.

Zpočátku bychom mohli myslet, že naše použití `\docat` makra v `Zaplatil jsem \docat{$90} za tu knihu.` je totéž jako přímé napsání odpovídajícího kódu TeXu (nebo LaTeXu) — například následujícího, který *ne* funguje:

```
\begin{document}
Zaplatil jsem \catcode`\$=11 $90 za tu knihu.
\end{document}
```

![Nějaký kód TeXu běžící na Overleafu](/files/bf30ba5e78e19ebda413dabe9671721bb79c29f6)

Jak jsme však viděli výše, způsob, jakým TeX zpracovává argumenty maker, dává výsledek (`! Vložen chybějící $.`) zcela odlišný od zapsání kódu TeXu: nyní prozkoumáme *proč* co se děje.

### Makra a argumenty jako seznamy tokenů

Abychom plně porozuměli chování `\docat` makra a jeho argumentu (`$90`), a proč selže, musíme si znovu představit definici `\docat` makra a jakékoli použité argumenty (když je \docat voláno) jako *seznamy tokenů*, nikoli jako posloupnost znaků.

Jak TeX prohledává váš vstupní text, rozpozná `\docat` jako příkaz makra; poté zkontroluje, zda bere nějaké parametry — jak TeX to dělá, je vysvětleno v následující části pro čtenáře, kteří se zajímají o jemnější detaily.

#### Pro ty, kteří mají rádi detaily...

Poté, co je makro zavoláno, TeX zkontroluje, zda je úplně první token (v uloženém seznamu tokenů definice makra) tokenem **end match** : pokud ano, TeX si může být jist, že makro nemá žádné parametry.

**Příklad**

Následující diagramy seznamů uzlů porovnávají seznamy tokenů pro dvě makra:

* `\def\foo A#1B{#1}`: toto má `<parametrický text>` pro `A#1B`, proto je **end match** tokenem **ne** prvním tokenem, takže TeX bude pokračovat a hledat parametry;
* `\def\foo{X}`: toto nemá `<parametrický text>` sekci, proto je **end match** token prvním v seznamu tokenů a TeX ví, že nemá hledat žádné parametry.

![Jak TeX kontroluje, zda makro bere parametry](/files/a4f5dcbb9940d1556e4470c2d8413d3c2e7859e2)

## Směrem ke „Grand Finále“: rozvinutí

Připomeňme si otázku: proč následující makro nefungovalo; tj. proč TeX nemění kategorický kód žádných `$` znaků dolaru použitých v argumentu `\docat` makra, jako je `\docat{$90}`?

```
\begin{document}
\def\docat #1{\catcode`\$=11 #1}
Zaplatil jsem \docat{$90} za tu knihu.
\end{document}
```

Jak je vysvětleno výše, když TeX prochází váš vstup a rozpozná příkaz makra — ve chvíli, kdy jej bude provádět — nejprve zkontroluje, zda toto makro bere nějaké parametry. Pokud ano, TeX pak bude muset dále prohledat vstupní soubor, aby identifikoval skutečné *argumenty* které uživatel poskytl pro toto konkrétní volání makra: TeX to musí udělat **dříve, než** může zavolat skutečný kód makra. Je zřejmé, že TeX potřebuje určit data, která chce uživatel makru předat.

Aby identifikoval argumenty přítomné ve vstupu (volání makra od uživatele), bude se TeX řídit interně uloženou definicí tohoto makra: konkrétně `<parametrický text>` částí uložené definice makra (seznamu tokenů) — která poskytuje jakousi „šablonu tokenů“. Pomocí této „šablony tokenů“ musí TeX určit, které *tokeny* ve volání makra od uživatele jsou jen *oddělovače*  (v podstatě „interpunkce“) a které *tokeny* tvoří součást *argumentu*. Je to v okamžiku, kdy TeX narazí na token **parametru oddělovače** v uložené definici makra `<parametrický text>` části („šablona tokenů“), kdy ví, že má začít vytvářet *seznam tokenů* pro daný argument.

Jakmile TeX rozpozná potřebu identifikovat uživatelův argument, prohledá vstup, aby vygeneroval tokeny, a velmi pečlivě je kontroluje token po tokenu proti uložené definici makra. TeX pokračuje ve shromažďování tokenů pro argument, dokud nezjistí token, který je ve skutečnosti oddělovač, nebo dokud nezjistí token **end match** : v obou případech pak TeX ví, že je čas přestat hledat tokeny, které tvoří součást daného argumentu.

### Proč makro \docat selhalo

Jak bylo uvedeno, *dříve, než* Aby TeX mohl makro skutečně zavolat, musí identifikovat a připravit všechny argumenty, které se s tímto makrem mají použít. Aby však identifikoval argument(y), připravené k předání do makra, musí TeX vygenerovat každý argument jako *seznam tokenů*: a to je důvod `\docat`neúspěchu.

V našem příkladu jsme poskytli `\docat` s argumentem `$90` ale tento argument je nejprve *převáděn na seznam tokenů* při prohledávání volání makra — argument je převáděn na tokeny *dříve, než* než je makro skutečně zavoláno. Zde, pro argument `$90`, TeX vygeneruje tři znakové tokeny: jeden token pro každý z `$`, `9` a `0`.

Následující obrázek ukazuje seznam tokenů vygenerovaný pro argument `$90`, před předáním do těla `\docat` makra:

![Seznam tokenů TeXu vygenerovaný pro argument makra](/files/7974e6ea78d59da07669ddbb2d385c11a936e960)

Na výše uvedeném obrázku jasně vidíme, že seznam tokenů argumentu obsahuje `$` jako znakový token založený na kategoriálním kódu 3.

Jak jsme viděli v částech 1 až 3, znakové tokeny se vytvářejí pomocí hodnot kategoriálních kódů *platných v okamžiku, kdy je znak načten*— tj. v okamžiku, kdy je vytvořen seznam tokenů argumentu (převeden na tokeny). V době, kdy se argumenty tokenizují, `\docat` makro ještě nebylo provedeno, takže změna kategoriálního kódu, kterou jsme vložili do volání makra (``\catcode`\$=11``) *ne* ) neovlivňuje kategoriální kódy používané k vytváření tokenů argumentu.

Jakmile TeX vytvoří seznam tokenů představující argument `$90`, tyto tři znakové tokeny jsou předány do skutečného makra `<náhradní text>`. To však vede k tomu, že `$` je předán jako *znakový token* vytvořený pomocí kategoriálního kódu 3: „matematika zapnuta“ a viděli jsme, že jakmile je znakový token vytvořen, přiřazený kategoriální kód je trvalý.  `$` je *ne* předán do makra *ne jako znak*, ale jako *znakový token* založený na `$` tom, že má kategoriální kód 3.

### Spuštění \docat: rozvinutí makra

TeX označuje proces „provádění“ makra jako *rozvinutí makra*rozvinutí; termín, který je podle tohoto autora poněkud matoucí, ale je to přijatá terminologie, takže jej budeme nadále používat.

#### Skutečný význam rozvinutí makra

Poté, co TeX rozpozná `\docat` příkaz ve vstupu uživatele, prohledá argumenty a vygeneruje pro jeho argument(`$90`). Aby makro provedl (rozvinul), TeX odvrátí svůj pohled od souboru se vstupem uživatele a začne číst tokeny obsažené `\docat`’s `<náhradní text>` v tokenovém seznamu uloženém v paměti TeXu.

Jak TeX zpracovává `\docat`definici, uvidí a provede sekvenci tokenů původně použitých k definování makra (`**catcode**`, ``**`**``, `**\$**`, `**=**`, `**1**`, `**1**`, `**#1**`).

Následující obrázek ukazuje proces rozvíjení `\docat` makra: TeX přestane získávat tokeny ze vstupního souboru a začne číst tokeny z `<náhradní text>` části `\docat` definice makra uložené v paměti. TeX pokračuje v provádění těchto předpřipravených tokenů, dokud neuvidí token **výstupního parametru** který pokyne TeXu, aby v tomto místě přečetl („vložil“) a „provedl“ tokeny argumentu. V našem příkladu jde o tři znakové tokeny představující `$90` a to vede k chybě, protože předpřipravený znakový token pro `$` má kategoriální kód 3. Protože pracujeme se znakových tokeny, nikoli se znaky,  `$` není ovlivněn předchozí změnou kategoriálního kódu způsobenou tokeny v ``\catcode`\$=11``.

![Zobrazení procesu rozvíjení makra \docat](/files/88ea5c3de7db2360ed3fd82cae057dca063191c8)

Poté, co TeX zpracuje tokeny představující ``\catcode`\$=11``, změna kategoriálního kódu pro `$` nyní začne platit. TeX pak narazí na „zvláštní token“ zvaný **výstupního parametru** který říká TeXu, aby **vloží** tokenový seznam pro argument. Tento tokenový seznam je však tvořen třemi znakovými *tokeny*, z nichž první je token pro `$` s kategoriálním kódem 3 („matematika zapnuta“) přiřazeným k němu: předchozí změna kategoriálního kódu uvnitř makra nemůže tento znakový token ovlivnit, takže TeX považuje tento token za signál k zahájení zpracování matematiky, což způsobí selhání makra.

### Lze makro \docat opravit?

Z výše uvedených diskusí je zřejmé, že jakékoli znaky objevující se v argumentech makra jsou tokenizovány pomocí kategoriálních kódů platných v okamžiku, kdy tokenizace probíhá — což je v našem příkladu *vždy* předtím, než je `<náhradní text>` toho `\docat` makro skutečně provedeno. Jak tedy můžeme zajistit, aby byly kategoriální kódy argumentů makra změněny?

Jedním ze způsobů je upravit `\docat` tak, aby bylo makrem bez parametrů, které pouze provede změnu kategoriálního kódu — nemá žádné argumenty, které by bylo třeba tokenizovat. Poté použijeme druhé makro, `\getarg`, které bere jediný parametr, a zařídíme, aby bylo jeho argument tokenizován, když je příslušný kategoriální kód pro `$` v provozu.

```
\begin{document}
\def\docat{\catcode`\$=11 \getarg} % Žádné parametry, volá druhé makro \getarg
\def\getarg#1{#1} %1 parametr, jehož argument bude tokenizován
Teď to můžete spustit takto a bude to fungovat:

Zaplatil jsem \docat{$90} za tu knihu.
\end{document}
```

Když použijeme naši novou verzi `\docat` (takto `\docat{$90}`) *to* vypadá `$90` jako by se `\docat` stále používalo jako argument pro `\docat` makro. Jak však bylo uvedeno výše, když TeX rozpozná `\docat` ve vstupu, zkontroluje, zda má nějaké argumenty: nyní nemá, takže TeX pokračuje a provádí (rozvíjí) jej. Rozvinutí `**catcode**`, ``**`**``, `**\$**`, `**=**`, `**1**`, `**1**`, `**mezera**`, `**getarg**` a to se děje *dříve, než* TeX začne číst (tokenizovat) další znaky obsažené ve vstupním souboru — tj. skupinu `{$90}`. Pamatujte, že když TeX rozvíjí makro, získává svůj další vstup čtením tokenů obsažených v tokenovém seznamu definice tohoto makra; tj. z jeho `<náhradní text>` části uložené v paměti.

TeX bude zpracovávat a provádět rozvinutí `\docat` a rozpozná token *token* **`getarg`**, přičemž jej rozpozná jako token, který představuje příkaz s parametry. V tomto okamžiku TeX prohledá vstupní soubor pro **`getarg`**&#x61;rgument makra getarg: znaky: `{$90}`. Jak je obvyklé, tyto jsou tokenizovány, ale protože TeX přečetl a zpracoval rozvinutí `\docat`, znaky `$90` jsou tokenizovány ve chvíli, kdy byl kategoriální kód `$` změněn na 11. Definice (`<náhradní text>`) `\getarg` je prostě `#1` což znamená vysázet poskytnutý argument, a to se stane, což vede k `$` s kategoriálním kódem 11, který je vygenerován a bezpečně vysázen.

## Závěrečné poznámky: příběh v uzlech

Sekvence událostí vyplývající z přepsání `\docat` tak, aby používalo makro `\getarg` je obsažena v následujícím anotovaném diagramu seznamu uzlů, který ukazuje proces rozvinutí makra `\docat`. Čtenáři, kteří si chtějí tento diagram pečlivě prostudovat, si mohou stáhnout obrázek jako [PDF](https://assets.ctfassets.net/nrgyaltdicpt/7MOBdavza4WxAEQGISEEht/cabe5097d9063a6415bc553cd38237e6/newdocatexpansion.pdf) nebo [SVG](https://images.ctfassets.net/nrgyaltdicpt/2FIqqVRXjakdAzTpZsV0m9/10ccc1353741d42d3df18f1692d8aa84/newdocatexpansion--plain.svg) soubor pro použití offline.

![Zobrazení procesu rozvíjení upraveného makra \docat a makra \getarg](/files/579d20d0866ac58f47fec387dd513d4a13f0023f)

[Část 1](/latex/cs/dalsi-temata/19-how-tex-macros-actually-work-part-1.md) [Část 2](/latex/cs/dalsi-temata/20-how-tex-macros-actually-work-part-2.md) [Část 3](/latex/cs/dalsi-temata/21-how-tex-macros-actually-work-part-3.md) [Část 4](/latex/cs/dalsi-temata/22-how-tex-macros-actually-work-part-4.md) [Část 5](/latex/cs/dalsi-temata/23-how-tex-macros-actually-work-part-5.md) [Část 6](/latex/cs/dalsi-temata/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://overleaf-pro.ayaka.space/latex/cs/dalsi-temata/24-how-tex-macros-actually-work-part-6.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.
