I Vnitřnosti TEXu

1 Čich a hmat … Styk s vnějším světem:

• Tabulka překladu znaků na vstupu 256 → 256 (dovnitř leze pozměněný vstup … v tom se liší instalace Kamenických od Latin2).

• Tabulka překladu znaků na výstup 256 → 256 (aby mohl opět zpracovat výstupní soubory pomocí vstupní tabulky).

• Tabulka přepisu znaků na terminál 256 → slova (zápisy typu ˆ ˆ de).

2 Ústa … Lexikální analýza:

• Řízeno tabulkou “catcode a numerickou proměnnou “endlinechar. Výstupem jsou tokeny a_{11}, 0_{12}, –_{1}, #_{6}, …, ale i par v případě prázdného řádku, nebo třeba def či sum .

• Ústa TEXu používají buffer na jeden řádek vstupu.

Ústa TEXu mohou být ve třech stavech: ∘ New line – značíme N ∘ Middle of a line – značíme M ∘ Skipping blanks – značíme S

- Je-li požadován další znak, buffer je prázdný a soubor skončil, nebo byl zpracován “endinput, pak TEX ukončí čtení daného souboru, a pokračuje číst tam, odkud byl vyvolán příslušný “input.

- Je-li požadován další znak, buffer je prázdný, a má pokračovat čtení ze souboru, TEX načte do bufferu nový řádek, a všechny mezery na konci řádku odstraní (snaha o ekvivalenci stejně vypadajících vstupů). Poté na konec řádku doplní “endlinechar (je-li v intervalu 0..255), a přejde do stavu ‘N’.

- Kdykoli TEX narazí na dva stejné znaky ˆ (category 7), otestuje, zda dva následující znaky jsou malé hexadecimální číslice (0–9,a–f). Pokud ano, je tato čtveřice znaků nahrazena znakem příslušné hodnoty. (Tento znak již není konvertován tabulkou viz. čich, proto ˆ ˆ a9 odpovídá Š nezávisle na tom, zda vstup je Kamenických nebo třeba Latin 2.) Jinak, je-li ˆ ˆ následováno znakem c < ”80, je nahrazeno c ⊕ ”40, a je-li ˆ ˆ následováno znakem c ≥ ”80, pak je hlášena chyba.

Příklad 2.1: Co je výsledkem ‘$$eˆ ˆ 5eˆ 5$$’, a co ‘$$eˆ ˆ 5eˆ 5e5$$’? (”5e je ASCII hodnota ˆ ).

Příklad 2.2: Je-li “catcode‘“*=7, čím se liší ‘**5eˆ 5’ a ‘ˆ **5e5’?

- Kdykoli TEX narazí na “ (category 0), pak (a) Není-li již nic na řádku, výsledkem je ;

(b) Není-li další znak písmeno (category 11), pak je výsledkem c, kde c je daný znak;

(c) Je-li další znak písmeno, pak výsledkem je w, kde w je slovo obsahující nejdelší úsek písmen nepřerušený nepísmenem, ani koncem řádku.

TEX přejde do stavu ‘S’, je-li v případě (b) “ následován mezerou (category 10), a vždy v případě (c). Jinak přechází do stavu ‘M’.

Příklad 2.3: Jaké tokeny jsou výsledkem ‘“ˆ ˆ 54ˆ ˆ %ˆ ˆ 58ˆ 32 .’?

