TeX pro každého - jak TeX láme sazbu

4. 11. 2002
Doba čtení: 5 minut

Sdílet

Minule jsme se seznámili se základní konstrukcemi TeXu. Dnes se dozvíme, jak láme TeX sazbu do odstavců a odstavce do stran. TeX byl prvním použitelnou implemetací těchto algoritmů a i po čtvrtstoletí patří mezi nejlepší.
Penalty a zlom řádků

Dalšími objekty, které v TEXu vystupují, jsou penalty. Nemají žádnou grafickou reprezentaci, ale slouží výhradně pro potřeby zlomu. Řádek i stránka se mohou lámat pouze mezi jednotlivými boxy. Každé takové místo případného zlomu řádku (v horizontálním režimu) nebo strany (ve vertikálním režimu) má určité ohodnocení v podobě jakýchsi trestných bodů. Tyto trestné body jsou přidělovány buď explicitně pomocí primitiva \penalty za rozdělení řádku v určitém místě, nebo implicitně podle povahy objektu – například za rozdělení slova, za rozdělení na předposledním řádku odstavce, za rozdělení v označením místě apod. Ke každému z těchto případů existuje zvláštní primitivum. Kromě toho existují ještě demerits, což jsou zvláštní primitiva, která se počítají jako kvadrát penalty (například pro dvě rozdělení slov pod sebou).

Hodnota penalty se pohybuje mezi −10000 (povinný zlom) a 10000 (zakázaný zlom). Tolerance a badness pak jsou nezáporná čísla menší nebo rovna 10000.

Narazí-li TEX na primitivum \par (tedy většinou na konci odstavce), pustí se do zalamování. Při zlomu řádků TEX sčítá trestné body za zlom. K tomu připočítá trestné body za roztažení nebo zhuštění mezislovních mezer (TEX nepodporuje novodobý nešvar – vyrovnávání řádků změnou mezer mezi písmeny) a získá finální ohodnocení jednotlivých řádků. To tvoří míru ošklivosti (badness) odstavce. TEX ji porovnává s nastavenou míroutolerance, která určí, zda je takový odstavec ještě únosný, nebo není.

Pokud počet trestných bodů v některém řádku přesáhne primitivem definovanou hodnotu tolerance, TEX takový zlom nepřijme a snaží se najít vhodnější.

Aby byl zlom odstavce co nejlepší, pokouší se jej TEX zlomit až třikrát – nejdříve bez dělení slov, poté s dělením slov, a pokud ani to nevyjde, snaží se trochu roztáhnout mezery (o hodnotu \emergencystretch) a zlom zopakovat.

Poznamenávám, že ke každé z výše uvedených veličin existuje primitivum pro její nastavení.

Dělení slov

Pro dělení slov v TEXu byl poprvé použit Liangův algoritmus (dnes úspěšně adoptovaný mnoha komerčními programy). Spočívá v definici vzorů dělení. Jedná se o skupiny hlásek (nebo znaků konce a začátku slova). Pro rozdělení slov lze mezi každé dva znaky vzoru vložit ohodnocení. Liché ohodnocení znamená místo vhodné pro dělení, sudé ohodnocení nevhodné místo. S těmito vzory se slovo porovnává a mezi písmena se vkládá nejvyšší nalezené ohodnocení. Pokud je liché, jedná se o místo vhodné pro dělení, je-li sudé nebo žádné, jde o nevhodné místo.

Ukázka:

Ke slovu „pejsek“ najdeme tři vzory:

p e j s e k

   2j1s2
     1s e
        e2k
-----------
p e2j1s2e2k

Po nalezení nejvyššího ohodnocení získáváme jediné liché číslo, a tedy i dělení – „pej-sek“

Protože takový systém vzorů není neomylný a jeho vytvoření není nijak triviální (k jeho vytváření ze slovníku správně rozdělených slov slouží patgen), existuje ještě slovník výjimek. Kromě toho můžeme každému slovu explicitně předepsat dělení pomocí\-.

A protože TEX je připraven pro vícejazyčnou sazbu, existuje proměnná \language, s jejíž pomocí můžeme zároveň sázet až 256 jazyků. Další primitiva pak slouží na definici počtu písmen, která musí po dělení slova zůstat na prvním a druhém řádku.

TEX zvládá i jazyky, které při dělení slov mění hlásky (např. němčina – viz zucker ×zuk-ker).

Zlom stránek

Zlom stránek se také zakládá na boxech a penaltách. Jak se hromadí hotové odstavce, TEX si je shomažďuje ve vertikálním seznamu. Kromě základního vertikálního seznamu si může též schovávat vertikální boxy pro plovoucí objekty (např. poznámky pod čarou, obrázky k umístění na horní části strany –tedy vše, co není pevně vázáno na určité místo textu). Když součet jejich výšek (případně hloubek, zde je ale situace komplikovanější) přesáhne požadovanou výšku sazby, připraví TEX výstupní box (má číslo 255) a vyvolá výstupní rutinu (\output). Úkolem výstupní rutiny je použít výstupní box a plovoucí objekty, opatřit stránku všemi náležitostmi (hlavičkou, patičkou s číslem strany) a případně vyrobit výstup (\shipout). Poté se vrací běh TEXu do normálních kolejí.

Při tvorbě složitějších testů je třeba pamatovat, že k vyvolání výstupní rutiny dochází většinou teprve při sazbě následující strany.

Do výstupní rutiny si můžeme zapsat cokoliv, co se nám zlíbí. Zde je nejjednodušší příklad:

\output={\shipout\box255}

Toto je test.

\bye

Speciální příkazy a zápisy do souborů

Posledními typy objektů jsou speciální příkazy (\special) a zápisy do souboru. Oboje lze vložit do určitého místa boxu.

Speciální příkazy jsou bez dalšího zpracování (pouze s expandovanými makry) zapsány do DVI souboru, kde si je převezme ovladač k dalšímu zpracování. Dnes se nejčastěji používají k přímému vkládání příkazů v PostScriptu, tedy obrázků, grafických symbolů a barev.

Výstup se naproti tomu používá nejčastěji pro vytvoření obsahů a rejstříků (TEX si je na vhodném místě opět načte). S výhodou využijeme skutečnosti, že se výstup generuje až v okamžiku výstupu boxu, a tak v tomto okamžiku již TEX zná přesně stránku, na které se příslušné místo v boxu objevilo. Výstup je možno vynutit i nepodmíněně v okamžiku jeho zpracování, nikoliv až při výstupu boxu (primitivem \immediate).

Podtečené a přetečené boxy

Pokud se TEXu nepodaří vejít se do povolené tolerance, vydá nám varování. Méně špatné varování je o podtečeném boxu – jde o upozornění na příliš velké mezery mezi boxy.

Horší bývá přetečený box – situaci, kde se řádek (či stránku) nepodařilo zlomit. Pokud se jedná o horizontální box, označí jej TEX malým obdélníkem.

V obou případech je řešení podobné – povolit více dělení, upravit ručně dělení slov. Posledním řešením pro přetečené boxy je zvýšit toleranci. Pomůže-li to, získáme sice hůře vypadající, ale nepřetečený box.

bitcoin_skoleni

Literatura

Pokud chcete do TEXu proniknout co nejhlouběji, doporučuji knihy D. E. Knutha: The TEXbook aTEX – The Program nebo knihu Petra Olšáka TEXbook naruby. Chcete-li něco velmi zhuštěného, doporučuji si prostudovat Slovníček TEXových primitivů, též od Petra Olšáka.