summaryrefslogtreecommitdiff
path: root/macros/generic/docbytex/docby.d
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/generic/docbytex/docby.d
Initial commit
Diffstat (limited to 'macros/generic/docbytex/docby.d')
-rw-r--r--macros/generic/docbytex/docby.d2635
1 files changed, 2635 insertions, 0 deletions
diff --git a/macros/generic/docbytex/docby.d b/macros/generic/docbytex/docby.d
new file mode 100644
index 0000000000..4404875f3a
--- /dev/null
+++ b/macros/generic/docbytex/docby.d
@@ -0,0 +1,2635 @@
+
+%% DocBy.\TeX{} -- nástroj na dokumentování zdrojových kódů
+
+\def\projectversion{\dbtversion}
+\def\headtitle{DocBy.\TeX}
+
+\showboxbreadth=1500 \showboxdepth=2
+
+\chyph
+\input docby.tex
+
+\title DocBy.\TeX{} -- nástroj na dokumentování zdrojových kódů
+
+\author Petr Olšák
+
+\centerline{\ulink[http://www.olsak.net/docbytex.html]%
+ {www.olsak.net/docbytex.html}}
+
+\def\db{\dg\nb}
+\def\du#1{\api{\nb#1}}
+\let\quotehook=\langleactive
+\def\insdef#1 {\ifirst{docby.tex}{def\nb#1 }{^^B\cbrace}{++}}
+\def\inssdef#1 {\ifirst{docby.tex}{def\nb#1}{\empty}{+-}}
+\bgroup
+ \catcode`\[=1 \catcode`]=2 \catcode`\{=12 \catcode`\}=12
+ \gdef\obrace[{] \gdef\cbrace[}]
+\egroup
+\def\indexhook{Kontrolní sekvence označené šipkou ($\succ$) jsou
+ uživatelskými příkazy. Ostatní kontrolní sekvence jsou
+ v~DocBy.\TeX{}u interní. Tučně je označena strana, kde je slovo
+ dokumentováno, pak následuje seznam stran s výskyty slova.
+ Uživatelské příkazy mají v seznamu stránek podtržené číslo,
+ což je stránka, kde je příkaz vyložen na uživatelské úrovni.
+ \medskip}
+\def\nn#1 {\noactive{\nb#1}} \nn insert \nn undefined
+
+\def\cnvbookmark#1{\lowercase{\lowercase{#1}}}
+\def\bookmarkshook{\lo ěe \lo šs \lo čc \lo řr \lo žz \lo ýy
+ \lo áa \lo íi \lo ée \lo úu \lo ůu \lo óo \lo ňn }
+\def\lo #1#2{\lccode`#1=`#2}
+
+\dotoc \bookmarks
+
+\sec Úvod
+%%%%%%%%%
+
+DocBy.\TeX{} umožňuje jednoduše dokumentovat pomocí \TeX{}u
+zdrojové kódy programu napsaném v~jazyce~C případně v jakémkoli
+jiném jazyce.
+
+Na rozdíl od Knuthova literárního programování tento nástroj nepoužívá
+žádné preprocesory nebo filtry pro oddělení informace pro člověka a
+pro počítač. Vycházím z toho, že programátor je zvyklý psát tyto
+informace odděleně a chce mít věci pod vlastní kontrolou. Rovněž mnozí
+programátoři uvítají, že mohou psát dokumentaci dodatečně, a přitom
+skoro nezasahovat do už napsaného (a možná odladěného) zdrojového
+kódu. Doba, kdy Knuth navrhoval literární programování, pokročila a
+tvůrce dokumentace dnes může mít zároveň ve více oknech otevřeno více
+textů. Některé jsou určeny pro člověka a jiné pro počítač. Nevnímám
+tedy tak hlasitou potřebu tyto informace slučovat do jednoho
+souboru, jako tomu bylo kdysi.
+
+V první části (sekce~\cite[uziv]) dokumentu seznamujeme čtenáře
+s použitím \docbytex{}u na uživatelské úrovni. V další sekci jsou
+dokumentovaná výchozí makra \docbytex{}u, u nichž se předpokládá, že
+je bude chtít náročný uživatel měnit, aby přizpůsobil chování \docbytex{}u
+obrazu svému. Dále následuje sekce~\cite[design] s dokumentací
+maker, která rovněž budou měněna, pokud uživatel bude chtít jiný
+vzhled dokumentu. V~poslední sekci~\cite[implementace]
+je dokumentován kompletní \docbytex{} na implementační úrovni.
+Takže se tam můžete dočíst, jak makra fungují.
+
+Tento dokument je zpracován \docbytex{}em, takže slouží mimo jiné jako
+ukázka, co je možné tímto nástrojem vytvořit.
+
+\sec [uziv] Pro uživatele
+%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\subsec [cleneni] Členění souborů
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\docbytex{} je implicitně navržen pro dokumentování zdrojových kódů
+v~jazyce~C. Proto i následující ukázka dokumentuje hypotetický program
+napsaný v tomto jazyce. Chcete-li dokumentovat jiný jazyk, můžete
+implicitní chování \docbytex{}u pozměnit. Tomu je věnována
+sekce~\cite[zmeny].
+
+Předpokládá se, že zdrojové kódy programu jsou členěny na moduly. Každý modul
+je myšlenkově samostatná záležitost. Alespoň pro programátora. Každý modul
+má své jméno (například "cosi") a je napsán v souborech "cosi.h" a "cosi.c",
+případně v dalších. Tyto soubory se kompilují, aby vznikl "cosi.o" a
+v~závěru kompilace se linkují všechny kompilované moduly do výsledného
+programu.
+
+Chceme-li takové zdrojové kódy dokumentovat, připíšeme ke každému
+modulu soubor s příponou ".d", například "cosi.d", který obsahuje
+dokumentaci k danému modulu. Dále založíme třeba soubor
+"program.tex", ze kterého postupně načítáme dokumentace jednotlivých
+modulů pomocí příkazu "\module"\du{module}. V \uv{hlavním souboru} "program.tex"
+můžeme též použít příkazy "\title" pro vyznačení názvu programu,
+"\author" se jménem autora programu a třeba "\dotoc" pro vytvoření
+obsahu a "\doindex" pro vygenerování rejstříku. Samozřejmě zde můžeme
+napsat třeba úvodní poznámky ke zdrojovým kódům programu a použít plno
+dalších vymezovacích příkazů (viz dále). Obsah souboru "program.tex"
+může vypadat třeba takto:
+
+\begtt
+\input docby.tex
+\title Program lup -- dokumentace ke zdrojovým textům
+
+\author Progr a Mátor
+
+\dotoc % tady bude obsah
+
+\sec Členění zdrojových textů
+
+Zdrojové texty programu "lup" jsou rozděleny do tří modulů.
+V "base.c" jsou definovány pomocné funkce a v "base.h" jsou jejich
+prototypy. Podobně ve "win.c" jsou funkce pro okenní záležitosti a
+"win.h" obsahuje jejich prototypy. Konečně "main.c" obsahuje hlavní
+funkci programu.
+\module base
+\module win
+\module main
+\doindex % v tomto místě bude sestaven rejstřík
+\bye
+\endtt
+
+V tomto příkladě jsme se rozhodli čtenáře dokumentace seznamovat s
+programem \uv{zdola nahoru}, tedy od elementárních funkcí až k hotovému
+programu. Někdo možná preferuje cestu \uv{shora dolů} a může mít v
+dokumentaci napsáno:
+
+\begtt
+\module main
+\module win
+\module base
+\doindex
+\bye
+\endtt
+
+Oba přístupy jsou možné, protože dokumentace je automaticky provázána
+hyperlinky. Čtenář se kdykoli může podívat na dokumentaci té funkce,
+jejíž použití zrovna čte, a obráceně může projít výskyty veškerého
+použití funkce, když čte její dokumentaci.
+
+\subsec [priklad] Příklad dokumentace modulu
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Soubor s dokumentací jednotlivého modulu budu pro tento
+případ značit "cosi.d". Ten je načten příkazem "\module"~"cosi ".
+V souboru "cosi.d" je možno se literárně vyřádit a kdykoli vložit část
+existujícího zdrojového kódu programu se stejným jménem modulu.
+To provedeme příkazem "\ins"~"c keyword "\du{ins}, který vloží do dokumentace
+část zdrojového kódu ze souboru "cosi.c", která je vymezena pomocí slova
+"keyword". Místo písmene "c" je možno použít "h" nebo jakoukoli jinou
+příponu souboru, ze kterého chceme vložit část do dokumentace. K
+vymezení částí, které se mají vložit, je nutno mít ve zdrojovém
+souboru text "//: keyword". Vše vysvětlí následující příklad.
+
+Předpokládejme, že v souboru "cosi.d" máme napsánu tuto dokumentaci:
+
+\begtt
+Struktura \dg dvojice se používá jako návratová hodnota funkce
+"uzasna_funkce" a sdružuje dvě hodnoty typu "float".
+\ins c dvojice
+
+Funkce \dg [struct dvojice] uzasna_funkce() si vezme jeden parametr "p"
+a vrátí ve struktuře "dvojice" dvojnásobek a trojnásobek tohoto parametru.
+\ins c uzasna_funkce
+\endtt
+
+V tomto případě je nutné, aby v souboru "cosi.c" existoval vymezující
+text "//: "{\tt dvojice} a text "//: "{\tt uzasna\_funkce}.
+Tyto texty vymezují úseky,
+které se mají do dokumentace vložit. Soubor "cosi.c" může vypadat
+třeba takto:
+
+\begtt
+#include <stdio.h>
+
+//: dvojice
+
+struct dvojice {
+ float x, y;
+};
+
+//: uzasna_funkce
+
+struct dvojice uzasna_funkce (float p)
+{
+ struct dvojice navrat;
+ navrat.x = 2*p; // tady nasobim p dvema
+ navrat.y = 3*p; // tady nasobim p tremi
+ return navrat;
+}
+\endtt
+
+Výsledek po zpracování části dokumentace z "cosi.d" pak vypadá takto:
+
+\bigskip
+
+Struktura \dg [struct] dvojice se používá jako návratová hodnota funkce
+"uzasna_funkce" a sdružuje dvě hodnoty typu "float".
+\def\modulename{cosi}
+\ins c dvojice
+
+Funkce \dg [struct dvojice] uzasna_funkce() si vezme jeden parametr "p" a vrátí
+ve struktuře "dvojice" dvojnásobek a trojnásobek tohoto parametru.
+\ins c uzasna_funkce
+
+V ukázkovém zdrojovém kódu je první vložený úsek vymezen na
+začátku textem "//: "{\tt dvojice} a na konci textem "//:". Druhý úsek je
+vymezen textem "//: "{\tt uzasna\_funkce} a končí na konci souboru.
+
+Na pořadí úseků, které zahrnujeme ze zdrojového textu do dokumentace,
+nezáleží. Klidně jsme mohli dokumentaci začít od povídání o úžasné
+funkci (včetně vložení jejího kódu) a potom ještě dopsat, co to je ta
+struktura "dvojice" a následně vložit deklaraci této struktury.
+
+Kdybychom před řádek "#include "{\tt<stdio.h>} vložili třeba text
+"//: start", bylo by možné příkazem "\ins"~"c start " vložit
+do dokumentace začátek souboru "cosi.c", který v ukázce vložen není.
+
+Všimněme si, že \TeX{} zapsal čísla řádků přesně podle toho, jak
+jsou ve zdrojovém kódu. Tj. počítal i přeskakovaný řádek
+"#include "{\tt<stdio.h>} i přeskakované prázdné a vymezující řádky.
+
+Vymezení "//: keyword" se může v řádku nacházet kdekoli, není nutné,
+aby se vyskytovalo na začátku řádku. Řádek s~tímto vymezením není do
+dokumentace zahrnut a pokud následuje za řádkem s~vymezením prázdný
+řádek, ani ten není do dokumentace zahrnut.
+
+Stejně tak koncové vymezení "//:" se může v řádku nacházet kdekoli a
+celý řádek s tímto vymezením není do dokumentace zahrnut.
+Pokud před tímto koncovým řádkem je prázdný řádek, ani ten
+není do dokumentace zahrnut.
+
+Konečně za povšimnutí stojí použití příkazu "\dg" v dokumentaci. Za
+ním následuje slovo (separované mezerou), které dokumentujeme. Toto
+slovo se v dokumentaci výrazně označí (v PDF verzi červenou barvou
+navíc v barevném rámečku) a jakýkoli jiný výskyt takového slova ve
+zdrojovém textu nebo mezi uvozovkami {\tt\char`\"...\char`\"} bude
+automaticky označen modrou barvou a bude klikací. Kliknutí na modrý
+výskyt slova kdekoli v dokumentaci vrátí čtenáře na červený výskyt,
+kde je slovo dokumentováno.
+
+Dokumentované slovo může mít před sebou v hranatých závorkách text,
+který např. označuje typ funkce a za sebou může mít kulaté závorky
+"()". Tím můžeme dát najevo, že dokumentujeme funkci. V místě
+dokumentace se neobjeví ani tento nepovinný text ani závorky, ale v
+poznámce pod čarou a v~rejstříku se tyto informace vytisknou.
+
+\uv{Palcové uvozovky} {\tt\char`\"...\char`\"} vymezují kusy kódu
+uvnitř odstavce. Text takto uvozený je psán strojopisem a pokud se
+v něm vyskutují deklarovaná slova, tato slova automaticky modrají
+a stávají se klikatelnými odkazy.
+Text mezi těmito uvozovkami je navíc přepisován ve \uv{verbatim}
+módu \TeX{}u, tj. žádné znaky nemají speciální vlastnosti (s výjimkou
+koncové palcové uvozovky).
+
+Na stránce, kde je slovo dokumentováno (pomocí "\dg"), je v poznánkách
+pod čarou slovo znovu zmíněno a vedle této zmínky je seznam všech
+stránek, na kterých se kdekoli v textu vyskytuje použití tohoto slova.
+Dále jsou všechna dokumentovaná slova zahrnuta do závěrečného
+abecedního rejstříku, který odkazuje jednak na stránku, kde je
+slovo dokumentováno, i na stránky se všemi výskyty slova.
+
+
+\subsec Jaký \TeX{} pro \docbytex{}?
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Aby fungovaly všechny výše uvedené vlastnosti, je potřeba použít
+pdf\TeX{} rozšířený o enc\TeX{}. Dále je dle "\language" detekován
+jazyk, který se použije v automaticky generovaných slovech.
+\docbytex{} se ohlásí na terminálu například těmito slovy:
+
+\def\begtthook{\catcode`\!=0}
+\begtt
+This is DocBy.TeX, version !dbtversion, modes: enc+PDF+ENG
+\endtt
+
+\def\begtthook{}
+
+\docbytex{} rozlišuje tři módy, každý může nabývat dvou stavů:
+mód "enc/NOenc", dále mód "PDF/DVI" a konečně mód jazyka "ENG/CS".
+
+Mód "enc"\api{enc} se zapne, je-li detekována přítomnost enc\TeX{}u.
+Pokud enc\TeX{} není dostupný, vypíše o~tom \docbytex{} varování a
+přejde do "NOenc"\api{NOenc} módu. V tomto módu nefunguje automatická detekce
+slov, která jsou dokumentována, takže tato slova nemodrají a nestávají
+se klikacími odkazy. V rejstříku pak také není seznam stránek se všemi
+výskyty slova, ale jen místo, kde je slovo dokumentováno.
+V~tomto případě tedy je deaktivována nejdůležitější vlastnost
+\docbytex{}u, takže je žádoucí vynaložit jisté úsilí a enc\TeX{}
+zprovoznit. V současných distribucích \TeX{}u bývá enc\TeX{}
+v pdf\TeX{}u zahrnut a je aktivován například ve formátu "pdfcsplain".
+
+Mód "PDF"\api{PDF} je detekován, pokud je použit pdf\TeX{}, jinak \docbytex{}
+přejde do módu "DVI"\api{DVI} a napíše o tom varování na terminál. V módu "DVI"
+nefungují barvy ani klikací odkazy. Ovšem seznam stránek s~použitím
+dokumentovaného slova se generuje, je-li přítomen enc\TeX.
+
+\docbytex{} detekuje mód jazyka "ENG" (angličtina), je-li
+"\language=0". To je implicitní chování.
+Pokud například v "csplainu" nastavíte "\chyph" před
+"\input docby.tex", \docbytex{}
+to vyhodnotí jako dokument v češtině ("CS").
+Jiné jazyky nejsou zatím podporovány.
+V módu "ENG" jsou automaticky generované názvy
+\uv{Contents}, \uv{Index} anglické,
+v módu "CS" jsou tyto názvy \uv{Obsah}, \uv{Rejstřík} české.
+V~sekci~\cite[nazvy] je řečeno, jak jsou tato slova generována
+a co tedy udělat, když chcete mít dokument v jiném jazyce.
+
+\subsec Vyhledávání slov enc\TeX{}em
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Slova, která se stávají klikatelnými odkazy vyhledává enc\TeX{}. Ten
+má zabudován tzv. \uv{hladový algoritmus}. To znamená, že jsou-li
+dokumentována např. slova "abc" a "abcde", pak text "abcdefgh" zmodrá
+až po písmeno "e" a odkazuje na "abcde", zatímco "abcdx" zmodrá až po
+písmeno "c" a odkazuje na "abc". To bývá obvykle žádoucí.
+%
+V enc\TeX{}u není možno programovat vyhledávání podle regulárních
+výrazů, takže není možné jednoduše říci, aby enc\TeX{} hledal jen
+slova, která jsou ohraničena mezerou, tečkou, závorkou, středníkem,
+atd. Místo toho enc\TeX{} tupě vyhledá slovo třeba uvnitř jiného slova.
+
+Může se tedy stát, že máme dokumentováno kratší slovo, které se
+objevuje jako část jiných nedokumentovaných slov. Například je
+dokumentována struktura "turn", ale ve výpisech programu nechceme, aby
+v každém výskytu klíčového slova "return" zmodrala jeho část. V
+takovém případě je potřeba explicitně definovat "return" jako
+\uv{normální} nedokumentované slovo. K tomu slouží příkaz
+"\noactive{<slovo>}"\du{noactive}, tedy například
+"\noactive{return}". Tento příkaz globálně
+deklaruje "<slovo>" jako vyhledávané slovo (pro enc\TeX), ale
+specifikuje jej jako neaktivní.
+
+Může se také stát, že máme dokumentováno slovo, které se objevuje ve
+zdrojových textech i v jiném (nedokumentovaném) významu. Přitom dokumentované
+slovo poznáme podle toho, jak vypadá text před slovem a za slovem.
+Pak lze použít deklaraci "\onlyactive{<před>}{<slovo>}{<za>}"\du{onlyactive},
+která sama o sobě nedělá nic. Pokud ale vyznačíme "<slovo>" pomocí
+"\dg" (nebo podobného makra na dokumentování slov, viz
+sekce~\cite[ddsl]), pak bude "<slovo>" automaticky modrat jen tehdy,
+předchází-li mu text "<před>" a následuje text "<za>". Texty "<před>"
+nebo "<za>" mohou být prázdné (ne oba současně) a k jednomu "<slovu>"
+můžeme napsat více různých deklarací "\onlyactive".
+
+\docbytex{} aktivuje enc\TeX{} (pomocí "\mubytein=1") jen uvnitř
+skupiny, když zpracovává text mezi palcovými uvozovkami
+({\tt\char`\"...\char`\"}) nebo při načítání zdrojového textu
+programu. Předpokládá se, že nepoužíváte enc\TeX{} k~dekódování UTF-8
+kódu. Pokud používáte, zkuste si zapnout "\mubytein=1" pro celý dokument,
+ale na {\it vlastní riziko}. V takovém případě vám budou modrat slova
+nebo jejich části i v~běžném textu a pokud je dokumentované slovo
+podmnožinou nějaké \TeX{}ové sekvence, kterou používáte, pak se
+dočkáte nepříjemných chyb.
+
+\subsec Generování rejstříku, obsahu, poznámek pod čarou a záložek
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Generování rejstříku i obsahu probíhá v \docbytex{}u zcela
+automaticky. Pro vytvoření rejstříku není nutné používat externí
+program (\docbytex{} si slova abecedně zatřídí sám).
+Stačí tedy vložit na požadovaná místa příkazy "\dotoc"\du{dotoc} a
+"\doindex"\du{doindex}. Upozorňuji, že rejstřík ani obsah nejsou správně
+vygenerovány po prvním průchodu \TeX{}u. Je potřeba \TeX{}ovat
+dvakrát. Po druhém průchodu dojde zřejmě k přestránkování textu
+(protože je například vložen obsah). Je tedy nutné \TeX{}ovat ještě
+jednou. Tři průchody \TeX{}em jsou (snad) dostačující.
+Slovo \uv{snad} vychází z problému s poznámkami pod čarou podrobně
+popsaném v sekci~\cite[specfootnote].
+Poznámky pod čarou se totiž průběžně v průchodech mění a ovlivňují
+zpětně vertikální sazbu. \docbytex{} proto provádí na konci zpracování
+v příkaze "\bye"\du{bye} kontrolu, zda nedošlo ke změnám v referencích.
+Je proto užitečné používat "\bye" místo "\end".
+V závěru zpracování pak \docbytex{} vypíše zprávu
+"OK, all references are consistent" nebo vypíše
+varování, že některé reference jsou nekonzistentní a
+že je tedy potřeba \TeX{}ovat znovu.
+
+Další test konzistence můžeme provést například následujícím skriptem:
+
+\begtt
+#!/bin/bash
+cp dokument.ref dokument.r0
+pdfcsplain dokument.d
+diff dokument.r0 dokument.ref
+\endtt
+
+\docbytex{} se snaží (z důvodu záruky konvergence dokumentu) fixovat
+zpracování poznámek pod čarou po druhém průchodu. Pokud poté měníte
+rozsáhle dokument, takže seznamy stránek vedle poznámek pod čarou jsou
+výrazně jiné délky, \docbytex{} to nepozná a může docházet
+k přeplnění nebo nenaplnění stránek. V takovém případě je rozumné
+vymazat soubor {\tt.ref} a znovu spustit tři průchody.
+
+Pro vytvoření záložek se strukturovaným obsahem v PDF výstupu slouží
+příkaz "\bookmarks"\du{bookmarks}. Je zcela jedno, v které části
+dokumentu je tento příkaz napsaný, neboť sestaví stukturovaný seznam
+záložek prolinkovaný s dokumentem na základě údajů ze souboru~{\tt.ref}.
+Může se stát, že některé texty v záložkách nejsou optimálně čitelné. O
+možnostech, jak toto řešit, pojednává sekce~\cite[hooky].
+
+\subsec [vkladani] Vkládání zdrojových textů podrobněji
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Kromě jednoduchého příkazu "\ins" na vkládání zdrojových textů jsou
+k dispozici příkazy "\ifirst"\du{ifirst} a "\inext"\du{inext},
+které nabízejí uživateli
+daleko více možností.
+
+Příkaz "\ifirst{<soubor>}{<odkud>}{<kam>}{<jak>}" vloží do
+dokumentu část souboru "<soubor>" (plný název souboru včetně přípony)
+od prvního řádku, na kterém se vyskytuje text "<odkud>" po
+řádek, na kterém se vyskytuje text "<kam>", nebo (pokud text "<kam>"
+nelze nalézt) po konec souboru. Neexistuje-li ani řádek s textem
+"<odkud>", \docbytex{} vypíše pouze varování na terminál.
+
+Příkaz "\ifirst" si své parametry nejprve
+expanduje a pak teprve použije.
+Aktivní vlnka v parametru expanduje na mezeru.
+
+Parametr "<jak>" udává, zda se bude tisknout výchozí řádek (s~textem
+"<odkud>") a koncový řádek (s~textem "<kam>"). Tento parametr obsahuje
+právě dva znaky (plus nebo mínus) s následujícím významem:
+
+\begtt
+jak: -- netiskne se výchozí ani koncový řádek
+jak: +- tiskne se výchozí řádek a netiskne se koncový řádek
+jak: -+ netiskne se výchozí řádek, tiskne se koncový řádek
+jak: ++ tisknou se oba řádky
+\endtt
+
+Je-li parametr "<odkud>" prázdný (zapíšeme pomocí "{}"), tiskne se od
+začátku souboru. Je-li parametr "<kam>" prázdný, tiskne se jediný řádek.
+Je-li parametr "<kam>=\end",\du{end} tiskne se až do konce souboru.
+Koncový řádek v tomto případě neexistuje.
+
+Má-li parametr "<odkud>" (nebo "<kam>") hodnotu "\empty"\du{empty}
+(zapíšeme pomocí "{\empty}"), tiskne se od (nebo do) prvního prázdného řádku.
+Parametr "<jak>" ovlivní jeho tisk.
+
+Parametry "<odkud>" nebo "<kam>" mohou mít na svém začátku znak "^^B"
+(tím dáváme najevo, že text musí na řádku začínat) nebo na svém konci
+znak "^^E" (tím dáváme najevo, že text musí na řádku končit). Takže
+třeba "^^Btext^^E" znamená, že se vyhledává řádek, ve kterém je pouze
+"text" a nic jiného.
+
+V parametrech "<odkud>" a "<kam>" se nesmějí vyskytovat speciální
+\TeX{}ové znaky (speciální kategorie). Pro použití znaků
+"\", "{", "}", "%" a {\tt\char`\"} v těchto parametrech jsou
+v~\docbytex{}u připraveny zástupné kontrolní
+sekvence "\nb"\du{nb}, "\obrace"\du{obrace}, "\cbrace"\du{cbrace},
+"\percent"\du{percent} a "\inchquote"\du{inchquote}.
+Sekvence pro další speciální
+znaky "#", "$", atd. si musíte vytvořit např. pomocí:
+
+\begtt
+{\catcode`\#=12 \gdef\vezeni{#}}
+\endtt
+
+Jsou-li parametry "<odkud>" a "<kam>" stejné, nebo oba texty jsou na
+stejném řádku, pak se při "<jak>=++" nebo "<jak>=+-" vytiskne
+tento jeden řádek. Při "<jak>=-+" nebo "<jak>=--" se tiskne až
+do konce souboru nebo do dalšího výskytu textu "<kam>".
+
+Příkaz "\ifirst" si zapamatuje název čteného souboru a pozici
+posledního přečteného řádku v~daném souboru. Pak je možné použít
+příkaz "\inext{<odkud>}{<kam>}{<jak>}", který začíná hledat výchozí řádek
+s textem "<odkud>" od místa v souboru, kde naposledy skončilo čtení
+příkazem "\ifirst" nebo "\inext". Parametry "<odkud>", "<kam>" a "<jak>"
+mají stejný význam, jako u příkazu "\ifirst".
+
+V registru "\lineno"\du{lineno} je po ukončení příkazu "\ifirst" nebo "\inext"
+číslo řádku, které bylo naposledy přečteno (třebaže tento řádek nebyl
+vytištěn). Pokud bylo dosaženo konce souboru, obsahuje "\lineno"
+počet řádků souboru. Pomocí "\ifeof\infile" je možné se zeptat, zda
+bylo dosaženo konce souboru.
+
+Příklady
+
+\begtt
+\ifirst {soubor.txt}{textik}{textik}{++} % vytiskne první výskyt řádku
+ % obsahující slovo textik
+\inext {textik}{textik}{++} % vytiskne následující výskyt
+ % řádku obsahující slovo textík
+\ifirst {soubor.c}{//: odkud}{//:}{--} % analogie příkazu \ins
+\ifirst {soubor.c}{funkce(}{)}{++} % tisk prototypu funkce
+\ifirst {soubor.c}{funkce(}{^^B\cbrace}{++} % tisk celého kódu funkce
+\ifirst {soubor.txt}{}{\end}{++} % tisk celého souboru
+\ifirst {soubor.txt}{}{\empty}{+-} % tisk po prázdný řádek
+\endtt
+
+Je-li první řádek, který se má tisknout, prázdný, netiskne se. Je-li
+poslední řádek, který se má tisknout, prázdný, také se netiskne. Toto
+je implicitní chování. Pokud napíšete "\skippingfalse",\du{skippingfalse}
+uvedená inteligence je zrušena a přepisují se i prázdné řádky vpředu a vzadu.
+Příkazem "\skippingtrue"\du{skippingtrue} se vrátíte k původnímu nastavení.
+
+Parametrům "<odkud>" a "<kam>" může předcházet text
+"\count=<číslo> ".\du{count} Hodnota "<číslo>" označuje,
+kolikátý výskyt textu "<odkud>" nebo "<kam>" se má použít.
+Například "{\count=3 <odkud>}" znamená, že se má
+při vyhledávání "<odkud>" přeskočit dva jeho výskyty a začít
+přepisovat soubor až od výskytu třetího. Podobně "{\count=5 <kam>}"
+značí, že se při přepisování souboru ignorují čtyři výskyty "<kam>" a
+přepisování se zastaví až u výskytu pátého.
+
+Implicitně, není-li "\count=<číslo> " uvedeno, předpokládá se
+"\count=1 ".
+
+Pokud je text "<odkud>" prázdný, pak
+"\count" označuje číslo řádku, na kterém se má zahájit výpis. Je-li
+prázdný parametr "<kam>", pak "\count" označuje počet přepisovaných
+řádků. Toto platí pro "<jak>=++" a pro "\skippingfalse".
+Při jiných hodnotách "<jak>" se
+uvedená čísla logicky posunou o jedničku. Při prázdném "<odkud>" nebo
+"<kam>" není mezera za "\count=<číslo>" povinná. Příklady:
+
+\begtt
+\skippingfalse
+\ifirst {soubor.txt}{\count=20}{\count=10}{++} % tisk řádků 20 až 29
+\ifirst {soubor.txt}{}{\count=2 \empty}{+-} % tisk po druhý prázdný řádek
+\ifirst {soubor.txt}{\count=50}{\end}{++} % tisk od 50. řádku do konce
+\ifirst {soubor.tex}{\count=5 \nb section}{\count=2 \nb section}{+-}
+ % tisk páté sekce z TeXového souboru
+\endtt
+
+
+\subsec [lineodkazy] Odkazy na čísla řádků
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Pomocí "\cite[<lejblík>]" je možné odkazovat na číslo řádku ve výpisu
+zdrojového kódu. Tento příkaz se promění na skutečné číslo řádku.
+Před použitím příkazu "\ifirst" nebo "\inext" je nutné "<lejblík>"
+deklarovat příkazem "\ilabel [<lejblík>]{<text>}".\du{ilabel}
+Těchto příkazů může být před použitím "\ifirst" resp. "\inext" více.
+Na pořadí příkazů "\ilabel" před jedním "\ifirst" nebo "\inext" nezáleží.
+
+Existují-li deklarované "<lejblík>"y a "<text>"y, pak příkaz
+"\ifirst" nebo "\inext" si všímá výskytu "<text>"u ve vkládaných
+řádcích. Pokud takový "<text>" najde, přiřadí číslo řádku
+odpovídajícímu "<lejblík>"u, takže příkaz "\cite" bude fungovat, jak má.
+
+Parametr "<lejblík>" musí být jednoznačný v celém dokumentu. Příkaz
+"\cite" funguje dopředně i zpětně.
+
+Příkazy "\ilabel" mají lokální působnost a spolupracují jen
+s nejbližším následujícím "\ifirst" a "\inext".
+Takže před použitím dalšího "\ifirst" resp. "\inext"
+je potřeba deklarovat další vyhledávané texty
+pomocí "\ilabel" znovu.
+
+\docbytex{} nevypíše žádné varování, pokud nějaký "<text>"
+deklarovaný v "\ilabel" nenajde. Ovšem při použití "\cite" se objeví
+varování, že není známý "<lejblík>" a toto varování nezmizí ani při
+opakovaném \TeX{}ování.
+
+Pokud se "<text>" vyskytuje ve více řádcích ukázky, je odkazován
+řádek s prvním výskytem.
+
+V následující ukázce je čten již známý soubor "cosi.c"
+(viz kapitolu~\cite[priklad]).
+
+\begtt
+Na řádku~\cite[ufunkce] je deklarovaná úžasná funkce.
+
+\ilabel [ufunkce] {funkce (float}
+\ilabel [navratx] {navrat.x}
+\ifirst {cosi.c}{}{}{++}
+
+Zvláště upozorňuji na geniální myšlenku na řádku~\cite[navratx],
+kde je vstupní parametr vynásoben dvěma.
+\endtt
+
+\subsec Verbatim ukázky pomocí {\tt\nb begtt}/{\tt\nb endtt} a
+ palcových uvozovek
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Verbatim ukázky můžete do dokumentace vkládat pomocí "\begtt"\du{begtt} a
+"\endtt"\du{endtt}. Ty jsou (na rozdíl od vkládaných souborů) napsány přímo ve
+zdrojovém textu \TeX{}u.
+Všechny řádky za "\begtt" jsou vloženy beze změn až po
+ukončovací "\endtt". Řádky nejsou číslovány a texty v nich nemodrají a
+nestávají se klikatelnými odkazy.
+
+Následující sekce~\cite[hooky] a~\cite[begtt] obsahují informace,
+jak je možné toto implicitní chování změnit.
+
+Verbatim ukázky uvnitř odstavce lze vymezit palcovými uvozovkami
+{\tt\char`\"...\char`\"}. V tomto prostředí probíhá tisk strojopisem a
+je aktivní enc\TeX{}, takže dokumentovaná slova se stávají
+automaticky odkazy na místo, kde je "\dg". Doporučuje se toto
+prostředí používat na výpisy veškerých částí kódů dokumentovaného
+programu, které jsou vloženy uvnitř textu v odstavci (analogie
+matematického prostředí "$...$").
+
+\subsec [ddsl] Deklarace dokumentovaného slova
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Na deklaraci slova, které dokumentujeme, lze použít příkaz "\dg",\du{dg}
+"\dgn",\du{dgn} "\dgh",\du{dgh} "\dl",\du{dl} "\dln"\du{dln}
+nebo "\dlh"\du{dlh}. Významy jednotlivých
+příkazů vysvětlíme později. Nejprve se věnujme syntaxi parametrů.
+Všechny příkazy mají stejnou syntaxi, takže nebude vadit, když bude
+vyložena jen v souvislosti s příkazem "\dg". Syntaxe je poněkud
+zvláštní. Účelem totiž bylo minimalizovat práci písaře, takže jsem se
+vyhnul kučeravým závorkám, parametr separuji podle mezery nebo něčeho
+jiného, atd.
+
+Existují tyto možnosti syntaxe parametrů:
+
+\def\begtthook{\langleactive \mubytein=1}
+\begtt
+\dg <slovo> % <slovo> separované mezerou
+\dg [<text>] <slovo> % navíc nepovinný "přední" <text>
+\dg [<text>]<slovo> % <slovo> může na [<text>] navazovat bez mezery
+\dg <slovo>() % <slovo> s dvojicí "()" separované mezerou
+\dg [<text>]<slovo>() % kombinace předchozího
+\dg <slovo>, % <slovo> separované čárkou
+\dg [<text>] <slovo>, % kombinace předchozího
+\dg <slovo>(), % <slovo> s dvojicí "()" separované čárkou
+\dg [<text>]<slovo>(), % kombinace předchozího
+\dg <slovo>. % slovo separované tečkou
+atd...
+\endtt
+\def\begtthook{}
+
+Obecně: za příkazem "\dg" může následovat nepovinná "[". Pokud
+následuje, pak se přečte "<text>" až po ukončovací "]". Parametr
+"<text>" může obsahovat mezery. Za ukončovací "]" může a nemusí být
+mezera. Pokud tam je, pak ji makro přesune před koncovou závorku "]",
+takže "\dg"~"[aha] slovo" je totéž jako "\dg"~"[aha ]slovo".
+Dále následuje čtení parametru "<slovo>".
+Tento parametr nesmí obsahovat mezeru, čárku, tečku, středník
+a dvojtečku. Čtení parametru je ukončeno, jakmile se objeví mezera
+nebo čárka nebo tečka nebo středník nebo dvojtečka. Uvedená
+interpunkce není součástí parametru "<slovo>" a po zpracování parametru
+se vrátí do vstupní fronty, takže se běžně vytiskne.
+Nakonec se zjistí, zda přečtený parametr až po separátor není ve tvaru
+"<slovo>()". Pokud je, pak symbol "()" se nepovažuje za součást
+parametru "<slovo>", ale mluvíme o "<slovu>" následovaném dvojicí~"()".
+
+Pozor, za separátorem typu čárka, tečka, středník a dvojtečka se musí
+vyskytnout mezera. Ne nutně ihned, ale dříve, než se objeví úsek
+textu, který má být přečten s jinými kategoriemi
+(např.~{\tt\char`\"...\char`\"}). Není tedy možné psát
+"\dg" {\tt text,\char`\"...\char`\"}.
+Pokud za separátorem mezera následuje znak {\tt\char`\`} (obrácený
+apostrof), mezera ani tento znak se netiskne. To je možné využít
+například pro vložení nezlomitelné mezery nebo pro jiné účely:
+"\dg"~"<slovo> `~<přilepený text>"
+nebo "\dg"~"<slovo> `"{\tt\char`\"...\char`\"}.
+
+Příkazy "\dgh", "\dgn", "\dln", "\dlh" separující mezeru
+netisknou nikdy, protože tyto příkazy většinou netisknou nic (viz níže).
+
+Parametr "<slovo>" je dokumentované slovo. Pokud se takové "<slovo>"
+vyskytne někde jinde v dokumentu mezi {\tt\char`\"...\char`\"} nebo ve
+vloženém zdrojovém kódu, automaticky zmodrá a stává se klikatelným
+odkazem na místo, kde je použito "\dg". V místě použití "\dg" je slovo
+zvýrazněno červenou barvou. Je vytištěno samotné bez parametru
+"<text>" a bez případných závorek "()". V poznámce pod čarou se vypíše
+"<slovo>" (červeně). Tam je i případný "<text>" (před slovem) a za ním
+je případná dvojice "()". Vedle tohoto výpisu je
+seznam stránek s výskyty "<slova>". V rejstříku se objeví něco podobného,
+jako v poznámce pod čarou. Rejstřík je řazen abecedně podle "<slovo>",
+nikoli podle "<text>".
+
+Příkaz "\dg" deklaruje "<slovo>" globálně. Bude na něj odkazováno v celém
+dokumentu.
+
+Příkaz "\dgh" pracuje jako "\dg", ale slovo nebude v místě "\dgh"
+vypsáno ("\dg" hidden). Bude tam jen cíl odkazů a "<slovo>"
+se objeví v poznámce a v rejstříku.
+
+Příkaz "\dgn" způsobí, že první následující výskyt
+"<slova>" ve vypisovaném zdrojovém kódu
+se stane cílem všech ostatních odkazů, zčervená (tedy
+nezmodrá) a v místě tohoto výskytu se objeví příslušná poznámka pod
+čarou. Příkaz "\dgn" čteme jako "\dg" next, nebo "\dg" následující.
+
+Příkaz "\dl" deklaruje "<slovo>" lokálně. Bude na něj odkazováno svým
+krátkým jménem "<slovo>" jen v místě stejného jmenného prostoru,
+typicky při dokumentaci jednoho modulu. Každý modul zahájený příkazem
+"\module" zavádí jmenný prostor tvaru "<slovo>./<název>", kde
+"<název>" je jméno modulu. Slovo deklarované pomocí "\dl" žije ve dvou
+variantách. V krátké variantě jako "<slovo>" jen v rozsahu jednoho
+jmenného prostoru a v dlouhé variantě "<slovo>./<název>" žije globálně
+v celém dokumentu. Případný výskyt dlouhého názvu odkáže na místo
+deklarace napříč celým dokumentem.
+
+Podrobněji o jmenných prostorech a možnosti jejich změny najdete
+v~sekci~\cite[jmenneprostory].
+
+Každé "<slovo>" musí být v dokumentu deklarováno nejvýše jednou, jinak
+\docbytex{} ohlásí chybu. V případě "\dl" musí existovat
+jednoznačný dlouhý název.
+
+Příkaz "\dlh" je skrytý "\dl". Příkaz "\dln" znamená "\dl" next.
+Analogicky, jako příkazy "\dgh" a "\dgn".
+
+Pokud někoho irituje vysoká inteligence těchto příkazů při čtení
+parametrů, může použít interní verzi příkazů s povinnými třemi
+parametry obalenými do kučeravých závorek: "\iidg",\du{iidg}
+"\iidgh",\du{iidgh} "\iidgn",\du{iidgn}
+"\iidl",\du{iidl} "\iidlh",\du{iidlh} "\iidln".\du{iidln}
+Parametry vypadají
+takto: "\iidg{<před>}{<slovo>}{<za>}". Pravda, tyto příkazy umožňují
+více než jejich krátké verze: umožňují do parametru "<slovo>"
+propašovat čárku, mezeru, středník atd. a do parametru "<za>" napsat
+cokoli, nejen kulaté závorky.
+
+
+\subsec [jmenneprostory] Jmenné prostory
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Jmenný prostor je pravidlo, podle kterého se krátký název
+dokumentovaného "<slova>" transformuje při použití "\dl"
+na název dlouhý. Je možné jej nastavit nebo změnit pomocí příkazu
+"\namespace"\du{namespace}, který se použije takto:
+"\namespace" "{<text1>#1<text2>}...\endnamespace".\du{endnamespace}
+Pokud je uvnitř tohoto prostředí použit příkaz
+"\dl<slovo>", je slovu přidělen krátký název "<slovo>" a dlouhý název
+"<text1><slovo><text2>".
+Uvnitř takto deklarovaného prostředí se všechny výskyty
+krátkého názvu "<slovo>" transformují na dlouhý název a jsou
+prolinkovány s odpovídajícím místem "\dl". Jmenný prostor je lokální
+uvnitř svého prostředí, takže vně prostředí se "<slovo>"
+chová, jakoby nebyl žádný příkaz "\dl" použit.
+Například uvnitř prostředí "\namespace"~"{#1//uff}...\endnamespace" je ke
+každému slovu deklarovanému pomocí "\dl<slovo>" přidělen dlouhý název
+"<slovo>//uff" a výskyty "<slovo>" odkazují na místo "\dl<slovo>".
+
+Vně všech prostředí "\namespace...\endnamespace" není jmenný prostor definován,
+takže tam není možné použít příkaz "\dl".
+Ovšem příkaz "\module"~"<název> " nastaví jmenný
+prostor na "{#1./<název>}", takže uvnitř dokumentace modulu
+je možné používat příkaz~"\dl".
+
+V rejstříku a v poznámce pod čarou se tisknou dlouhé názvy. Rejstřík
+abecedně řadí podle dlouhých~názvů. V obsahu se tisknou názvy krátké.
+
+Příklad práce se jmennými prostory:
+
+\begtt
+\namespace {ju::#1} %% nastavuji namespace ju
+Tady deklaruji slovo \dl aha.
+Tady slovo "aha" automaticky odkazuje na místo deklarace.
+Slovo "ju::aha" také odkazuje na místo deklarace.
+\endnamespace
+\namespace {hele::#1} %% nastavuji namespace hele
+Tady znovu deklaruji slovo \dl aha.
+Zde slovo "aha" odkazuje na lokální deklaraci uvnitř "hele"
+\endnamespace %% ruším namespace
+Zde slovo "aha" neodkazuje nikam, ale slova "ju::aha"
+a "hele::aha" stále odkazují na místa, kde byla deklarována.
+\endtt
+
+Prostředí "\namespace...\endnamespace" je možné vnořovat, ovšem vnořená
+prostředí musejí mít jiný jmenný prostor než prostředí vnější. Prostředí
+jmenných prostorů pracují globálně nezávisle na "\bgroup", "\egroup".
+Příkaz "\endnamespace" použitý vně všech prostředí
+"\namespace...\endnamespace" neudělá nic. Prostředí není nutné před
+příkazem "\bye" ukončovat.
+
+
+\subsec Místo pro dokumentaci aplikačního rozhraní
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Může se stát, že píšeme dokumentaci jednak pro uživatele, které zajímá
+způsob použití dokumentovaných funkcí a co zhruba dělají (tzv.~API),
+ale nezajímá je, jak je funkce naprogramovaná. Druhak chceme mít
+dokumentován i způsob, jak funkce funguje uvnitř. V takovém případě
+musí dokumentované "<slovo>" odkazovat na dvě místa v dokumentu.
+
+Místo, kde je podrobně "<slovo>" popsáno, je vymezeno příkazem "\dg"
+nebo podobným. Místo, kde slovo dokumentujeme pro uživatele (je-li
+toto místo odlišné od prvního místa), lze vyznačit příkazem
+"\api{<slovo>}"\du{api}. V místě použití "\api{<slovo>}" se nestane
+nic, jen se tam umístí neviditelný cíl odkazů. V obsahu se pak
+"<slovo>" objeví s odkazem na toto místo. V rejstříku se v seznamu
+stránek objeví jedna stránka podtržená: to je stránka, kde byl použit
+příkaz~"\api{<slovo>}". Ovšem, aby se v rejstříku "<slovo>" vůbec
+objevilo, musí se někde v dokumentu vyskytovat i jeho plná deklarace
+pomocí "\dg" nebo podobných příkazů. Na stránce, kde je použito "\dg",
+je pod čarou vedle slova seznam stránek a rovněž je tam jedna stránka
+podtržená. Když čtete implementační popis pro "<slovo>", snadno se
+tedy dostanete na stránku, kde je API k tomuto "<slovu>". V~rejstříku
+a obsahu jsou také slova, která byla deklarovaná pomocí "\api", zleva
+vyznačena textem "\apitext"\du{apitext}. Ten je implicitně nastaven na
+šipku. Můžete se podívat do rejstříku a do obsahu tohoto dokumentu. V
+tomto místě bylo použito "\api{\nb api}", zatímco skutečná definice
+příkazu "\api" je v sekci~\cite[reference].
+
+Je-li použito "\api{<slovo>}", pak je možné se na místo odkazovat také
+pomocí "\cite[+<slovo>]". Tato konstrukce se promění v číslo stránky,
+kde je dokumentováno API daného slova. Například v tomto dokumentu
+se "\cite[+\nb api]" promění na:~\cite[+\nb api].
+
+Pokud toto slovo má také svůj API cíl (vytvořený pomocí
+"\api"), pak se červený text (tištěný v místě "\dg")
+stává aktivním odkazem na API cíl. Tam
+typicky čtenář najde výskyt slova, který je zase klikatelným odkazem
+na "\dg" cíl. Takže tyto dva cíle jsou prolinkovány křížem.
+
+\subsec [kapsec] Sekce, sekcičky, část, titul
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Sekce se uvozují příkazem "\sec"~"<název sekce>\par"\du{sec}. Každá
+sekce může mít několik podsekcí (sekciček), které lze vyznačit
+příkazem "\subsec"~"<název podsekce>\par"\du{subsec}.
+Symbol "\par" zde znamená,
+že název sekce či podsekce je oddělen od dalšího textu prázdným
+řádkem (viz ukázku v~\cite[cleneni]).
+
+Několik sekcí může tvořit část. Část je uvozena příkazem
+"\part"~"<název části>\par"\du{part}. Části jsou automaticky označeny
+písmeny A,B,C,\dots a jsou vyznačeny výrazněji než sekce v~místě
+začátku části i v~obsahu. Části ale nenarušují číslování
+sekcí. Tj. sekce jsou číslovány od jedné napříč celým dokumentem bez
+ohledu na to, zda jsou nebo nejsou rozděleny na části.
+
+Příkaz "\module <soubor> " automaticky založí sekci s názvem
+"Modul <soubor>" a deklaruje svůj jmenný prostor.
+Toto chování lze změnit, viz~\cite[nazvy], \cite[module].
+
+Příkaz "\title<název>\par"\du{title} vytiskne název dokumentu větším písmem a v
+rámečku. Je-li definováno makro "\projectversion"\du{projectversion},
+bude jeho obsah vytištěn drobně vpravo nahoře doplněný zepředu textem
+"verze". Pokud váš projekt nemá verzi, může se hodit třeba:
+
+\begtt
+\def\projectversion{\the\day. \the\month. \the\year}
+\endtt
+
+Příkaz "\author<text>\par"\du{author} napíše do
+středu řádku tučně "<text>",
+což bývá obvykle jméno autora (jména autorů).
+
+Do záhlaví každé stránky se začne přepisovat zleva název aktuální
+sekce a zprava název dokumentu. Uživatel může text pro pravé záhlaví
+změnit změnou makra "\headtitle"\du{headtitle}.
+
+Příkazy "\sec" a "\subsec" mohou mít v hranaté závorce nepovinný
+parametr "<lejblík>". V takovém případě vypadají parametry takto:
+"\sec"~"[<lejblík>] <název sekce>\par". Po takovém použití je možné
+se na sekci (podsekci) odkazovat příkazem "\cite[<lejblík>]". Tento příkaz se
+promění v číslo odkazované sekce (podsekce) a navíc se stane
+aktivním odkazem.
+
+Pomocí příkazu "\savetocfalse"\du{savetocfalse} lze před použitím
+příkazu "\sec" nebo "\subsec" zajistit, že název sekce se
+nedostane do obsahu a nebude mít své číslo. Místo čísla se
+vytiskne obsah makra "\emptynumber"\du{emptynumber}, které je
+implicitně prázdné. Příkaz "\savetocfalse" ovlivní jen
+první následující "\sec" nebo "\subsec".
+
+\subsec [krizodkaz] Křížové odkazy
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Cíl, kam směřuje odkaz, je potřeba vyznačit pomocí "<lejblíku>".
+To je možné udělat v příkaze "\sec", "\subsec" (viz předchozí
+sekci~\cite[kapsec]) nebo kdekoli v textu samostatným příkazem
+"\label[<lejblík>]"\du{label}. Také je možné odkazovat na číslo řádku
+(viz sekci~\cite[lineodkazy]).
+Všechny lejblíky musejí být jednoznačné (bez ohledu na jejich typ)
+napříč celým dokumentem.
+
+Příkaz "\pgref[<lejblík>]"\du{pgref} expanduje na číslo strany, na které se
+vyskytuje cíl odkazu. Příkaz "\numref[<lejblík>]"\du{numref} expanduje
+v~závislosti na typu cíle na:
+
+\begitems
+\item * číslo sekce, je-li cílem sekce,
+\item * dvojčíslí "<sekce>.<podsekce>", je-li cílem podsekce,
+\item * číslo řádku, je-li cílem řádek zdrojového kódu,
+\item * prázdné makro, je-li "<lejblík>" deklarovaný pomocí "\label".
+\enditems
+
+Oba příkazy "\pgref" a "\numref" expandují na uvedené texty bez další
+inteligence. Tj. výstupní text se nestává klikatelným odkazem.
+
+K aktivaci odkazu v PDF módu slouží
+makro "\ilink"~"[<lejblík>]{<text>}"\du{ilink}. Toto makro vytiskne modře
+"<text>", který se stává klikatelným odkazem na cíl, deklarovaný
+pomocí "<lejblíku>". Takže již známý příkaz "\cite[<lejblík>]"\du{cite}
+udělá zhruba to samé, jako "\ilink[<lejblík>]{\numref[<lejblík>]}".
+Skutečný příkaz "\cite" navíc ověří, zda není "\numref[<lejblík>]"
+prázdné makro. Pokud je, obarví namísto výstupu "\numref"
+výstup makra "\pgref".
+
+Pokud "<lejblík>" jako argument příkazu "\pgref", "\numref" nemá svůj
+cíl, příkaz "\pgref" expanduje na hodnotu $-1000$ a "\numref"
+expanduje na prázdný výstup. Jsou to expanzní makra, takže v nich není
+implementován například tisk varování. Podívejte se na definici
+příkazu "\cite" (na straně~\cite[@\nb cite]), jak se dá tisk varování
+implementovat.
+
+Makro "\module"~"<jméno> " založí sekci s lejblíkem "m:<jméno>", takže
+lze na ní pak odkazovat. Například si můžete vytvořit makro
+
+\begtt
+\def\refmodul[#1]{\ilink[m:#1]{\tt#1}}
+\endtt
+%
+které aktivizuje svůj parametr, pokud tento je názvem nějakého
+modulu. Třeba "\refmodul[base]" vytiskne slovo "base" strojopisem a
+modře a stává se klikatelným odkazem na začátek sekce
+\uv{Modul base}, pokud je tato sekce založena příkazem "\module".
+
+Makra "\dg", "\dgn", "\dgh" interně provedou příkaz "\label[@<slovo>]"
+a makra "\dl", "\dln", "\dlh" provedou příkaz
+"\label[@<dlouhé slovo>]", kde "<dlouhé slovo>" je "<slovo>"
+po transformaci podle aktuálního jmenného prostoru.
+Na místa, kde jsou slova dokumentovaná, je tedy možné odkazovat
+například pomocí
+"\link[@<slovo>]{<slovo> dokumentované na straně~\pgref[@<slovo>]}".
+
+Makro "\api{<slovo>}" interně provede "\label[+<slovo>]", takže je
+možné na toto místo odkazovat třeba pomocí
+"\ilink[+<slovo>]{API: <slovo>}".
+
+\docbytex{} nenabízí kromě čísel sekcí, podsekcí a čísel řádků žádné další
+automatické číslování. Pokud tedy chcete implementovat např. číslování
+obrázků, čísla publikací atd., musíte si napsat makra vlastní.
+K tomu můžete využít makro
+"\labeltext[<lejblík>]{<text>}"\du{labeltext}, které uloží v
+horizontálním módu do sazby neviditelný cíl odkazu, a při dalším
+průchodu \TeX{}em expanduje makro "\numref" na "<text>".
+Použití makra ukážeme na příkladě, ve kterém definujeme makro
+"\bib[<lejblík>]". Toto makro zahájí sazbu další položky v seznamu
+literatury. Odkazovat na knihu pak lze pomocí "\cite[b:<lejblík>]".
+
+\begtt
+\newcount\bibnum
+\def\bib [#1]{\par\advance\bibnum by1 \indent
+ \llap{[\the\bibnum] }\labeltext[b:#1]{[\the\bibnum]}\ignorespaces}
+\endtt
+
+\subsec Vkládání obrázků
+%%%%%%%%%%%%%%%%%%%%%%%%
+
+Příkazem "\ifig" "<šířka> <jméno obrázku> "\du{ifig} je možné vložit obrázek.
+Obrázek musí být připraven v souboru "fig/<jméno obrázku>.eps" (v případě
+DVI módu) a v souboru "fig/<jméno obrázku>.pdf" (v~případě PDF módu).
+Adresář, kde \docbytex{} vyhledává obrázky ("fig/"), lze změnit
+předefinováním sekvence "\figdir"\du{figdir} . Rozměr "<šířka>"
+je bez jednotky a udává poměr požadované šířky obrázku ku
+šířce sazby. Obrázek je umístěn zarovnán doleva na odstavcovou zarážku.
+
+Máte-li připraven obrázek ve formátu "eps", pak jej do "pdf" převedete
+příkazem
+
+{\def\begtthook{\langleactive}
+\begtt
+ps2pdf -dEPSCrop <jméno obrázku>.eps
+\endtt
+\par}
+
+\subsec Výčty
+%%%%%%%%%%%%%
+
+Seznam položek obklopíte "\begitems"\du{begitems} a
+"\enditems"\du{enditems}. V tomto prostředí je text odsazen zleva
+o~odstavcovou zarážku. Prostředí lze vnořovat. Jednotlivou položku
+zahájíte pomocí "\item"~"<značka> <text>",\du{item}
+přitom "<značka>" se
+vystrčí vlevo od "<textu>". Je-li "<značka>" hvězdička, promění se v
+puntík. Další možnost: "\item"~"\the\itemno) <text>",\du{itemno}
+což vytvoří číslované výčty, v každém prostředí číslovány od jedné.
+
+Makro plainu "\item" není předefinováno globálně, ale jen uvnitř
+"\begitems...\enditems". Můžete tedy použít i makro plainu,
+pokud se vám koncept položek nabízený \docbytex{}em nelíbí.
+
+
+\noactive{/*}\noactive{*/}\noactive{//}
+\setlinecomment{\percent} \noactive{\nb\percent} \noactive{\percent\cbrace}
+
+
+\sec [zmeny] Pro náročné
+%%%%%%%%%%%%%%%%%%%%%%%%
+
+V této sekci jsou uvedeny a vysvětleny definice základních
+příkazů \docbytex{}u. Uživatel si může tyto definice změnit, pokud chce
+změnit chování \docbytex{}u. Pokud například pracuje s jiným
+programovacím jazykem, může si změnit makro "\docsuffix" nebo
+kompletně předefinovat makra "\module" a "\ins".
+
+\subsec [nazvy] Interní názvy
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Příkazem "\doindex" vytvoří \docbytex{} automaticky novou
+sekci s názvem \uv{Rejstřík}. Podobně při tvorbě obsahu nebo natažení
+modulu vzniká název \uv{Obsah} nebo \uv{Modul}. Před názvem verze
+v~titulu při použití "\projectversion" se objeví slůvko \uv{verze}.
+Část (vytvořená pomocí "\part") má v záložkách uvozující text
+">> CAST".
+Tyto texty jsou definovány v makrech
+\db titindex, \db tittoc, \db titmodule, \db titversion a \db opartname.
+
+\ifirst {docby.tex}{Intern}{\empty}{--}
+
+Za povšimnutí stojí, že jsou jinak tato makra definována při použití
+klasického "plain"u a jinak při použití "csplain"u. To ovšem
+neznamená, že uživatel si tyto názvy nemůže předefinovat ještě jinak,
+nezávisle na použitém formátu.
+
+\subsec [hooky] Vložené skupiny příkazů (hooks)
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Některá složitější makra ("\begtt", palcové uvozovky, "\ifirst",
+"\inext", "\doindex", "\dotoc") dovolují vkládat uživateli na začátku
+zpracování různé příkazy (tzv.~hooks). Implicitně
+jsou tyto vložky prázdné:
+
+\ifirst {docby.tex}{begtthook}{\empty}{+-}
+
+Makro \db begtthook je vloženo po založení skupiny a nastavení všech
+kategorií těsně před začátkem zpracování prostředí "\begtt...\endtt".
+Makro \db quotehook je vloženo po založení skupiny a nastavení všech
+kategorií těsně před začátkem zpracování prostředí {\tt\char`\"...\char`\"}.
+Makro \db indexhook je vloženo makrem "\doindex" po založení sekce
+a před přechodem do sazby ve dvou sloupcích. V tomto dokumentu je v
+něm úvodní povídání k rejstříku.
+Makro \db tochook je vloženo makrem "\dotoc" po založení sekce
+před sazbou prvního řádku obsahu.
+Makro \db bookmarkshook je vloženo uvnitř skupiny na začátku
+zpracování záložek. Je možné v něm nastavit expanze maker
+vyskytujících se v nadpisech na rozumnou hodnotu pro záložky.
+Pokud navíc nastavíte "\let\cnvbookmark=\lowercase", budou všechny
+znaky pro záložky procházet filtrem "\lowercase". Uvnitř
+"\bookmarkshook" je pak možné nastavit "\lccode" vybraným znakům
+(například pro odstranění háčků a čárek).
+Makro \db outputhook je vloženo na začátek výstupní rutiny. Je vhodné
+v něm nastavit vybrané příkazy na hodnotu "\relax", aby se
+neexpandovaly do souboru {\tt.ref}.
+
+Příklady použití
+
+\bgroup
+\catcode`'13 \def'{\nb} \catcode`?=13 \def?{<}
+\def\begtthook{\langleactive\mubytein=1}
+\begtt
+\def\quotehook{\obeyspaces} % ve výpisech "..." budou normální mezery
+\def\quotehook{\langleactive} % ?text> se promění na <text>
+\def\begtthook{\mubytein=1} % mezi 'begtt...'endtt bude aktivní encTeX
+\def\begtthook{\setsmallprinting} % ukázky 'begtt...'endtt budou malé
+\def\begtthook{\catcode`\!=0} % mezi 'begtt...'endtt fungují !prikazy
+\def\indexhook{To čubrníte, jaký tu mám rejstřík.}
+\def\outputhook{\let\mylogo=\relax} % \mylogo nebude expandovat
+\endtt
+\par
+\egroup
+
+\subsec [module] Příkaz {\tt\nb module} a {\tt\nb ins}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Uživatelská dokumentace k těmto příkazům je v sekci~\cite[cleneni].
+Příkaz \db module "<soubor> " načte soubor s názvem
+"<soubor>\docsuffix", kde makro
+\db docsuffix obsahuje příponu souboru včetně tečky.
+
+\ilabel [linkincomment] {extension}
+\insdef docsuffix
+
+Příkaz "\module" vloží název čteného souboru (bez přípony)
+do pomocného makra
+\db modulename. Toto makro pak využívá příkaz
+\db ins "<pripona> <text> ".
+
+\inssdef ins
+
+\subsec Zelenající komentáře
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Příkazy "\ifirst" a "\inext" si také všímají (implicitně) C komentářů
+tvaru "//..<eol>" a "/* .. */". Tyto komentáře barví ve výpisu
+programu zeleně. Zrušit tuto vlastnost lze příkazem "\noactive<string>".
+Pomocí \db setlinecomment "{<string>}" lze nastavit nový typ komentářů,
+které budou barveny zeleně od "<string>" do konce řádku. Příkazy mají globální
+platnost. Například
+
+{\def\begtthook{\mubytein=1}
+\begtt
+\noactive{/*}\noactive{*/}\noactive{//}
+\setlinecomment{\percent} \noactive{\nb\percent}}
+\endtt
+\par}
+\noindent
+nastaví komentáře podle zvyklostí v \TeX{}u a PostScriptu.
+
+Příkazem \db setlrcomment "{<levý>}{<pravý>}"
+lze nastavit komentáře typu "/*...*/".
+
+Pro změnu vlastností obarvování komentářů stačí uvedená makra
+použít. Kdo chce vědět, jak jsou implementovaná, nechť čte dále.
+
+\inext {mubyte}{\empty}{+-}
+
+Uvedené příkazy jsou prázdné v módu bez enc\TeX{}u a při
+detekci enc\TeX{}u zapíší informace do enc\TeX{}ové tabulky
+prostřednictvím primitivů "\mubyte...\endmubyte".
+
+Příkazy \db linecomment a \db leftcomment se díky enc\TeX{}u
+automaticky vloží před detekovanou sekvenci znaků. Tyto
+příkazy nastaví barvu textu na zelenou:
+
+\inext {linecomment}{\empty}{+-}
+
+Na druhé straně příkaz \db rightcomment potřebuje vypnout zelenou barvu
+až po přeskočení detekované sekvence. Proto enc\TeX{} v tomto případě
+detekovanou sekvenci zruší a příkaz "\rightcomment" má za úkol ji vrátit
+do sazby zpět a teprve poté pomocí \db returntoBlack se vrátit
+k~černé barvě.
+
+\inext {returntoBlack}{\empty}{+-}
+
+Je potřeba vysvětlit, proč přepínače barev jsou tak komplikovaně
+zapsány. Přepínač totiž v PDF zapíná barvu nezávisle na skupině a
+barva textu se drží tak dlouho, dokud není použit jiný přepínač barvy.
+Každý tisk řádku kódu je uveden přepínačem "\Black", takže při
+poznámce \uv{do konce řádku} stačí jen přepnout na "\Green". Ovšem
+uvnitř komentáře se může objevit link obalený
+příkazy "\Blue...\Black" (viz např. řádek~\cite[linkincomment] v
+předchozí sekci). Pak ale chceme, aby "\Black" vrátil barvu
+"\Green". Proto je provedeno předefinování pomocí "\let". Toto
+předefinování je lokální. Protože řádek je tištěn uvnitř skupiny, je
+další řádek už černý.
+
+Při tisku komentáře, který má úvodní a koncový znak a může přesáhnout
+jeden řádek, musíme globálně předefinovat "\Black" na "\Green", aby i
+další řádky (uvozené příkazem "\Black") byly zelené. Koncový znak
+komentáře pak musí uvést barvy do původního stavu.
+
+\docbytex{} inicializuje poznámky podle pravidel jazyka C:
+
+\inext {setlinecomment}{\empty}{+-}
+
+\sec [design] Pro designéry
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Následuje dokumentace definic maker ovlivňující vzhled dokumentu.
+Jejich předefinování může způsobit změnu vzhledu podle požadavku
+uživatele. Místo komplikovaných maker s množstvím parametrů pro řízení
+vzhledu jsou zde jednoduchá dobře dokumentovaná makra pro jedno
+použití. Předpokládá se, že při potřebě jiného vzhledu dokumentu je
+uživatel předefinuje.
+
+Makra zabývající se vzhledem dokumentu jsou
+pokud možno oddělena od složitosti ostatních maker, ve kterých probíhá
+hlavní zpracování \docbytex{}u. To umožňuje designérovi zaměřit se
+jen na programování vzhledu a neutopit se v různých cyklech a
+rekurzích interních maker \docbytex{}u.
+
+Typicky jsou makra pro vzhled ve dvou verzích: pro pdf\TeX{} a bez
+pdf\TeX{}u. To je důvod, proč ve výpisech se často vyskytuje test
+"\ifx\pdfoutput\undefined".
+
+\subsec Parametry a pomocná makra pro nastavení vzhledu
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Velikost \db hsize ani \db vsize neměníme. Buď si ji nastaví uživatel,
+nebo se převezme velikost z~plainu (vhodné pro papír letter) či
+csplainu (vhodné pro papír A4). Nastavujeme ale větší \db parindent,
+neboť chceme do proužku vymezeného "\parindent" dát podbarvené
+čtverečky u názvů sekcí.
+
+\ifirst {docby.tex}{parindent=}{\empty}{+-}
+
+Připravíme si \uv{zúženou šířku} \db nwidth využitou např. jako šířka záhlaví:
+
+\inext {nwidth}{\empty}{+-}
+
+Příkazem plainu "\raggedbottom"
+nastavíme pružnost stránky dole, a ne mezi jednotlivými řádky.
+Nastavením "\exhyphenpenalty=10000" zakážeme zlom za pomlčkou
+(v~tisku rozsahu stránek, např. 11--13, takový zlom působí rušivě).
+
+\inext {raggedbottom}{\empty}{+-}
+
+Zavedeme potřebné fonty
+\db bbf, \db bbbf, \db btt,
+\db ttsmall, \db rmsmall, \db itsmall a \db partfont.
+
+\inext {bbf=}{\empty}{+-}
+
+Makro \db setsmallprinting přepne do malého strojopisu, připraví
+\db ttstrut vhodné velikosti a pomocí "\offinterlineskip" připraví tisk
+řádků v režimu, kdy se o sebe opírají. Hodnota "\parskip" je nastavena
+na "-1pt", aby docházelo k mírnému překrývání a nevznikaly v tisku
+nebo na obrazovce pruhy. Analogicky pracuje makro \db setnormalprinting.
+
+\inext {setsmallprinting}{\empty}{+-}
+
+V návrhu vzhledu pracuji jen s barvami
+\db Blue, \db Red, \db Brown, \db Green, \db Yellow a \db Black.
+Pokud budete chtít další barvy, definujte si je.\par\penalty1234
+
+\inext {pdfoutput}{\empty}{+-}
+
+Barvy jsou definovány pomocí makra \db setcmykcolor, které je v
+případě DVI výstupu nastaveno na prázdné makro a v případě PDF výstupu
+je použit PDF~"\special". Takže příkazy "\Brown" atd. je možné použít i
+ve verzi maker pro DVI, ovšem v této verzi neudělají nic.
+Barva \db oriBlack je konstantně černá barva. Některá makra totiž
+normální "\Black" předefinovávají a pak se potřebují vrátit pomocí
+"\oriBlack" ke skutečné černé barvě.
+
+Makro \db rectangle "{<výška>}{<hloubka>}{<šířka>}{<obsah>}"
+vytvoří rámeček o stanovených rozměrech se stanoveným obsahem.
+V PDF verzi je rámeček ve tvaru plného žlutého obdélníku na kterém
+se nachází "<obsah>" zatímco v~DVI verzi se vytvoří obrysový rámeček.
+Pozor: parametr "<obsah>" musí obsahovat přepínač barvy, jinak nebude v
+PDF verzi viditelný. Na druhé straně makro "\rectangle" se postará
+o návrat do \uv{normální} černé barvy.
+
+\inext {pdfoutput}{\empty}{+-}
+
+Nakonec připravíme makro \db docbytex jako zkratku pro logo \docbytex{}u.
+
+\inext {def\nb docbytex}{\empty}{+-}
+
+\subsec Vzhled sekcí a podsekcí
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Makra \db printsec "{<nadpis>}" a \db printsecbelow,
+jsou volána z makra pro vytvoření sekce "\sec" a mají za úkol
+vytisknout nadpis. Ostatní problematika, kterou musí řešit makro
+"\sec" (reference do obsahu, cílové reference, čísla sekcí, plovoucí
+záhlaví atd.) je zde odstíněna a nemusíme se jí v tuto chvíli zabývat.
+
+Musíme ale dodržet následující úmluvu: Na začátku makra "\printsec"
+přejdeme pro jistotu do vertikálního módu, pak vložíme potřebné
+mezery, pak vložíme text nadpisu. V okamžiku, kdy přejdeme do
+horizontálního módu, vložíme makro "\makelinks", které zajistí
+umístění cílů odkazů. Nakonec přejdeme do vertikálního módu příkazem
+"\par" a {\it nevkládáme žádné další vertikální mezery}. Makro "\sec" vloží pod
+vytištěný nadpis do horizontálního seznamu další prvky a posléze
+zavolá "\printsecbelow". Tam teprve vložíme mezery obvykle blokované
+proti zlomu pomocí "\nobreak". Základní řazení vertikálního seznamu
+v \TeX{}u totiž vypadá takto: box, (whatsit, mark, atd.), penalty, glue.
+O objekty uvedené v~závorce se postará "\sec", my zde řešíme jen box
+(v makru "\printsec"), a dále penaltu a glue (v makru "\printsecbelow").
+
+K dispozici máme hodnotu "\secnum" a "\subsecnum" a dále můžeme použít
+test "\ifsavetoc", kterým se ptáme, zda daný nadpis bude v
+obsahu. Nebude-li, měli bychom místo "\the\secnum" tisknout
+"\emptynumber". V makru "\seclabel" je obsah lejblíku sekce, nebo
+je makro prázdné. To můžeme využít při tisku v režimu \uv{nahrubo},
+například tisknout tyto lejblíky do okrajů. \docbytex{} tuto
+vlastnost implicitně neimplementuje.
+
+\ifirst {docby.tex}{def\nb printsec }{\empty}{+-}
+
+Makra \db printsubsec a \db printsubsecbelow fungují analogicky jako právě
+zmíněná, ale spolupracují s makrem "\subsec".
+
+\inext {def\nb printsubsec }{\empty}{+-}
+
+Makro \db printpart vytiskne nadpis části a dopředu dá veliké
+písmeno. Makro \db printpartbelow tiskne mezeru pod nadpisem části.
+
+\inext {def\nb printpart }{\empty}{+-}
+
+Makro \db emptynumber, které se použije při "\savetocfalse", je
+implicitně nastaveno na prázdnou hodnotu.
+
+\inext {emptynumber}{\empty}{+-}
+
+\subsec Titul, autor
+%%%%%%%%%%%%%%%%%%%%
+
+Makro \db title "<titul>\par" čte parametr "<titul>"
+pomocí makra "\secparam", které se postará o~případné
+ignorování mezery na konci parametru (viz~sekci~\cite[secsec]).
+Makro "\secparam" uloží parametr
+"<titul>" do tokenlistu "\sectitle" a spustí interní
+\db iititle. Toto makro pracuje ve dvou módech
+(DVI a PDF). V~obou módech "\iititle" uloží "<titul>" do makra
+"\headtitle" (pokud je toto makro prázdné, tedy neinicializované
+uživatelem) a pomocí příkazu "\noheadline" potlačí na aktuální stránce
+tisk záhlaví.
+
+\inext {def\nb title}{\empty}{+-}
+
+Makro "\title" v DVI verzi je prosté "\centerline", zatímco v PDF
+verzi tiskne podkladový obdélník šířky "\nwidth".
+
+Pokud není makro \db projectversion definováno, nastavíme mu výchozí
+hodnotu jako prázdné makro:
+
+\inext {ifx\nb project}{\empty}{+-}
+
+Makro \db author "<autor>\par" je společné v obou módech.
+Umístí jméno autora tučně a na střed.
+
+\inssdef author
+
+\subsec Hlavičky a patičky
+%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\docbytex{} nemění výstupní rutinu plainu. Využívá tedy klasické
+nástroje na modifikaci vzhledu, tj. text "\footline" a "\headline".
+
+Návrh vzhledu stránky nepočítá s pravou a levou
+stranou, protože dokumentaci většinou čteme na monitoru a když ji
+tiskneme, tak kdo ví, na čem...
+
+Text \db footline je nastaven tak, aby byla stránková číslice uprostřed
+podbarvena případně orámována pomocí "\rectangle".
+
+\inext {footline}{\empty}{+-}
+
+Text \db headline se mění. Implicitně obsahuje jen makro \db normalhead,
+ale při použití příkazu "\noheadline" na chvíli změní svůj obsah.
+
+\ilabel[headlinebox] {headlinebox}
+\inext {headline}{\empty}{+-}
+
+Makro "\normalhead" uloží stránkový link pomocí "\savepglink"
+a "\vbox/\hbox" gymnastikou vytvoří potřebné záhlaví. Zleva je tištěn
+název sekce ("\firstmark") a zprava konstantní text "\headtitle".
+
+Makro \db noheadline nastaví "\headline" přechodně na text, podle
+kterého se vloží jen stránkový odkaz a provede změna obsahu
+"\headline" na standardní hodnotu. Operace musíme provádět globálně,
+protože jsme uvnitř výstupní rutiny.
+
+\inssdef noheadline
+
+Makro \db headtitle obsahuje text shodný v celém dokumentu tištěný
+vpravo v záhlaví. Implicitně je makro prázdné, po použití příkazu
+"\title" obsahuje název dokumentu, pokud si uživatel makro nedefinoval sám.
+
+\inext {headtitle}{\empty}{+-}
+
+Pomocné makro \db headlinebox udělá v DVI módu prázdný čtvereček a
+v PDF módu plný (žlutý) čtvereček. Je použito na řádku~\cite[headlinebox]
+pro vytvoření čtverečkované čáry v záhlaví,
+
+\inext {ifx\nb pdfoutput}{\empty}{+-}
+
+\subsec Tisk cíle odkazu a odkazů pod čarou
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Cíl odkazu vytvořený makry "\dg" nebo "\dl" je potřeba vytisknout
+výrazně, aby jej čtenář pokud možno rychle našel. Tisk
+probíhá v makru \db printdg "{<před>}{<slovo>}{<za>}", kde "<před>" je
+text před slovem a "<za>" je prázdný parametr nebo obsahuje "()",
+pokud tyto závorky uživatel v příkaze "\dg", "\dl" použil.
+
+Současný návrh \docbytex{}u tiskne z těchto tří parametrů jen jeden,
+sice "<slovo>". V DVI módu tiskne "<slovo>" v rámečku a v PDF módu
+tiskne "<slovo>" červeně a na pozadí je žlutý obdélník.
+
+\inext {ifx\nb pdfoutput}{\empty}{+-}
+
+Červený text se tiskne pomocným makrem \db printdginside, které tiskne
+jednoduše červeně, pokud ke slovu neexistuje "\api" cíl a tiskne
+červeně pomocí "\ilink", jestliže existuje "\api" cíl.
+
+\inext {def\nb printdginside}{\empty}{+-}
+
+Údaj pod čáru tiskneme makrem
+\db printfnote "{<před>}{<d-slovo>}{<za>}{<k-slovo>}",
+kde parametry "<před>" a "<za>" mají stejný význam, jako u makra "\printdg".
+Parametr "<k-slovo>" (krátká verze slova) tiskneme červeně,
+ostatní parametry černě. Parametr "<d-slovo>" (dlouhá verze slova) není
+použit.
+
+K naprogramování tohoto makra využiji makro
+"\specfootnote"~"{<text>}", které pošle text do speciální poznámky pod
+čarou. Dále je potřeba vědět, že "\pgref[+<slovo>]" vrátí číslo
+strany, kde je "\api" deklarace "<slova>" nebo vrátí $-1000$.
+Toto číslo vložíme do "\apinum" a je-li nezáporné, tak jej uvedeme
+jako první v seznamu stránek a podtržené.
+Seznam stránek vytiskneme pomocí
+"\listofpages{<slovo>}". V seznamu bude chybět stránka "\apinum", protože
+makro "\listofpages" ji vynechává. Prázdný seznam stránek (při kterém
+netiskneme dvojtečku ani čárku) poznáme podle toho, že "\box0" má
+nulovou šířku.
+
+\inext {def\nb printfnote}{\empty}{+-}
+
+\subsec Tisk údaje v obsahu a v rejstříku
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Příkaz \db ptocline "{<číslo>}{<text>}{<strana>}" se postará o tisk
+údaje o sekci nebo části do obsahu. Dále příkaz \db ptocsubline
+"{<číslo>}{<text>}{<strana>}" vytiskne údaj o subsekci. Jak je patrné,
+tyto dva příkazy se liší jen o jeden "\indent":
+
+\inext {def\nb ptocline}{\empty}{+-}
+
+Příkaz \db mydotfill vytiskne tečky do obsahu tak, aby byly pod sebou
+zarovnány.
+
+Příkaz \db ptocentry "<typ>{<slovo>}{<k-slovo>}" vytiskne jednu položku
+o dokumentovaném slově do obsahu. Parametr "<typ>=+", pokud je v daném
+místě "\api" dokumentace, a "<typ>=@", je-li v daném místě "\dg"
+dokumentace. "<k-slovo>" je prázdné, ale při použití "\dl" je v něm
+krátká verze slova, zatímco ve "<slovo>" je dlouhá verze slova.
+Dlouhou verzí odkazujeme, krátkou verzi tiskneme.
+
+\inext {def\nb ptocentry}{\empty}{+-}
+
+Kdyby bylo potřeba tisknout text před slovem nebo závorky za slovem,
+je možné využít kontrolní sekvenci "\csname-<slovo>\endcsname" jako
+v následujícím makru "\printindexentry".
+
+Makro \db myldots vytvoří tři tečky, které jsou zarovnány s ostatními
+tečkami v obsahu.
+
+Makro \db printindexentry "{<slovo>}" tiskne údaj o slově do
+rejstříku. Začíná ve vertikálním módu uvnitř sloupce, vytiskne údaj a
+pomocí "\par" se musí vrátit do vertikálního módu.
+
+\inext {def\nb printindexentry}{\empty}{+-}
+
+Pomocí \db separeright uložím do "\tmpa" text vlevo od slova a do
+"\tmpb" text vpravo od slova. Makro "\refdg" tyto údaje uložilo do
+makra "\csname-<slovo>\endcsname" oddělené od sebe značkou "\right".
+Pomocí makra "\pgref[@<slovo>]" získám stránku s "\dg" deklarací
+slova. Pomocí "\pgref[+<slovo>]" získám stránku s "\api" deklarací
+slova. Tuto stránku (pokud existuje) tisknu podtrženě.
+
+\subsec Tisk zdrojového textu
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Makra "\ifirst" a "\inext" přetisknou požadovanou část zdrojového
+textu. Při řešení návrhu vzhledu tisku nás nyní pouze zajímá, že tato
+makra založí skupinu, pak zavolají příkaz \db printiabove, pak pro tisk
+každého řádku zavolají \db printiline "{<číslo>}{<text řádku>}" a nakonec před
+ukončením skupiny se spustí \db printibelow. Právě tato tři makra si
+nyní naprogramujeme. Budeme rozlišovat mezi DVI a PDF
+módem.
+
+\ilabel [isnameprinted] {raise8}
+\ilabel [isnameprinted2] {pt \nb inputfilename}
+\inext {ifx\nb pdfoutput}{\empty}{+-}
+
+V DVI módu tiskneme nahoře čáru se jménem souboru pomocí "\leaders"
+a makra \db specrule. Dole pak tiskneme jen jednoduchou čáru.
+V~PDF módu nahoře pouze nastavíme "\setsmallprinting"
+a vložíme malou mezeru. Dole vložíme střední mezeru.
+
+Makro "\printiline" přejde nejprve do horizontálního módu, tam vloží v
+DVI módu podpěru a dále box s číslem a box s řádkem. Mezi řádky
+vkládám penaltu~11. V PDF módu se místo podpěry tiskne celý žlutý
+proužek v~"\rlap". Protože přes první řádek je potřeba vpravo nahoru
+vytisknout jméno souboru (později než žlutý proužek), je potřeba
+zjistit, zda tisknu první řádek nebo další řádky. K tomu slouží
+kontrolní sekvence \db isnameprinted, která je typicky "\undefined".
+Po vytištění jména souboru (řádky~\cite[isnameprinted] a~\cite[isnameprinted2])
+nastavím "\isnameprinted" na "\relax" a tím poznám, že už je práce
+provedena. Až makro "\ifirst" nebo "\inext" ukončí skupinu, bude zase
+mít "\isnameprinted" hodnotu "\undefined".
+
+\subsec [begtt] Tisk z prostředí {\tt\nb begtt}/{\tt\nb endtt}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Makro "\begtt" založí skupinu a zavolá \db printvabove.
+Dále pro každý tištěný řádek volá makro \db printvline "{<číslo>}{<text řádku>}"
+a nakonec zavolá \db printvbelow. Číslo řádku jsme se rozhodli
+nevyužít. V DVI verzi kreslíme jen čáry nahoře a dole. V~PDF verzi
+kreslíme žluté čáry nahoře a dole a v~každém řádku pomocí "\rlap" kreslíme
+žluté obdélníky vpravo a vlevo.
+
+\inext {ifx\nb pdfoutput}{\empty}{+-}
+
+\subsec Vkládání obrázků
+%%%%%%%%%%%%%%%%%%%%%%%%
+
+Obrázky jsou vkládány nalevo podle odstavcové zarážky. Tato
+zarážka je dostatečně velká, takže to působí docela dobře.
+Celkovou šířku prostoru pro obrázek \db figwidth spočítám jako
+"\hsize" mínus "\parindent"
+
+\inext {newdimen\nb figwidth}{\empty}{+-}
+
+Makro \db ifig "<poměr šířky> <název> " v DVI módu vloží "<název>.eps" a
+využije k tomu makrobalík {\tt epsf.tex}. V PDF módu vloží
+"<název>.pdf" a využije k tomu pdf\TeX{}ové primitivy "\pdfximage",
+"\pdfrefximage", "\pdflastximage".
+
+\inext {ifx\nb pdfoutput}{\empty}{+-}
+
+Makro \db figdir obsahuje adresář, ze kterého se obrázky loví.
+
+\subsec Výčty
+%%%%%%%%%%%%%
+
+Makra pro výčty jsou natolik jednoduchá, že asi nepotřebují dalšího
+konimentáře. \db begitems zahájí prostředí s výčty, \db enditems ukončí
+toto prostředí, \db itemno čísluje a \db dbtitem "<značka> " zahajuje položku,
+přičemž se uvnitř prostředí převtělí na \db item.
+
+\inext {newcount\nb itemno}{def\nb enditems}{++}
+
+
+\sec [implementace] Pro otrlé
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Zde je dokumentována implementace \docbytex{}u. Je zde výpis
+všech jeho interních maker včetně podrobného
+komentáře, jak fungují. Asi není rozumné tato makra měnit, ledaže by
+si chtěl čtenář naprogramovat \docbytex{} vlastní.
+
+\subsec Pomocná makra
+%%%%%%%%%%%%%%%%%%%%%
+
+Makro \db dbtwarning zprostředkuje tisk varovných hlášek:
+
+\inext {def\nb dbtwarning}{\empty}{+-}
+
+Makra \db defsec "{<text>}", \db edefsec "{<text>}" a \db undef "{<text>}"
+jsou zkratky za časté operace s~"\csname<text>\endcsname".
+
+\inext {def\nb defsec}{\empty}{+-}
+
+Makro "\undef" je potřeba použít takto:
+
+{\def\begtthook{\langleactive\mubytein=1}
+\begtt
+\undef{<text>}\iftrue <sekvence nedefinovaná> \else <sekvence definovaná> \fi
+\endtt
+\par}
+
+Nutnost použití "\iftrue" se bohatě vyplatí, až budeme "\undef" přeskakovat
+vnějšími podmínkami typu~"\if".
+
+Definuji makro \db nb (normální backslash). Toto makro je pak možné
+používat při vyhledávání textu s tímto znakem. Rovněž definuji aktivní
+tabelátor a zástupné sekvence \db obrace, \db cbrace, \db percent
+a \db inchquote.
+
+{\catcode`\%=12 \noactive{\nb %} \noactive{[%} }
+
+\inext {catcode}{\empty}{+-}
+
+Makro \db softinput je vysvětleno v \TeX{}booku naruby na straně 288,
+takže bez komentáře.
+
+\inext {def\nb softinput}{\empty}{+-}
+
+Makro \db setverb nastaví kategorie všech speciálních znaků na
+normální. Viz \TeX{}book naruby, stranu~28.
+
+\inext {def\nb setverb}{\empty}{+-}
+
+\subsec Inicializace
+%%%%%%%%%%%%%%%%%%%%
+
+Ohlásíme se na terminál:
+
+\inext {This is DocBy}{\empty}{+-}
+
+Makro \db dbtversion obsahuje verzi \docbytex{}u a je definováno
+na začátku souboru {\tt docby.tex}. Tam je autor \docbytex{}u pozmění,
+pokud přejde na novou verzi.
+
+\inssdef dbtversion
+
+Je-li použit "csplain", je aktivován UTF-8 vstup pomocí enc\TeX{}u. To
+ale bohužel není kompatibilní s použitím enc\TeX{}u \docbytex{}em.
+Je tedy potřeba deaktivovat UTF-8 vstup a české texty napsat například
+v ISO-8859-2.
+
+\inext {utf8off}{\empty}{+-}
+
+%Inicializujeme csplain mód:
+%
+%\inext {ifx\nb chyph\nb undefined \nb else}{\empty}{+-}
+
+Inicializujeme enc\TeX{}ový mód:
+
+\inext {encTeX ??}{\empty}{+-}
+
+Makro \db enctextable "{<slovo>}{<tělo makra>}" vloží do enc\TeX{}ové
+tabulky vzor "<slovo>". Jakmile takový vzor enc\TeX{}
+objeví, zruší jej ze vstupního proudu a promění jej v kontrolní
+sekvenci "\.<slovo>", která expanduje na "<tělo makra>".
+Například makro "\dg"~"<slovo>" aktivuje pro enc\TeX{} "<slovo>", takže
+provede (mimo jiné)
+"\enctextable{<slovo>}{\sword{<slovo>}}", což způsobí,
+že se "<slovo>" v načítaném zdrojovém kódu promění na "\sword{<slovo>}".
+
+Makro "\enctextable" odmítá uložit do enc\TeX{}ové tabulky slova,
+která jsou v seznamu \uv{zakázaných} slov \db owordbuffer. Tam jsou
+slova (oddělená z obou stran čárkou), která se nesmějí aktivovat kvůli
+"\onlyactive". Pro taková slova provede "\enctextable" jen definici
+sekvence "\.<slovo>".
+
+Makro \db noactive "{<text>}" vloží do enc\TeX{}ové tabulky vyhledávaný
+text, který ve vstupu zůstane a před něj bude vložena sekvence \db emptysec.
+Protože enc\TeX{} neumí ze své tabulky zrušit údaj (umí jen přepsat
+informaci, na co se má vyhledávaný text proměnit), je potřeba texty,
+které už v encTeXové tabulce nepotřebujeme, deaktivovat alespoň pomocí
+"\noactive".
+
+Na \db sword "{<text>}" se díky enc\TeX{}u proměňují texty, které se mají
+automaticky stát klikatelnými linky.
+
+\inext {def\nb sword}{\empty}{+-}
+
+Makro \db onlyactive "{<před>}{<slovo>}{<za>}" zakáže vkládat
+"<slovo>" do enc\TeX{}ové tabulky (vloží je do "\owordbuffer",
+ovšem jen za předpokladu, že už tam není),
+a nechá celý text "<před><slovo><za>" proměnit v~"\oword{#1}{#2}{#3}".
+Dále pomocí "\noactive" dekativuje "<slovo>" (při čtení "\reffile"
+totiž pravděpodobně bylo aktivováno).
+Makro \db oword "{<před>}{<slovo>}{<za>}"
+tiskne normálně "<před>", dále, pokud je definováno "\.<slovo>", tak
+je spustí, jinak tiskne normálně "<slovo>". Konečně tiskne vždy
+normálně text "<za>".
+
+\inext {def\nb onlyactive}{\empty}{+-}
+
+Nakonec inicializujeme DVI/PDF mód:
+
+\inext {ifx\nb pdfoutput}{\empty}{+-}
+
+\subsec Makra {\tt\nb ifirst}, {\tt\nb inext}, {\tt\nb ilabel}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Deklarujeme \db lineno jako číslo řádku, \db ttlineno jako číslo řádku
+pro "\begtt...\endtt" výpisy, \db ifcontinue pro řízení cyklu a
+\db infile je deskriptor souboru otevřeného ke čtení.
+\db ifskipping implementuje uživatelské \db skippingfalse a
+\db skippingtrue.
+
+\inext {newcount\nb lineno}{\empty}{+-}
+
+%Makra "\ifirst", "\inext" jsou pro uživatele popsána
+%v~sekci~\cite[vkladani] a makro "\ilabel" má své povídání
+%v~sekci~\cite[lineodkazy].
+
+Příkaz \db ifirst "{<soubor>}{<odkud>}{<kam>}{<jak>}" nejprve
+pomocí "\readiparamwhy" analyzuje parametr "<jak>", pak otevře soubor
+ke čtení primitivem "\openin". Je-li otevření neúspěšné, vypíše
+varování, jinak si uloží název souboru do makra \db inputfilename
+a analyzuje parametry pomocí "\scaniparam": "<odkud>" je uloženo do
+"\tmpa" a "<kam>" do "\tmpb". Do "\tmpA" a "\tmbB" se uloží počet
+opakování (z konstruktoru "\count=<num>"). Nakonec se spustí makro
+"\insinternal" s expandovanými parametry "<odkud>", "<kam>".
+K tomu je použit známý trik s makrem "\act".
+
+\insdef ifirst
+
+Příkaz \db inext "{<odkud>}{<kam>}{<jak>}" pracuje analogicky, jako
+"\ifirst", pouze neotevírá soubor, ale pomocí testu na definovanost
+makra "\inputfilename" kontroluje, zda náhodou nebyl spuštěn příkaz
+"\inext" bez předchozího "\ifirst".
+
+\insdef inext
+
+V rámci expanze parametrů chceme, aby zmizely všechny kontrolní sekvence, které
+nám do textu vložil automaticky enc\TeX{}. To provede makro
+\db noswords.
+
+\inssdef noswords
+
+Makro \db readiparamwhy načte znaky "+" nebo "-" z parametru "<jak>" a
+uloží je do sekvencí \db startline a \db stopline.
+
+\inssdef readiparamwhy
+
+Makro \db scaniparam "<param>^^X<out><outnum>" čte "<param>"
+ve tvaru "\count=<num> <text>". Do sekvence "<out>" uloží "<text>"
+a do sekvence "<outnum>" uloží "<num>". Protože konstruktor
+"\count=<num>" je nepovinný, dá trochu více práce parametr analyzovat.
+K tomu slouží i pomocná makra \db scaniparamA, \db scaniparamB, \db scaniparamC.
+V případě nepřítomnosti "\count=<num>" je v~"<outnum>" jednička.
+
+\inssdef scaniparam
+
+Hlavní práci při vkládání zdrojového textu do dokumentace dělá makro
+\db insinternal s parametry "{<odkud>}{<kam>}".
+
+\ilabel [prvniloop] {preskakovani}
+\ilabel [konec:prvniloop] {ifcontinue \nb repeat}
+\ilabel [druhyloop] {pretisk}
+\ilabel [konec:druhyloop] {readnewline \nb repeat}
+\ilabel [insinternal:end] {printibelow}
+\insdef insinternal
+
+Makro "\insinternal" se skládá ze dvou hlavních cyklů. První (na
+řádcích~\cite[prvniloop] až~\cite[konec:prvniloop]) čte postupně
+řádky ze vstupního souboru (makrem
+"\readnewline") a uloží je do makra "\etext". V tomto cyklu hledá
+výskyt textu "<odkud>" a nic netiskne.
+
+Druhý cyklus na řádku~\cite[druhyloop] až~\cite[konec:druhyloop]
+čte postupně řádky ze vstupního
+souboru a hledá výskyt textu "<kam>". V této chvíli tiskne pomocí
+makra "\printilineA".
+
+Před prvním cyklem jsou provedeny přípravné práce: nastavení
+kategorií, fontů, "\mubytein".
+Dále je v přípravné fázi definováno makro \db testline se separátorem
+"<odkud>", pomocí něhož budeme testovat přítomnost textu "<odkud>".
+Variantní definice makra "\testline" následují pro speciální případ
+parametru "<odkud>" (viz uživatelská dokumentace v~sekci~\cite[vkladani]).
+Ukončení cyklu je řízeno podmínkou "\ifcontinue". Příkaz \db nocontinue
+provede "\continuefalse", ovšem ne vždy. Pokud je zadáno "\count>1", tj.
+"\tempnum>1", pak příkaz pouze zaznamená výskyt hledaného textu a sníží
+"\tempnum" o jedničku.
+
+\inssdef nocontinue
+
+Před druhým cyklem v makru "\insinternal" jsou provedeny podobné přípravné
+práce jako před
+prvním, znovu je definováno makro "\testline", tentokrát se separátorem
+"<kam>". Vyhledávání probíhá podobně, jako když jsme hledali "<odkud>".
+
+Pomocí "\ifx+\startline" testujeme, zda tisknout výchozí řádek.
+Pomocí "\ifx+\stopline" testujeme, zda tisknout ukončovací řádek.
+
+Makro "\ilabellist" obsahuje testování přítomnosti lejblíků
+deklarovaných příkazem "\ilabel".
+
+Trikoidní je makro \db returninsinternal "{<text>}{<možná fi>}{<ignoruj>}",
+které se spustí při dosažení konce čteného souboru. Marko opustí svůj
+cyklus pomocí parametru "<ignoruj>", který je separován textem
+"\printibelow", takže to přeskočí větší část obsahu makra "\insinternal" až
+po řádek~\cite[insinternal:end]. Abychom správně opustili vnořené
+podmínky, jsou přečtena v druhém parametru případná "\fi" a v makru použita.
+První parametr obsahuje varovací hlášku, chceme-li vypsat varování.
+Chceme-li být zticha, je parametr prázdný.
+
+\insdef returninsinternal
+
+Makro \db readnewline je naproti tomu jednoduché:
+
+\inssdef readnewline
+
+Pracujeme s řádkem čteného souboru ve dvou verzích: neexpandovaným
+\db text a expandovaným \db etext při "\noswords". Tím máme zaručeno,
+že v "\etext" nejsou kontrolní sekvence vytvořené enc\TeX{}em (pro
+test přítomnosti "<odkud>" nebo "<kam>" by tam ty sekvence překážely).
+Verze s enc\TeX{}ovými sekvencemi "\text" se použije při tisku.
+
+Makro \db printilineA musí mít svou inteligenci: nesmí bezhlavě tisknout
+prázdné řádky, ale ty tiskne až se zpožděním, následuje-li tisk
+neprázdného řádku. Tím je zaručeno, že se při "\skippingtrue" nevytiskne poslední
+prázdný řádek. Makro \db lastline má tři stavy: "\empty" (na začátku),
+"\relax" (po vytištění řádku), "<číslo řádku>" (je-li předchozí řádek
+prázdný).
+
+\insdef printilineA
+
+Pro uložení deklarací pomocí \db ilabel "[<lejblík>]{<text>}"
+slouží makro \db ilabellist, které musíme nastavit nejprve na prázdnou
+hodnotu.
+
+\insdef ilabellist
+
+Makro "\ilabel" nejprve expanduje své parametry (pomocí
+"\act") a zavolá interní \db ilabelee. Toto makro přidá do
+"\ilabellist" toto:
+
+\def\begtthook{\langleactive\mubytein=1}
+\begtt
+\expandafter\testilabel\etext\end{<lejblík>}{<text>}
+\endtt
+
+Makro \db testilabel "<řádek>\end{<lejblík>}{<text>}"
+si definuje pomocné makro "\tmp" se separátorem "<text>", aby
+zjistilo, zda je "<text>" uvnitř "<řádek>". Pokud se to povede,
+registruje cíl odkazu pomocí "\labeltext".
+
+\inext {testilabel}{\empty}{+-}
+
+\def\begtthook{}
+
+\subsec Příkazy {\tt\nb begtt}, {\tt\nb endtt}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Makro \db begtt a "\endtt"
+je podrobně popsáno v \TeX{}booku naruby
+na stranách~27 až~30. Makru \db startverb dodáme kompletní
+verbatim text separovaný "\endtt".
+Tento text je dělený znakem "^^M" (kategorie 12) na řádky a koncový řádek
+obsahuje token "\end". Makro spustí ve spolupráci s makrem \db runttloop
+cyklus a řádky rozebere, každý řádek zvlášť předá makru "\printvline".
+Na konci cyklu se provede makro \db endttloop. To udělá závěrečné
+činnosti (zavolá "\printvbelow", ukončí skupinu) a pomocí makra
+\db scannexttoken otestuje první následující
+token. Pokud to není "\par", není pod "\endtt" prázdný řádek,
+takže se provede "\noindent".
+
+\ifirst {docby.tex}{def\nb begtt }{\empty}{+-}
+
+V numerickém registru "\ttlineno" je číslo řádku průběžně zvětšované
+v celém dokumentu. Pokud by někdo chtěl toto číslo využít, může jej
+nulovat například na začátku každé sekce.
+
+\subsec [ns] Jmenné prostory
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Každý jmenný prostor si udržuje své \db namespacemacro, což je makro
+s jedním parametrem, které příkazem "\namespace{<tělo makra>}" mimoděk
+definuje uživatel. Na počátku je "\namespacemacro" prázdné:
+
+\ifirst {docby.tex}{def\nb namespacemacro}{\empty}{+-}
+
+Ke každému jmennému prostoru budeme chtít přiřadit lejblík. Rozhodl
+jsem se za lejblík považovat výsledek expanze "\namespacemacro{@!}".
+Budu jej nadále značit "<nslejblík>".
+Existuje sice určité riziko nejednoznačnosti "<nslejblíku>", ale
+předpokládám, že v praxi nenastane.
+
+Každý jmenný prostor už na počátku musí vědět, jaká všechna lokální
+slova obsahuje, aby jejich výskyt mohl směřovat na místo, kde je
+deklarace "\dl", která může být třeba později než výskyt. Jmenný
+prostor na svém startu musí tedy do enc\TeX{}ových tabulek uložit
+všechna lokální slova a na svém konci vrátit vše pokud možno do
+původního stavu. Je tedy zřejmé, že není vhodné čekat až na příkaz
+"\dl", ale že je třeba využít soubor "\reffile". V prvním průchodu
+tedy jmenné prostory nemohou být aktivní.
+
+Po přečtení "\reffile" má každý jmenný prostor k dispozici makro
+"\ns:<nslejblík>", které obsahuje seznam všech svých
+lokálně deklarovaných slov ve formátu
+
+{\def\begtthook{\mubytein=1\langleactive}
+\begtt
+\locword{<slovo1>}\locword{<slovo2>}\locword{<slovo3>}...
+\endtt
+\par}
+
+Protože ukládání do enc\TeX{}ové tabulky je globální, definujeme
+v rámci duševní hygieny všechna makra s tím spojená globálně. Proto je
+prostředí "\namespace...\endnamespace" nezávislé na skupinách \TeX{}u.
+
+Při startu \db namespace je třeba definovat "\namespacemacro".
+Původní hodnotu "\namespacemacro" uložíme do "\no:<nslejblík>",
+abychom se k němu mohli na konci prostředí
+"\namespace...\endnamespace" vrátit. Dále definujeme makro \db locword
+tak, aby uložilo potřebné údaje do enc\TeX{}ové tabulky a před tím
+ještě si uložilo stávající významy předefinovávaných kontrolních
+sekvencí. Pak se prostě spustí "\ns:<nslejblík>".
+
+\inext {def\nb namespace }{^^B\cbrace}{++}
+
+Na konci \db endnamespace znovu definujeme makro "\locword" tentokrát tak, aby
+vrátilo pozměněným sekvencím původní význam. Pokud původní význam byl
+\uv{nedefinovaná sekvence}, je potřeba do enc\TeX{}ové tabulky vložit
+aspoň "\nword", protože zcela odstranit údaj z tabulky nelze.
+Dále se vrátíme k~původní hodnotě "\namespacemacro", kterou máme
+uloženu v "\no:<nslejblík>".
+
+\inext {def\nb endnamespace}{^^B\cbrace}{++}
+
+Uvedená makra pracují s užitečnou zkratkou \db ewrite, která zapíše
+text do "\reffile" se zpožděním (primitivem "\write"), ale expanzi
+udělá hned. Přitom neexpanduje "\nb".
+
+\inext {def\nb ewrite}{\empty}{+-}
+
+Enc\TeX{} od startu jmenného prostoru vkládá tedy místo každého
+lokálního "<slova>" kontrolní sekvenci "\.<slovo>", která expanduje
+na "\lword{<slovo>}". Jakmile se tedy objeví výskyt lokálního slova,
+pracuje \db lword takto:
+
+\inext {def\nb lword}{\empty}{+-}
+
+Makro \db genlongword "<tmp>{<slovo>}"
+vytvoří z krátké verze slova dlouhou verzi slova a uloží ji do "<tmp>".
+Výskyt "<slova>" dává o sobě vědět v parametru "\ilink" i při zápisu
+do souboru svým dlouhým (jednoznačným) jménem, zatímco krátké jméno
+se tiskne.
+
+Zbývá zařídit čtení ze souboru "\reffile". Makro
+\db refns "{<nslejblík>}" se objeví v souboru v místě začátku jmenného
+prostoru a \db refnsend "{<nslejblík>}" na konci jmenného prostoru. Mezi
+nimi se vyskytují "\refdg{<před>}{<slovo>}{<za>}{<k-slovo>}", přičemž
+si nyní všímáme jen takových výskytů, které mají neprázdné
+"<k-slovo>". Právě tyto výskyty zanesl do "\reffile" příkaz "\dl".
+
+\inext {def\nb refns}{\empty}{+-}
+
+Makro "\refns" si zapamatuje předchozí "<nslejblík>", který je uložen
+v makru \db currns, do sekvence "\o:<nový nslejblík>" a definuje pak "\currns"
+jako "<nový nslejblík>". Připraví také výchozí stav makra "\ns:<nslejblík>"
+na prázdnou hodnotu. Makro "\refdg" pak postupně plní buffer
+"\ns:<nslejblík>" (viz řádky~\cite[ns1] až~\cite[ns2] v~definici makra
+"\refdg" v~sekci~\cite[reference]). Konečně makro "\refnsend" vrátí
+"\currns" do stavu, v jakém bylo před vstupem do stávajícího jmenného
+prostoru.
+
+
+\subsec {\tt\nb dg} a přátelé
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Makra \db dg, \db dl, \db dgn, \db dgh, \db dln, \db dlh
+uloží do "\tmpA" svůj název, spustí sken parametrů pomocí \db dgpar
+a nakonec se promění ve svou interní verzi pomocí
+"\csname ii\tmpA\endcsname".
+
+\inext {def\nb dg}{\count=2 \empty}{+-}
+
+Předchozí makra připraví čtení nepovinného parametru. Hlavní práci
+provede makro \db dparam.
+
+\ilabel [managebrackets] {managebrackets}
+\ilabel [ii] {csname ii}
+\inext {def\nb dparam}{\empty}{+-}
+
+Je-li za ukončovací závorkou "]" mezera, pak je parametr "#2" prázdný (je
+separovaný mezerou). V~této situaci se makro "\dparam" protočí ještě
+jednou prostřednictvím makra \db nextdparam, které sežere obsah zbytku
+makra "\dparam", vloží mezeru dovnitř závorky a spustí "\dparam" ještě
+jednou. Nyní už je možné začít parametr "#2", tj. "<slovo>" rozdělit
+na část před první čárkou, tečkou, středníkem nebo dvojtečkou a za za
+tímto znakem. Část před bude v "\tmpa" a část za (včetně separátoru)
+bude v "\tmpb". Tuto práci vykoná postupné volání makra \db varparam:
+
+\inext {def\nb varparam}{\empty}{+-}
+
+Makro "\varparam<separ>" definuje pomocné makro "\tmp#1<separ>#2 ", kterému
+je předloženo "<slovo><separ> ". Je-li "#2" prázdné, pak zabral až
+"<separ>" na konci, takže uvnitř "<slova>" není "<separ>". Pak v
+"\tmpa" zůstává "<slovo>". Je-li uvnitř "<slova>" separátor, pak je
+potřeba doplnit k "\tmpb" zbytek za separátorem včetně tohoto
+separátoru. V "#2" máme "<zbytek><separ>" a my potřebujeme do "\tmpb"
+uložit stávající obsah "\tmpb" před kterým předchází "<separ><zbytek>".
+Tuto práci udělá \db gobblelast, kterému je předložen
+"<obsah tmpb>\end<separ><zbytek><separ>". Makro definuje
+"\tmp#1<separ>" a předloží mu "<zbytek><separ>". Je tedy v "#1" holý
+"<zbytek>" a do "\tmpb" se dostává "<separ><zbytek><starý obsah tmpb>".
+
+Po rozdělení vyhledání separátoru máme n "\tmpa" <slovo>, ovšem může
+obsahovat na konci "()". Proto spustíme na řádku~\cite[managebrackets]
+makro \db managebrackets, které se postará o případné oddělení těchto
+závorek. Pokud se závorky skutečně oddělily od "\tmpa", zůstávají
+v~\db printbrackets.
+
+\inext {def\nb managebrackets}{\empty}{+-}
+
+Makro \db maybespace v závěru činnosti makra "\dparam" vytiskne za
+obsahem "\tmpb" mezeru, ale jen tehdy, když je jméno makra
+dvoupísmenkové ("\dg", "\dl") a nenásleduje znak "`".
+
+\inext {def\nb maybespace}{\empty}{+-}
+
+Na řádku~\cite[ii] vytvoří makro "\dparam" z původního příkazu
+"\dg*" resp. "\dl*" jeho interní verzi "\iidg*" resp. "\iidl*".
+Parametry předá expandovány, aby s nimi bylo méně práce.
+Stačí tedy naprogramovat uvedená interní makra.
+
+Makro \db iidg vloží do enc\TeX{}ové tabulky "\sword" (je to mírně
+nadbytečné, totéž se provede na začátku zpracování při čtení
+"\reffile" příkazem "\refdg"). Dále makro vytvoří cíl
+odkazu tvaru "@<slovo>", uloží informaci do "\reffile"
+ve formátu "\refdg{<před>}{<slovo>}{<za>}{}",
+vytiskne "<slovo>" zvýrazněné pomocí "\printdg" a vloží poznámku pod
+čáru pomocí "\printfnote".
+
+\inext {def\nb iidg }{^^B\cbrace}{++}
+
+Makro \db iidl nevkládá nic do enc\TeX{}ové tabulky,
+vytvoří cíl pomocí "\label [@<dlouhé slovo>]", zapíše info do
+"\reffile" ve formátu "\refdg{<před>}{<d-slovo>}{<za>}{<k-slovo>}",
+vytiskne "<k-slovo>" zvýrazněné pomocí "\printdg" a vloží poznámku
+pomocí "\printfnote{<před>}{<d-slovo>}{<za>}".
+
+\inext {def\nb iidl }{^^B\cbrace}{++}
+
+Makra \db iidgh a \db iidlh dělají to samé jako jejich non-"h"
+protějšky, jen netisknou slovo v místě výskytu. Lokálně tedy
+předefinujeme, aby "\printdg" nedělalo nic.
+
+\inext {def\nb iidgh}{\empty}{+-}
+
+Makro \db iidgn předefinuje makro "\.<slovo>", které vyrábí enc\TeX,
+tak, že výsledkem expanze je "\fword{<před>}{<slovo>}{<za>}"
+(namísto obvyklého "\sword{<slovo>}").
+
+\inext {def\nb iidgn}{\empty}{+-}
+
+Až se \db fword spustí (při prvním následujícím výskytu "<slova>"), má
+za úkol provést "\iidgh", vytisknout "<slovo>" červeně a vrátit
+"\.<slovo>" do původního stavu.
+
+\inext {def\nb fword}{\empty}{+-}
+
+Makro \db iidln si uloží stávající význam "\.<slovo>" do
+sekvence "\;<slovo>" a předefinuje makro "\.<slovo>",
+které vyrábí enc\TeX, tak, že výsledkem je
+"\flword{<před>}{<slovo>}{<za>}".
+
+\inext {def\nb iidln}{\empty}{+-}
+
+Makro \db flword má za úkol provést "\iidlh", vytisknout "<slovo>"
+červeně a vrátit význam makra "\.<slovo>" do původního stavu (který je uložen
+v sekvenci "\;<slovo>". Byl-li tento původní význam nedefinován, je
+potřeba potlačit další činnost makra "\.<slovo>" registrováním jako
+"\nword{<slovo>}", protože z enc\TeX{}ové tabulky už záznam nelze
+odebrat.
+
+\inext {def\nb flword}{\empty}{+-}
+
+\subsec [specfootnote] Speciální poznámky pod čarou
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Poznámky pod čarou jsou řazeny vedle sebe a obsahují jen slova, která
+mají na stránce své "\dg". Protože toto řešení je vizuálně
+nekompatibilní s uživatelskými poznámkami pod čarou, jednoduše je
+zakážeme:
+
+\inext {let\nb footnote=}{\empty}{+-}
+
+Pro speciální poznámky pod čarou využiji už deklarovaný insert
+"\footins". Problém je, jak odhadnout, kolik zabere vertikálního místa
+v poznámkách jedno slovo, když jich může být vedle sebe
+více. Dirty trick z \TeX{}booku (vkládat inserty ve výšce rovné jistému
+procentu své šířky) se neujal, neboť zlom často nekonvergoval, ale osciloval.
+V druhém průchodu poznámky teprve dostávají své seznamy stránek a tyto
+seznamy se pak mohou dále upřesňovat, což zpětně ovlivní vertikální
+sazbu. Po její změně se mění seznamy stránek a tak pořád dokola.
+
+Rozhodl jsem se tedy pracovat pouze s průměrným koeficientem
+poznámek, který budou mít všechny poznámky společný. Tento koeficient
+získám jako celkový počet řádků poznámek v celém dokumentu dělený
+počtem poznámek. Každá poznámka pak \uv{překáží} v hlavním vertikálním
+seznamu výškou řádku poznámek (10pt) násobenou tímto koeficientem.
+Stačí tedy nastavit "\count\footins".
+
+Aby problém určitě konvergoval, bylo nutné fixovat výše uvedený
+koeficient po druhém průchodu. Kdybych jej každý následující průchod
+měnil, zase se nedočkáme konvergence. Získat uvedený koeficient hned
+po prvním průchodu není rozumné, protože v té době poznámky ještě
+nemají vedle sebe seznamy stránek. Výchozí koeficient pro první a
+druhý průchod je tedy nastaven na "\count\footins=200" (předpokládám
+zhruba pět poznámek na řádku).
+
+Pracovat s průměrem místo s každou jednotlivou poznámkou může
+samozřejmě způsobit, že některé stránky jsou plnější a některé
+prázdnější. Proto je potřeba mít rezervu ve "\skip\footins" a
+vertikálně pružit kolem poznámkové čáry.
+
+\inext {skip\nb footins}{\empty}{+-}
+
+V registru \db totalfoocount se bude postupně přičítat jednička za každou
+poznámku a na konci zpracování tam tedy je celkový počet poznámek.
+V registru \db totalfoodim bude na konci zpracování celková výška
+všech řádků s poznámkami.
+
+\inext {newcount\nb totalfoocount}{\empty}{+-}
+
+Makro \db specfootnote "{<text>}"
+vloží do insertu "\footins" jediný "\hbox{<text>}" a připočte
+jedničku do "\totalfoocount".
+
+\inext {def\nb specfootnote}{\empty}{+-}
+
+Protože jsem se rozhodl neměnit výstupní rutinu plainu, musel jsem se
+\uv{nabourat} aspoň do její části na tisk poznámek pod čarou. Je to
+provedeno předefinováním makra "\footnoterule" výstupní rutiny plainu.
+Separátor "\unvbox\footins" způsobí odstranění stejného textu
+z output rutiny plainu.
+
+\inext {def\nb footnoterule}{\empty}{+-}
+
+Makro rozebere vertikální seznam insertů "\footins" a poskládá je
+vedle sebe do boxu~4. Pak nastaví parametry sazby na praporek a
+vypustí box~4 do horizontálního seznamu ("\noindent") ukončeném
+"\endgraf". Tím jsou ve výstupní rutině poznámky pod čarou vysázeny.
+Nakonec připočteme "\totalfoodim".
+
+V závěru zpracování v makru "\bye" (viz řádek~\cite[write]) zapíšeme
+do souboru "\reffile" informaci o~počtu poznámek "<počet>", o celkové
+výšce řádků poznámek v dokumentu "<výška>" a přidáme aktuální
+koeficient příspěvku poznámek do vertikálního seznamu "<koeficient>".
+Informaci zapisujeme jen tehdy, když je "\indexbuffer" neprázdný,
+tj. když probíhá aspoň druhý průchod. Kdybychom zapisovali i první
+průchod, dostali bychom velmi zkreslené informace (poznámky v~tu
+chvíli nemají vedle sebe seznamy stránek).
+%
+Uvedenou informaci zapsanou v předchozím průchodu
+přečteme na začátku zpracování makrem
+\db refcoef "{<koeficient>}{<počet>}{<výška>}" a
+nastavíme podle toho společný koeficient všech poznámek
+"\count\footins". Makro změní koeficient z výchozí
+hodnoty 200 na vypočtenou jen jednou. Při dalších průchodech už
+zůstává u vypočtené hodnoty.
+Pomocné makro \db gobblerest odstraní cifry za desetinou
+tečkou včetně nápisu~"pt".
+
+\inext {def\nb refcoef}{\empty}{+-}
+
+Výstupní rutina "\plainoutput" není změněna. Potřebuji ale uvnitř
+"\output" potlačit expanzi některých maker, které se objeví v argumentu
+"\write". Tato makra jsou tedy uvnitř "\output" nastavena na "\relax".
+Aby toto nastavení nezměnilo sazbu záhlaví, je potřeba "\makeheadline"
+provést před změnou maker a uložit si výsledek do boxu.
+
+\inext {\nb output=}{\empty}{+-}
+
+\subsec [secsec] Sekce, podsekce
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Nejprve zapíšeme deklarace \db secnum, \db subsecnum,
+\db sectitle, \db ifsavetoc. Poslední deklarace připraví
+uživatelské \db savetocfalse.
+
+\ifirst {docby.tex}{newcount\nb secnum}{\empty}{+-}
+
+Makra \db sec a \db subsec mají možnost nepovinného parametru
+"[<lejblík>]", za ním může a nemusí být mezera, kterou musíme ignorovat.
+Na konci parametru "<titul>" před "\par" rovněž může a nemusí být
+mezera, kterou musíme ignorovat. Dá tedy práci parametry správně
+načíst. Makra si uloží svůj název do "\tmpA" a spustí proces načítání
+parametrů pomocí "\secparam".
+
+\inext {def\nb sec}{\empty}{+-}
+
+Makro \db secparam se vypořádá s případným nepovinným parametrem
+"[<lejblík>]". Pokud je přítomen, uloží "<lejblík>" do pomocného makra
+\db seclabel, jinak tam je prázdno. Makro \db secparamA se vypořádává
+s případnou mezerou za hranatou závorkou "]" a odstraní ji.
+Makro \db secparamB "<titul>\par" načte "<titul>", ale ten může mít
+nežádoucí mezeru zcela na konci. S tím se vypořádá makro
+\db nolastspace ve spolupráci s makrem \db setparamC. Posledně jmenované
+makro uloží už od nežádoucí mezery ošetřený "<titul>" do "\sectitle" a
+spustí "\iisec" resp. "\iisubsec".
+
+\inext {def\nb secparam}{\empty}{+-}
+
+Makro \db iisec nejprve nastaví hodnoty "\secnum" a "\subsecnum",
+dále definuje \db makelinks, kde je připravena tvorba odkazů (to
+použije makro "\printsec").
+Dále zavolá "\printsec" na vytištění názvu sekce.
+Poté uloží informace do "\reffile" ve tvaru
+"\reftocline"~"{<secnum>}{<titul>}{<strana>}"
+Nakonec se provede "\mark{<secnum> <titul>}" a
+vloží se závěrečná mezera pomocí "\printsecbelow".
+
+\inext {def\nb iisec}{^^B\cbrace}{++}
+
+Makro \db iisubsec, které vytváří podsekci, pracuje analogicky, jako
+makro "\iisec".
+
+\inext {def\nb iisubsec}{^^B\cbrace}{++}
+
+Makro "\part" bylo zapracováno dodatečně ve verzi Jan. 2009.
+Registr \db partnum uchovává číslo části a makro \db thepart
+toto číslo konvertuje na písmeno.
+
+\inext {newcount\nb partnum}{\empty}{+-}
+
+Makro \db part má svou implementaci v makru \db iipart
+podobně jako například makro "\sec".
+
+\inext {def\nb part}{\empty}{+-}
+
+\subsec [reference] Odkazy, reference
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Klikací odkazy řeší makra \db savelink "[<lejblík>]" a a \db ilink
+"[<lejblík>]{<text>}". Makro "\savelink" uloží do sazby cíl
+odkazu. Cíl odkazu vystrčí do
+výšky \db linkskip nad účaří. Makro "\ilink" (čti interní link) je
+dokumentováno v~sekci~\cite[krizodkaz]. Konečně makro "\savepglink"
+uloží cíl numerického typu (číslo stránky), který bude využit makrem
+"\pglink" při odkazech na stránky.
+
+\ifirst {docby.tex}{Odkazy, ref}{\empty}{--}
+
+Uvedená makra jsem definoval zvlášť pro DVI výstup (jako prázdná
+makra) a zvlášť pro PDF výstup. Až zase tvůrci pdf\TeX{}u změní
+syntaxi nebo názvy primitivů, bude stačit pozměnit uvedená makra.
+V makru "\ilink" je přímo řečeno, že se má použít modrá barva pro
+vytvoření odkazů a že odkaz má být bez rámečku. Pokud to někomu
+nevyhovuje, může si makro předefinovat.
+
+Trik s předefinováním "\nb" (normální backslash) při tvorbě PDF linků
+vychází ze zkušenosti, že pokud se v názvu linku objeví backslash,
+některé PDF prohlížeče si s tím neporadí a chovají se podivně. Je tedy
+nutné, aby argument příkazů "\savelink" a "\ilink" byl neexpandovaný.
+
+Makro \db savepglink (definice je v předchozím výpisu) je použito v
+"\headline" každé stránky, takže vytvoří cíl \uv{nahoře} na každé
+stránce. Makro \db pglink "<number>" přečte "<number>" (může být ve
+tvaru numerického registru i přímo jako číslo) a vytvoří link na
+stránku s tímto číslem. Číslo samotné je vytištěno modře a dá se na ně
+kliknout. Ke čtení numerického registru je použit primitiv "\afterassignment"
+a pomocné makro \db dopglink.
+
+V souboru "\jobname.ref" se prostřednictvím makra
+"\labeltext[<lejblík>]{<text>}" uloží řádek, který obsahuje
+"\reflabel"~"{<lejblík>}{<text>}{<strana>}". Makrem \db reflabel tyto
+údaje přečtu a zapíšu do kontrolních sekvencí "^^X<lejblík>" a
+"^^Y<lejblík>". Tyto kontrolní sekvence jsou následně využity
+v~makrech \db numref a \db pgref.
+Za povšimnutí stojí, že pokud je "<text>" prázdný
+(to jsou například všechny případy dokumentovaných slov), pak
+kontrolní sekvenci "^^X<lejblík>" vůbec nedefinuji, abych šetřil
+pamětí, kterou má \TeX{} rezervovánu na kontrolní sekvence.
+
+\inext {reflabel}{\empty}{+-}
+
+Makro \db labeltext "[<lejblík>]{<text>}", jak bylo před chvílí
+řečeno, uloží do souboru potřebné údaje. Jednak zapíše PDF link pomocí
+makra "\savelink" a dále uloží do souboru "\reffile" potřebné údaje.
+K tomu je makro \db writelabel "[<lejblík>]{<text>}", které
+pracuje se zpožděným "\write" (aby číslo strany bylo správně).
+V okamžiku načtení parametru
+"<text>" jej potřebuji expandovat, protože tam obvykle bývá něco jako
+"\the\secnum". Pro vyřešení tohoto problému jsem
+na chvíli prohodil parametry ("<lejblík>" totiž nechci
+expandovat) a zavedl pomocné makro
+\db writelabelinternal "{<text>}{<lejblík>}".
+První část, tj. "\writelabel{<text>}" expanduji pomocí "\edef".
+
+\inext {labeltext}{\empty}{+-}
+
+Makro \db label je už definováno jednoduše jako \uv{prázdný}
+"\labeltext".
+
+\inext {label}{\empty}{+-}
+
+Makro \db cite "[<lejblík>]" vytiskne klikatelný text. Při chybném
+"<lejblíku>" vytiskne varování na terminál. Makro je dokumentováno
+v~sekci~\cite[krizodkaz].
+
+\inext {cite}{\empty}{+-}
+
+S odkazy souvisí makro \db api "{<slovo>}", které vloží
+"\label[+<slovo>]" dá o sobě vědět ještě jednou do "\reffile".
+
+\inext {def\nb api}{\empty}{+-}
+
+Makro \db apitext obsahuje text tištěný vedle "<slova>" do obsahu a
+rejstříku.
+
+Při činnosti makra \db bye zapíšeme do souboru "\reffile" údaje
+pro "\refcoef" (řádek~\cite[write]) a dále se zabýváme testem
+konzistence referencí.
+
+\ilabel [texttoc] {text\nb tocbuffer}
+\ilabel [vypust] {indexbuffer}
+\ilabel [write] {write\nb reffile}
+\inext {def\nb bye}{^^B\cbrace}{++}
+
+Test konzistence vypadá následovně: nejprve
+uzavřeme zápis do souboru "\reffile", pak
+pomocí "\setrefchecking" předefinujeme
+kontrolní sekvence vyskytující se v "\reffile" a soubor znovu
+načteme. Nyní makra v něm napsaná dělají test a pokud narazí na
+problém, provedou "\continuefalse". Můžeme tedy pomocí "\ifcontinue"
+zjistit, jak test dopadl. Po přečtení souboru je potřeba udělat ještě
+důkladnou kontrolu všech automatických odkazů. Proč je tato kontrola
+vyřešena vypuštěním "\indexbuffer" do vstupní fronty bude jasné po prostudování
+makra \db setrefchecking.
+
+\ilabel[jerelax] {=\nb relax}
+\inext {def\nb setrefchecking}{\empty}{+-}
+
+Zde předefinujeme makro "\refcoef", aby nedělalo nic.
+Dále nová verze "\reflabel" kontroluje, zda odkaz je na stejné stránce, jako byl
+a má stejný text.
+Nové makro "\refuseword" pracuje jako jeho originální protějšek, jen místo
+sekvencí "w:<slovo>" plní sekvence "-<slovo>". Tyto sekvence už známe,
+nyní je využijeme jinak. Šetříme pamětí \TeX{}u, proto nezakládáme
+sekvence nové. Nejprve je nutné těmto sekvencím nastavit výchozí
+hodnotu "\relax", což je provedeno na řádku~\cite[jerelax].
+Pak znovu předefinuji sekvenci "\,", aby provedla test shodnosti sekvence
+"w:<slovo>" se sekvencí "-<slovo>" a v makru "\bye" na
+řádku~\cite[vypust] spustím tento test expandováním makra
+"\indexbuffer\relax". Když makro najde nekonzistenci, ohlásí chybu a
+uteče pomocí \db ignoretorelax.
+Dále je předefinováno makro "\refdg", aby pouze
+zapisovalo do "\tocbuffer". Ostatní makra z "\reffile" také zapisují
+do "\tocbuffer". Stávající verzi "\tocbuffer" uložíme do "\text" a
+"\tocbuffer" se při načtení "\reffile" vytvoří znovu. Na
+řádku~\cite[texttoc], zda se nezměnil obsah.
+
+\subsec Tvorba obsahu, rejstříku a záložek
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Obsah i rejstřík se mohou pomocí "\dotoc" a "\doindex" objevit kdekoli
+v dokumentu (třeba na začátku, na konci, uprostřed...). Musíme být
+připraveni je kdykoli vytisknout. Soubor "\reffile" z minulého běhu
+můžeme otevřít ke čtení jen na začátku, pak jej mažeme a začínáme
+znova zapisovat. Při čtení ze souboru "\reffile" tedy musíme uložit
+všechny potřebné informace k sazbě obsahu i rejstříku. Používáme na to
+makro "\tocbuffer" a "\indexbuffer". Na začátku tyto \uv{buffery}
+vyprázdníme. Makro \db addtext "<text>\to<buffer>" budeme používat na
+vkládání "<textu>" do "<bufferu>", čímž buffery postupně naplníme.
+
+\inext {def\nb tocbuffer}{\empty}{+-}
+
+V souboru \db reffile se vyskytují tyto příkazy:
+
+{\def\begtthook{\langleactive\catcode`\!=0\mubytein=1}
+\begtt
+\reftocline{<číslo>}{<název>}{<strana>} % údaje o sekci a subsekci pro obsah
+\refdg{<před>}{<slovo>}{<za>}{<k-slovo>} % údaj o použití \dg, \dl
+\refapiword{<slovo>} % údaj o výskytu \api{<slovo>}
+\refuseword{<slovo>}{<strana>} % údaj o přímém výskytu <slova>
+\reflabel{<lejblík>}{<text>}{<strana>} % viz sekci !cite[reference], odkazy, reference
+\refcoef{<koeficient>}{<počet>}{<výška>} % viz sekci !cite[specfootnote], spec. poznámky
+\refns{<nslejblík>} % viz sekci !cite[ns], jmenné prostory
+\refnsend{<nslejblík>} % viz sekci !cite[ns], jmenné prostory
+\endtt
+\par}
+
+Při čtení souboru "\reffile" ukládáme potřebné údaje do
+bufferů. Nejprve se zaměříme na {\bf obsah} a definujeme
+\db reftocline "{<číslo>}{<název>}{<strana>}".
+
+\inext {def\nb reftocline}{\empty}{+-}
+
+V \db tocbuffer tedy máme postupně údaje o všech sekcích a podsekcích v
+za sebou jdoucích sekvencích \db dotocline "{<číslo>}{<název>}{<strana>}".
+Mezi sekcí a subsekcí rozlišíme jen podle toho, zda
+parametr "<číslo>" obsahuje tečku. K tomu slouží pomocné makro
+\db istocsec.
+
+\inext {def\nb dotocline}{\empty}{+-}
+
+Kdybychom spustili makro "\tocbuffer", dostaneme obsah. Ale ten se
+neskládá jen z údajů o~sekcích a podsekcích. Ještě je potřeba přečíst
+\db refdg a \db refapiword, abychom mohli vkládat do obsahu i údaje
+o~dokumentovaných slovech.
+
+\ilabel [right] {right}
+\ilabel [ns1] {\nb dl}
+\ilabel [ns2] {locword}
+\inext {def\nb refdg}{\empty}{+-}
+
+Makro "\refdg" pracuje s parametry "{<před>}{<slovo>}{<za>}{<k-slovo>}",
+kde "<před>" je text před slovem, "<slovo>" je dlouhé slovo, "<za>" obsahuje
+případné závorky "()". Je-li dlouhé slovo rozdílné od krátkého slova
+(při použití "\dl"), obsahuje "<k-slovo>" krátké slovo, jinak je tento
+parametr prázdný.
+Makro "\refdg" ukládá informace nejen do "\tocbuffer",
+ale také do "\indexbuffer". Rovněž při prázdném "<k-slovo>" makro
+ukládá "\sword" do enc\TeX{}ové tabulky a při
+neprázdném "<k-slovo>" makro cosi kutí se jmennými prostory.
+Nyní je ale naše pozornost věnována tvorbě
+obsahu. Ten vytvoří makro \db dotoc.
+
+\inext {def\nb dotoc}{\empty}{+-}
+
+{\bf Rejstřík} je vybudován z bufferu \db indexbuffer, ve kterém je seznam
+deklarovaných slov v dokumentu. Každé slovo je v bufferu zapsáno jako
+kontrolní sekvence (to zabere v paměti \TeX{}u nejmíň místa) a je
+odděleno od další sekvence oddělovačem. Před zatříděním podle abecedy
+jsou položky v~"\indexbuffer" odděleny čárkami za položkami, po
+zatřídění jsou položky odděleny "\," před položkami. Takže obsah
+"\indexbuffer" vypadá zhruba takto:
+
+{\def\begtthook{\langleactive}
+\begtt
+před zatříděním: \-<slovo1> , \-<slovo2> , \-<slovo3> , \-<slovo4> , ...
+po zatřídění: \, \-<slovoA> \, \-<slovoB> \, \-<slovoC> \, \-<slovoD> ...
+\endtt
+\par}
+
+\noindent Zde zápis "\-<slovo>" znamená jednu kontrolní sekvenci.
+Každá taková kontrolní sekvence je makrem tvaru "<před>\right<za>".
+To zařídí řádek~\cite[right]. Rejstřík vytiskneme makrem \db doindex.
+
+\ilabel [calculatedimone] {calculatedimone}
+\inext {def\nb doindex }{^^B\cbrace}{++}
+
+Příkaz "\calculatedimone" s následujícím testem "\dimen1" souvisí se
+sazbou do dvou sloupců, což necháme na sekci~\cite[dvasloupce]. Makro
+tedy založí příkazem "\sec" sekci nazvanou "\titindex" a pokud je
+"\indexbuffer" neprázdný, spustí sazbu rejstříku. Nejprve se příkazem
+"\sortindex" setřídí "\indexbuffer" podle abecedy (viz sekci~\cite[abeceda]).
+Pak makro "\doindex" založí
+dvousloupcovou sazbu ("\begmulti 2") a oddělovači "\," přidělí význam
+"\doindexentry". Nakonec vypustí "\indexbuffer" do vstupní fronty,
+takže další práci opakovaně provede makro \db doindexentry
+"\-<slovo>", které se postará o tisk slova v~rejstříku.
+
+\inext {def\nb doindexentry}{\empty}{+-}
+
+Makro "\doindexentry" pomocí \db ignoretwo odstraní z kontrolní
+sekvence "\-<slovo>" úvodní dva znaky "\-", takže v "\tmp" zůstane "<slovo>".
+Pokud "<slovo>" začíná backslashem, uděláme z něj makrem
+\db remakebackslash sekvenci "\nb", neboť přímý backslash není uložen
+v PDF odkazech (zlobí některé PDF prohlížeče, viz sekci~\cite[reference].
+Nakonec se vytiskne položka v rejstříku už známým makrem "\printindexentry".
+
+Při tvorbě {\bf strukturovaných záložek} je potřeba vědět, kolik má
+každý uzel potomků. Tento údaj je počítaný při čtení "\reffile"
+voláním makra \db addbookmark "<uzel>" (viz makra "\reftocline" a "\refdg").
+Parametr "<uzel>" může být číslo sekce, nebo dvojčíslí "<sekce>.<podsekce>".
+V makru \db currb je "<uzel>", ke kterému je potřeba přičítat potomka
+a \db currsecb je případný nadřazený "<uzel>" sekce.
+Makro "\addbookmark" připočte jedničku k hodnotě makra "\bk:<uzel>".
+
+\inext {def\nb addbookmark}{\empty}{+-}
+
+Makro \db bookmarks založí skupinu, předefinuje "\dotocline" a
+"\ptocentry" (tj.~makra obsažená v~"\tocbuffer") vloží první záložku
+s názvem dokumentu a spustí "\tocbuffer".
+
+\inext {def\nb bookmarks}{^^B\cbrace}{++}
+
+Makro \db setoutline "[<lejblík>]{<text>}{<prefix>}" vytvoří záložku
+"<prefix><text>" a prolinkuje ji s cílem označeným "<lejblík>".
+V "\tempnum" musí být uložen počet potomků záložky.
+
+\inext {def\nb setoutline}{\empty}{+-}
+
+V tomto makru je použito konverzní makro \db cnvbookmark, které je
+implicitně neaktivní. Uživatel může například nastavit
+"\let\cnvbookmark=\lowercase"
+a nechat konvertovat pomocí "\lccode" znak "č" na "c", znak "ž" na
+"z", atd. Nastavení "\lccode" musí mít v "\bookmarkshook".
+
+Dále je text před vložením do záložky podroben konverzi \db nobraces,
+která ve spolupráci s makrem \db nobrA sundá případné závorky "{}".
+Takže, pokud máme třeba "{\tt text} v \TeX{}u",
+po konverzi dostáváme "text v TeXu".
+
+\subsec [abeceda] Abecední řazení rejstříku
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Tuto práci provede makro "\sortindex". Původně bylo v \docbytex{}u
+implementováno algoritmem bubblesort, což vyšlo na šest řádků makrokódu
+(prezentováno na tutoriálu \TeX{}perience~2008), ale pro větší
+rejstříky to bylo pomalé. Např. pro rejstřík tohoto dokumentu to
+vygenerovalo 52 tisíc dotazů na porovnání a trvalo to asi dvě
+vteřiny. Můj syn Mirek byl pozorný
+posluchač tutoriálu, takže nabyté znalosti okamžitě využil a přepsal
+třídicí makro na mergesort. Ten na stejně velkém rejstříku generuje
+1600 dotazů na porovnání, tedy třicetkrát méně. Cena za to je
+skutečnost, že makro už nemá jen šest řádků, ale je mírně
+komplikovanější. Od možnosti použít quicksort jsme upustili, protože
+implementace by vyžadovala vyšší paměťové nároky na inputstack
+\TeX{}u.
+
+Nejprve deklarujeme podmínku pro výsledek srovnání dvou položek
+\db ifAleB a vytvoříme pomocná makra \db nullbuf, \db return a
+\db fif. Pomocné makro "\return" ve spolupráci se zakrytým "\fi"
+uvnitř "\fif" budeme používat pro únik z košatých hluboce vnořených
+podmínek typu "\if..\else..\fi". Jak uvidíte, makro pracuje na úrovni
+expandprocesoru a nebude potřeba psát žádné "\expandafter".
+
+\inext {newif\nb ifAleB}{\empty}{+-}
+
+Makro \db sortindex vypustí do vstupní fronty celý "\indexbuffer",
+přimaluje k němu "\end,\end", pronuluje "\indexbuffer" a spustí
+"\mergesort".
+
+\inext {def\nb sortindex}{^^B\cbrace}{++}
+
+Makro \db mergesort pracuje tak, že bere ze vstupní fronty vždy dvojici skupin
+položek, každá skupina je zatříděná. Skupiny jsou od sebe odděleny
+čárkami. Tyto dvě skupiny spojí do jedné a zatřídí. Pak přejde na
+následující dvojici skupin položek. Jedno zatřídění tedy vypadá
+například takto: dvě skupiny: "eimn,bdkz," promění v~jedinou
+skupinu "bdeikmnz,". V tomto příkladě jsou položky jednotlivá písmena,
+ve skutečnosti jsou to kontrolní sekvence, které obsahují celá slova.
+
+Na počátku jsou skupiny jednoprvkové ("\indexbuffer" odděluje každou
+položku čárkou). Makro "\mergesort" v tomto případě projde seznam a vytvoří
+seznam zatříděných dvoupoložkových skupin, uložený zpětně v
+"\indexbuffer". V dalším průchodu znovu vyvrhne "\indexbuffer" do vstupní fronty,
+vyprázdní ho a startuje znovu. Nyní vznikají čtyřpoložkové zatříděné
+skupiny. Pak osmipoložkové~atd. V~závěru (na řádku~\cite[konecsortu])
+je první skupina celá setříděná a druhá obsahuje "\end", tj.
+všechny položky jsou už setříděné v první skupině, takže stačí
+ji uložit do "\indexbuffer" a ukončit činnost. Pomocí "\gobblerest"
+odstraníme druhé "\end" ze vstupního proudu.
+
+\noactive{dvojice}
+\ilabel [merge:porovnani] {isAleB}
+\ilabel [merge:trojka] {mergesort p1+}
+\ilabel [merge:p1] {ifx,}
+\ilabel [merge:p2] {fif\nb mergesort\cbrace}
+\ilabel [konecsortu] {empty\nb indexbuffer}
+\ilabel [napercarky] {napercarky}
+\inext {def\nb mergesort }{^^B\cbrace}{++}
+
+{\def\quotehook{\catcode`\<12}
+Jádro "\mergesort" vidíme na řádcích~\cite[merge:porovnani]
+až~\cite[merge:trojka]. Makro "\mergesort" sejme ze vstupního proudu
+do "#1" první položku první skupiny, do "#2" zbytek první skupiny a do
+"#3" první položku druhé skupiny. Je-li "#1<#3", je do výstupního
+zatříděného seznamu "\indexbuffer" vložen "#1", ze vstupního proudu je
+"#1" odebrán a "\mergesort" je zavolán znovu. V případě "#3<#1"
+je do "\indexbuffer" vložen "#3", ze vstupního proudu je "#3" odebrán a
+"\mergesort" je zavolán znovu. Řádky~\cite[merge:p1]
+až~\cite[merge:p2] řeší případy, kdy je jedna ze skupin prázdná:
+je potřeba vložit do "\indexbuffer" zbytek neprázdné skupiny a přejít
+na další dvojici skupin. Ostatní řádky makra se vyrovnávají se
+skutečností, že zpracování narazilo na zarážku "\end,\end" a je tedy
+potřeba vystartovat další průchod.
+\par}
+
+Vlastní srovnání dvou položek dělá makro
+\db isAleB "<polA><polB>". Položky jsou tvaru kontrolní
+sekvence "\-<slovoA>" a "\-<slovoB>".
+Makro konvertuje své parametry pomocí "\string" na řadu znaků a
+expanduje na "\testAleB"~"<slovoA>\relax<slovoB>\relax".
+Navíc je na tento test aplikováno "\lowercase",
+neboť nerozlišujeme při řazení mezi velkými a malými písmeny.
+
+\ilabel [teckanula] {0\nb relax}
+%\ilabel [teckajedna] {2.1}
+\inext {def\nb isAleB }{^^B\cbrace}{++}
+
+Makro \db testAleB "<slovoA>\relax<slovoB>\relax" zjistí, zda je
+"<slovoA>" menší než "<slovoB>". Makro volá
+samo sebe, pokud jsou první porovnávané znaky stejné. Rekurze určitě
+skončí, neboť na řádku~\cite[teckanula]
+jsou k porovnávaným slovům připojeny různé ocasy.
+
+\inext {def\nb testAleB}{^^B\cbrace}{++}
+
+Makro \db napercarky vloží mezi položky do "\indexbuffer" separátory "\,".
+To se provede uvnitř "\edef\indexbuffer" na řádku~\cite[napercarky].
+
+\inext {def\nb napercarky}{\empty}{+-}
+
+
+\subsec Transformace seznamu stránek
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Každý výskyt "<slova>"
+uloží do "\reffile" údaj \db refuseword "{<slovo>}{<strana>}", který
+přečteme na začátku zpracování v dalším průchodu:
+
+\inext {def\nb refuseword}{^^B\cbrace}{++}
+
+V sekvenci "\w:<slovo>" tedy máme seznam stránek s výskyty "<slova>",
+stránky jsou odděleny čárkami. Seznam může vypadat třeba takto:
+
+\begtt
+2,5,5,10,11,12,12,13,13,13,27
+\endtt
+
+Cílem je takovýto seznam stránek vytisknout ve formátu
+"2, 5, 10--13, 27", tj. odstranit duplicity a nahradit souvisle jdoucí
+řadu stránek zápisem ve tvaru "<od>--<do>". Tuto práci dělá makro
+\db listofpages "{<slovo>}", které předhodí makru "\transf" expandovaný seznam
+stránek ukončený ",0,".
+
+\inext {def\nb listofpages}{^^B\cbrace}{++}
+
+Makro "\transf" vyloučí ze seznamu stránek ty, které jsou rovny
+\db dgnum a \db apinum. Nechceme totiž, aby se v seznamu opakovala hlavní
+stránka "<slova>" a podtržená stránka. Tyto stránky jsou vytištěny už
+dříve. Deklarujeme uvedené registry:
+
+\inext {newcount\nb apinum}{\empty}{+-}
+
+Kromě toho jsme deklarovali pomocné \db tempnum (aktuálně zpracovávaná
+stránka), \db ifdash (zda zpracováváme souvislou skupinu stránek
+a vytiskli jsme "--") a
+\db iffirst (zda vkládáme první číslo, tj. není nutné vložit čárku).
+
+Makro \db transf "<seznam stránek>,0," spustí cyklus pomocí \db cykltransf.
+
+\inext {def\nb transf}{def\nb carka}{++}
+
+Makro "\cykltransf" je takový malý stavový automat. Věřím, že mu čtenář
+porozumí bez dalšího komentáře.
+
+\subsec [dvasloupce] Více sloupců
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Sazba do více sloupců je kompletně převzata z \TeX{}booku naruby,
+strany 244--246.
+
+\ilabel [dimen1] {dimen1<2}
+\inext {newdimen\nb colsep}{TBN}{++}
+
+Zde navíc řešíme problém, že na začátku přepnutí do
+dvou sloupců pomocí \db begmulti "2" si makro na řádku~\cite[dimen1]
+zkontroluje, zda není blízko dna stránky a v takovém případě zahájí
+dva sloupce až na nové stránce. Ovšem vypadá hloupě, pokud se kvůli
+tomu ulomí nadpis \uv{Rejstřík} od jeho obsahu. Je tedy potřeba
+provést podobné měření stránky už před tiskem nadpisu \uv{Rejstřík}.
+K tomu slouží makro \db calculatedimone spuštěné na
+řádku~\cite[calculatedimone] v makru "\doindex".
+
+\inext {def\nb calculatedimone}{\empty}{+-}
+
+\subsec Závěrečná nastavení, kategorie
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Kategorie je rozumné nastavit až na konci souboru {\tt docby.tex}.
+Na rozdíl od plainu přidáváme aktivní kategorii pro znak palce a
+nastavujeme podtržítko na obyčejnou kategorii, protože se ve
+zdrojových kódech programů často používá a vůbec ne ve významu
+matematického indexu. Kdyby mu tento význam zůstal, byly by jen
+potíže.
+
+Podtržítko je další problém. Skoro vždy chceme, aby se ve
+vnitřních makrech chovalo jako normální podtržítko, ale když tiskneme text s
+podtržítkem fontem, který na dané pozici podtržítko nemá (to je Knuthův
+odkaz), pak by se to mělo udělat plainovským makrem "\_", Toto makro tedy
+schováme do \db subori a pak ho probudíme k~životu jen v~okamžiku tisku
+v~makrech "\printsec", "\printsubsec", "\title" a "\normalhead".
+Uživatel tedy může napsat "\sec moje\_funkce" a v~makrech se bude "\_" jako
+obyčejné podtržítko, zatímco při tisku v nadpise se použije "\subori".
+
+\inext {catcode`\nb_}{\empty}{+-}
+
+Nastavením "\everymath" a "\everydisplay" zaručíme matematikům stále
+možnost používat podtržítko ve významu indexu.
+
+Aktivní palec spustí lokální verbatim prostředí uvnitř odstavce:
+
+\inext {catcode`\nb}{\empty}{+-}
+
+Makro \db langleactive nastaví aktivní kategorii pro znak je menší
+({\tt<}), takže bude možné zapisovat {\tt<text>} a vytiskne se
+"<text>".
+
+\inext {def\nb langleactive}{\empty}{+-}
+
+V tomto dokumentu jsem "\langleactive" použil v makru
+"\quotehook", protože nechat znak {\tt<} aktivní všude nedělalo dobrotu.
+
+\doindex
+
+\bye
+
+