- Čte-li TEX znak c kategorie t, kde t = 1 (–), t = 2 (˝ ), t = 3 ($), t = 4 (&), t = 6 (#), t = 7 (ˆ ) (nenásleduje-li stejný znak c), t = 8 (˙ ), t = 11 (písmeno), t = 12 (jiné), t = 13 (˜ — aktivní znak), je tento znak c kategorie t konvertován na token c_{t}, a TEX přechází do stavu ‘M’.

- Pokud TEX uvidí znak ˆ ˆ M (category 5), vyprázdní řádkový buffer. Byl-li TEX ve stavu ‘N’, vydá token par , byl-li ve stavu ‘M’, vydá token _{10} a byl-li ve stavu ‘S’, nevydá žádný token.

- Pokud TEX narazí na znak c kategorie 9, pokračuje dálším znakem, jako by znak c vůbec na vstupu nebyl.

- Pokud TEX uvidí znak (category 10), závisí na stavu, ve kterém se nachází. Pokud TEX byl buď ve stavu ‘N’ nebo ve stavu ‘S’, nic se nezmění (jako by mezera nebyla na vstupu). Jinak je vydán token _{10} a TEX přejde do stavu ‘S’. (Projde-li c_{10} z úst do hltanu, pak c = ”20.)

- Pokud TEX uvidí znak % (category 14), vyprázdní řádkový buffer (jako ve stavu ‘S’ při ˆ ˆ M).

- A nakonec, pokud TEX uvidí znak c kategorie 15 (invalid), vydá chybové hlášení a zůstává ve stejném stavu.

Příklad 2.4: Nechť “catcode‘“*=9. Co je výsledkem ‘ˆ ˆ **5e5’?

Příklad 2.5: Nechť “catcode‘“*=9. Co je výsledkem ‘ˆ *ˆ *5e5’?

Příklad 2.6: Jakým způsobem je možno zajistit, aby znak ˆ ˆ 7f způsobil okamžité ukončení čtení souboru? (Nevydá již žádný token).

3 Hltan … Makro expanze:

• Řízeno tabulkou významu aktivních tokenů a tokenů . (Tabulka aktivních tokenů nezávisí na aktuální kategorii příslušného znaku, je zde položka pro všechny tokeny c_{13}.)

• Expanze maker je řízena pro každé makro dvěma seznamy tokenů … seznamem parametrů a se-

znamem náhrady.

. Seznam parametrů může obsahovat speciální tokeny \underline{ci} (kde c je znak původně kategorie 6 (#) a i je dekadická číslice od 1 do 9 (původně kategorie 12)) Pro každé i je tam takový token nejvýš jednou, a pokud se tam vyskytuje token \underline{ci}, kde i > ‘1’, pak se někde před ním vyskytl token \underline{c′(i − 1)}. (Znak c tokenu \underline{ci} nemá význam z hlediska substitucí, je však používán při expanzi “meaning, případně když “tracingmacros¿0) Mimo dvojic \underline{ci} mohou být v seznamu parametrů i jiné tokeny. Nevyskytují se tam však tokeny kategorie 2(˝ ), a pokud se zde vyskytuje token kategorie 1(–), je to poslední token seznamu parametrů (a zároveň poslední token seznamu náhrady). . V seznamu náhrady se nevyskytují tokeny \underline{ci}, ale speciální tokeny \underline{i}. Nemůže zde být \underline{i} pokud se v seznamu parametrů nevyskytl token \underline{ci} (pro nějaké c). Tokeny kategorií 1(–) a 2(˝ ) jsou v seznamu náhrady správně uzávorkovány s výjimkou tokenu kategorie 1(–), na konci seznamu náhrady, pokud je tento token na konci seznamu parametrů.

• Pro expanze “the je potřeba mnoho proměnných TEXu (viz. žaludek) — výjimkami jsou box registry.

• Pro expanze “ifvoid, “ifhbox, “ifvbox jsou potřeba i box registry.

• Pro expanze “topmark, “firstmark, “botmark, “splitfirstmark a “splitbotmark jsou potřeba stejnojmenné registry obsahující seznamy tokenů.

Každý token může mít nastaven flag ‘noexpand’, ovlivňující případnou expanzi. V dalším budeme značit c_{t}^{∘}, token^{∘} tokeny, kde tento flag není nastaven, a c_{t}^{•}, token^{•} tokeny, kde flag ‘noexpand’ nastaven je, a c_{t}, token tokeny, pokud nechceme zdůrazňovat nastavení tohoto flagu. V hltanu jsou expandovány expandovatelné tokeny jejichž flag ‘noexpand’ není nastaven. Tokeny jejichž flag ‘noexpand’ byl nastaven jsou pouze opsány (i s flagem).

Nyní je na místě upozornit na používanou konvenci: Kdykoli se bavíme o tokenu “token , máme na mysli token, jehož význam odpovídá významu token při startu TEXu (iniTEXu). Aktuální význam tokenu token může být odlišný.

Z hlediska expandovatelných tokenů může být hltan v následujících režimech:

∘ Provádějí se expanze expandovatelných tokenů. ∘ Všem tokenům je nastavován flag ‘noexpand’. Tento režim má několik variant:

. Tokeny jsou přeskakovány v průběhu zotavování se z chyb. . Provádí se expanze “if … a všechny tokeny s výjimkou “if …^{∘}, “or^{∘}, “else ^{∘} a “fi ^{∘} jsou pohlcovány. . Provádí se expanze “or nebo “else a všechny tokeny s výjimkou “if …^{∘} a “fi ^{∘} jsou pohlcovány. . TEX čte aktivní token nebo token , jenž má být předefinován pomocí “let , “futurelet , “def , “gdef , “edef , “xdef , “chardef , “mathchardef , “countdef , “dimendef , “skipdef , “muskipdef , “toksdef , “read nebo “font . . TEX čte token jakožto argument pro “expandafter , “noexpand, “string , “meaning, “let , “futurelet , “ifx , “show, “afterassignment nebo “aftergroup . . Když TEX čte seznam parametrů při definici “def , “gdef , “edef nebo “xdef . . Když TEX načítá seznam tokenů ať již jako seznam náhrady při definici “def nebo “gdef , nebo při dosazování do token registrů, nebo při čtení argumentu primitiv, jejichž argumentem je neexpandovaný seznam tokenů … “uppercase , “lowercase , “read a “write . . Když čte TEX hlavičku tabulky, s výjimkou tokenů následujících za primitivem “span, nebo při čtení ⟨glue⟩ po “tabskip . . Následující token za c_{3}, kvůli testu zda se jedná o c′_{3}. (Daný token je pak expandován později.) . Po tokenu ‘_{12} který začíná konstantu zadávanou pomocí ascii.

Z hltanu dále vystupují jenom tokeny, jejichž význam není expandovatelný, nebo jejichž flag ‘noexpand’ je nastaven.

Tokeny následujících druhů jsou expandovány, je-li požadována jejich expanze:

− Makra … TEX nejprve určí argumenty makra podle seznamu parametrů (každý argument je seznam tokenů). Poté je makro nahrazeno podle seznamu náhrady. (Tento seznam může obsahovat ‘parametrické tokeny’ \underline{1}, …, \underline{9}. Každý z nich bude nahrazen seznamem tokenů příslušného argumentu). Při čtení argumentů makra nejsou prováděny žádné expanze. Pravidla určení argumentů makra jsou následující: TEX čte vstup zároveň se seznam parametrů, a snaží se ţpárovat� tokeny těchto seznamů v odpovídajícím si pořadí. V případě, že v seznamu parametrů je ţneparametrický� token, musí být tento spárován s přesně stejným tokenem vstupu. Je-li v seznamu parametrů parametrický token \underline{ci}, je tento token párován s nějakým podseznamem tokenů vstupu.

Tokeny následující za tokenem, jehož makro expanzi provádíme se musí shodovat s tokeny předcházejícími token \underline{c1} seznamu parametrů (případně do konce seznamu parametrů, pokud \underline{c1} v seznamu parametrů není). Jinak TEX ohlásí chybu. Kdykoli se před dočtením seznamu parametrů načte více tokenů kategorie 2(˝ ) než tokenů kategorie 1(–), ohlásí TEX chybu. Pokud by token par vstupu měl být párován s nějakým tokenem \underline{ci} a expandované makro není “long, bude také ohlášena chyba.

Zabývejme se nyní tím, jak poznáme podseznam vstupu, s nímž je párován token \underline{ci}: Pokud v seznamu parametrů za tokenem \underline{ci} následuje token různý od \underline{c′(i + 1)} , pak bude \underline{ci} párován s nejkratším (případně prázdným) seznamem tokenů vstupu, správně uzávorkovaným z hlediska tokenů kategorií 1(–) a 2(˝ ), který je následován seznamem tokenů shodným s podseznamem tokenů seznamu parametrů za \underline{ci} a před \underline{c′(i + 1)} (případně do konce seznamu parametrů, pokud \underline{c′(i + 1)} v seznamu parametrů není). Pokud seznam tokenů vstupu s nímž je token \underline{ci} zpárován začíná znakem kategorie 1(–) a končí znakem kategorie 2(˝ ), a podseznam mezi těmito znaky je správně uzávorkován z hlediska znaků kategorií 1(–) a 2(˝ ), pak je i–tým argumentem podseznam tohoto seznamu zkrácený o první a poslední token. Jinak je i–tým argumentem celý seznam tokenů zpárovaných s \underline{ci}. Pokud v seznamu parametrů za tokenem \underline{ci} ihned následuje dvojice \underline{c′(i + 1)} (nebo konec seznamu parametrů), pak bude \underline{ci} párováno s následujícími tokeny _{10} vstupu a následujícím nejkratším řetězcem tokenů vstupu správně uzávorkovaným vzhledem k tokenům kategorií 1(–) a 2(˝ ). Pokud v seznamu tokenů zpárovaných s \underline{ci} za tokeny _{10} následuje token kategorie 1(–), pak je kategorie posledního tokenu tohoto seznamu 2(˝ ), podseznam mezi těmito tokeny je správně uzávorkován vzhledem ke znakům kategorií 1(–) a 2(˝ ), a i–tým argumentem je podseznam tohoto seznamu počínající za prvním tokenem kategorie 1(–) a končící před posledním tokenem kategorie 2(˝ ). Jinak je i–tým argumentem podseznam tokenů zpárovaných s \underline{ci} počínající prvním tokenem různým od _{10}.

Příklad 3.1: Předpokládejme, že bylo provedeno “catcode‘“*=“catcode‘“ , a “def“a#1#2–˝ Co je výsledkem expanze při vstupu ‘“a*a*b*c’?

− Podmínky “if . . . . . . TEX zaznamená status “or^{∘} a “else ^{∘} (zda jsou povoleny či zakázány) na aktuální úrovni vnoření “if …“fi , zvýší tuto úroveň a zaznamená novou úroveň u vnoření “if …“fi . Poté TEX provede vše, co je nutné k vyhodnocení podmínky. Podle výsledku určí, po kolika výskytech “or^{∘} na této úrovni vnoření má přestat ignorovat tokeny, případně že “or^{∘} je nepřípustný token. Pokud nemá ignorovat tokeny, expanze “if … končí. Jinak hltan přechází do vynechávacího režimu, kde jsou tokeny s výjimkou “if …^{∘}, “or^{∘}, “else ^{∘} a “fi ^{∘} ignorovány. Expanze “if … končí při ukončení tohoto režimu. Ve vynechávacím režimu jsou vyjmenované tokeny zpracovány následovně:

. Příchod “if …^{∘} vede ke zvýšení úrovně vnoření “if …“fi . . Příchod “or^{∘} na jiné úrovni vnoření “if …“fi než u je ignorován. Jinak vede buď k chybovému hlášení (pokud “or^{∘} není povoleno) nebo ke snížení počtu přeskakovaných “or^{∘}. Je-li pak tento počet nulový, vynechávací režim končí. . Příchod “else ^{∘} na jiné úrovni vnoření “if …“fi než u je ignorován. Jinak vede buď k chybovému hlášení (pokud “else ^{∘} není povoleno) nebo k zákazu “or^{∘} a “else ^{∘}, a ukončení vynechávacího režimu. . Příchod “fi ^{∘} vede ke snížení úrovně vnoření “if …“fi . Klesla-li úroveň vnoření “if …“fi pod u, je ukončen vynechávací režim.

Expanze “or případně “else vede buď k chybovému hlášení (není-li “or^{∘} případně “else ^{∘} povoleno), nebo ke vstupu do vynechávacího režimu (s parametrem u) v němž jsou vynechávány tokeny s výjimkou “if …^{∘} a “fi ^{∘} (“or^{∘} a “else ^{∘} jsou také vynechávány). Expanze “or případně “else končí při ukončení vynechávacího režimu. Expanze “fi vede ke snížení úrovně vnoření “if …“fi . A obnovení statusu “else ^{∘} a “or^{∘} na nové aktuální úrovni. Pokud tato úroveň klesla pod 0, je vydáno chybové hlášení. Při startu TEXu je úroveň vnoření “if …“fi rovna 0 a “or^{∘} a “else ^{∘} jsou zakázány. Podmínky a jejich způsoby vyhodnocení jsou následující:

. “ifnum⟨number_{1}⟩⟨relation⟩⟨number_{2}⟩ … porovná čísla number_{1} a number_{2}. Relací musí být jeden z tokenů ¡_{12}, =_{12} a ¿_{12}. . “ifdim ⟨dimen_{1}⟩⟨relation⟩⟨dimen_{2}⟩ … porovná dimenze dimen_{1} a dimen_{2}. Relací musí být jeden z tokenů ¡_{12}, =_{12} a ¿_{12}. . “ifodd ⟨number⟩ … test lichosti čísla number. . “ifvmode , “ifhmode , “ifmmode … test režimu žaludku. . “ifinner … doplňující test režimu žaludku (vnitřní vertikální, omezený horizontální nebo malý matematický). . “if , “ifcat … TEX provádí expanze, dokud nenalezne dva neexpandovatelné tokeny následující za “if resp. “ifcat , nebo dokud nenarazí na “or^{∘}, “else ^{∘} nebo “fi ^{∘}. Pokud není za “if … žádný token (před “or^{∘}, “else ^{∘} nebo “fi ^{∘}) je výsledkem true. Je-li za “if … jediný token, je jeho význam porovnán s 256_{16}. Jinak jsou v případě “if porovnány znaky významů prvních dvou tokenů. V případě “ifcat jsou porovnány kategorie významů prvních dvou tokenů. (Pokud není význam tokenu dvojice c_{t}, použije se umělý význam 256_{16}.)

Příklad 3.2: Co je výsledkem ‘“ifcat“/“cr T“else F“fi’ případně ‘“if“ “wd T“else F“fi’?

. “ifx ⟨token_{1}⟩⟨token_{2}⟩ … true (a) pokud token_{1} a token_{2} nejsou makra a reprezentují tentýž pár c_{t}, nebo pokud je význam obou totéž primitivum TEXu nebo stejný “chardef, “mathchardef, “countdef, “dimendef, “skipdef, “muskipdef, “toksdef, “read nebo “font, nebo (b) pokud jsou token_{1} a token_{2} makra, která mají stejný status vůči “long a “outer, stejný seznam paramterů a stejný seznam náhrady.

Příklad 3.3: Co je výsledkem ‘“catcode‘“*6“def“a#1–˝ “def“b*1–˝ “ifx“a“b T“else F“fi’

. “ifvoid ⟨8-bit number⟩, “ifhbox ⟨8-bit number⟩, “ifvbox ⟨8-bit number⟩ … test zda “box⟨8bit number⟩ je ţvoid�, nebo zda obsahuje “hbox nebo “vbox (tyto tři možnosti se navzájem vylučují). . “ifeof ⟨4-bit number⟩ … true, pokud odpovídající čtecí kanál není otevřen, nebo je zcela přečten. . “iftrue , “iffalse … true resp. false . “ifcase ⟨number⟩ … jediný případ, kdy je “or^{∘} přípustný token. Number udává pořadí “or^{∘}, které ukončí expanzi “ifcase .

− “number⟨number⟩ … TEX načte číslo následující token “number. Expanze obsahuje dekadickou

reprezentaci onoho čísla případně se znaménkem -_{12}. − “romannumeral⟨number⟩ … TEX načte číslo následující token “romannumeral. Expanze obsahuje

reprezentaci onoho čísla malými římskými číslicemi. Pro nekladná čísla je expanze prázdná. − “string ⟨token⟩ … TEX nejprve načte token následující token “string . Jde-li o token c_{t} (znak

s kategorií), je výsledkem expanze znak c. Jde-li o token w, kde w je neprázdný řetězec znaků, je výsledkem expanze znak “chr“escapechar (pokud “escapechar ∈ {0, …, 255}), následovaný písmeny řetězce w. Jde-li o token , je výsledkem znak “chr“escapechar následovaný znaky csname, opět znak “chr“escapechar tentokrát následovaný endcsname (znak “chr“escapechar je použit jen pokud “escapechar ∈ {0, …, 255}).

− “jobname … TEX nahradí tento token jménem ‘zakázky’ (výstupem TEXu jsou soubory jejichž

jména závisí na jménu zakázky … “jobname.log a “jobname.dvi). − “fontname⟨font⟩ … Expanzí je ‘vnější jméno’ příslušného fontu (např. cmr10 at 12pt) − “meaning⟨token⟩ … Expanzí je textová forma položky tabulky významu tokenů.

. Je-li významem makro, expanzí je ‘macro:⟨parameter list⟩-¿⟨substitution list⟩’ Kde v parameter list se vypisují znakové hodnoty jednotlivých tokenů seznamu parametrů (je-li zde \underline{ci}, vypíše se ‘ci’), v substitution list se vypisují znakové hodnoty tokenů, ale místo tokenů \underline{i} se vypisuje ‘ci’, kde ‘c’ je znak z poslední dvojice \underline{ci} seznamu parametrů. Místo tokenů c′_{6} se vypisuje ‘cc’.

− “csname…“endcsname … TEX expanduje vše předcházející “endcsname. Zbylé neexpandovatelné tokeny musí být c_{t} (znaky s kategorií). Výsledkem expanze je token w, kde w je řetězec oněch zbylých neexpandovatelných znaků. Pokud w není v tabulce významů, je mu přidělen význam “relax (do tabulky zařazen není!).

− “expandafter ⟨token⟩ … TEX nejprve načte token t následující token “expandafter , poté TEX expanduje token t′ následující token t (kvůli expanzi tokenu t′ mohou být přečteny i další tokeny jako argumenty). Poté TEX vrátí token t^{∘} před výsledek expanze.

Příklad 3.4: Co je výsledkem expanze a^{∘}, A_{11}, “expandafter ^{∘}, “else ^{∘}, b_{13}^{∘}, B_{11}, “fi ^{∘}, C_{11}, “fi ^{∘}, pokud jsou a , b_{13} tokeny s významem “iftrue nebo “iffalse. Prozkoumejte všechny varianty.

− “noexpand⟨token⟩ … TEX nejprve načte token t následující “noexpand, výsledkem je t^{•}.

Příklad 3.5: Co je výsledkem ‘“expandafter“if“noexpand“else AB“else C“fi’?

Příklad 3.6: Co je výsledkem ‘“expandafter“csname“noexpand“endcsname’?

Příklad 3.7: Co bude výsledkem, pokud do hltanu v režimu expanzí vstupuje ‘“iftrue ^{∘}, k_{11}, o_{11}, l_{11}, o_{11}, “noexpand^{∘}, “else ^{∘}, b_{11}, ě_{11}, ž_{11}, k_{11}, y_{11}, “fi ^{∘}’?

(Vstup “iftrue kolo“noexpand“else běžky“fi při běžných “catcode.)

Příklad 3.8: Má nějaký smysl “expandafter v ‘“expandafter –“noexpand“b˝ ’?

Příklad 3.9: Co je výsledkem expanze ‘“expandafter“expandafter“noexpand“a A ’, bylo-li provedeno ‘“def“a#1–a˝ ’?

Příklad 3.10: Předpokládejme, že bylo provedeno “uccode‘“ =c, “uppercase–“def“*– ˝ ˝ , “edef“b–“noexpand“a“*˝ a “def“a#1–˝ Jak závisí expanze ‘ b , a_{11}, b_{11}’ na hodnotě c?

- “topmark, “firstmark , “botmark, “splitfirstmark a “splitbotmark … Expanzí je seznam tokenů odpovídajícího ţmark� registru.

- “input ⟨file name⟩ … Expanze je prázdná, ale TEX zaznamená dosaženou pozici v aktuálním souboru a připraví ke čtení určený soubor. Po ukončení čtení souboru pokračuje zpracování tokenů následujících za ⟨file name⟩. Pravidla na ukončení jména souboru jsou závislá na konkrétní implementaci TEXu.

- “endinput … Expanze je prázdná, ale TEX ukončí čtení aktuálního souboru při pokusu načíst další řádek vstupu.

- “the ⟨internal quantity⟩ … Expanzí je většinou textová podoba příslušné proměnné TEXu. Výjimkami jsou expanze “the⟨font⟩, vracející token, který vyvolává daný font, nebo “the⟨token variable⟩, kde výsledkem je seznam (libovolných) tokenů uložený v dané proměnné. Proměnná může mít některý z následujících významů:

. “the⟨parametr⟩ … čísla “pretolerance, “tolerance, “hbadness, “vbadness, “linepenalty, “hyphenpenalty, “exhyphenpenalty, “binoppenalty, “relpenalty, “clubpenalty, “widowpenalty, “displaywidowpenalty, “brokenpenalty, “predisplaypenalty, “postdisplaypenalty, “interlinepenalty, “floatingpenalty, “outputpenalty, “doublehyphendemerits, “finalhyphendemerits, “adjdemerits, “looseness, “pausing, “holdinginserts, “tracingonline, “tracingmacros, “tracingstats, “tracingparagraphs, “tracingpages, “tracingoutput, “tracinglostchars, “tracingcommands, “tracingrestores, “language, “uchyph, “lefthyphenmin, “righthyphenmin, “globaldefs, “defaulthyphenchar, “defaultskewchar, “escapechar, “endlinechar, “newlinechar, “maxdeadcycles, “hangafter, “fam, “mag, “delimiterfactor, “time, “day, “month, “year, “showboxbreadth a “errorcontextlines, “the⟨parametr⟩ … dimenze “hfuzz, “vfuzz, “overfullrule, “emergencystretch, “hsize, “vsize, “maxdepth, “splitmaxdepth, “boxmaxdepth, “lineskiplimit, “delimitershortfall, “nulldelimiterspace, “scriptspace, “mathsurround, “predisplaysize, “displaywidth, “displayindent, “parindent, “hangindent, “hoffset a “voffset, “the⟨parametr⟩ … glue “baselineskip, “lineskip, “parskip, “abovedisplayskip, “belowdisplayskip, “belowdisplayshortskip, “leftskip, “rightskip, “topskip, “splittopskip, “tabskip, “spaceskip, “xspaceskip a “parfillskip “the⟨parametr⟩ … matematické glue “thinmuskip, “medmuskip a “thickmuskip. . “the⟨register⟩ … čísla “count⟨8-bit number⟩, “the⟨register⟩ … dimenze “dimen⟨8-bit number⟩, “the⟨register⟩ … glue “skip⟨8-bit number⟩, “the⟨register⟩ … matematické glue “muskip⟨8-bit number⟩. . “the⟨codename⟩⟨8-bit number⟩, kde codename je buď “catcode, “mathcode, “lccode, “uccode, “sfcode nebo “delcode. . “the⟨special register⟩ … čísla “prevgraf, “deadcycles, “insertpenalties, “inputlineno, “badness a “parshape(“parshape značí pouze počet řádek), “the⟨special register⟩ … a dimenze “pagetotal, “pagegoal, “pagestretch, “pagefilstretch, “pagefillstretch, “pagefilllstretch, “pageshrink, “pagedepth, “spacefactor a “prevdepth (“spacefactor je přístupný pouze v horizontálních režimech žaludku a prevdepth je přístupný pouze ve vertikálních režimech žaludku). . “the“fontdimen⟨parameter number⟩⟨font⟩ … příslušná dimenze fontu určená z tfm souboru (viz. ). . “the“hyphenchar⟨font⟩, skewchar⟨font⟩ … tato čísla. . “the“lastpenalty, “lastkern, “lastskip … pokud poslední položka sázeného seznamu (žaludek) je příslušného typu, pak její hodnota, jinak 0 nebo 0.0pt. . “the⟨defined character⟩, kde ⟨defined character⟩ je token, jemuž byla přiřazena číselná hodnota pomocí “chardef nebo “mathchardef. … výsledkem je tato hodnota.

Tokeny expanzí “number, “romannumeral, “string, “jobname, “fontname a “the mají kategorii 12, s výjimkou , která dostává kategorii 10.

Příklad 3.11: Pokud vysázíme ‘“penalty0“skip“the“lastskip plus 0pt’, vyskytne se ‘plus 0pt’ v dvi souboru?

Syntaktická pravidla, podle nichž poznáme, kde končí ⟨number⟩ apod. uvedeme později.

4 Žaludek … Runtime:

∘ 6 různých režimů tvorby seznamů (2 horizontální, 2 vertikální a 2 matematické).

4.1 Proměnné TEXu

• Obhospodařuje zásobník následujících tabulek (lokalita unvitř group):

“catcode 256→16
“uccode 256→256 | a → A
“lccode 256→256 | A → a
“sfcode 256→2^{15} | A → 999 a → 1000 .→ 3000 (rozlišování mezer)
“mathcode 256→8 · 16^{3} | class · 16^{3} + family · 256 + char position
“delcode 256→16^{6} | small · 16^{3} + large; (family · 256 + char position)

• Obhospodařuje zásobníky následujících registrů (lokalita unvitř group):

“count  256→−2^{31} … 2^{31}
“dimen 256→−2^{30} … 2^{30} (sp)
“skip  256→glue,
“muskip 256→matematické glue,
“box  256→boxy,
“toks  256→seznam tokenů,
“read  16 →čtecí kanál,
“write  16 →kanál na zápis,
“family 16 →matematické fonty (různé velikosti)
“language 16 →čísla jazyků (tabulky dělení slov)

4.2 Příkazy nezávislé na režimu

Nesázecí příkazy (dosazování do proměnných, definice maker, “uppercase, “lowercase, “aftergroup, “afterassignment, apod.) jsou nezávislé na sázecím režimu.

4.3 Vytváření horizontálních seznamů 4.4 Vytváření vertikálních seznamů 4.5 Uzavírání seznamů do boxů 4.6 Lámání horizontálního seznamu do řádek 4.7 Lámání vertikálního seznamu do stránek 4.8 Tvorba matematického seznamu 4.9 Přepracování matematického seznamu 4.10 Komunikace s uživatelem 4.11 Tabulky 4.12 Tam kde TEX nestačí

5 Řešení příkladů … Solutions:

2.1: Výsledkem prvního je $_{3}, $_{3}, e_{11}, u_{11}, $_{3}, $_{3} výsledkem druhého je $_{3}, $_{3}, e_{11}, _{ ˆ 7}, 5_{12}, $_{3}, $_{3}.

2.2: Výsledkem prvního je u_{11}, výsledkem druhého je _{ ˆ 7}, _{ ˆ 7}, 5_{12}, což vede následně k hlášení chyby.

2.3: TeX , _{ ˆ 7}, 3_{12}, 2_{12}., _{10}, ._{12}.

2.4: j_{11}, *_{12}, 5_{12}, e_{11}, 5_{12}.

2.5: _{ ˆ 7}, _{ ˆ 7}, 5_{12}, e_{11}, 5_{12}.

2.6: Tato úloha nemá řešení. V ústech můžeme ovlivnit způsob zpracování řádku, nemůžeme ale ovlivnit čtení dalšího řádku. Chování TEXu při čtení dalšího řádku můžeme ovlivnit až v hltanu (příchodem “endinput, případně v žaludku předefinováním “catcode nebo “endlinechar). Buď tedy musí “endinput přijít do hltanu, nebo příslušný token (“catcode nebo “endlinechar) musí přijít z hltanu, to ale můžeme vyvolat jedině tak, že z úst vyjde nějaký token.

3.1: Na vstupu do hltanu jsou tokeny a , a_{11}, _{10}, b_{11}, _{10}, c_{11}, Prvním argumentem a je a_{11}, druhým argumentem je b_{11} takže po ţexpanzi� dostaneme _{10}, c_{11}.

3.2: V obou případech T.

3.3: Odlišný je seznam parametrů, proto je výsledkem F.

3.4:

F Je-li význam a “iffalse , pak jsou tokeny A_{11} a “expandafter ^{∘} ignorovány. Expanze a končí

příchodem “else ^{∘}. Výsledek je buď B_{11}, C_{11} nebo pouze C_{11} v závislosti na významu b_{13}. T Je-li význam A “iftrue, pak nejprve vystoupí A_{11} a pak je vyhodnoceno b_{13}.

F Je-li význam b_{13} “iffalse, je token B_{11} ignorován, a token “fi ^{∘} ukončí expanzi b_{13}. Poté je expandováno “else ^{∘}, které způsobí ignorování tokenu C_{11} expanze “else ^{∘} je ukončena závěrečným tokenem “fi ^{∘} (výsledkem tedy je pouze token A_{11}).

T Je-li význam b_{13} “iftrue, je jeho expanze ihned ukončena. Následuje expanze “else ^{∘} (na úrovni druhého “iftrue), která způsobí ignorování tokenu B_{11}, a je ukončena prvním “fi ^{∘}. Poté vystoupí token C_{11}, a expanze závěrečného “fi ^{∘} sníží úroveň “if …“fi na původní úroveň (výsledkem je tedy A_{11}, C_{11}).

3.5: “if porovná význam tokenu “else ^{•} (“relax… 256) s významem tokenu A_{11} (… 65). Výsledkem je false, tudíž je B_{11} pohlceno a “else ^{∘} končí expanzi “if . Poté vystoupí z hltanu token C_{11}, a “fi ^{∘} sníží úroveň vnoření “if… “fi na původní úroveň.

3.6: Výsledkem je . Všimněte si, že není požadováno “endcsname^{∘}.

3.7: k_{11}, o_{11}, l_{11}, o_{11}, “else ^{•}, b_{11}, ě_{11}, ž_{11}, k_{11}, y_{11}.

Je-li žaludek v nějakém režimu sázení, je výstup stejný, jako při běžných “catcode při vstupu ‘koloběžky’. Pokud však žaludek daný seznam tokenů něčemu přiřadí, výsledkem pro přiřazení bude k_{11}, o_{11}, l_{11}, o_{11}, “else , b_{11}, ě_{11}, ž_{11}, k_{11}, y_{11}.

3.8: Ano, v případě, kdyby měly například –, ˝ omezovat tokeny které mají být přiřazeny bez předchozí expanze (např. “def ). Bez “expandafter ^{∘} je výsledkem ‘“noexpand, b ’. Díky “expandafter je výsledkem ‘ b ’. Pokud však mají být tokeny uvnitř – a ˝ expandovány, výsledek je v obou případech stejný … –, b^{•}, ˝

3.9: Po expanzi prvního “expandafter dostaneme ‘“expandafter ^{∘}, a^{•}, A_{11}’. Po expanzi druhého “expandafter dostaneme ‘ a^{∘}, A_{11}’. Po expanzi a^{∘} dostaneme ‘a_{11}’, což poté výstoupí z hltanu.

3.10: Expanzí * je c_{10}, expanzí b je a , c_{10} a expanze a , c_{10}, a_{11}, b_{11} závisí na tom, zda c = ‘“ . Pokud ano, pak prvním argumentem je a_{11}, takže po ţexpanzi� dostaneme b_{11}. Pokud c ≠ ‘“ , pak je prvním argumentem c_{10}, takže po expanzi dostaneme a_{11}, b_{11}.

3.11: Ne.