> 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/22-how-tex-macros-actually-work-part-4.md).

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

[Čá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

V částech 1–3 jsme se podrobně ponořili do některých základních detailů na nižší úrovni, abychom se připravili na pochopení toho, jak fungují makra TeXu. V tomto článku se budeme chtít „vynořit na chvíli nad hladinu“, abychom si zopakovali některé základní praktické principy maker TeXu a připravili se na další hluboký ponor v částech 5 a 6. V celém tomto článku budeme ukazovat příkladová makra definovaná pomocí primitivního příkazu TeXu `\def`: nebudeme používat možná známější příkaz LaTeXu `\newcommand`. Je k tomu velmi dobrý důvod: naším cílem je porozumět základním principům, na nichž spočívá chování maker TeXu, ale k tomu musíme používat základní příkazy *vestavěné do* softwaru TeX. Příkazy LaTeXu, jako například `\newcommand`, jsou samy o sobě makra: příkazy se specifickým naprogramovaným chováním, které jsou nakonec vystavěny z vrstev nižší úrovně primitivních příkazů TeXu. Chceme-li lépe porozumět základnímu chování TeXu, musíme používat primitiva TeXu, nikoli makra LaTeXu.

### Kam směřujeme?

V podstatě směřujeme k vysvětlení maker jako specializované formy seznamu tokenů: když TeXu nařídíte definovat makro, vytvoří sekvenci tokenů (seznam tokenů) a uloží je ve své paměti navázané na název, který určíte. V částech 5 a 6 se na seznamy tokenů maker podíváme podrobněji, ale pokud byste se raději z tohoto článku odrazili a přečetli si nějaké základní informace, najdete je v [Co je seznam tokenů TeXu?](/latex/cs/clanky-do-hloubky/54-what-is-a-tex-token-list.md)

Seznamy tokenů pro makra a jejich parametry zahrnují ještě několik dalších záludností, kterými se budeme podrobně zabývat — a použijeme spoustu příkladů. Chcete-li lépe porozumět chování zpracování maker TeXem, je tu skutečně jeden klíčový faktor, na který je třeba pamatovat: TeX se o znaky zajímá jen v nejranější fázi zpracování vstupu: od té chvíle už jde jen o tokeny! V tomto i v dalších článcích této série budeme zkoumat roli, kterou tokeny v makrech TeXu hrají.

## Čtyři části makra

### Připomínka: parametry makra a argumenty makra

Než začneme, stojí za to si připomenout rozdíl mezi *parametry* a *argumenty*argumenty makra, protože oba pojmy budeme v celém tomto článku používat. Předpokládejme, že definujete makro \foo

```
\def\foo#1#2{Toto je #1, toto je #2}
```

Konstrukty (tokeny) `#1`, `#2` (až po `#9`) se nazývají *parametry*: představte si je jako „zástupné symboly“ pro skutečná data, která použijete při volání makra:

```
\foo{alpha}{beta}
```

Zde `alpha` a `beta` jsou *argumenty* použité při tomto volání \foo: argumenty makra jsou skutečné hodnoty vložené do zástupných symbolů parametrů (`#1`, `#2`... `#9`) použitých při definování makra.

### Definice makra: má 4 prvky

Začneme tím, co možná vypadá jako poněkud formální definice makra, ale poskytuje užitečný rámec pro další diskusi.

Každá definice makra se skládá ze 4 částí:

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

kde:

* `<TeX makro primitivum>`: jedním z `\def`, `\edef`, `\gdef` nebo `\xdef`;
* `<název makra>`: název daný vašemu příkazu makra, například `\foo`;
* `<parametrický text>`: tento údaj může chybět, ale pokud je přítomen, jde o sled *tokeny* které se objevují před `<náhradní text>` text parametrů `<parametrický text>` může obsahovat parametry makra (`#1`, `#2`... `#9`) a jiné typy tokenů. V podstatě, a jak uvidíme podrobně,  `<parametrický text>` poskytuje jakýsi *šablonu tokenů* kterou TeX používá, aby zjistil, které tokeny chce uživatel použít jako argumenty makra: když makro zavoláte, TeX předá *argumentu* tokeny do vašeho makra `<náhradní text>` (které je také seznam tokenů);
* `{<náhradní text>}`: toto je skutečné tělo vašeho makra: je to sled tokenů, do kterých se při zpracování makra (rozšíření) „vkládají“ *argumenty* argumenty. Argumenty se vkládají do pozic označených parametry makra použitémi v původní definici.

**POZNÁMKA**: V celém tomto výkladu předpokládáme, že `<název makra>` bude následován znakem mezery s kódem kategorie 10, který bude fungovat jako oddělovač ukončující `<název makra>`. My *ne* jsme tento znak mezery v našem textu/výkladu výslovně neukázali, ale předpokládáme, že tam je. Přesně vzato bychom to měli znázornit nějak takto:

```
<primitivní příkaz makra TeXu><název makra><mezera><text parametrů>{<náhradní text>}
```

Nicméně explicitní zahrnutí `<mezera>` znaku vynecháme a budeme jeho přítomnost mlčky předpokládat.

#### Poznámky k {}

Ukázali jsme použití dvou složených závorek: `{` a `}` které obklopují (ohraničují) skutečné tělo vašeho makra `<náhradní text>`. Nicméně použití `{` a `}` je jen převzatá konvence, protože TeX ve skutečnosti očekává, že text vašeho makra `<náhradní text>` začíná znakem s kódem kategorie 1 („Začít skupinu“) a končí znakem s kódem kategorie 2 („Ukončit skupinu“). Podle konvence jsou to `{` a `}` znaky v uvedeném pořadí. Nicméně pokud chcete, můžete pro to přiřadit libovolnou dvojici znaků. Například

```
\catcode`\(=1
\catcode`\)=2
```

Nyní můžete definovat a používat makra takto:

```
\def\foo #1(Hello, #1)
\foo(World!)
```

A stále můžete používat `{` a `}` protože jsme jejich kódy kategorií nezměnili — více znaků může mít a také má stejný kód kategorie, takže byste mohli pokračovat v definování maker obvyklým způsobem:

```
\def\foo #1{Hello, #1}
\foo{World!}
```

### a {}

Nejrelevantnějšími složkami definice makra pro náš výklad jsou `<parametrický text>` a `{<náhradní text>}`. Když definujete makro, je `<parametrický text>` ve skutečnosti přísná šablona tokenů, která určuje, jak se má makro používat. Jak již bylo uvedeno, `<parametrický text>` může být prázdný, např. `\def\foo{Some text}` kde se mezi názvem našeho příkazu (`\foo`) a otevírací složenou závorkou `{` která zde signalizuje začátek našeho `<náhradní text>`.

**Poznámka**: Někteří čtenáři mohou znát TeXův mechanismus „hashquote“ (`#{`) ale zde se jím nebudeme zabývat.

### a oddělovače makra

Tento konkrétní článek není koncipován jako důkladně komplexní přehled o psaní maker, ale stojí za to mít krátké zopakování s několika příklady, které ukazují, že `<parametrický text>` může stát složitým, protože TeX umožňuje `<parametrický text>` obsahovat:

* **parametry makra**: (`#1`, `#2`,... `#9`) které fungují jako „zástupné symboly“ pro hodnoty, které uživatel poskytne při spuštění makra — *argumenty*;
* **oddělovací tokeny**: libovolné tokeny, rozptýlené mezi tokeny parametrů nebo kolem nich, a používané k určení hranice mezi parametry makra. Tyto oddělovače si můžete představit jako jakési „interpunkční znaménko“, které činí `<parametrický text>` šablonu tokenů“, kterou budete muset při použití makra dodržet. Oddělovací tokeny se nevysazují.

Co to tedy vlastně znamená — podívejme se na některé příklady. Text oddělovačů `<parametrický text>` je mezi názvem makra a levou složenou závorkou `{` definice makra.

#### Oddělovače: příklad 1

Předpokládejme, že definujeme základní makro `\foo` takto:

```
\def\foo ABC{ahoj, tam}
```

* `<parametrický text>` = `ABC`
* Neexistují žádné parametrové tokeny (`#1`, `#2`,... `#9`)
* Oddělovači jsou *tři znakové tokeny* `ABC` ale v tomto příkladu jsou poněkud nadbytečné a slouží jen jako ukázka.

Tři znakové tokeny `ABC` se považují za oddělovače: ne za něco, co se má vysázet, ale za „interpunkci“, o níž se očekává, že bude přítomna při volání makra — když makro použijete, `\foo` musíte dodat stejné oddělovače, které byly přítomny při jeho definici.

Pokud napíšete `\foo ABC` v textu, vysází se `ahoj, tam`—znakové tokeny `ABC` se nevysazují, ale TeX velmi pečlivě zkontroloval, zda byly přítomny ve vašem vyvolání (volání) `\foo`. TeX hledá tyto oddělovače („interpunkci“) a odstraňuje je (pohlcuje je), jak můžete vidět na následujícím snímku obrazovky z Overleafu: `ABC` se nevysazuje:

![Overleaf spouští makro TeXu](/files/9d15a36310b02a88d55ec2c70615cc95d0ab82dc)

Pokud se pokusíte použít `\foo` bez `ABC` oddělovačů, TeX si bude stěžovat `Použití \foo neodpovídá jeho definici.`:

![Zobrazení chyby TeXu v Overleafu](/files/155c9c66b651ed4c35a2122257e6bceb41df9d89)

Ve výše uvedeném příkladu, po zjištění `\foo` TeX očekává, že uvidí tři znakové tokeny `ABC` ale nevidí je: vidí znakový token pro `w` a okamžitě zjistí, že je něco špatně.

#### Oddělovače: příklad 2

Zajímavým a možná překvapivým faktem je, že oddělovači mohou být libovolné tokeny příkazů — včetně příkazů, které *nebyly ani definovány*. Například bychom mohli definovat `\foo` takto:

```
\def\foo A\bob B\anne{Ahoj \TeX{}}
```

* `<parametrický text>` = `A\bob B\anne`
* Neexistují žádné parametrové tokeny (`#1`, `#2`,... `#9`)
* Oddělovači jsou tokeny `A\bob B\anne` ale opět jsou v tomto příkladu nadbytečné a slouží jen pro účely výkladu. Všimněte si, že `\bob` a `\anne` jsou smyšlené příkazy, které *nebyly definovány*—a ani být nemusí.

Když makro voláte, TeX kontroluje (prohledává) `<parametrický text>` tokeny, které jsou přítomny *ve vašem volání makra* a porovnává je token po tokenu s verzí „šablony tokenů“ *uloženou v paměti*—tou, která byla vytvořena v době definice makra. TeX prohledává *použité ve vašem volání makra* a jednoduše převádí všechny příkazy, které tam najde, na jejich číselnou hodnotu tokenu: nesnaží se tyto příkazy spouštět, a proto nevadí, že `\bob` a `\anne` nikdy nebyly definovány. TeX jednoduše používá šablonu tokenů uloženou v paměti jako vodítko, které mu umožňuje zjistit, které tokeny v `<parametrický text>` vašeho volání makra jsou skutečné argumenty, které se mají předat do `<náhradní text>`.

Jak můžete vidět z následujícího výřezu obrazovky z Overleafu, ani jeden ze znakových tokenů (`Zkopírovaný` a `B`) uvnitř `A\bob B\anne` se nevysázel a naše nedefinované příkazy `\bob` a `\anne` nezpůsobily žádné problémy. Všechny tyto tokeny byly *pohlceny* TeXem při porovnávání vašeho použití `\foo` s definicí (šablonou tokenů) `\foo` uloženou v paměti.

![Overleaf spouští makro TeXu](/files/dcbc5bed0ed7ce0f25992f474c4c268208be5070)

#### Oddělovače: příklad 3

Můžete mezi sebe prokládat různé oddělovače (znakové tokeny, tokeny příkazů) s parametry makra, jako v tomto příkladu:

```
\def\foo A\bob#1B\anne#2\jane#3bye!{Ahoj od \TeX{} pro \#1=#1, \#2=#2 a \#3=#3}
```

* `<parametrický text>` = `A\bob#1B\anne#2\jane#3bye!`
* Existují 3 parametrové tokeny makra: `#1`, `#2`, `#3`
* Tentokrát jsou parametry (`#1`, `#2`, `#3`) odděleny kombinací tokenů:

  `A\bob#1B\anne#2\jane#3bye!`

Zde jste ve skutečnosti TeXu poskytli šablonu, kterou se bude velmi pečlivě snažit a očekávat, že ji při volání `\foo`: projde vaše volání makra, *token po tokenu*, a bude očekávat shodu (nalezení):

* dvou tokenů `Zkopírovaný` a `\bob` dříve, než `#1`
* dvou tokenů `B` a `\anne` dříve, než `#2`
* tokenu `\jane` před parametrem `#3` a *čtyř znakových tokenů* `b`, `y`,`e` a `!` za `#3`.

**Pamatujte**: TeX přemýšlí v tokenech, takže `bye!` je *čtyř znakových tokenů*.

Existují dva způsoby, jak můžeme toto makro použít — mohli bychom jakékoli více-tokenové argumenty umístit do složených závorek a vytvořit tak skupinu:

```
\foo A\bob{Toto}B\anne{Tamto}\jane{Jiné}bye!
```

Nicméně to *není nutné* protože naše definice makra má oddělovače, které poskytují šablonu tokenů. TeX může tuto šablonu použít k vybrání tokenů pro každý argument z tokenů, které jsou čistě oddělovače. Naše makro můžeme použít takto:

```
\foo A\bob ThisB\anne That\jane Otherbye!
```

a TeX může vybrat argumenty tak, aby se dosáhlo stejného výsledku jako při použití skupin `{...}`:

![Overleaf spouští makro TeXu s použitím oddělovačů](/files/702f8afc3ddea85264b46c984387615c2293bcc6)

Všimněte si, jak TeX dokázal přesně zjistit, které tokeny odpovídaly parametrům `#1` a `#3`:

![Overleaf spouští makro TeXu s použitím oddělovačů](/files/fb5dfdb1b239f468e1aadc8290aa8be3c015b579)

#### Oddělovače: příklad 4 (jde o tokeny, ne o znaky!)

Zde je krátký příklad, který ukazuje, že při práci s makry je důležité pamatovat na to, že se skutečně pohybujeme ve světě *tokeny* a **ne** *znaky*…

Definujeme následující krátké makro, kde A a B jsou znaky fungující jako oddělovače a oba mají kód kategorie 11. Tohle funguje bez problémů:

```
\documentclass{article}
\begin{document}
\def\foo A#1B{Ahoj, #1}
\foo AGrahamB
\end{document}
```

a vysází `Ahoj, Grahame`.

Nicméně pokud změníte kód kategorie A nebo B na něco jiného než 11, volání makra selže. Předpokládejme, že změníme kód kategorie B na 12 pomocí ``\catcode`B=12`` a zkusíme makro zavolat znovu, jako předtím:

```
\documentclass{article}
\begin{document}
\def\foo A#1B{Ahoj, #1}
\foo AGrahamB % Tohle funguje
\catcode`\B=12\relax
\foo AGrahamB
\end{document}
```

Selže to s poněkud záhadnou chybou:

```
Uteklý argument?
GrahamB \end {document}
! Soubor skončil při prohledávání použití \foo.
<vložený text>
                \par
<*> main.tex

Mám podezření, že jste zapomněli `}', což mě
přimělo číst dál, než jste chtěli, abych skončil.
Zkusím se zotavit; ale pokud je chyba vážná,
raději teď napište `E' nebo `X' a soubor opravte.

! Nouzové zastavení.
<*> main.tex

*** (úloha přerušena, nebyl nalezen žádný platný \end)
```

![Overleaf zobrazuje chybu makra TeXu](/files/f7d0451b3473b0af328b5fda63742c608631d5f1)

Bohužel výchozí návrh TeXu ``Mám podezření, že jste zapomněli `}'`` je **nesprávný**, není způsoben chybějící složenou závorkou (`}`).

