> 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/clanky-do-hloubky/09-an-introduction-to-luatex-part-2-understanding-directlua.md).

# Úvod do LuaTeXu (část 2): Porozumění \directlua

## Cílem tohoto článku

V první části tohoto článku, [Úvod do LuaTeXu (1. část): Co to je — a čím je tak odlišný?](/latex/cs/clanky-do-hloubky/07-an-introduction-to-luatex-part-1-what-is-it-and-what-makes-it-so-different.md), jsme stručně představili LuaTeX jako mimořádně všestranný TeXový engine: sofistikovaný, programovatelný sazební systém, který poskytuje širokou škálu nástrojů pro vytváření řešení pro návrh a produkci dokumentů.

V tomto závěrečném pokračování se podrobně podíváme na nejdůležitější součást sady nástrojů LuaTeXu: `\directlua` příkaz, který poskytuje „bránu“ k programovému řízení sazby LuaTeXu prostřednictvím skriptovacího jazyka Lua.

Nicméně, plné využití LuaTeXu prostřednictvím `\directlua` vyžaduje určité základní znalosti několika témat TeXu: tokeny TeXu, seznamy tokenů a mechanismus rozšiřování. Cílem tohoto článku je prozkoumat a vysvětlit tyto základní koncepty TeXu: poskládat dohromady procesy související s TeXem, které stojí za `\directlua` za účelem pochopení, jak funguje, a poskytnout základy, na nichž můžete pomocí LuaTeXu stavět vlastní sazební řešení.

Tento článek obsahuje řadu krátkých příkladů, které demonstrují a vysvětlují klíčové aspekty `\directlua`jeho chování, přičemž se záměrně vyhýbá příliš složitému kódu ve prospěch krátkých úryvků kódu. Kde je to nutné, používají příklady základní (raw/plain) TeX — ačkoli většina lidí používá a upřednostňuje LaTeX (makra), základní příkazy TeXu mají výhodu jednoduchosti.

## Úvod do Lua v LuaTeXu

