Predefinovani pismene v makru

Rylek Tomas RYLEK at cslab.felk.cvut.cz
Wed Nov 20 12:58:52 CET 1996


    Vazeny pane kolego!

> Mohu se zeptat, proc zde nepomuze \edef ?
>  \edef\NewKeyboard{
>  \catcode`\o=\active \def o{XYZ}
>  Kudrnovo kolo
>  }
>  \begin{document}
>  \NewKeyboard
>  \end{document}
>
> (Zkousel jsem to a TeX hlasi tutez chybu...)

Problem je v tom, ze zpracovani zdrojoveho textu v TeXu se sklada z
nekolika fazi; pokud jste se nekdy zabyval teorii prekladacu, budete
urcite hned vedet, o cem mluvim.

Na zacatku je tzv. lexikalni analyzator; ten cte vstupni text a
rozklada ho na logicky souvisejici shluky znaku - klicova slova
(sekvence zacinajici lomitkem), mezery, znaky `konec radku' a ostatni
znaky. Knuth tuto cast ve sve knize TeXBook nazyva `mouth' (usta
TeXu). Vystupem z ni je posloupnost znaku a klicovych slov, kterym se
od teto chvile rika `tokens'. Kazdy `token' je `okomentovan' cislem,
ktere udava jeho logicky typ: napriklad leva slozena zavorka ma typ
1, prava 2 atd. Tech typu je celkem 16.

Lexikalni analyzator pri analyze vstupniho souboru provadi analyzu a
prirazovani kodu na zaklade vnitrni prevodni tabulky, ktera kazdemu z
256 ASCIIZ znaku prirazuje jeho kod. Takze napriklad kdyz se nacte
znak, kteremu odpovida kod `escape' (implicitne je to zpetne
lomitko), nacitaji se dal znaky, oznacene v tabulce kodem `pismeno'.
Po nalezeni prvniho znaku, ktery neni `pismeno', se preskoci
libovolny pocet znaku `mezera' a drive nactena sekvence `pismen' se
spoji v klicove slovo, ktere se zaradi do nejake vnitrni hashovaci
tabulky a do fronty `tokenu' se vlozi jeho poradove cislo v teto
tabulce.

V minulem odstavci jsem pouzival schvalne uvozovky u slov jako
`pismeno', `mezera' atd., abych zduraznil, ze nemusi nutne jit o
`opravdova' pismena; jsou to proste libovolne ASCIIZ znaky, kterym je
v jiz zminene prevodni tabulce prirazen typ `pismeno' (cislo tohohle
kodu si z hlavy nepamatuju - myslim, ze je to 11 nebo neco okolo
toho).

Tim se napriklad vysvetluje, proc v souborech, psanych v LaTeXu
nemuzete bezne pouzivat identifikatory (nazvy maker) se znakem `@',
zatimco v samotnem souboru latex.tex je jich az hanba: na zacatku
prekladu souboru latex.tex se totiz nastavi, ze znak `@' je
`pismeno', takze `usta' TeXu jej klidne sni jako soucast klicovych
slov. Jako jeden z poslednich prikazu v souboru latex.tex je

    \makeatother

ktery nastavi znaku `@' (v anglictine se mu rika `at-sign', proto to
at) typ `other' - tedy jiny znak, coz souhrnne oznacuje napr.
interpunkci. Od te chvile (do pouziti prikazu

    \makeatletter

) znak `@' v identifikatorech pouzivat nelze.

Popsana prevodni tabulka se ridi prikazem \catcode ASCII-
kod=logicky kod. Takze pokud napriklad date

    \catcode`o=\active

nastavi se do prevodni tabulky, ze `o' ma kod `active' (12 nebo 13,
nejsem si ted jist). Problem je, ze se to provede AZ PO PROVEDENI
prikazu \catcode.

Pokud mate ve zdrojovem souboru prikaz \edef\neco{neco jineho}, nacte
se nejprve z `ust' cely obsah slozenych zavorek; nezpracuje se, jenom
se nacte, token po tokenu. Takto se nacte i token \catcode, ale jenom
se nacte - nezpracovava se. Po tokenu \catcode, tokenu `, tokenu \o,
tokenu =, tokenu \active a tokenu \def se tedy nacte token o - ale
jeste se starym kodem znaku `o', coz je LETTER (protoze \catcode se
zatim neprovedl). Nacitani retezce ve slozenych zavorkach je vlastne
soucasti vnitrniho predzpracovani argumentu pro JAKYKOLI prikaz
(predstavte si, jako kdyby nekde uvnitr TeXu bylo systemove receno
neco jako

    \def\edef#1#2{definuj makro #1 jako expandovany retezec #2}.

Takze kdyz se vyvola prikaz \edef, dostane jako parametry jiz
zpracovany (snedeny) retezec ve slozenych zavorkach. Ten zacne
zpracovavat - expanduje ho; pri teto expanzi se sice provede prikaz
\catcode, takze v prevodni tabulce se na pozici znaku `o' zapise kod
\active, ale prevodni tabulka se uz v tuto chvili vubec nepouzije -
protoze znak o je uz proste nacteny a prelozeny na token. Takze
nasledujici prikaz \def zjisti, ze jeho prvni parametr (znak `o') ma
typ LETTER - a ohlasi chybu, protoze prvni parametr prikazu \def musi
byt bud \active, nebo klicove slovo.

Takze opravdu je treba PRED ZAPOCETIM definice \def zmenit \catcode.

Omlouvam se, ze jsem se tak rozepsal, ale mel jsem pocit, ze by se
tu a tam nekomu mohla hodit presnejsi predstava o tom, jak TeX pri
zpracovani textu postupuje.

P.S.: Dalsi prikazy, ktere s timto tematem souviseji, jsou napr.
\csname & \endcsname a \string.

                                                   S pozdravem

                                                        Tomas Rylek



More information about the csTeX mailing list