#### Co se stalo?

TeX se snaží porovnat `\foo` makro *volání* s `\foo` makro *definicí* kterou má uloženou v paměti. Když voláte makro, které potřebuje jeden nebo více argumentů, TeX musí prozkoumat (prohledat) vaše použití makra, aby zjistil *argumenty* které tomuto makru poskytujete. Zde TeX očekává, že argument bude uzavřen mezi A (kód kategorie 11) a B (kód kategorie 11). Pamatujte: TeX přemýšlí v *tokeny*, **ne** *znaky*.

Hodnoty tokenů pro A a B, $$\mathrm{T\_A}$$ a $$\mathrm{T\_B}$$ v uvedeném pořadí, jsou:

$$\mathrm{T\_A = 256 \times 11 + 65 = 2881}$$ $$\mathrm{T\_B = 256 \times 11 + 66 =2882}$$

Nicméně jak TeX pokračuje ve svém hledání, uvidí B *ale* nyní má kód kategorie 12 a to vede k jiné hodnotě tokenu:

$$\mathrm{T'\_B= 256 \times 12 + 66 =3138}$$

V `\foo` v definici makra byla hodnota tokenu pro B (použitou jako oddělovač) 2882, ale TeX nyní vidí hodnotu tokenu 3138: myslí si, že je to jen další token určený k použití v *argumentu* poskytnutý do `\foo`. Z pohledu TeXu dosud nebyl nalezen poslední token argumentu, takže jde získat další token při hledání B s kódem kategorie 11. To je okamžik, a důvod, proč makro selže: při snaze najít argument TeX „přestřelí“ a začne číst tokeny, o nichž jste nechtěli, aby se staly součástí argumentu pro `\foo` volání makra. Co se stane dál, závisí na tokenech, které TeX objeví po B — vyvolají různé `Uteklý argument?` chyby.

V našem příkladu TeX přestřelí a pohltí proud tokenů `\end {document}` a rychle narazí na konec souboru, odtud chybová zpráva:

```
! Soubor skončil při prohledávání použití \foo
```

## Část 5

Jak jsme viděli výše, `<parametrický text>` sekce definice našeho makra může sahat od extrémně jednoduché až po složitou směs parametrů makra prokládaných znakových tokenů a tokenů příkazů fungujícími jako oddělovače. TeX dokáže zpracovat různé kombinace tokenů přítomné v `<parametrický text>` aby z nich extrahoval argumenty předané makru — a zjistil, když se pokusíme použít makro nesprávně. Jak to dělá, je předmětem dalšího článku série.

[Čá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/22-how-tex-macros-actually-work-part-4.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.