[Lua](https://www.lua.org/about.html) je skriptovací jazyk, jehož [zdrojový kód](https://www.lua.org/download.html) je vysoce přenositelný a snadno se vkládá do softwarových aplikací, což vývojářům umožňuje do jejich programů začlenit skriptovací schopnosti. Lua byl vložen do [mnoha aplikací](https://en.wikipedia.org/wiki/List_of_applications_using_Lua) a je oblíbenou volbou v odvětví vývoje her — snad nejznámějším příkladem je [World of Warcraft](https://wowwiki.fandom.com/wiki/Lua_functions).

LuaTeX, jak název napovídá, je TeXový engine, který v sobě integruje skriptovací jazyk Lua a poskytuje uživatelům možnost řídit sazební chování LuaTeXu tak, že do svých dokumentů vkládají programy (skripty) v jazyce Lua. Kromě přímého řízení LuaTeXu mohou uživatelé využít Lua čistě jako velmi schopný programovací jazyk k provádění úloh, které by mohlo být extrémně obtížné dosáhnout pomocí jazyka TeX — a ten je při spravedlivém posouzení výzvou k naučení i zvládnutí. Přidáním a integrací Lua se LuaTeX stává velmi všestranným a výkonným TeXovým enginem, který přímo podporuje dva programovací jazyky.

### Použití Lua a TeXu ve vašem dokumentu: zavolejte \directlua

Lua a TeX jsou dva *velmi odlišné* programovací jazyky: Lua má mnohem blíže k tomu, co si většina lidí pod pojmem programovací jazyk představuje, ale TeX se svými kategoriálními kódy, tokeny, makry a mechanismem rozšiřování je od zkušeností/očekávání většiny lidí od jazyka, v němž se píší programy, velmi vzdálený. Nicméně, jak ukázala historie, jazyk TeX přetrval, protože je dobrý v tom, pro co byl navržen: řízení sazby, i když je jeho způsob fungování poněkud esoterický.

Aby se řešila výzva míchání jazyků Lua a TeX v jednom TeXovém dokumentu, vývojáři LuaTeXu představili nový příkaz nazvaný `\directlua` který je cestou k používání Lua — jak jako samostatného programovacího jazyka samého o sobě, tak k řízení sazebního chování LuaTeXu.

Ta `\directlua` příkaz umožňuje uživatelům vkládat kód Lua do jejich TeXových dokumentů; tento kód je následně předán vestavěnému interpretu jazyka Lua v LuaTeXu. Nicméně, `\directlua` také umožňuje, abyste *zkombinovali* kód Lua a (La)TeXu dohromady, v rámci stejného `\directlua` příkazu — to však přináší další složitosti kvůli zásadním rozdílům mezi programovacími jazyky založenými na Lua a TeXu. Klíčovou výzvou při používání kombinace kódu (La)TeXu a Lua je zajistit, aby tyto dva jazyky v poklidu koexistovaly a „nelezly si do cesty“.

`\directlua` se nejlépe hodí pro použití s kratšími úryvky kódu Lua v dokumentu, ale můžete jej použít i s rozsáhlejšími programy v Lua, pokud si to přejete. Obecně se větší programy v Lua a knihovny kódu Lua ukládají do externích souborů, které lze načíst pomocí funkce Lua `dofile()` v rámci `\directlua` příkazu. Z pohledu zpracování TeXem je významnou výhodou používání externích souborů s kódem Lua vyhnutí se komplikacím, které vyplývají z mechanismu kategoriálních kódů TeXu — téma plně rozebrané v tomto článku.

### Formálnější popis \directlua

Ta [Referenční příručka LuaTeXu](http://www.pragma-ade.com/general/manuals/luatex.pdf) popisuje `\directlua` takto (mírně upraveně):

> Aby bylo možné sloučit kód Lua se vstupem TeXu, je třeba několik nových primitivit. Primitiva `\directlua` se používá k okamžitému spuštění kódu Lua. Základní syntaxe je `\directlua{⟨code⟩}`. Balíček `⟨code⟩` je plně rozvinut a poté předán interpretu Lua. Po načtení a aplikaci rozvinutí na `⟨code⟩`, se výsledný seznam tokenů převede na řetězec, jako by byl zobrazen pomocí `\the\toks`.

Toto je samozřejmě technicky přesné, ale možná ne tak snadno pochopitelné bez určité znalosti nízkoúrovňových procesů TeXu — jako jsou tokeny a rozšiřování.

## Porozumění \directlua: Která témata probereme?

V tomto článku se podrobněji podíváme na některá klíčová související témata a nabídneme řadu příkladů navržených k demonstraci toho, jak `\directlua` funguje a kde (nebo proč) musíte být opatrní při kombinování TeXu a Lua ve svém `⟨code⟩`.

Probereme dostatečně podrobně následující témata, abychom poskytli základ pro pochopení `\directlua` a jeho „předzpracování“ kódu, který v něm používáte:

* kategoriální kódy a tokeny TeXu: převod textu na tokeny a tokenů na text;
* proces rozšiřování TeXu (a zabraňování rozšiřování);
* únikové mechanismy/sekvence v Lua pro znaky a řetězce;
* používání komentářů ve stylu Lua;
* stručný úvod do Lua API v LuaTeXu.

Pokud chápete, jak TeXové enginy vytvářejí a používají tokeny, a rozvíjíte povědomí o mechanismu rozšiřování TeXu, pak budete mít základy potřebné k odemčení neuvěřitelné všestrannosti LuaTeX `\directlua` příkaz.

## Základy: od textu k tokenům a od tokenů k textu

Overleaf publikoval několik článků, které se do hloubky zabývají tokeny TeXu a souvisejícími pojmy, takže zde nebudeme celý tento materiál opakovat; místo toho nastíníme ty oblasti/témata, která jsou relevantní pro rozvoj lepšího porozumění `\directlua`.

Zde je seznam dříve publikovaných článků, které by vás mohly zajímat:

* [Co je token TeXu?](/latex/cs/clanky-do-hloubky/53-what-is-a-tex-token.md)
* [Co je seznam tokenů TeXu?](/latex/cs/clanky-do-hloubky/54-what-is-a-tex-token-list.md)
* [Jak funguje \expandafter: Úvod do tokenů TeXu](/latex/cs/clanky-do-hloubky/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md)
* [Šestidílná série: Jak vlastně fungují makra TeXu?](/latex/cs/dalsi-temata/01-a-six-part-series-how-do-tex-macros-actually-work.md)

### Porozumění znakových tokenů

Každý znak, který je TeXový engine schopen přečíst z textového souboru, je reprezentován dvěma číselnými hodnotami:

* jeho *znakový kód* (hodnota ASCII nebo dnes jeho kódový bod Unicode);
* druhou, na TeX zaměřenou hodnotou zvanou jeho *kategoriální kód*.

Čtenáři, kteří by se chtěli dozvědět více o kategoriálních kódech, si mohou přečíst tento úvod publikovaný Overleafem: [Tak kde začneme? U kategoriálních kódů](/latex/cs/dalsi-temata/19-how-tex-macros-actually-work-part-1.md#so2c-where-do-we-start3f-with-category-codes).

Pokud například TeXový engine načte znak `Zkopírovaný` měl by přístup ke dvěma informacím: `Zkopírovaný`znakovému kódu (65) a jeho kategoriálnímu kódu (obvykle 11). Jakmile TeX daný znak vstoupí, `Zkopírovaný`, jeho kategoriální kód se nezmění, ale uživatelská makra mohou provést změny kategoriálního kódu, které by mohly ovlivnit jakýkoli *následující* znaku `Zkopírovaný` který *dosud nebyl načten* TeXem. TeX si proto musí zaznamenat, že *tento* znaku `Zkopírovaný`, *právě načtený*, má kategoriální kód 11. K tomu TeX používá dvojici celých čísel (65,11) k výpočtu další celočíselné hodnoty, kterou nazývá *znakový token*. Výpočtem této tokenové hodnoty, která je předána vnitřnímu zpracování TeXu, jsou daný `Zkopírovaný` a jeho kategoriální kód *svázány dohromady*; ve skutečnosti tento znakový token *zabaluje* data, která TeX potřebuje o tomto znaku vědět pro použití při jakýchkoli následujících sazebních činnostech hluboko uvnitř TeXového enginu.

#### Jak se vypočítávají znakové tokeny?

Nejprve si musíme uvědomit, že TeXové enginy používají pro vytváření tzv. *aktivních znaků*: každý znak s kategoriálním kódem 13 se chová jako miniumakro; proto, a jak uvidíme níže, se tokeny pro aktivní znaky vypočítávají jinak než pro běžné znaky s jinými kategoriálními kódy, jako je 10, 11 nebo 12.

Pro *neaktivních* znaků:

* starší 8bitové enginy (TeX Knutha, e-TeX, pdfTeX) počítají znakové tokeny pro *neaktivních* znaky pomocí

$$\text{(non-active) character token} = (256 \times \text{category code}) + (\text{ASCII character code})$$

* u LuaTeXu, který se musí vypořádat s hodnotami znaků Unicode, je výpočet pro *neaktivních* znaky podobný, ale produkuje mnohem větší celočíselné hodnoty:

$$\text{(non-active) character token} = (2^{21} \times \text{category code}) + (\text{Unicode value})$$

Vrátíme-li se k našemu dřívějšímu příkladu písmene A s kategoriálním kódem 11, LuaTeX by vypočítal hodnotu znakového tokenu $$2^{21} \times 11 + 65 = 23068737$$. Jakmile je vypočtena, tato hodnota znakového tokenu *váže* toto konkrétní písmeno A na hodnotu kategoriálního kódu 11. Uživatelská makra mohou změnit kategoriální kód jakéhokoli následujícího písmene A, ale kategoriální kód tohoto je pevně dán jeho převodem na token pro použití při průchodu vnitřním fungováním LuaTeXu. LuaTeX uchoval, neboli zakódoval, zamýšlený význam tohoto znaku tak, jak byl určen v okamžiku jeho načtení.

TeXové enginy používají celkem [16 různých kategoriálních kódů](/latex/cs/dalsi-temata/43-table-of-tex-category-codes.md) a *kterýkoli* z těchto kategoriálních kódů lze přiřadit prostřednictvím `\catcode` příkazu *kterýkoli* libovolnému znaku, který je TeXový engine schopen přečíst. Změny kategoriálních kódů se používají k úpravě způsobu, jakým TeXové enginy zpracovávají určité znaky ve vstupu, což uživatelům TeXu umožňuje psát makra, která vytvářejí speciální sazební výsledky nebo chování.

**Aktivní znaky**

Jak bylo poznamenáno, TeXové enginy používají kategoriální kód 13 k přiřazení „zvláštního významu“ znaku, čímž z něj činí tzv. *aktivní znak* který se chová jako miniumakro: není vyžadován žádný úvodní `\` , izolovaný znak, díky svému kategoriálnímu kódu, stačí k vyvolání jeho makro-podobného chování.

Protože aktivní znak funguje jako miniumakro, nepřevádí se na *znakový token* ale na druhý (celočíselný) typ tokenu nazývaný *příkazový token*. Ty se počítají následovně:

* u starších 8bitových enginů (TeX Knutha, e-TeX, pdfTeX) se tokeny pro aktivní znaky počítají pomocí:

1. vypočítat mezihodnotu nazvanou $$\text{curcs}$$ (**aktu**ální **c**řídicí **s**ekvence) kde $$\text{curcs} = \text{character code} + 1$$3. vypočítejte hodnotu tokenu, kde $$\text{active character token} = \text{curcs} + \text{4095}$$

* pro LuaTeX je výpočet o něco složitější, protože musí pracovat s celým rozsahem znaků Unicode, z nichž kterýkoli by mohl být aktivní:

1. vypočítat mezilehlou celočíselnou hodnotu $$\text{curcs}$$ použitím tzv. *hashovací funkce* na hodnotu kódového bodu Unicode aktivního znaku vyjádřenou v UTF-8: $$\text{curcs}=\texttt{hashfunction}\text{(UTF-8 text for Unicode value of active character)}$$3. vypočítejte celočíselnou hodnotu tokenu: $$\text{active character token} = \text{curcs} + 2^{29} - 1$$

**Příklady**

* 8bitové enginy: výpočet tokenu pro aktivní znak `~` (znakový kód 126) vede k $$\text{curcs} = 126 + 1 = 127$$, což dává hodnotu tokenu $$4095 + 127 = 4222$$.
* LuaTeX: výpočet tokenu pro aktivní znak `~` vede k $$\text{curcs}=3186$$ což dává hodnotu tokenu $$3186 + 2^{29} - 1 = 536874097$$. Tokeny LuaTeXu používají mnohem větší celočíselné hodnoty!

### Porozumění příkazovým tokenům

Kromě zpracování *jednotlivých* znaků mohou TeXové enginy samozřejmě zpracovávat *sekvence* znaků nazývané *příkazy* (nebo přesněji, *kontrolní sekvence*). Podle tradice se `\` znak používá k označení začátku příkazu, ale je to jen konvence — ve skutečnosti by bylo možné použít jakýkoli znak s kategoriálním kódem 0 (znak úniku).

TeXové enginy rozpoznávají dva typy příkazů, známé jako *kontrolní slova* a *kontrolní symboly*:

* **kontrolní slova**: příkazy vytvořené z jednoho nebo více znaků, které mají kategoriální kód 11;
* **kontrolní symboly**: jednoznakové příkazy, u nichž má daný znak kategoriální kód *není* 11: například `\$`, `\#` nebo `\\`.

**Poznámka**: Primitiva TeXu `\chardef`, `\mathchardef`, `\countdef`, `\dimendef`, `\skipdef`, `\muskipdef` a `\toksdef` se také používají k definování kontrolních sekvencí, ale na rozdíl od běžných definic maker výsledné kontrolní sekvence (kontrolní slova nebo kontrolní symboly) *nejsou rozšiřitelné*—probereme je podrobněji níže.

#### Jak se vypočítávají příkazové tokeny?

Stejně jako aktivní znaky používají TeXové enginy druhý typ celočíselné hodnoty tokenu k reprezentaci příkazů: *příkazové tokeny*—pamatujte, že aktivní znaky také generují příkazové tokeny, protože se chovají jako miniumakra.

Výpočty používané 8bitovými enginy k vytváření celých čísel příkazových tokenů najdete v tomto [článku Overleafu](/latex/cs/clanky-do-hloubky/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md#how-tex-calculates-token-values). Zde shrneme klíčové kroky výpočtů příkazových tokenů pro LuaTeX — které jsou poněkud odlišné, protože LuaTeX musí zpracovávat hodnoty znakových kódů Unicode, které mohou být podstatně větší než 8bitové hodnoty; nicméně výpočty LuaTeXu sledují stejné obecné principy, které používají starší 8bitové enginy.

Poté, co detekují příchozí příkaz, TeXové enginy, včetně LuaTeXu, ignorují úvodní `\` znak: nepoužívá se ve výpočtech hodnot příkazových tokenů, ale slouží pouze jako „spínač“, který TeXovému enginu sděluje, že potřebuje zpracovat příkaz. Hodnota příkazového tokenu se vypočítá pomocí posloupnosti (jednoho nebo více) znaků přítomných v názvu příkazu — LuaTeX vypočítává příkazové tokeny pro kontrolní symboly i kontrolní slova stejným algoritmem:

1. vypočítat mezilehlou celočíselnou hodnotu $$\text{curcs}$$ použitím tzv. [hashovací funkce](https://en.wikipedia.org/wiki/Hash_function) na řetězec znaků Unicode UTF-8 obsažený v názvu příkazu: $$\text{curcs}=\texttt{hashfunction}\text{(Unicode UTF-8 string of characters in command name)}$$3. vypočítejte hodnotu příkazového tokenu, kde $$\text{command token} = \text{curcs} + 2^{29} - 1$$

**Příklady**

* pro `\\` příkaz (kontrolní symbol), LuaTeX vypočítá $$\text{curcs}=94$$, což vede k hodnotě tokenu pro `\\` pro $$94 + 2^{29} - 1 = 536871005$$.
* pro `\vskip` primitivní příkaz (kontrolní slovo) LuaTeX vypočítá $$\text{curcs}=3560$$, což vede k hodnotě tokenu pro `\vskip` pro $$3560 + 2^{29} -1 = 536874471$$.
* pro uživatelem definované makro `\mynewmacro` (kontrolní slovo) LuaTeX vypočítá $$\text{curcs} = 2971$$, což vede k hodnotě tokenu pro `\mynewmacro` pro $$2971 + 2^{29} -1 = 536873882$$.

Jakmile jsou tokeny vytvořeny, mohou být uloženy pro pozdější použití pomocí tzv. *seznamů tokenů* nebo mohou být okamžitě předány k dalšímu zpracování uvnitř TeXového enginu. Používání celočíselných hodnot k reprezentaci tokenů funguje nejen na všech typech výpočetních platforem/operčních systémů, ale je to také velmi efektivní způsob, jak TeX ukládá/zpracovává data.

### Jak TeXový engine identifikuje typ tokenu (příkaz nebo znak)

Pro danou celočíselnou hodnotu tokenu, $$T$$, může TeXový engine snadno určit, zda $$T$$ reprezentuje příkaz nebo znak tím, že otestuje, zda $$T$$ přesahuje určitou $$\text{threshold value}$$—to $$\text{threshold value}$$ závisí na TeXovém enginu. Pokud $$T \geq \text{threshold value}$$ pak $$T$$ je příkazový token, jinak $$T$$ je znakový token. Prahová hodnota je $$\text{threshold value}$$ je $$4095$$ 4095 pro 8bitové enginy a $$2^{29}-1$$ (536 870 911) pro LuaTeX. Knuth navrhl metody použité ve vzorcích pro výpočet tokenů tak, aby jeho TeXový engine i všechny následující enginy založené na jeho kódu/architektuře mohly rychle a snadno testovat hodnoty tokenů.

## Tokeny lze rozkládat (a převádět zpět na text)

Tokeny (celá čísla) jsou mechanismus, jímž TeXový engine „zabaluje“ vše, co potřebuje zaznamenat o položce vstupu (znaku nebo příkazu). Jsou však chvíle, kdy TeXový engine potřebuje proces tokenizace obrátit — zjistit, co bylo původně načteno, aby vznikla daná hodnota tokenu — jednotlivý znak nebo posloupnost jednoho či více znaků tvořících název příkazu:

* **pro znakové tokeny**: Každý znakový token lze rozdělit na jeho dvě složky: znakový kód a odpovídající kategoriální kód přiřazený tomuto znaku *v okamžiku, kdy byl původně načten*. Stejně jako všechny TeXové enginy, ani LuaTeX tuto původní alokaci kategoriálního kódu nezmění, ale při dalším interním zpracování ji využije.
* **pro příkazové tokeny:** Ty jsou o něco podrobnější, ale podíváte-li se na výpočet příkazových tokenů v LuaTeXu, včetně tokenů pro aktivní znaky, uvidíte, že se řídí určitým vzorem: $$\text{command token} = \text{curcs} + 2^{29} -1$$

kde $$\text{curcs}$$ se vypočítává podle typu generovaného příkazového tokenu: aktivní znak, kontrolní symbol nebo kontrolní slovo. Proměnná $$\text{curcs}$$ je *mimořádně* důležitou součástí vnitřních operací TeXového enginu: pro libovolnou celočíselnou hodnotu příkazového tokenu může LuaTeX velmi snadno extrahovat hodnotu $$\text{curcs}$$ z tohoto příkazového tokenu pomocí $$\text{curcs} = \text{token value} - (2^{29} -1)$$.

### Proč je $$\text{curcs}$$ tak důležitý?

Vnitřní proměnná TeXu $$\text{curcs}$$ (**aktu**ální **c**řídicí **s**sekvence) je životně důležitou součástí vnitřních „pod kapotou“ operací TeXového enginu. Ačkoli ji ve svém kódu nebudete a nemůžete používat ani k ní přistupovat přímo, $$\text{curcs}$$ hraje klíčovou roli, protože TeXové enginy používají aktuální hodnotu $$\text{curcs}$$ jako index do interních tabulek, které ukládají data o každém příkazu, který je v daném okamžiku enginu znám. Tyto tabulky ukládají informace o aktuálním významu příkazu: co dělá nebo co představuje, a navíc zaznamenávají posloupnost znaků původně použitých k výpočtu této $$\text{curcs}$$ hodnoty. Tím, že z příkazového tokenu získá hodnotu $$\text{curcs}$$ může TeXový engine určit název, tj. text čitelný pro člověka, odpovídající libovolnému (příkazovému) tokenu, což mu umožňuje provádět převody tokenu na text, které jsou klíčovým aspektem `\directlua`jeho fungování.

### Převod celočíselných tokenů zpět na znaky nebo posloupnosti znaků (názvy příkazů)

Viděli jsme, že TeXové enginy převádějí vstupní znaky nebo posloupnosti znaků na celočíselné hodnoty tokenů, ale někdy TeXový engine potřebuje *obrátit* ten proces — k výstupu textu čitelného pro člověka, který byl původně použit k vytvoření těchto celočíselných hodnot tokenů; například:

* při zápisu chybových nebo varovných zpráv na obrazovku nebo `.log` soubor;
* při výstupu kódu TeX/LaTeX do textového souboru prostřednictvím `\write` příkazu;
* při převodu posloupnosti tokenů na text uvnitř `\directlua` (jak brzy uvidíme!)

#### Převod znakových tokenů na text

Jak bylo poznamenáno, tokeny pro neaktivní znaky se počítají pomocí kategoriálního kódu a znakového kódu vstupního znaku (hodnota Unicode). LuaTeX používá vzorec:

$$\text{character token} = (2^{21} \times \text{category code}) + (\text{Unicode value})$$

Je to přímočarý programátorský úkol rozdělit celočíselnou $$\text{character token}$$ hodnotu tokenu, abychom získali jeho složku znakový kód ($$\text{Unicode value}$$) a $$\text{category code}$$.

#### Převod příkazových tokenů na text

Všechny TeXové enginy ukládají název (posloupnost znaků) každého příkazu, který „znají“: ať už je tím příkazem uživatelem definované makro nebo vestavěná primitiva — ukládání názvů primit se provádí při startu TeXového enginu, dávno předtím, než začne zpracovávat váš kód. U uživatelem definovaných příkazů (maker) je název tohoto makra (bez úvodního `\`) uložen jako součást procesů definice maker uvnitř TeXových enginů.

Když TeXový engine potřebuje získat nebo vypsat text čitelný pro člověka, z něhož byla původně vypočítána celočíselná hodnota příkazového tokenu, nejprve určí $$\text{curcs}$$ hodnotu pro tento token; v LuaTeXu, $$\text{curcs} = \text{token} - (2^{29} -1$$). Pomocí hodnoty $$\text{curcs}$$ získané z příkazového tokenu může TeXový engine přistupovat k interní datové struktuře nazývané *zásobník řetězců* a určit posloupnost znaků čitelných pro člověka, původně použitou k výpočtu dané hodnoty pro $$\text{curcs}$$ a tedy i odpovídajícího příkazového tokenu.

Jak uvidíme, tyto činnosti zpracování tokenů — převod sekvencí znaků na celočíselné hodnoty tokenů a převod celočíselných hodnot tokenů zpět na sekvence znaků („de-tokenizace“) — jsou *základní mechanismy* používané uvnitř `\directlua`.

## Seznamy tokenů

Když TeXový engine čte vstup, generuje znakové a příkazové tokeny (a zpracovává je), může narazit na určité příkazy, které enginu nařizují, aby (dočasně) přestal předávat tokeny dál k dalšímu zpracování a místo toho je uložil stranou pro pozdější použití. Nejběžnějším příkladem je definice makra pomocí jednoho z příkazů pro definici maker `\def`, `\edef`, `\gdef` nebo `\xdef`—příkazy LaTeXu jako `\newcommand` jsou makra, která poskytují dodatečnou funkcionalitu vytvořenou kolem nízkoúrovňových primitiv, jež nakonec provedou skutečný proces definice makra. Makro lze považovat za název daný určitému seznamu uložených tokenů: seznamu tokenů.

TeXové enginy využívají *rozsáhle* seznamy tokenů, zejména [dočasné interní seznamy](/latex/cs/clanky-do-hloubky/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md) používané pro účely interního zpracování. Každý TeXový engine také poskytuje uživatelské příkazy pro vytváření seznamů tokenů, které se ukládají stranou pro případ, že je uživatel nebo sám TeXový engine potřebuje. Počet příkazů pro vytváření seznamů tokenů (vestavěných primitiv) se liší podle TeXového enginu, ale všechny sdílejí základní minimální sadu podporovanou každým enginem, jako je `\toks` primitiva.

V praxi je seznam tokenů jen uložená posloupnost celočíselných hodnot:

* vstup se načítá, aby se vytvořily (vypočetly) jednotlivé tokeny reprezentující znak nebo příkaz;
* každý token je poté uložen stranou, přičemž se zachová pořadí, v jakém byly tokeny ze vstupu vytvořeny.

TeXové enginy ukládají seznamy tokenů pomocí datové struktury nazývané [spojový seznam](https://en.wikipedia.org/wiki/Linked_list) (jednosměrně propojený typ). Čtenáři, kteří by se chtěli dozvědět více o seznamech tokenů, jsou zváni, aby si přečetli článek Overleafu [Co je seznam tokenů TeXu?](/latex/cs/clanky-do-hloubky/54-what-is-a-tex-token-list.md) který využívá analogii k vystavění konceptů/myšlenek stojících za seznamem tokenů. Podrobné zkoumání seznamů tokenů v TeXu a toho, jak se používají při zpracování maker, najdete v sérii článků Overleafu [Jak makra TeXu skutečně fungují?](/latex/cs/dalsi-temata/01-a-six-part-series-how-do-tex-macros-actually-work.md)

#### Seznam tokenů v grafické podobě

Následující grafika ukazuje seznam tokenů vygenerovaný LuaTeXem s odpovídajícími hodnotami tokenů vytvořenými z následujícího vstupu

`Ahoj, \TeX! \hskip 5bp`

Například, pokud definujeme `\mymacro` zapíšeme jako `\def\mymacro{Ahoj, \TeX! \hskip 5bp}` definice `\mymacro` by byla uložena v paměti pomocí takového seznamu tokenů:

![](/files/802831059d0110911ceb5cba681e9665b3588188)

Seznam tokenů je posloupnost propojených položek nazývaných *uzlů*, což je název daný malému balíčku paměti LuaTeXu alokované k uložení každé položky v seznamu (jako jednotlivé články řetězu). Každý uzel obsahuje celočíselnou hodnotu tokenu a paměťovou adresu *dalšího* uzlu v řetězu, čímž vzniká datová struktura nazývaná [spojový seznam](https://en.wikipedia.org/wiki/Linked_list). Poslední uzel označuje konec seznamu pomocí speciální „nulové hodnoty“ pro další uzel — protože žádný není.

**Poznámky:**

* Pro pohodlí jsme uvedli adresu každého jednotlivého uzlu, ale v praxi se tato data v uzlech seznamu tokenů neukládají; je vyžadována pouze adresa *následující uzel* k vytvoření seznamů tokenů TeXového enginu.
* Druhý sloupec v grafice s názvem „Co každý token znamená“ ukazuje řadu šedých políček obsahujících informace o tokenu obsaženém v každém uzlu: tyto slouží čistě pro informaci a *se* nejsou součástí skutečných dat uložených v seznamu tokenů.

Zde je tabulka hodnot tokenů obsažených v seznamu tokenů zobrazeném výše:

|                     |                    |                                                                               |                    |
| ------------------- | ------------------ | ----------------------------------------------------------------------------- | ------------------ |
| **Vstupní položka** | **Typ vstupu**     | <p><strong>Kategoriální kód</strong><br><br><strong>(pokud znak)</strong></p> | **Hodnota tokenu** |
| H                   | znaku              | 11                                                                            | 23068744           |
| i                   | znaku              | 11                                                                            | 23068777           |
| ,                   | znaku              | 12                                                                            | 25165868           |
|                     | znaku              | 10                                                                            | 20971552           |
| \TeX                | příkaz (makro)     |                                                                               | 536871539          |
| !                   | znaku              | 12                                                                            | 25165857           |
|                     | znaku              | 10                                                                            | 20971552           |
| \hskip              | příkaz (primitiva) |                                                                               | 536874247          |
| 5                   | znaku              | 12                                                                            | 25165877           |
| b                   | znaku              | 11                                                                            | 23068770           |
| p                   | znaku              | 11                                                                            | 23068784           |

**Poznámka:** Náš původní vstupní text má za `\hskip` příkazem, ale v seznamu tokenů neexistuje token představující tento znak. Tento znak byl pohlcen vstupním skenováním (čtením) LuaTeXu, protože byl použit k ukončení hledání znaků tvořících `\hskip` příkaz.

## Jak \directlua ve skutečnosti funguje

Nyní, když jsme prozkoumali tokeny, seznamy tokenů a převod tokenů na text, je dalším úkolem porozumět konceptu tokenu v TeXu *rozšiřování*.

Jak bylo uvedeno, `\directlua{⟨code⟩}` může být požádán, aby zpracoval `⟨code⟩` který obsahuje jak kód Lua, tak TeX/LaTeX, ale vestavěný interpret jazyka Lua v LuaTeXu TeX ani LaTeX nechápe: jak tedy může toto fungovat? Jak je možné, aby `⟨code⟩` obsahoval instrukce TeX/LaTeX, aniž by interpreta Lua důkladně zmátl příkazy, kterým nerozumí? Například následující `\directlua` příkaz používá pouze makra TeXu, ale funguje:

```
\def\aa{tex}
\def\bb{.}
\def\cc{print}
\def\dd{("Hello")}
\directlua{
   \aa\bb\cc\dd
}
```

Tento `\directlua` příkaz způsobí, že LuaTeX vysází `Hello` ale proč a jak to funguje, když jazyk Lua TeXovy makra nechápe?

Odpověď se skrývá v dřívějším popisu, který jsme si vypůjčili z [Referenční příručka LuaTeXu](http://www.pragma-ade.com/general/manuals/luatex.pdf) ale můžeme uvažovat, že `\directlua{⟨code⟩}` funguje tak, že LuaTeX nejprve „předzpracuje“ `⟨code⟩` předtím, než je cokoli předáno interpretovi Lua. Povaha tohoto „předzpracování“ — tedy co to skutečně znamená a jaké má důsledky pro vaše `⟨code⟩`— je dalším tématem, které probereme, abychom pomohli čtenářům, kteří chtějí využít sílu a flexibilitu `\directlua`.

### Jak LuaTeX zpracovává \directlua: první pohled

Abychom rozvinuli naše porozumění `\directlua`předzpracovacím aktivitám můžeme začít s následujícím zjednodušeným diagramem, který dává přehled o tom, co se děje.  `⟨code⟩` poskytnutý `\directlua{⟨code⟩}` se nejprve převede na tokeny pomocí postupů a výpočtů popsaných výše; tato posloupnost tokenů se uloží do seznamu tokenů. Jakmile je tento seznam tokenů vytvořen, každý token v něm se převede zpět do své textové reprezentace: text vytvořený každým tokenem — ať už znakový token nebo příkazový token — se spojí (zřetězí), aby vznikl jeden řetězec kódu předaný interpreteru Lua k provedení.

![](/files/de5f8f17a7f88c39b8896aae96abaa066302c07b)

Ale počkejte, k čemu by bylo převádět text na tokeny a hned tyto tokeny převádět zpět na text? Možná vás nepřekvapí, že ano, existuje ještě další a zásadní proces, který jsme do této grafiky nezahrnuli: *rozšiřování tokenů*. Každý token vzniklý z textu ve vašem `⟨code⟩` podléhá určitému typu „kontroly“, při níž LuaTeX aplikuje test, zda token představuje příkaz, který patří do podmnožiny známé jako *rozšiřitelné příkazy*. Pokud ano, LuaTeX tento příkaz odfiltruje *odstranění* z vašeho `⟨code⟩` a *jeho nahrazením* výsledkem/výsledky procesu, kterému TeXové enginy říkají *rozšiřování tokenů*.

### Jak LuaTeX zpracovává \directlua: druhý pohled (na expanzi)

Mechanismus expanze v TeXu je základní součástí všech sazebních enginů založených na TeXu, protože nakonec každý z nich je odvozen od (nebo založen na) Knuthově původním zdrojovém kódu a návrhu TeXu. Koncept expanze je však obtížné vysvětlit stručným, a přitom srozumitelným jazykem, protože v praxi je „expanze“ zastřešující termín používaný k popisu jediného procesu — ale takového, který vytváří řadu výstupů. Tyto rozmanité výsledky jsou důsledkem poněkud eklektické sady příkazů, na které lze expanzi aplikovat, takže si můžete představit, že každý rozšiřitelný příkaz má určité „chování při expanzi“.

Jako *prvotní aproximace* pro porozumění expanzi můžeme říci, že expanze tokenu (příkazu) znamená *odstranění* ten příkaz (token) z aktuálního vstupu TeXu a *nahrazení* nahradit jej posloupností tokenů, které vzniknou provedením daného rozšiřitelného příkazu — tedy nahradit původní token výsledky/důsledky jeho expanze *chování*. Toto úvodní „definiční“ pojetí expanze — ve smyslu generování nových tokenů, které má TeX číst — však není pro všechny rozšiřitelné příkazy zcela přesné, ale jako výchozí bod stačí.

Pro jednoduchý příklad: primitiv TeXu `\jobname` je rozšiřitelný příkaz a jeho *rozšiřování* je posloupnost znakových tokenů, které představují název hlavního vstupního souboru TeXu. Pokud se TeX rozhodne rozšířit `\jobname` příkaz (token), je *odstraněn* z aktuálního vstupního zdroje TeXu a *nahrazen* posloupností znakových tokenů, které vygeneruje — a které pak TeX začne číst/zpracovávat.

V rámci `\directlua`, po zpracování (odstranění) rozšiřitelného tokenu a jeho nahrazení novými tokeny bude LuaTeX pokračovat ve čtení těchto nových tokenů, které právě vložil na jejich místo — ale některé z těchto nových tokenů mohou být také rozšiřitelné. Protože `\directlua` provádí takzvanou *plnou expanzi*, bude LuaTeX tyto nové tokeny číst a znovu projde procesem expanze, aby rozšířil (odstranil) všechny nové (rozšiřitelné) tokeny — tento proces expanze pokračuje, dokud nezůstanou žádné rozšiřitelné tokeny. Existují však dvě důležité výjimky z tohoto pravidla „pořád dál expandovat“, a obě probereme níže:

* použitím konstruktu `\the\toks`;
* záměrným zabráněním (potlačením) expanze jednoho nebo více vybraných tokenů.

Jak bylo uvedeno, naše pracovní definice (prvotní aproximace) pro porozumění expanzi nepokrývá celý rozsah chování expanze prokázaný podmnožinou rozšiřitelných příkazů. Například některé rozšiřitelné příkazy negenerují tokeny způsobem, jakým to dělá `\jobname` , ale mohou:

* „filtrovat“ tokeny ze vstupu: podmínkové příkazy enginu TeXu (`\if`, `\ifcat`, `\ifnum`, `\ifdim`, `\ifodd`, `\ifvmode`, …) jsou rozšiřitelné. Jejich chování při expanzi je typem „filtrování tokenů“ — podmínky lze použít v `\directlua`.
* „přehazování“ tokenů ve vstupu:  [`\expandafter` příkaz](/latex/cs/clanky-do-hloubky/03-a-six-part-article-series-on-expandafter-tex-tokens-and-expansion.md) je rozšiřitelný a mění pořadí, v němž jsou dva tokeny rozšiřovány.
* zabránit expanzi: rozšiřitelné příkazy `\noexpand` a `\unexpanded` potlačují expanzi příkazových tokenů ve vstupu.
* převádět znakové sekvence ve vstupu na příkazové tokeny: `\csname … \endcsname.`
* převádět vnitřní veličiny na posloupnost znakových tokenů: `\number` a `\the` generují posloupnost znakových tokenů představujících hodnotu vnitřní veličiny.
* převádět příkazové tokeny na znakové tokeny: `\string` a `\detokenize` jsou rozšiřitelné příkazy, které převádějí své argumenty na posloupnost znakových tokenů s kategoriovým kódem 12. Všimněte si, že `\detokenize` se liší od `\string`: `\detokenize` může zpracovat více tokenů a po zpracování příkazových tokenů vytvořených z *kontrolní slova*vkládá mezeru s kategoriovým kódem 10. Ve skutečnosti `\detokenize` přidává za název příkazu závěrečnou znak mezeru — nějaké příklady uvidíme později v článku.

#### Upřesnění naší „definice“ expanze

Nyní můžeme naši definici zobecnit a říci, že expanze příkazu (tokenu) zahrnuje *odstranění* tohoto příkazu (tokenu) z aktuálního vstupního zdroje TeXu a *jeho nahrazením* nahrazení *výsledkem* tokenových operací

provedených tímto příkazem. V podstatě proces expanze způsobuje, že rozšiřitelný příkaz provede nějaký typ „operace“ na tokenech v aktuálním vstupu TeXu, což ovlivní počet nebo chování tokenů, které TeX následně přečte — přesná povaha této „operace“ závisí na tom, který příkaz se rozšiřuje. Všechna makra a aktivní znaky jsou rozšiřitelná, ale pouze malý počet vestavěných příkazů (primitivů) TeX enginu je klasifikován jako rozšiřitelný — seznam rozšiřitelných příkazů závisí na tom, jaký TeX engine používáte.

Další obtíž při vysvětlování/pochopení expanze, a možná ta skutečná výzva, spočívá v tom, že přesně vědět *kdy* TeX engine skutečně provede proces expanze, nebo ne. Je to velké a složité téma, protože expanze je hluboce vetkána do vnitřního fungování TeXových enginů: nemáme prostor se tím zabývat do detailu nad rámec použití expanze v `\directlua`.

### Jak LuaTeX zpracovává \directlua: závěrečný pohled

Následující diagram shrnuje `\directlua` předzpracovací aktivity, které probíhají přímo uvnitř enginu LuaTeXu. V tomto diagramu také ukazujeme dvě nízkoúrovňové (vnitřní) funkce LuaTeXu, které skutečně vykonávají práci: `scan_toks()` a `tokenlist_to_cstring()`. Tyto funkce jsou napsány v jazyce C a sídlí hluboko uvnitř spustitelného softwaru LuaTeXu: jsou součástí vnitřního mechanismu LuaTeXu a nejsou *přímo* přístupné z vašeho kódu TeX/LaTeX.

![](/files/e67d904ac5a322aba0da8efefc84d52b4ada050b)

Následující popis `\directlua ⟨code⟩`jeho předzpracovací činnosti shrnuje výše uvedený diagram.

1. Posloupnost znaků ve vašem ⟨code⟩ je zpracována funkcí `scan_toks()`. Jejím účelem je číst vaše ⟨code⟩ znak po znaku a vytvářet znakové tokeny a příkazové tokeny. Protože vytváří tokeny, je kategoriový kód přiřazený každému znaku v ⟨code⟩ v okamžiku jeho načtení nesmírně důležitý.
2. Během `scan_toks()`zpracování tokenů (generování) se každý rozšiřitelný příkaz (token) rozšiřuje *ledaže* zabráněno pomocí příkazů jako `\protected` (definice maker), `\noexpand`, `\unexpanded` atd. Aktivní znaky (kategoriový kód 13) se také rozšiřují (pokud tomu není zabráněno).
3. Tok tokenů vytvořený funkcí `scan_toks()` se sestaví do jednoho dlouhého seznamu tokenů — tokeny přítomné v tomto seznamu zahrnují ty, které vznikly aplikací expanze na rozšiřitelné příkazy (například makra) přítomné ve vašem `⟨code⟩`. Všimněte si také, že `scan_toks()` *ne* spustí nebo způsobí provedení jakéhokoli tokenu reprezentujícího nerozšiřitelný příkaz: takové nerozšiřitelné tokeny jsou jednoduše předány dál a začleněny do vytvářeného seznamu tokenů.
4. Jakmile je seznam tokenů hotov a veškerá expanzní činnost je dokončena, je tento seznam tokenů zpracován další funkcí zvanou `tokenlist_to_cstring()` která převádí každý token ve výsledném seznamu tokenů zpět do jeho textové reprezentace. Tím vznikne řetězec textu, který je kódem Lua, jenž má být předán interpreteru Lua. Aby se provedení zdařilo, musí tento řetězec obsahovat syntakticky správný kód Lua.
5. Zpracování tohoto kódu v Lua probíhá ve dvou krocích:
6. Vestavěný interpret Lua v LuaTeXu analyzuje a „kompiluje“ kód Lua vytvořený v předchozích krocích. Pokud tato analýza/kompilace selže, interpret Lua vygeneruje chyby (například syntaktické chyby) — tyto chyby mohou způsobit selhání běhu LuaTeXu, pokud jste se nerozhodli použít `--interaction=nonstopmode` na příkazové řádce.
7. Pokud analýza/kompilace uspěje, interpret Lua provede kód zkompilovaný v kroku (5a).

V podstatě funkce `scan_toks()` je jádrem předzpracovacích činností LuaTeXu: jejím hlavním úkolem je rozšířit všechny rozšiřitelné příkazy TeX/LaTeX obsažené v textu vašeho `⟨code⟩` a sestavit z všeho, co zpracovala, seznam tokenů. Znovu zdůrazňujeme, že `scan_toks()` *neprovádí neexpandovatelné příkazy* (tokeny): jednoduše *ukládá* tyto tokeny do seznamu tokenů, který vytváří. Po dokončení je tento seznam tokenů následně převeden *zpět do textové reprezentace* funkcí `tokenlist_to_cstring()`— seznam tokenů je koncept výhradně TeXu, který je pro interpret Lua zcela cizí, a proto je nutné převést jej na text, z nějž se stane kód Lua, který se předá interpretovi Lua.

## Expenze jako „rozhraní“ programovacího jazyka

Můžete na `\directlua`proces expanze v LuaTeXu pohlížet jako na mechanismus nebo rozhraní pro předávání dat/informací z „teXového světa“ do „světa Lua“: poskytuje způsob, jak jazyk TeX komunikuje data jazyku Lua. Například kód TeXu jako `\number\count75` lze použít k přenosu hodnoty z „teXového světa“ uložené v počítacím registru 75 do celočíselné proměnné x ve „světě Lua“:

```
\count75=1564 % Data existující v „TeXovém světě“
\directlua{
   local x=\number\count75 \space % Přenos dat TeXu do „světa Lua“
   tex.print("x= "..x)
   local y = (2*x-65)/5
   tex.print(" a y = "..y)
}
```

Tím vznikne kód Lua

```
 local x=1564 tex.print("x= "..x) local y = (2*x-65)/5 tex.print(" a y = "..y)
```

**Poznámka**: Přidali jsme `<space>\space` za `\number\count75` aby se zachovala znak mezery mezi `1564` a `tex.print`— zde to není striktně nutné, protože Lua by kód stále správně analyzovala, i kdybychom jej vynechali. Znak mezery následující bezprostředně po `\count75` je pohlcen během procesu, který TeXové enginy používají k vyhledávání číselných hodnot — zde jde o hodnotu předávanou do `\count`. Znak mezery za `75` se používá k ukončení hledání posloupnosti číslic v LuaTeXu `75` a je absorbován ze vstupu. Makro `\space` se rozšiřuje tak, aby poskytlo znak mezery potřebný k oddělení textu `1564` a `tex.print`.

Pomocí výše uvedeného kódu LuaTeX vysází

`x= 1564 and y = 612.6`

Zde je mechanismus „předávání dat“ realizován pomocí `\number`: rozšiřitelného příkazu, který v tomto případě nařizuje TeXu načíst hodnotu uloženou v `\count` registru `75` a z této hodnoty (`1546`) vygenerovat řadu znakových tokenů, jeden znakový token pro každou číslici, což vede k sekvenci tokenů pro číslice `1`, `5`, `6` a `4`. Tyto 4 znakové tokeny jsou začleněny do hlavního seznamu tokenů vytvářeného funkcí `\directlua` a následně převedeny zpět do své textové reprezentace, když je seznam tokenů převeden na text. Nepochybně je to velmi okliková cesta od `\count75` hodnoty registru uložené uvnitř LuaTeXu k číslicím určeným pro kód Lua, ale nakonec to funguje.

**TIP:** Pokud si chcete prohlédnout výsledky expanzních činností LuaTeXu, můžete napsat kód jako tento:

```
\directlua{
   local foo=[[local x=\number\count75
   tex.print("x= "..x)
   local y = (2*x-65)/5
   tex.print(" a y = "..y)]]
   print(foo)
}
```

V tomto příkladu používáme metodu dlouhých závorek k vytvoření řetězcové proměnné `foo` jejímž účelem je uchovat řetězec kódu Lua vzniklý expanzí všeho mezi `[[` a `]]`. Tento řetězec se vypíše do konzole pomocí volání funkce Lua `print(foo)`.

Na Overleafu můžete zobrazit podobné výsledky tak, že zapíšete obsah `foo` do `.log` souboru pomocí funkce Lua LuaTeXu `texio.write()`:

```
\directlua{
   local foo=[[local x=\number\count75
   tex.print("x= "..x)
   local y = (2*x-65)/5
   tex.print(" a y = "..y)]]
   texio.write(foo)
}
```

## Tokeny v tokenovém seznamu \directlua: nerozšiřitelné tokeny a nerozbalené tokeny

Poznamenali jsme, že `\directlua{⟨code⟩}` provádí *plnou expanzi* vašeho `⟨code⟩`: odstraňuje a rozšiřuje všechny rozšiřitelné příkazy, dokud nezůstanou jen nerozšiřitelné tokeny. Posloupnost tokenů vytvořená `\directlua`při zpracování (ve funkci `scan_toks()` ) se spojí do jednoho tokenového seznamu, jehož jednotlivé tokeny budou převedeny zpět na text pro předání do Lua.

Neřešili jsme však ještě závěrečnou část tohoto příběhu, protože musíme zvážit dvě „třídy“ příkazových tokenů, které se mohou dostat do tokenového seznamu vytvářeného v rámci `\directlua`: budeme jim říkat *zkrácené příkazové tokeny* a *nerozbalené* tokeny:

* **zkrácené příkazové tokeny**: Tento typ příkazového tokenu vzniká z řídicích sekvencí definovaných pomocí jednoho z TeXových primitiv `\chardef`, `\mathchardef`, `\countdef`, `\dimendef`, `\skipdef`, `\muskipdef` a `\toksdef`. Tyto primitivní příkazy se používají k definování řídicích sekvencí, které reprezentují číselnou hodnotu — výsledné řídicí sekvence jsou *ne* nerozšiřitelné.
* **nerozbalené tokeny**: Tento typ tokenu vzniká z příkazů, které by se normálně rozšířily, ale `\directlua` byl buď:
* výslovně instruován *ne* je rozšiřovat; například potlačení expanze pomocí příkazů `\noexpand` nebo `\unexpanded`— brzy vysvětlíme, jak se to dělá;
* vkládání tokenů zpracováním sekvence `\the\toks` (více o tom níže).

### Dvě „skupiny“ tokenů v tokenovém seznamu \directlua

Na základě našich diskusí můžeme říci, že tokeny obsažené v tokenovém seznamu vytvářeném během první fáze `\directlua`předzpracování v LuaTeXu (ve funkci `scan_toks()` ) spadají do dvou skupin:

1. *vnitřně nerozšiřitelné* tokeny

* jakýkoli token reprezentující neaktivní *znaku*;
* jakýkoli token reprezentující nerozšiřitelný *primitiv* *příkaz*;
* jakýkoli token reprezentující *zkrácený příkaz* (ty nejsou rozšiřitelné, viz níže).

3. *nerozbalené* tokeny:

* jakýkoli token reprezentující rozšiřitelný příkaz, jehož expanze byla *potlačena* (nebo se jí zabránilo) během `\directlua`předzpracování v LuaTeXu.

#### Zkrácené příkazové tokeny: vytváření nerozšiřitelných příkazů

Jak bylo uvedeno, TeXové enginy poskytují sadu primitiv (vestavěných příkazů), které lze použít ke konstrukci *nerozšiřitelných* řídicích sekvencí (zde označených jako `⟨příkaz⟩`). Tato primitiva mají tvar:

* `\chardef ⟨příkaz⟩ = ⟨číselná hodnota⟩`
* `\mathchardef ⟨příkaz⟩ = ⟨číselná hodnota⟩`
* `\countdef ⟨příkaz⟩ = ⟨číselná hodnota⟩`
* `\dimendef ⟨příkaz⟩ = ⟨číselná hodnota⟩`
* `\skipdef ⟨příkaz⟩ = ⟨číselná hodnota⟩`
* `\muskipdef ⟨příkaz⟩ = ⟨číselná hodnota⟩`
* `\toksdef ⟨příkaz⟩ = ⟨číselná hodnota⟩`

kde `⟨číselná hodnota⟩` je nějaká celočíselná hodnota vhodná pro každý příkaz.

Zde si stručně ukážeme použití `\chardef` abychom demonstrovali klíčovou vlastnost těchto primitiv — vytvoření `⟨příkaz⟩` který je nerozšiřitelný. Můžete použít ``\chardef\mydollar=`\$`` k vytvoření řídicí sekvence `\mydollar` a použít ji k vysázení `$`:

`Zaplaceno \mydollar30.`

Tím se vysází `Zaplaceno $30.` Řídicí sekvence `\mydollar` vytvořená pomocí `\chardef` není rozšiřitelná, jak vidíme z následujícího příkladu:

```
\chardef\mydollar=`\$
\directlua{
   local x =[[Zaplaceno \mydollar30.]]
   texio.write(x)
}
```

Což vyprodukuje následující text v souboru `.log` souboru

`Zaplaceno \mydollar 30.`

To ukazuje `\mydollar` byla *ne* rozšířena během `\directlua`předzpracování v LuaTeXu. Mezera objevující se za `\mydollar` se přidává, když je příkazový token převeden na svou reprezentaci jako text.

Když použijete `\chardef` k vytvoření řídicí sekvence, vnitřní klasifikace této řídicí sekvence (příkazu) v TeXu vede k tomu, že je *nerozšiřitelných* což je velmi odlišné chování ve srovnání s řídicími sekvencemi definovanými jedním z příkazů pro definici maker: \def, \edef, \gdef nebo \xdef. Jak bylo uvedeno výše, během procesu vytváření svého tokenového seznamu `\directlua` zkoumá každý příchozí příkazový token, aby zjistil rozšiřitelnost. Pokud příkazový token není rozšiřitelný, projde přímo do seznamu tokenů a jeho textová reprezentace se později znovu objeví v řetězci kódu Lua vzniklém převodem tokenů v seznamu tokenů zpět do jejich textové podoby.

**Krátké poznámky o plain TeXu vs. LaTeXu**

Historicky Knuthův původní plain TeX definoval běžně používané řídicí symboly `\%`, `\&`, `\#` a `\$` pomocí `\chardef`— nikoli pomocí jednoho ze standardních příkazů pro definici maker `\def`, `\edef`, `\gdef` nebo `\xdef`. Například:

```
   \chardef\#=`\#
   \chardef\$=`\$
   \chardef\%=`\%
   \chardef\&=`\&
```

Podivná `` `\ `` syntaxe je metoda TeXu, jak získat číselnou hodnotu znakového kódu. Ve starém plain TeX režimu nejsou tyto řídicí symboly rozšiřitelné (kvůli `\chardef`) ale LaTeX (nebo balíčky) je může redefinovat jako *makra* aby poskytly rozšířenou funkcionalitu — to by z nich udělalo rozšiřitelné, takže je dobré o tom vědět.

**Jak to ovlivňuje \directlua?**

Porovnejme výsledek následujícího kódu spuštěného v plain TeXu a v LaTeXu. Pro jednoduchost budeme výsledky zapisovat do souboru `.log` pomocí funkce LuaTeXu v Lua API `texio.write()`.

```
\directlua{
   local x=[[\$150 for the "\#1" product---20\%! more than its competitor, Widget \& Co.]]
   texio.write(x)
}
```

Spuštěním tohoto kódu pomocí **plain TeX** vznikne následující výstup v souboru `.log` , který ukazuje výsledek jakýchkoli expanzí:

```
\$150 for the "\#1" product---20\%! more than its competitor, Widget \& Co.
```

Je zřejmé, že v plain TeXu se žádný z řídicích symbolů`\$`, `\#`, `\%` nebo `\&` nerozšířil — protože všechny jsou vytvořeny pomocí `\chardef`.

Spuštěním tohoto kódu v **LaTeX** dokumentu:

```
\documentclass{article}
\begin{document}
   \directlua{local x=[[\$150 for the "\#1" product---20\%! more than its competitor, Widget \& Co.]] texio.write(x)}
\end{document}
```

vznikne následující výstup v souboru `.log` souboru

```
\protect \TU\textdollar 150 for the "\#1" product---20\%! more than its competitor, Widget \& Co.
```

Je zřejmé, že spuštění LaTeXu vytvoří výsledek odlišný od plain TeXu, protože v LaTeXu byl příkaz `\$` rozšířen, což ukazuje, že jde o makro.

**Poznámka:** V plain TeXu i v LaTeXu `\directlua` nebyly žádné z řídicích symbolů plně zpracovány `\%`, `\&`, `\#` a `\$` tak, aby vygenerovaly odpovídající znak. Během procesu expanze prováděného `\directlua` tokeny reprezentující tyto řídicí symboly — nebo u LaTeXu jejich expanze — projdou přímo do hlavního seznamu tokenů, který se vytváří.

**Poznámka:** Řídicí symboly jsou tvořeny jedním znakem, který nemá kategoriový kód 11, například `\#`. Když se token reprezentující řídicí symbol převádí zpět do své textové reprezentace, TeXové enginy za tento text nevkládají znak mezery. Toto zvláštní zacházení s řídicími symboly je vestavěné pravidlo fungování TeXových enginů.

### Nerozbalené tokeny: potlačování expanze

`\directlua`’s předzpracování je jeden z příkladů, kdy TeXový engine provádí expanzi, ale možná budete chtít *zabránit* tomu, aby byla expanze použita na jeden nebo více tokenů, které by jinak byly rozšířeny. Jako další příklad, LuaTeX (a všechny TeXové enginy) provádějí proces expanze, podobný tomu u `\directlua`, když zpracovávají `\write` příkazu:

`\write file-number {⟨material⟩}`

\write dává TeXovému enginu pokyn vypsat `⟨material⟩`—často obsahující příkazy TeX/LaTeX—do textového souboru (`file-number`); všechny rozšiřitelné příkazy uvnitř `⟨material⟩` budou, pokud tomu nebude zabráněno, rozšířeny předtím, než `⟨material⟩` budou skutečně zapsány do tohoto souboru.

Jak byste očekávali, TeXové enginy poskytují příkazy k potlačení nebo řízení expanze:

* `\noexpand⟨token⟩`: brání expanzi jediného `⟨token⟩`;
* `\unexpanded{⟨material⟩}`: brání expanzi všech rozšiřitelných příkazů (tokenů) v `⟨material⟩`. Ve skutečnosti je to vícetokenová verze `\noexpand`;
* `\protected`: prefix přidávaný k definicím maker, který brání expanzi tohoto makra za určitých okolností (například během `\directlua`, `\write` nebo `\edef`).

Navzdory názvům, které naznačují opak, oba `\noexpand` a `\unexpanded` jste *rozšiřitelné příkazy* a poskytují dobré příklady toho, jak lze na expanzní proces TeXového enginu nahlížet jako na provádění „operací s tokeny“: zde jde o operaci, která zabrání expanzi jednoho nebo více následujících tokenů (příkazů). Protože `\noexpand` a `\unexpanded` jsou oba rozšiřitelné příkazy, jsou během `\directlua`’s předzpracování, když sestavuje seznam tokenů z vašeho `⟨code⟩`.

#### \noexpand ⟨token⟩

`\noexpand ⟨token⟩` brání expanzi jediného `⟨token⟩`. `\noexpand` uvnitř `\directlua` bude rozšířen (odstraněn z vstupu) a nahrazen výsledky svého „expanzního chování“. Výsledkem rozšíření `\noexpand` je vytvoření speciálního (skrytého) `⟨marker token⟩` který je vložen před původní `⟨token⟩` jehož expanze má být potlačena: ten `⟨marker token⟩` funguje jako příznak říkající „nerozšiřuj následující token“. Protože `\directlua` provádí plnou expanzi, znovu zpracuje všechny tokeny, které vzniknou z „expanzního chování“ rozšiřitelného příkazu. Proto, když expanze `\noexpand ⟨token⟩` je dokončena, LuaTeX se vrátí, aby přečetl výsledky, a uvidí dvoutokenovou sekvenci `⟨marker token⟩⟨token⟩` což způsobí, že původní `⟨token⟩` projde nerozšířený do seznamu tokenů, který sestavuje `\directlua`.

**Příklad**

Pokud napíšeme

```
\directlua{
   local x= "\TeX"
}
```

webových stránkách `\TeX` makro je rozšířeno na své složkové tokeny, což v plain TeXu povede k tomu, že se následující text předá Lua (pozn.: Lua tento kód nemůže zpracovat, je to jen příklad demonstrující postup):

`local x = "T\kern -.1667em\lower .5ex\hbox {E}\kern -.125emX"`

Pokud *potlačíme* expanzi `\TeX` makra pomocí `\noexpand`

`\directlua{local x= "\noexpand\TeX"}`

se vygeneruje následující Lua kód (opět, Lua tento kód nemůže spustit; jde pouze o příklad demonstrující `\noexpand`):

`local x= "\TeX "`

Díky `\noexpand`, `\directlua` nebude rozšířen `\TeX` a jednoduše umožní tokenové hodnotě reprezentující `\TeX` příkaz projít neporušeně do seznamu tokenů vytvářeného během první fáze `\directlua`předzpracování v LuaTeXu.

**Poznámka:** Mezera, která se objeví za `\TeX` je zavedena následnou konverzí LuaTeXu z `\TeX` číselné hodnoty tokenu zpět na její textovou reprezentaci (v rámci `tokenlist_to_cstring()` funkce).

#### \unexpanded{⟨material⟩}

`\unexpanded` je rozšiřitelný příkaz, který potlačuje expanzi všech tokenů vytvořených z `⟨material⟩`. Jak jsme poznamenali, když TeXový engine provádí expanzi, jakýkoli rozšiřitelný příkaz je *odstraněn* ze vstupu a *nahrazen* výsledky jeho „expanzního chování“; co to tedy vlastně znamená pro `\unexpanded`? Obvykle během *plnou expanzi*, jakmile je proces expanze pro určitý příkaz dokončen, TeXový engine pokračuje ve čtení/zpracování všech tokenů vzniklých z „expanzního chování“ tohoto příkazu — musí dále rozšířit všechny tokeny, které byly vytvořeny. Nicméně, `\unexpanded` *obchází* jakékoli další rozšíření: takto to dělá.

Uvnitř TeXového enginu `\unexpanded` příkaz nejprve převede znaky a příkazy v `⟨material⟩` na dočasný seznam tokenů složený z *nerozbalené* tokenů. Poté, co jsou všechny tokeny vytvořeny a uloženy v tomto dočasném seznamu tokenů, příkaz `\unexpanded` způsobí, že `\directlua` na *přeskočí* návrat k jejich čtení a zpracování — i když \directlua provádí plnou expanzi. Místo toho tyto *nerozbalené* tokeny projdou přímo skrz a stanou se součástí hlavního seznamu tokenů vytvářeného `\directlua` (v `scan_toks()` funkci). Tímto způsobem je vše v `⟨material⟩` převedeno na tokeny a pro tuto sadu tokenů je proces expanze přeskočen. Chování `\unexpanded{⟨material⟩}` je podobné použití `\the\toks`, o kterém pojednáme níže.

**Příklad**

`\unexpanded` vytváří výsledky podobným způsobem jako `\noexpand` s výjimkou toho, že může zabránit expanzi více tokenů; zde je příklad:

```
\directlua{
   local x = "\unexpanded{\foo\bar\foobar}. But Lua can't process this code!"
}
```

což vytvoří následující text jako kód pro Lua:

`local x = "\foo \bar \foobar . But Lua can't process this code!"`

**Poznámka**: Za každým názvem příkazu jsou mezery. I ty jsou opět důsledkem následné konverze nerozšířených tokenů `\foo`, `\bar` a `\foobar` zpět na text ve `tokenlist_to_cstring()` funkci.

#### definice maker \protected

Ta `\protected` příkaz je prefix aplikovaný na definici makra, aby zabránil rozšíření tohoto makra, když TeX vytváří rozšířený seznam tokenů, například seznam tokenů vytvořený pomocí `\directlua`předzpracování v LuaTeXu.

**Příklad**

Předpokládejme, že definujete následující makra s použitím i bez použití `\protected` prefixu:

```
\def\macroA{"This unprotected macro contains a string"}
\protected\def\macroB{"This protected macro also contains a string"}
```

Pokud použijete operátor spojování řetězců v Lua (`..`) k zápisu

```
\directlua{
   local x=\macroA..\macroB
}
```

`\directlua`’s předzpracování by pro předání Lua vytvořilo následující kód:

`local x="This unprotected macro contains a string"..\macroB`

`\macroA` není definováno pomocí `\protected` takže je rozšířeno a vytváří první část řetězce ke spojení, ale `\macroB` je definováno pomocí `\protected` takže nebylo rozšířeno.

Během předzpracování LuaTeXu `scan_toks()` funkce vytvořila token pro `\macroA`, rozpoznala, že jde o běžný rozšiřitelný příkaz, a rozšířila ho: toto rozšíření vytváří sekvenci znakových tokenů, jeden znakový token pro každý znak v `"This unprotected macro contains a string"`. Každý znakový token je předán dál a přidán do vytvářeného seznamu tokenů.

Když `scan_toks()` vytvoří token pro `\macroB` všimne si, že tento příkaz byl definován jako `\protected` a nerozšiřuje ho: token reprezentující `\macroB` projde bez zásahu (nerozšířený) do vytvářeného seznamu tokenů. Poté, co je tento seznam tokenů vytvořen, další fáze předzpracování, v rámci `tokenlist_to_cstring()` funkce, převádí všechny tokeny v seznamu tokenů zpět na jejich textovou reprezentaci. Nerozšířený token reprezentující `\macroB` je detekován a převeden na svou textovou reprezentaci, čímž vznikne text `\macroB` objevující se v kódu určeném pro Lua. Upozorňujeme, že Lua ve skutečnosti nemůže spojit `"This unprotected macro contains a string"..\macroB` a vytvořit konečný řetězec, protože `\macroB` nemá v syntaxi Lua žádný význam, což vede k chybě `neočekávaný symbol poblíž '\\'`.

**Zajímavost**: Ten `\protected` příkaz byl zaveden $$\varepsilon\text{-}\mathrm{\TeX}$$první významné rozšíření původního Knuthova softwaru TeX, a je podporován všemi TeXovými enginy, jejichž původ kódu zahrnuje $$\varepsilon\text{-}\mathrm{\TeX}$$.

### Nerozšířené tokeny: Použití \the\toks v \directlua

Život v programování by nebyl stejný bez těchto „speciálních případů“, které je třeba řešit, a použití `\the` v kombinaci s `\toks` v `\directlua` příkaz je jedním z takových speciálních případů.

#### Stručné pozadí o \toks

Primitiva TeXu `\toks` dává TeXovému enginu pokyn uložit některé tokeny pro pozdější použití: místo toho, aby byly předány k dalšímu zpracování, jsou tyto tokeny odloženy stranou a uloženy do paměťového umístění určeného pomocí *tokenového registru*. Například můžeme TeXovému enginu říct, aby vytvořil nějaké tokeny a uložil je do umístění tokenového registru `100` pomocí

`\toks100={Hi, \TeX! \hskip 5bp}`

Zde TeX používá tokenový registr `100` k přístupu k známému umístění ve své paměti: úložnému prostoru určenému pro uchovávání seznamů tokenů.

Tokeny reprezentující vše mezi `{` a `}` jsou vytvořeny, *ale nejsou rozšířeny*, a spojeny do seznamu tokenů — podobně jako seznam tokenů, který jsme zkoumali dříve v tomto článku. Abychom tyto tokeny znovu použili, napsali bychom `\the\toks100` v němž `\the` (rozšiřitelný příkaz) dává TeXu pokyn načíst uložené tokeny a vložit je na místo, kde jste napsali `\the\toks100`. Jiný způsob, jak o tom přemýšlet, je `\the\toks` způsobí, že TeX na dané místo vloží nějaké tokeny.

Ta `\toks` příkaz *nerozšiřuje* žádný z tokenů, které má vytvořit a uložit: jednoduše převádí znaky a příkazy mezi `{` a `}` na tokeny a ukládá je.

#### Zpět k \directlua

V diskusi o expanzi jsme poznamenali `\directlua{⟨code⟩}` provádí *plnou expanzi* pro `⟨code⟩`: odstranit všechny rozšiřitelné příkazy a nahradit je výsledkem jejich expanzního chování — pokračovat v *dalším rozšiřování* všech tokenů vzniklých z počáteční expanze rozšiřitelného příkazu.

`\the` je rozšiřitelný příkaz, takže `\directlua` ho rozšíří; nicméně když `\the` je použito v kombinaci s `\toks` uvnitř `\directlua`, jako v `\the\toks⟨token register⟩`, jsou vložené tokeny *dále nerozšiřovány*. Expanze `\the\toks⟨token register⟩` vloží sekvenci *nerozbalené* tokenů uložených v `⟨token register⟩`, přímo do seznamu tokenů vytvářeného `\directlua`: toto chování obchází obvyklý proces plné expanze. Ve skutečnosti tyto tokeny procházejí, *nerozbalené*přímo skrz a stanou se součástí hlavního seznamu tokenů vytvářeného `\directlua`—tento průchod nerozšířených tokenů je svou funkcí podobný `\unexpanded`, jak bylo uvedeno dříve.

**Příklad**

Předpokládejme, že definujeme makro `\mymacro` zapíšeme jako `\def\mymacro{\TeX}`. Obsahuje jen jeden token pro `\TeX` příkaz (což je makro): máme tedy rozšiřitelný příkaz `\mymacro` který obsahuje další makro `\TeX`, které je také rozšiřitelné.

Následující kód způsobí, že se Lua pokusí vytvořit řetězcovou proměnnou `x`:

```
\def\mymacro{\TeX}
\directlua{
   local x="\mymacro"
}
```

Uvnitř \\`directlua`, je token pro `\mymacro` rozšířen, ale to vede k dalšímu rozšiřitelnému tokenu, `\TeX`který je dále rozšířen. V plain TeXu tato rozšíření vedou k následujícímu textu předanému Lua:

`local x = "T\kern -.1667em\lower .5ex\hbox {E}\kern -.125emX"`

Tento kód se pokouší definovat řetězec, který obsahuje text reprezentující rozšířenou verzi `\TeX` makra. Pokud se pokusíte tento příklad spustit, Lua se pokusí tento řetězec sestavit, ale selže a vygeneruje chybu:

`neplatná úniková sekvence poblíž ' "T\k'.`

Později v tomto článku prozkoumáme význam „neplatná úniková sekvence“.

Porovnejme nyní použití `\mymacro` s umístěním `\TeX` tokenu do seznamu tokenů vygenerovaného pomocí `\toks` příkazu:

```
\toks100={\TeX}
\directlua{
   local x="\the\toks100"
}
```

LuaTeXu `\directlua` zpracování vygeneruje pro Lua tento textový řetězec:

`local x = "\TeX "`

Znak mezery za `\TeX` je generován procesem převodu příkazu-tokenu na řetězec v LuaTeXu.

**Ale všimněte si,**: Ten `\TeX` makro bylo *ne* rozšířeno na své složkové tokeny. `\the\toks100` způsobilo vložení tokenů uložených v registru 100, ale to je vše: nejsou *ne* dále rozšiřovány a stávají se součástí hlavního seznamu tokenů vytvářeného `\directlua` (uvnitř funkce `scan_toks()`). Vkládání tokenů do seznamu tokenů vytvořeného pomocí `\toks` je dalším způsobem, jak zabránit rozšiřování tokenů.

Když tento příklad spustíme, také vyvolá chybu:

`neplatná úniková sekvence poblíž ' "\T'.`

Únikové sekvence Lua prozkoumáme později v článku.

## Další příkazy/techniky používané při expanzi

V této části se podíváme na některé další TeXové příkazy/metody, které mohou být užitečné v situacích, kdy se používá expanze (například uvnitř `\directlua`).

### \string ⟨token⟩

`\string` je rozšiřitelný příkaz, který převádí ⟨token⟩ na řadu znakových tokenů, z nichž každý má kód kategorie 12.

Například, `\string\TeX` by vytvořil řadu 4 znakových tokenů `\`, `T`, `e` a `X` kde je každému znaku přiřazen kód kategorie 12 (včetně úvodního `\` znaku).

Pokud napíšeme

```
\directlua{
   local x="I will use \string\newcommand"
   print(x)
}
```

webových stránkách `\string` příkaz bude rozšířen, což povede k sekvenci znakových tokenů s kódem kategorie 12. Po `\string` je rozšířen, budou výsledné znakové tokeny (reprezentující každý znak v `\newcommand`) začleněny do hlavního seznamu tokenů vytvářeného `\directlua`. Jakmile `\directlua` dokončí sestavování svého hlavního seznamu tokenů, jeho jednotlivé tokeny jsou převedeny zpět na textovou reprezentaci, což vytvoří následující kód k předání interpreteru Lua:

`local x="I will use \newcommand" print(x)`

Když je tento kód předán Luě, `print(x)` vypíše řetězec `x` na obrazovku (konsoli). Avšak byli jsme trochu zákeřní a záměrně použili ukázkový příkaz začínající na `\n`. Pokud můžete tento příklad spustit na lokální instalaci TeXu, všimnete si, že Lua vypíše na obrazovku následující text:

```
   Budu používat
   ewcommand
```

Chcete-li tento kód spustit na Overleafu, můžete LuaTeXu nařídit, aby zapisoval přímo do `.log` pomocí funkce LuaTeXu v Lua API `texio.write(*string*)`:

```
\directlua{
   local x="I will use \string\newcommand"
   texio.write(x)
}
```

Pokud si prohlédnete výsledný `.log` soubor, uvidíte, že také obsahuje

```
   Budu používat
   ewcommand
```

Tento neočekávaný výstup je způsoben tím, že Lua interpretuje `\n` na začátku `**\n**ewcommand` jako únikovou sekvenci pro znak odřádkování (kód znaku 10): předpokládá, že chcete začít nový řádek textu, který začíná `ewcommand`na . Únikové sekvence Lua probíráme později v tomto článku.

### \detokenize{⟨material⟩}

`\detokenize` je svými účinky vícetokenovou verzí `\string` a je také rozšiřitelný příkaz, který převádí vše v `⟨material⟩` na sekvenci znakových tokenů s kódem kategorie 12—*s tím rozdílem, že* znaky mezery (hodnota ASCII/Unicode 32), které získají kód kategorie 10. `\detokenize` také vkládá koncový znak mezery za názvy příkazů, které jsou *kontrolní slova* (např., `\foo`) ale za *kontrolní symboly* (např., `\#`, `\%` atd.) se žádný znak mezery nevkládá.

### Příklad

I když makra `\foohoo`, `\foo`, `\bar` a `\foobar` nejsou definována, pokud napíšete toto:

```
\directlua{
   local x = "\string\foohoo\detokenize{\foo\bar\foobar}"
}
```

vytvořilo by to následující text jako kód pro předání interpreteru Lua

`local x = "\foohoo\foo \bar \foobar "`

Pokud nepoužijete `\string` a `\detokenize` a napíšete:

`\directlua{local x = "\foohoo\foo\bar\foobar"}`

`\directlua` by zpracoval `\foohoo`, rozpoznal by, že jde o příkaz, a pokusil by se ho rozšířit; ale protože `\foohoo` není definován, vedlo by to k chybě:

```
   ! Nedefinovaná řídicí sekvence.
   l.1 \directlua{local x = "\foohoo
                      \foo\bar\foobar"}
         ?
```

Protože `\string` a `\detokenize` převádějí své argumenty na řadu znakových tokenů, `\directlua`’s expanzní proces dostane příležitost detekovat tokeny rozšiřitelných příkazů `\foohoo`, `\foo`, `\bar`, nebo `\foobar`jsou totiž převedeny na sekvence znakových tokenů mnohem dříve, než mohou vyvolat expanzi.

Jak již bylo uvedeno, expanze příkazu zahrnuje jeho odstranění ze vstupu a nahrazení výsledkem jeho „expanzního chování“. Výsledky expanze (obvykle tokeny) jsou následně čteny TeXovým enginem. Zde je „expanzní chování“ pro `\string` a `\detokenize` je absorbovat znakové a příkazové tokeny ze vstupu a převádět je na sekvence znakových tokenů, které jsou zpočátku uloženy v dočasném seznamu tokenů, který `\directlua` následně čte. Tyto znakové tokeny se stanou součástí hlavního seznamu tokenů vytvářeného `\directlua`.

Následující obrázek znázorňuje, jak `\string` převádí `\foohoo` příkaz na sekvenci znakových tokenů, čímž vytváří dočasný seznam tokenů, který je následně čten `\directlua` za účelem začlenění těchto znakových tokenů do vytvářeného hlavního seznamu tokenů.

![](/files/cb903425fb8d809e3bf3267501e139290f6c9483)

Pokud `\string` nebo `\detokenize` setkají se ve svém argumentu se znaky, např., `\string a` nebo `\detokenize{abc}` tyto znaky (zde s kódem kategorie 11) vytvářejí znakové tokeny, ale s kódem kategorie 12.

Poznámky:

Vrátíme-li se k výše uvedenému příkladu:

`\directlua{local x = "\string\foohoo\detokenize{\foo\bar\foobar}"}`

což vytvoří následující text jako kód k předání interpreteru Lua

`local x = "\foohoo\foo \bar \foobar "`

můžeme pozorovat následující:

* `\detokenize` vložilo znak mezery za každý název makra, ale `\string` ne.
* `\string` působí na jediný token.
* V řetězci `"\foohoo\foo \bar \foobar "` použitém k definování `x` znovu narazíme na mechanismus únikových znaků v Lua (probíraný níže):

  * `\bar` začíná na `\b` což je úniková sekvence Lua používaná k reprezentaci [znaku backspace](https://en.wikipedia.org/wiki/Backspace) (kód znaku 8);
  * příkazy `\foohoo`, `\foo` a `\foobar` všechno začíná na `\f`úniková sekvence Lua používaná k reprezentaci [znaku posunu formuláře](https://en.wikipedia.org/wiki/Page_break#Form_feed) (kód znaku 12).

  Protože znakové sekvence `\b` a `\f` používají se uvnitř řetězce vytvořeného pomocí dvojitých uvozovek `"..."` budou vytvářet nežádoucí výsledky, pokud nebudou učiněny kroky k tomu, aby se tomu zabránilo pomocí tzv. Lua *dlouhých závorek* metody řetězce: téma, o němž nyní můžeme hovořit spolu s Lua únikovými sekvencemi.

## Co jsou „Lua únikové sekvence“?

Programovací jazyky vyhrazují určité znaky pro „speciální použití“ jako součást syntaxe jazyka: ve skutečnosti jsou tyto znaky definovány tak, že mají nějaký zvláštní význam. Někdy však potřebujete dočasně „vypnout“ zvláštní význam takového znaku, například když chcete, aby byl tento znak vložen jako součást delšího řetězce, kde by jeho standardní chování zavedlo syntaktické chyby. V podstatě je třeba, aby byl tento znak zpracován *bez* spouštějíc jeho standardní interpretaci — aby proklouzl bez povšimnutí. K tomu programátoři používají techniku zvanou *escapování* v níž je „speciální znak“ reprezentován tzv. svým *únikovou sekvencí*.

Standardním příkladem (podporovaným i Lua) je použití dvojitých uvozovek uvnitř řetězce, kde vnitřní dvojité uvozovky escapujete pomocí únikové sekvence `\"`:

`"Když se jich zeptali na LuaTeX, odpověděli: \"Je to úžasný TeXový engine!\" Souhlasil jsem."`

Jazyk Lua poskytuje řadu mechanismů pro práci s únikovými sekvencemi:

* standardní sekvence včetně `\n` (nový řádek), `\r` (návrat vozíku), `\\` (zpětné lomítko), `\"` (dvojité uvozovky), `\t` (horizontální tabulátor), `\v` (vertikální tabulátor) a `\'` (jednoduché uvozovky);
* `\xXX`, kde `XX` je sekvence přesně dvou hexadecimálních číslic;
* `\ddd`, kde `ddd` je sekvence až tří desítkových číslic;
* v době, kdy byl tento článek napsán (srpen 2019), nejnovější verze LuaTeXu, ačkoli ještě nebyla na Overleafu k dispozici, používá verzi 5.3 jazyka Lua, která zavedla podporu únikových sekvencí UTF-8: `\u{XXX}`. Tento mechanismus escapování je určen pro znaky Unicode kódované UTF-8, kde `XXX` je sekvence jedné nebo více hexadecimálních číslic představujících kódový bod znaku. Všimněte si, že uzavírací závorky `{ }` jsou povinné.

### Ovládání únikových sekvencí

Tradičně jsou řetězce definovány pomocí dvojitých uvozovek, jako v `"tohle je řetězec"`; uvnitř takového řetězce můžete použít únikové sekvence: `"tohle je řetězec.\nTeď začnu na novém řádku."`. Lua však má druhý a *velmi* pohodlný mechanismus pro definování řetězců: tzv. jeho *dlouhé závorky* mechanismus, v němž definujete řetězec tak, že text uzavřete do `[[` a `]]`:

`[[Jsem řetězec v dlouhých závorkách]]`

Uvnitř řetězce vytvořeného metodou dlouhých závorek je znakový mechanismus escapování jazyka Lua *vypnut*: únikové sekvence jsou považovány za běžné znaky. Například v řetězci

`[[Jsem řetězec v dlouhých závorkách\n string]]`

webových stránkách `\n` není úniková sekvence považována za jediný znak návratu vozíku (ASCII kód 13), ale za dva běžné znaky: `\` následující po `n`.

### Proč jsou řetězce v dlouhých závorkách tak užitečné?

Jak později uvidíme, LuaTeX poskytuje sadu specializovaných vestavěných funkcí jazyka Lua, které můžete použít s `\directlua` k řízení sazbového chování LuaTeXu. Mezi těmito mnoha funkcemi je jedna s názvem `tex.print(*string*)` která umožňuje předat `*string*` materiál z kódu Lua zpět do LuaTeXu k vysázení. Velmi jednoduchý příklad je:

`\directlua{tex.print("Hello, World!")}`

což způsobí, že LuaTeX vysází `Hello, World!`

Ta `*string*` použité v `tex.print(*string*)` může také obsahovat text představující příkazy TeXu a LaTeXu, které má LuaTeX zpracovat. Příkazy TeX/LaTeX však začínají `\` znakem, což je problematické u řetězců vytvořených pomocí dvojitých uvozovek, protože Lua by se pokusila řetězec analyzovat, detekovala by počáteční `\` znak a vyložila by jej jako začátek únikové sekvence. Když se Lua pokusí únikovou sekvenci zpracovat, obvykle selže, protože počáteční `\` spolu s prvním znakem v mnoha názvech příkazů TeX/LaTeX netvoří platnou únikovou sekvenci známou jazyku Lua. Například při zpracování řetězce jako `"Mám rád \LaTeX"` by Lua viděno jako `\L` a skončilo by to chybou „neplatná úniková sekvence“, a to je příčina výše zmíněných chyb.

#### Na pomoc přicházejí řetězce v dlouhých závorkách!

Metoda vytváření (definování) řetězců pomocí dlouhých závorek je nesmírně užitečná, protože i když příkazy TeX/LaTeX začínají `\` znakem, metoda řetězců s dlouhými závorkami deaktivuje (vypíná) mechanismus únikových sekvencí v Lua. Zde je krátký příklad, přičemž pamatujme, že musíme zabránit rozbalování maker pomocí například `\protected` nebo `\noexpand`.

Předpokládejme, že definujeme `\newtest` makro takto

`**\protected**\def\newtest#1{Argument: #1}`

a použijeme jej v `\directlua` spolu s funkcí Lua API LuaTeXu `tex.print()`:

```
\directlua{
   tex.print("\newtest{Hello}")
}
```

V důsledku použití `\protected`, není makro `\newtest` rozbaleno, což vede k následujícímu textu předanému do Lua:

`tex.print("\newtest {Hello}")`

Mezera přidaná za `\newtest` a před otevírací složku (`{`) je vedlejším efektem `\directlua`převodu příkazových tokenů zpět na jejich textovou reprezentaci v

Tento kód je předán do Lua, které následně provede funkci LuaTeXu `tex.print()` ale je tu problém, který se projevuje způsoby závislými na tom, jaká písma používáte. V LaTeXu na Overleafu byste viděli výstup jako tento:

![](/files/73a67389be6740f1fe05748b308e6692ce770623)

spolu s upozorněním v souboru protokolu:

```
   Chybějící znak: Neexistuje žádný
   (U+000A) v písmu [lmroman10-regular]:+tlig;!
```

V plain TeXu byste mohli vidět výstup, který vypadá nějak takto:

![](/files/ea534b9297c1f7fd79c73193aac6a531add38a1b)

V obou případech je `\newtest` makro nevyvoláno a výstup není to, co jsme zamýšleli. Chyba je způsobena mechanismem únikového znaku v Lua: v textu `\newtest {Hello}` název makra začíná `\n` který Lua rozpozná jako únikovou sekvenci pro znak nového řádku, takže jej nahradí `\n` znakem ASCII 10, neboli v hexadecimální soustavě 0A. V chybové zprávě LaTeXu, `U+000A` je způsob, jak reprezentovat hodnotu Unicode pomocí 4 hexadecimálních číslic.

Protože `\n` je převedeno na znak nového řádku, LuaTeX nevidí volání makra, ale místo toho se domnívá, že má vysázet nějaký text, který začíná znakem ASCII s kódem 10:

`⟨ASCII 10⟩ewtest {Hello}`

V závislosti na použitém písmu může, ale nemusí, LuaTeX být schopen vysázet `⟨ASCII 10⟩` znak, ale zbývající text je vypsán beze změny s `{` a `}` považována za skupinu a nevysázena.

Plain TeX dává jiný výsledek, protože výchozí písmo je Computer Modern Roman, které má zvláštní kódování, jež způsobí vysázení velkého Omegi, když je viděn znak s kódem 10.

Abychom těmto problémům zabránili, musíme použít řetězce v dlouhých závorkách, aby se na ně nepoužil Lua mechanismus escapování. Správný výsledek je vytvořen pomocí

`\directlua{tex.print([[\newtest{Hello}]])}`

což vytvoří výsledek zobrazený na následujícím snímku obrazovky:

![](/files/a7557cabc28eded099782c33462501c4242adf2b)

### Rozbalování a neprovádění nerozbalitelných příkazů

Při diskusi o rozbalování jsme poznamenali, že jde o proces, při němž TeXový engine *odstraní* rozbalitelný příkaz (token) z aktuálního vstupu a *nahradí* jej výsledkem/výsledky vytvořenými tímto rozbalitelným příkazem. Protože \directlua provádí *pouze rozbalování* činnosti (za účelem vytvoření seznamu tokenů), *ne* neposouvá zpracování v LuaTeXu dál než sem. Jakmile je rozbalitelný příkaz přečten a plně rozbalen, výsledky tohoto rozbalení — které často zahrnují nerozbalitelné příkazy (tokeny) — budou začleněny do vytvářeného seznamu tokenů, připraveného k převodu zpět na text a předání do Lua.

Zde působí důležitý princip: během *pouze rozbalování* činností určených k vytvoření seznamu tokenů TeXové enginy, včetně LuaTeXu, *neprovádějí* žádné nerozbalitelné primitivní vestavěné příkazy TeXu.

V případě `\directlua{⟨code⟩}`, pokud plně rozbalená verze vašeho `⟨code⟩` produkuje nebo obsahuje nerozbalitelné příkazy TeX/LaTeX, budou *předány do Lua* (zobrazené jako text).

#### Příklad

Zde je příklad, který ukazuje, že nerozbalitelné primitivy nejsou během zpracování pouze rozbalováním (například uvnitř `\directlua`). Předpokládejme, že definujeme makro `\setcountreg` takto:

`\def\setcountreg#1#2{\count#1=#2\relax}`

**Poznámka**: Používáme \relax za parametrem `\relax` za parametrem `#2` aby LuaTeX nepřesáhl při skenování vstupu při hledání číselné hodnoty (argumentu) odpovídající parametru `#2`.

Pokud mimo `\directlua`, později spustíme makro takto

```
   \setcountreg{100}{50}
   Hodnota v číselném registru 100 je \the\count100.
```

vysázelo by

`Hodnota v číselném registru 100 je 50.`

V tomto kontextu by jakýkoli TeXový engine zpracoval makro `\setcountreg`—rozbalil by makro, určil argumenty a pokračoval ve čtení *a prováděl* (vykonával) příkazy obsažené v náhradním textu makra (definici). Výsledkem zde je přiřadit `50` jako hodnotu uloženou v registru `\count100`.

Když však TeXový engine provádí *pouze rozbalování* činnosti, jako je tomu u `\directlua`, *nebude vykonávat* nerozbalitelné příkazy obsažené v definici makra.

Pokud napíšeme

```
\def\setcountreg#1#2{\count#1=#2\relax}
\directlua{
   local x = [[\setcountreg{100}{50}]]
}
```

vygeneruje následující text jako kód pro Lua:

`local x = [[\count 100=50\relax ]]`

Výše vytvořený kód Lua ukazuje, že uvnitř `\directlua` webových stránkách `\setcountreg` bylo rozbaleno, jeho argumenty byly identifikovány a dosazeny do odpovídajícího parametru (`#1` a `#2`) ale nejde to dál: nerozbalitelný primitivní příkaz TeXu `\count` byla *není vykonán* během `\directlua`zpracování rozbalování v

Pokud však výsledný řetězec předáme zpět do LuaTeXu, ten vykoná kód TeXu `x` *zpět do LuaTeXu* prostřednictvím `tex.print(x)` takto

```
\count100=50 % nastaví \count100 na počáteční hodnotu 50
\def\setcountreg#1#2{\count#1=#2\relax}
\directlua{
   local x = [[\setcountreg{100}{250}]]
   tex.print(x)
}
Hodnota uložená v číselném registru 100 je \the\count100.
```

Po `\directlua` skončení bude výstup

`Hodnota uložená v číselném registru 100 je 250.`

což ukazuje, že číselný registr `100` nyní obsahuje hodnotu `250`.

Kód Lua vytvořený z výše uvedeného příkladu je

`local x = [[\count 100=250\relax ]] tex.print(x)`

Tento kód definuje `x` jako řetězec vytvořený metodou dlouhých závorek, která se používá k zabránění chybám způsobeným chybnými únikovými sekvencemi. Kdybychom použili dvojité uvozovky `"..."` k definování x, kombinace znaků `\c` na začátku `\count` by vyvolala chybu: `neplatná úniková sekvence poblíž ' "\c"'`.

Volání Lua API LuaTeXu `tex.print(x)` způsobí, že LuaTeX vykoná sekvenci kódu TeXu `\count 100=250\relax` a `\count100` je přiřazena hodnota `250` jak je vidět z vysázeného výstupu:

`Hodnota uložená v číselném registru 100 je 250.`

#### Pozor: makra a Lua API LuaTeXu

Ve výše uvedeném příkladu jsme viděli, že během `\directlua`předzpracování (rozbalování) v LuaTeXu nebyl vykonán kód `\count 100=250`, který obsahuje `nerozšiřitelných` primitivní příkaz `\count`: abychom tento kód spustili (vykonali), museli jsme *předat jej zpět do LuaTeXu* prostřednictvím `tex.print()`.

`\directlua` je pouze jeden případ, kdy LuaTeX provádí zpracování pouze rozbalováním za účelem vytvoření seznamu tokenů. Existují i další příkazy, které provádějí podobné zpracování rozbalování a generování seznamu tokenů, jako například `\write` a `\edef`: tyto příkazy také během svého zpracování rozbalování nevykonávají nerozbalitelné primitivy. Obecným principem je, že TeXové enginy nevykonávají nerozbalitelné primitivy při vytváření seznamu tokenů během činností pouze rozbalování.

**Přepsání našeho makra tak, aby používalo Lua API LuaTeXu**

Můžeme přepsat `\setcountreg` makro pomocí funkce Lua API LuaTeXu nazvané `tex.setcount()`, čímž se vyhneme příkazům TeXu pro změnu hodnoty uložené v číselném registru `100`:

```
   \def\setcount#1#2{\directlua{tex.setcount(#1,#2)}}
   \count100=50
   číselný registr 100 obsahuje \the\count100\par
   \setcount{100}{250}
   číselný registr 100 nyní obsahuje \the\count100\par
```

Tento kód vysází:

```
číselný registr 100 obsahuje 50
číselný registr 100 nyní obsahuje 250
```

Zde používáme `tex.setcount()`, jednu z mnoha funkcí Lua API LuaTeXu, k tomu, aby *přímý přístup k* vnitřní oblasti úložiště dat LuaTeXu, abychom umístili hodnotu `250` do paměťového místa představujícího číselný registr `100`. Ve skutečnosti jsme *obešli* standardní metody zpracování vstupu TeXového enginu LuaTeXu: čtení vstupu, vytváření tokenů a vykonávání primitivních příkazů TeXu. Existuje však varovný příběh: používáním funkcí Lua API LuaTeXu může činnost zpracování pouze rozbalováním *mít vedlejší efekty*: změny hodnot uložených uvnitř TeXového enginu, které by jinak nebyly možné pomocí čistých příkazů TeXu/LaTeXu.

**Příklad: neočekávané vedlejší efekty**

Zde je příklad, který ukazuje *neočekávané* vedlejší efekty, které mohou vzniknout u maker používajících `\directlua`. Předpokládejme, že napíšeme následující kód:

```
\def\dochange{\directlua{tex.setcount(999,12345)}}
\edef\careful{\dochange}
\the\count999
```

Při spuštění tohoto kódu se vysází `12345`!

Jak je to možné? My jsme přece *výslovně* nezavolali žádný kód ani makra, která by tuto hodnotu vložila do číselného registru `999`. Nebo ano?

Definovali jsme `\dochange` za `\directlua` příkaz, který používá `tex.setcount()` k uložení hodnoty `12345` do číselného registru `999`: v kódu TeXu je to ekvivalent `\count999=12345`. Poté jsme použili standardní primitiv TeXu `\edef` k definování makra `\careful`—právě použití `\edef` spustí tento neočekávaný vedlejší efekt.

`\edef` plně rozbalí svůj argument: zde detekuje rozbalitelné makro `\dochange` a rozbalí jej.  `\dochange` makro používá rozbalitelný příkaz `\directlua` který obsahuje volání Lua API; takže rozbalení `\dochange` vede k rozbalení `\directlua` a to způsobí, `tex.setcount()` že bude zavoláno, což změní hodnotu v číselném registru `999`.

Pokud předefinujeme `\dochange` tak, aby používalo příkazy TeXu:

```
   Předtím: číselný registr 999 obsahuje \the\count999.\par
   \def\dochange{\count999=12345\relax}
   \edef\careful{\dochange}
   Potom: číselný registr 999 obsahuje \the\count999.\par
```

při spuštění tohoto kódu se vysází

```
Předtím: číselný registr 999 obsahuje 0.
Potom: číselný registr 999 obsahuje 0.
```

Je zřejmé, že to nemělo žádný vliv na `\count999`. Když `\edef` definuje `\careful` rozbalí se `\dochange` ale toto rozbalení vytváří pouze nerozbalitelné primitivy TeXu: ty nejsou *není vykonán* ale pouze *uloženy* v seznamu tokenů tvořícím definici `\careful`.

A pro jistotu stejný princip vysvětluje, proč toto vytváří vysázený výstup:

```
\def\dochange{\directlua{tex.print("Hello")}}
\edef\careful{\dochange}
```

## Stručný úvod do Lua API LuaTeXu

Jak jsme viděli, `\directlua` nejen umožňuje psát běžný kód Lua nebo směs kódu Lua a TeX/LaTeX, ale také poskytuje přístup k sadě dalších funkcí Lua (specifických pro LuaTeX), které můžete použít (volat) ke komunikaci s vnitřním fungováním sazebního softwaru LuaTeX nebo k jeho přímému řízení. V tomto článku jsme použili několik funkcí Lua, `tex.print()`, `texio.write()`, `tex.setcount()` a tyto, spolu s *mnoha* dalšími, jsou dokumentovány v [Referenční příručce LuaTeXu](http://www.pragma-ade.com/general/manuals/luatex.pdf) v němž jsou skupiny souvisejících funkcí označovány jako *knihovny*.

Tyto funkce Lua si můžete představit jako Lua API LuaTeXu (**Zkopírovaný**pplikace **P**rogramovací **I**rozhraní), které poskytuje nástroje pro vytváření sofistikovaných sazebních a dokumentově-inženýrských řešení tím, že řídí sazbové chování LuaTeXu pomocí Lua jako řídicího jazyka.

Jak bylo uvedeno, LuaTeX organizuje své API do sady funkcí, které nazývá knihovny: skupiny funkcí, jež jsou propojené svým účelem nebo činností. Každá sada funkcí je navržena tak, aby poskytovala přístup k určitému aspektu vnitřních procesů LuaTeXu, datových struktur, datového úložiště a sazebních algoritmů. Vnitřně je LuaTeX složen z mnoha komponent: softwarových knihoven/nástrojů (většinou napsaných v jazyce C), které netvoří jen samotný TeXový engine, ale i další subsystémy včetně Lua, MetaPostu, Kpathsea, FontForge, libpng a zlib. Tyto knihovny jsou integrovány tak, aby tvořily vlastnosti a funkce spustitelného softwaru LuaTeX, a právě prostřednictvím Lua API dostávají uživatelé přístup k funkcím LuaTeXu, odvozeným z integrace a koordinace těchto mnoha softwarových komponent.

## Některé příklady a úskalí

V této části uvádíme několik dalších příkladů, které využívají témata, pojmy a vysvětlení uvedená v tomto článku.

### Použití znaku tilda (\~)

Jazyk Lua používá `~` znak (nazývaný tilda) jako součást své syntaxe, včetně syntaxe pro provedení testu „nerovná se“; například pro test, zda proměnná `x` není rovna `4` bychom mohli napsat:

```
   local x=3
   if x ~= 4 then
   print("x není rovno 4")
   end
```

Pokud se pokusíme spustit tento jednoduchý kód Lua přes `\directlua`:

```
\directlua{
   local x=3
   if x ~= 4 then
   print("x není rovno 4")
   end
}
```

dostaneme chybu:

`[\directlua]:1: 'then' expected near '\'.`

To je zvláštní, protože náš kód je správný: použili jsme `'then'` a v našem kódu není žádný `\` znak, tak co se pokazilo? Abychom tomu porozuměli, musíme si pamatovat, že pro TeX/LaTeX je `~` obvykle definován jako „speciální znak“ s kategoriovým kódem 13: takzvané aktivní znaky, což jsou mini-makra, a proto podléhají rozbalování. Když `\directlua` rozpozná `~` znak, je rozbalen *jeho odstraněním* ze vstupu a *jeho nahrazením* a nahrazením výsledkem jeho rozbalení. Při použití plain TeXu výsledný text (kód), který LuaTeX vytváří a předává interpretoru Lua, ve skutečnosti neobsahuje `~` znak a je:

`local x=3 if x \penalty \@M \ = 4 then print("x není rovno 4") end`

Ta `~` znak byl *odstraněn* a *rozbalen* na své jednotlivé příkazy — výše uvedený kód Lua vzniká z definice aktivního znaku v plain TeXu `~`. Nyní vidíme, proč Lua odpovídá chybou `'then' expected near '\'`—začne tento kód analyzovat, ale narazí na slovo `\penalty` které pro Luu nic neznamená a vyvolá syntaktickou chybu.

Abychom to opravili, `~` musí mít znak v době, `\directlua` kdy LuaTeX zpracovává váš kód; například můžeme dočasně změnit kategoriový kód znaku `~` na 11 (písmeno) uzavřením kódu do skupiny:

```
\begingroup
\catcode`\~=11
\directlua{
   local x=3
   if x ~= 4 then
   print("x není rovno 4")
   end
}
\endgroup
```

Tento kód funguje podle očekávání a `x není rovno 4` se vypíše do konzole. Existují i další možnosti: můžeme použít rozbalitelné příkazy `\noexpand` nebo `\string`.

#### Použití \string⟨token⟩

Můžeme použít `\string` na jednoprvkový `⟨token⟩` `~` který má kategoriový kód 13 (aktivní znak); `\string` převádí `~` znak a vytvořit token znaku s kategoriovým kódem 12. Pokud uděláme

```
\directlua{
   local x=3
   if x \string~= 4 then
   print("x není rovno 4")
   end
}
```

vygeneruje požadovaný kód Lua:

`local x=3 if x ~= 4 then tex.print("x is not equal to 4") end`

#### Použití \noexpand⟨token⟩

Můžeme použít `\noexpand~` k potlačení rozbalování aktivního znaku `~`

```
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x není rovno 4")
   end
}
```

Nerozbalený `~` token projde do tokenového seznamu, který se vytváří v `\directlua` a bude převeden zpět na text, čímž vznikne funkční kód Lua.

### Použití znaku \#

V jazyce Lua lze znak `#` použít k určení délky tabulky. Pokud však zkusíme následující kód

```
\directlua{
   local tbl = {}
   tbl[1] = "Hello"
   tbl[2] = "World"
   tex.print("Table length is "..#tbl)
}
```

mohli bychom očekávat, že LuaTeX vysází

`Délka tabulky je 2`

ale vygeneruje chybu:

`\directlua]:1: attempt to get length of a number value`

Tato chyba se spustí, protože `#` znak má obvykle kategoriový kód 6 (parametr makra) — `#` znak má v TeX/LaTeXu dvě použití: k označení parametrů makra (`#1`, `#2`… `#9`) a náhradní text v zarovnávacích šablonách (pro `\halign` a `\valign`).

Když `\directlua` při generování tokenů pro vytvoření svého tokenového seznamu uvidí `#` znak s kategoriovým kódem 6 a vytvoří vhodný znakový token, který jej reprezentuje. Když přijde čas převést výsledný tokenový seznam zpět do textové podoby, znakový token pro # (s kategoriovým kódem 6) je zpracován zvláštním způsobem: vypíše se jako *dva po sobě jdoucí znaky*: `##`, což vede k tomu, že se Lua předá následující kód:

`local tbl = {} tbl[1] = "Hello" tbl[2] = "World" print(##tbl)`

Při převodu do kódu Lua byl původní `#` zdvojen a to generuje chybu:

`\directlua]:1: attempt to get length of a number value`

Tento problém vzniká kvůli syntaxi TeXu, která používá dvojitý znak mřížky `##` k reprezentaci nebo vygenerování jednoho `#` tokenu; tato syntaxe se používá v makrech, která definují jiná makra přijímající parametry, nebo v makrech používaných k vytváření šablon pro `\halign` nebo `\valign` příkazy pro konstrukci tabulek. To je poněkud matoucí, proto se podívejme na příklad.

#### Příklad

Předpokládejme, že definujeme makro `\mymacro` které bere jediný parametr, `#1`, ale zároveň definuje druhé makro `\foo` které samo bere jediný parametr. Abychom rozlišili mezi parametrem `#1` použitým s `\mymacro` a potřebou definovat `\foo` aby použilo svůj vlastní parametr `#1` syntaxe TeXu vyžaduje, abyste používali `##1` uvnitř `\mymacro` k reprezentaci parametru používaného s `\foo`:

`\def\mymacro#1{\def\foo##1{#1 Hello##1}}`

Kdybyste napsali `\mymacro{Hey!}` definovalo by makro `\foo` na

`\def\foo#1{Hey! Hello#1}`

Všimněte si, že `\mymacro`parametr makra `#1` (`Hej!`byl začleněn do definice `\foo` a posloupnost `##1` byla převedena na `#1` v definici `\foo`. Můžeme tedy použít `\foo` takto:

`\foo{, World!}`

že vysází `Hej! Ahoj, světe!`

Můžeme vyřešit `\directlua`zpracování znaku `#` dočasnou změnou jeho kategoriového kódu předtím, než LuaTeX kód zpracuje. Například:

```
\begingroup
   \catcode`\#=11
   \directlua{
   local tbl = {}
   tbl[1] = "Hello"
   tbl[2] = "World"
   tex.print("Table length is "..#tbl)
}
\endgroup
```

Tím vznikne kód Lua

```
local tbl = {} tbl[1] = "Hello" tbl[2] = "World" tex.print("Table length is "..#tbl)
```

který vysází očekávaný výsledek:

`Délka tabulky je 2`

### Použití znaku %

V TeXu/LaTeXu znak `%` se obvykle používá k vkládání jednřádkových komentářů do kódu: signalizuje enginu TeXu, že má ignorovat vše od tohoto místa až do konce řádku, na němž je `%` zapsán. Nicméně v jazyce Lua se znak `%` používá v některých velmi užitečných funkcích pro zpracování řetězců, jako jsou `string.format(...)`, `string.gmatch(...)`, a `string.gsub(...)` v nichž znak `%` hraje důležitou roli jako součást syntaxe těchto funkcí.

Při použití s TeXem/LaTeXem `%` funguje jako znak pro komentář, protože mu je přiřazen kategoriový kód 14. Aby se choval jako běžný znak a vypnulo se jeho obvyklé chování v TeXu/LaTeXu, musíme změnit jeho kategoriový kód na něco bezpečného, například 12.  `\directlua` Následující příklad používá několik technik diskutovaných dříve v článku spolu s jednou, kterou jsme dosud nezmínili: ``\catcode`\^^M=12``, což nám umožňuje používat v kódu komentáře Lua; o tom se mluví níže.

#### Příklad

Následující příklady jsou převzaty z [lua-users.org](http://lua-users.org/wiki/StringLibraryTutorial), vhodně upravené pro použití v `\directlua`.

```
\documentclass{article}
\begin{document}
\begingroup
\ttfamily
\let\\\relax
\catcode`\^^M=12 %<---dále to níže prozkoumáme!
\catcode`\%=12
\directlua{
   local str -- deklaruje lokální proměnnou pro uložení výsledku

   tex.print("Použití string.format():".."\\par")

   str=string.format("%s %q", "Hello", "Lua user!") -- řetězec a uvozený řetězec
   tex.print(str.."\\par")
   str = string.format("%c%c%c", 76, 117, 97) -- znak
   tex.print(str.."\\par")
   str=string.format("%e, %E", math.pi, math.pi) -- exponent
   tex.print(str.."\\par")
   str=string.format("%f", math.pi) -- desetinné číslo
   tex.print(str.."\\par")
   str=string.format("%g, %g", math.pi, 10^9) -- desetinné číslo nebo exponent
   tex.print(str.."\\par")
   str = string.format("%o, %x, %X", 99, 125, 125)  -- osmičkově, šestnáctkově, šestnáctkově
   tex.print(str.."\\par")

   tex.print("\\vskip3mm".."Použití string.gmatch():".."\\par")

   for word in string.gmatch("Hello TeX user", "%a+") do
      tex.print(word.."\\par")
   end

   tex.print("\\vskip3mm".."Použití string.gsub():".."\\par")
   str=string.gsub("banana", "(an)", "%1-") -- zachytí všechny výskyty "an" a nahradí je
   tex.print(str.."\\par")
}
\endgroup
\end{document}
```

Následující snímek obrazovky ukazuje vysázený výsledek výše uvedeného kódu:

![Použití řetězcových funkcí Lua v \directlua](/files/1787109f8a90066e95047373ac31341ee3831cb6)

## Proč je kód Lua zobrazen na jednom řádku?

Jak jste si možná všimli, všechny (vygenerované) úryvky kódu Lua zobrazené v příkladech tohoto článku jsou uvedeny jako jeden řádek textu: zalomení řádků původně přítomné v `\directlua` ukázkách kódu se nerespektují. Proč? Je to proto, že zalomení řádků v kódu Lua bylo *odstraněno* během předzpracování LuaTeXu v rámci `\directlua`, což způsobí, že se kód Lua stane jedním dlouhým řádkem textu. Toto chování lze vysledovat k tomu, jak enginy TeXu zacházejí se znaky konce řádku — označenými `\r` (carriage return) a `\n` (line feed) v programátorské literatuře. Proč bychom se měli těmito jemnými detaily zabývat, bude jasné, až budeme probírat používání Lua mechanismů pro odkomentování sekcí kódu.

Když software zapisuje (ukládá) textový soubor, každý jednotlivý řádek textu je ukončen takzvanými znaky „nového řádku“ — skutečný znak(y) nového řádku závisí na aplikaci a operačním systému používaném k zápisu daného souboru. Wikipedie má [zajímavý článek](https://en.wikipedia.org/wiki/Newline) který zkoumá historii/vývoj znaků nového řádku používaných dnes.

U jakéhokoli textového souboru mohou být jeho jednotlivé řádky ukončeny různými kombinacemi znaků, označovanými jako carriage return (znak ASCII/Unicode 13) a/nebo line feed (znak ASCII/Unicode 10), které jsou označovány `\r` a `\n` resp. Protože enginy TeXu jsou navrženy tak, aby byly nezávislé na platformě, potřebují metodu, jak obejít přirozeně na platformě závislou povahu konců řádků používaných v textových souborech. Enginy TeXu mají přirozeně vestavěnou (ale konfigurovatelnou) metodu pro práci se znaky ukončení řádku.

### Jak enginy TeXu zacházejí s konci řádků

Když LuaTeX zpracovává `\directlua{⟨code⟩}` čte text obsažený ve vašem `⟨code⟩` a použije standardní metody enginu TeXu pro zpracování všech konců řádků obsažených ve vašem `⟨code⟩`. Ve výchozím nastavení tyto standardní metody TeXu způsobí, že všechny znaky ukončení řádku (carriage return a line feed) jsou odstraněny a nahrazeny znaky mezery. Říkáme „ve výchozím nastavení“, protože zacházení enginu TeXu se znaky ukončení řádku lze upravit prostřednictvím uživatelsky konfigurovatelného parametru nazývaného `\endlinechar`. Zde poskytneme krátký dvoukrokový přehled, ale další podrobnosti najdete v článku na Overleafu [Úvod do \endlinechar: Jak TeX čte řádky z textových souborů](/latex/cs/clanky-do-hloubky/05-an-introduction-to-endlinechar-how-tex-reads-lines-from-text-files.md).

#### Krok 1: TeX vloží vlastní znak konce řádku

Po načtení řádku textu z vašeho vstupního souboru enginy TeXu okamžitě odstraní všechny `\r` nebo `\n` znaky z konce tohoto řádku. Poté enginy TeXu *vloží* (přidají zpět) vlastní znak ukončení řádku na konec tohoto řádku. Tento znak je určen hodnotou uživatelsky konfigurovatelného parametru TeXu nazývaného `\endlinechar` a právě prostřednictvím tohoto mechanismu mohou enginy TeXu zpracovávat znaky konce řádku způsobem nezávislým na platformě: zvolí a nastaví znak konce řádku bez ohledu na to, co bylo původně obsaženo ve vstupním textovém souboru.

Obvykle enginy TeXu používají nastavení

`\endlinechar=13`

což je znak carriage return (`\r`). Uživatelé však mohou jako hodnotu `\endlinechar`vždy přiřadit jiný kód znaku — jak uvidíme později v tomto článku.

V důsledku toho jsou jakékoli znaky ukončení řádku obsažené ve vašem `⟨code⟩` které mají být zpracovány `\directlua{⟨code⟩}` jsou odstraněny a nahrazeny jedním znakem určeným samotným enginem TeXu. Všimněte si, že enginy TeXu provádějí toto zpracování konce řádku okamžitě po načtení nového řádku textu ze souboru a *dříve, než* zpracování jakýchkoli znaků v tomto řádku (k vytvoření tokenů). To ale není konec příběhu: to, co engine TeXu *ne* s těmito znaky konce řádku dělá (které vložil) vysvětluje, proč se kód Lua stává jedním řádkem.

#### Krok 2: TeX převádí svůj znak konce řádku na mezeru

Kromě vkládání vlastního znaku ukončení řádku, definovaného hodnotou `\endlinechar`, používají enginy TeXu také kategoriový kód 5 pro znaky, které by měly být *považovány za* znak konce řádku. To vede k tomu, že enginy TeXu obvykle pracují s:

1. znakem konce řádku definovaným `\endlinechar`;
2. tímto samým znakem *obvykle* kterému je přiřazen kategoriový kód 5.

Právě to, co TeX dělá s tímto znakem konce řádku, vysvětluje náš problém s jednorádkovým kódem Lua. Když engine TeXu zpracovává řádek vstupu, nakonec detekuje poslední znak v tomto řádku: znak definovaný `\endlinechar`. Tento znak má obvykle kategoriový kód 5, což způsobí, že TeX *jej nahradí* znakem mezery: tj. na koncích řádků TeX ve skutečnosti odstraní svůj znak ukončení řádku a nahradí jej mezerou. Mimochodem, enginy TeXu také používají znaky s kategoriovým kódem 5 k detekci prázdných řádků a zahájení nového odstavce, ale tím se zde nebudeme zabývat.

Samozřejmě, protože jde o TeX, můžete provádět nejrůznější speciální programátorské triky s makry opětovným nastavením `\endlinechar` na nějaký jiný znak a/nebo přiřazením znaku `\endlinechar` hodnoty kategoriového kódu podle vašeho výběru.

Pokud chcete zabránit tomu, aby se kód Lua stal jedním jediným řádkem textu, můžete buď (dočasně) změnit hodnotu přiřazenou `\endlinechar` nebo změnit kategoriový kód standardního ukončovače řádku `\r`.

### TeXova bizarní notace ^^

V následujících oddílech narazíme na neobvyklou `^^` notaci, známou jako „rozšířený mechanismus znaků“. Knuth ji navrhl jako způsob, jak usnadnit psaní „řídicích znaků“, jako jsou ukončovače řádků, tabulátory a podobně. Například:

* `^^J` představuje kód znaku 10 (`\n`line feed);
* `^^M` představuje kód znaku 13 (`\r`carriage return).

Posloupnosti znaků jako `^^M` jsou na své odpovídající kódy znaků převedeny už na začátku procesu skenování vstupu v TeXu, když TeX čte vstupní znaky, aby vytvořil odpovídající znakové tokeny.

### Změna znaku přiřazeného k \endlinechar

Pamatujeme-li si, že stále musíme zabránit rozbalování `~` znaku, můžeme napsat

```
\begingroup
\endlinechar=10 % Změňte znak konce řádku na \n
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x není rovno 4")
   end
}% nechceme, aby se zde \n objevilo
\endgroup% ani \n zde
```

Výše uvedené nastavení pro `\endlinechar` způsobí, že LuaTeX připojí kód znaku 10 (`\n`, line feed) na konec každého řádku, který čte. Děláme to proto, že `\n` (line feed) obvykle má kategoriový kód 12, což můžete ověřit zápisem ``\the\catcode`\^^J``. Protože `\n` nemá kategoriový kód 5, LuaTeX jej nepřevede na znak mezery, takže zůstane na konci každého řádku načteného LuaTeXem. To vede k tomu, že znak s kódem 10 zůstane na konci každého řádku a tím projde do tokenového seznamu budovaného `\directlua` a následně se znovu objeví v kódu Lua, jakmile se tokenový seznam převede na text. Po výše uvedené změně je kód Lua předán interpreteru Lua jako následující posloupnost znaků:

**\n**local x=3\*\*\n**if x \~= 4 then**\n**print("x není rovno 4")**\n**end**\n\*\*

kde **\n** notace má představovat kód znaku 10 *ne* nějaké neznámé makro `\n`. Nyní interpreter Lua uvidí v kódu zalomení řádků přesně tak, jak byl původně napsán v `\directlua` příkazu:

```
   local x=3
   if x ~= 4 then
   print("x není rovno 4")
   end
```

Mimochodem si všimněte, že úplně první znak v řetězci kódu Lua je `\n` (před `místní` klíčovým slovem). To `\n` vyplývá z řádku

`\directlua{`

protože hned po otevírací `{` a i to je zachováno. Chcete-li tomu zabránit, můžete napsat

`\directlua{%`

### Změna kategoriového kódu \r

Abychom zachovali zalomení řádků v našem kódu Lua, můžeme také změnit kategoriový kód `\r` na něco jiného než 5, aby `\r` už nebyl rozpoznán (považován za) znak konce řádku. S touto technikou LuaTeX stále používá `\endlinechar=13` a bude i nadále přidávat `\r` na konec každého řádku; avšak protože `\r` již nemá kategoriový kód 5, LuaTeX nerozpozná `\r` znak jako znak konce řádku: nepřevede jej na mezeru a předá jej bez úhony dál, takže se objeví v kódu Lua.

Pamatujeme-li si, že stále musíme zabránit rozbalování `~` znaku, můžeme napsat

```
\begingroup
\catcode`\^^M=12 % změňte kategoriový kód \r na 12
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x není rovno 4")
   end
}
\endgroup
```

V tomto případě je kód Lua předán interpreteru Lua jako:

**\r**local x=3\*\*\r**if x \~= 4 then**\r**print("x není rovno 4")**\r**end**\r\*\*

kde `\r` notace má představovat kód znaku 13, nikoli nějaké neznámé makro `\r`. Stejně jako u `\endlinechar` příkladu uvidí interpreter Lua nyní v kódu zalomení řádků přesně tak, jak byl původně napsán v `\directlua` příkazu:

```
   local x=3
   if x ~= 4 then
   print("x není rovno 4")
   end
```

Mimochodem si opět všimněte, že úplně první znak v řetězci kódu Lua je `\r` (před klíčovým slovem local): i to vyplývá z řádku

`\directlua{`

#### Proč \r používalo kategoriový kód 12 a ne kategoriový kód 11?

Odpověď spočívá v riziku náhodného zavedení chyb vyvolaných `\r` (s kategoriovým kódem 11) přidanou na konec příkazů TeXu/LaTeXu čtených z našeho vstupního souboru. Vezměte si tento příklad:

```
\begingroup
\catcode`\^^M=11 % změňte kategoriový kód \r na 11
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x není rovno 4")
   end
}
\endgroup
```

což vygeneruje chybu:

```
   ! Nedefinovaná řídicí sekvence.
   l.9 \endgroup
```

Jak to může být pravda, když `\endgroup` je standardní primitivní příkaz TeXu? Příčina chyby je poměrně skrytá: když LuaTeX přečetl poslední řádek textu — ten obsahující `\endgroup`—přidal také `\endlinechar` znaku `\r` na konec tohoto řádku. Nyní LuaTeX ve své paměti vidí posloupnost znaků

`\endgroup\r`

kde používáme `\r` k označení znaku s kódem 13 — nikoli názvu nějakého neznámého makra TeXu `\r`.

V okamžiku, kdy LuaTeX četl tento řádek z našeho textového souboru, původní `\begingroup` je stále účinný: nacházíme se uvnitř skupiny, která ještě nebyla uzavřena provedením odpovídajícího `\endgroup` příkazu — což by způsobilo `\r` návrat na předchozí hodnotu kategoriového kódu 5.

Když LuaTeX začne zpracovávat (vytvářet tokeny) z řádku textu `\endgroup\r` rozpozná první znak `\` jako únikový znak, který spustí, že LuaTeX začne hledat název příkazu. Pro identifikaci názvu příkazu LuaTeX hledá posloupnost znaků s kategoriovým kódem 11, ale protože `\r` také má kategoriový kód 11, LuaTeX se domnívá, že `\r` znak (stále s kategoriovým kódem 11) tvoří *součást příkazu* nazvaného `\endgroup\r` který, samozřejmě, neexistuje, takže LuaTeX ohlásí `Undefined control sequence` chybu. Proto jsme použili kategoriový kód 12 a ne 11.

Protože chybová zpráva LuaTeXu byla vypsána do konzole, nemohli jsme snadno vidět/zaznamenat `\r` znak, takže nebylo zřejmé, co chybu způsobilo.

### Proč se zabýváme konci řádků?

Důvodem je umožnit použití metody komentování v Luě ve vašem kódu! Můžete použít standardní mechanismus LuaTeXu přidávání `%` znaků k zakomentování jednotlivých řádků ve vašem kódu; jazyk Lua však má svůj vlastní, velmi užitečný, *víceřádkový* mechanismus komentování, který byste možná chtěli využít.

Začněme tím, že se podíváme, co se stane, když se pokusíme použít jednořádkové komentáře jazyka Lua bez řešení problémů se zalomením řádků. Zatímco TeX používá znak `%` k zakomentování jednotlivých řádků kódu, Lua používá dvojitý spojovník: `--`.

Co se stane, když se to pokusíme spustit:

```
\directlua{
   local x=3
   if x \noexpand~= 4 then
   -- Hodlám vypsat výsledek tohoto složitého testu
   print("x není rovno 4")
   end
}
```

Dostaneme chybu:

`[\directlua]:1: 'end' expected near <eof>`

Tato chyba je způsobena absencí zalomení řádků v kódu Lua předaném interpreteru, který vidí pouze jeden souvislý řetězec, v němž komentář začíná uprostřed tohoto řetězce:

```

local x=3 if x ~= 4 then -- Hodlám vypsat výsledek tohoto složitého testu print("x is not equal to 4") end
```

Všechno po `**local x=3 if x ~= 4 then**` je považováno za zakomentované, což způsobí, že interpreter uvidí neúplný úsek kódu Lua, což vede k chybě

`'end' expected near <eof>`.

kde `<eof>` znamená konec souboru.

Jak jste už nejspíš uhodli, musíme to napravit tak, že zajistíme, aby se zalomení řádků přenášela do výsledného kódu Lua, čehož můžeme dosáhnout například změnou kategoriového kódu `\r` na 12:

```
\begingroup
\catcode`\^^M=12 % změňte kategoriový kód \r na 12
\directlua{
   local x=3
   if x \noexpand~= 4 then
   -- Chystám se vypsat výsledek tohoto složitého testu
   print("x není rovno 4")
   end
}
\endgroup
```

Nyní interpreter Lua vidí řetězec, ale ten obsahuje `\r` zlomy řádků, jak jsou zapsány v `\directlua` úryvku:

**\r**local x=3\*\*\r**if x \~= 4 then**\r\*\*-- Chystám se vypsat výsledek tohoto složitého testu\*\*\r**tex.print("x is not equal to 4")**\r**end**\r\*\*

To je ve skutečnosti ekvivalentní zápisu

```
   local x=3
   if x \noexpand~= 4 then
   -- Chystám se vypsat výsledek tohoto složitého testu
   print("x není rovno 4")
   end
```

což znamená, že Lua dokáže tento kód správně zpracovat a ignorovat řádek, který jsme zakomentovali.

**Blokové komentáře**

Jazyk Lua také podporuje syntaxi, kterou nazývá [„blokový komentář“](https://www.lua.org/pil/1.3.html) (nebo *dlouhý komentář*): tyto začínají na `--[[` a platí až do odpovídajícího `]]`. Tuto užitečnou syntaxi můžeme použít k psaní víceřádkových komentářů nebo k zakomentování částí kódu, které chceme dočasně odstranit:

```
\begingroup
\catcode`\^^M=12 % změňte kategoriový kód \r na 12
\directlua{
   local x=3
   if x \noexpand~= 4 then
   --[[ Chystám se vypsat výsledek tohoto složitého testu
   prostě proto, že opravdu je
   takový úžasný závěr]]
   print("x není rovno 4")
   end
}
\endgroup
```

## Na závěr

Především gratulujeme, pokud jste se prokousali tímto obsáhlým článkem! Snažili jsme se vytvořit poměrně komplexního průvodce pojmy a tématy souvisejícími s TeXem, které poskytují pozadí potřebné k tomu, abyste z LuaTeXu získali co nejvíce prostřednictvím `\directlua` příkazu. Doufáme, že se nám podařilo vytvořit článek, který je poučný a přináší něco užitečného a hodnotného uživatelské komunitě Overleafu i mimo ni. Jako vždy budeme rádi za zpětnou vazbu, takže nám klidně [nás kontaktovat](https://www.overleaf.com/contact) s komentáři k tomuto článku nebo s návrhy na další témata, o kterých byste si přáli, abychom psali.

Příjemné $$\text{Lua}\mathrm{\TeX}\text{-ing!}$$ od Grahama Douglase a týmu Overleaf.

### A nakonec... jednoduše použijte balíček luacode

Ačkoli TeX a Lua fungují zásadně odlišným způsobem, tyto jazyky sdílejí řadu znaků, které mají v kontextu každého z nich „zvláštní význam“ — například \\\\, %, \~, #, ^, & — samozřejmě Lua i TeX těmto zvláštním významům přiřazují pro *velmi* různé účely. Naše zkoumání problematických znaků ukazuje, proč mohou vznikat potíže a jak je můžete vyřešit; ruční oprava mnoha drobných úryvků kódu Lua však může být docela zdlouhavá, takže většina uživatelů dává přednost použití balíčků LaTeXu, které tyto potíže odstraňují. Jedním z takových balíčků je [`luacode`](https://ctan.org/pkg/luacode?lang=en) který poskytuje sadu funkcí navržených ke zjednodušení práce s `\directlua`, ale alespoň nyní možná lépe rozumíte problémům `luacode` které za vás řeší.


---

# 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/clanky-do-hloubky/09-an-introduction-to-luatex-part-2-understanding-directlua.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.
