Portál AbcLinuxu, 2. května 2025 17:41
Učiníme-li první procházku po TeXové distribuci, záhy narazíme na pojmy LaTeX, AMSTeX, eTeX, pdfTeX, encTeX, ConTeXt, LuaTeX, XeTeX, XeLaTeX a mnohé další. V krátkosti si tyto pojmy vysvětlíme.
Před výkladem uvedených pojmů nejprve odbočím a vysvětlím, co to je TeXový
formát. Programu TeX se nejprve předloží makra, metriky fontů, vzory dělení slov
a příkaz \dump
, který způsobí, že TeX nabyté vědomosti ze své paměti
uloží do binárního souboru s příponou fmt
(tzv. formátu). Při zpracování dokumentu
se pak TeX volá například takto:
tex -fmt soubor.fmt dokument
TeX si nejprve obnoví dříve nabyté vědomosti z binárního souboru a pak
teprve čte specifikovaný dokument, kde mohou být doplňující makra, příkazy
k načtení metrik dodatečných fontů a vlastní text dokumentu. Důvod tohoto
dvoufázového přístupu je zejména rychlost: při opakovaném zpracování dokumentu
není třeba znovu číst makra a fonty, které jsou už načteny ve formátu. Dnes
sice tento důvod není tak významný jako dříve, ale i tak zůstává koncept
dvoufázového zpracování zachován. Formáty (tedy zhruba sady přednačtených maker,
fontů a vzorů dělení slov) se generují v distribuci obvykle automaticky
bez zásahu uživatele. Ten pak jen vhodným příkazem volí, který formát chce použít.
Napíše-li na příkazový řádek latex
, spustí se TeX s předgenerovaným
formátem latex.fmt
, napíše-li csplain
, spustí se TeX
s formátem csplain.fmt
atd.
V dávných dobách existovaly dvě binárky TeXu: iniTeX se specializoval
na generování formátů a virTeX formát použil a zpracoval dokument.
Ta první binárka byla svými schopnostmi nadmnožinou druhé: uměla navíc příkaz
\patterns
pro čtení vzorů dělení slov a již zmíněný \dump
pro uložení obrazu paměti. Důvodem existence ořezaného virTeXu byla snaha šetřit
pamětí počítače při zpracování dokumentu (algoritmy pro \patterns
zabírají v binárce místo navíc). Již cca 20 let se ale toto dělení na iniTeX
a virTeX nepoužívá a pracuje se s jedinou binárkou, která má typicky
přepínač -ini
, aby fungovala jako iniTeX. Bez tohoto přepínače jsou
uvedené algoritmy kolem příkazu \patterns
a \dump
deaktivovány. Takže bez přepínače -ini
nelze zavádět do paměti dodatečně
další vzory dělení slov (dalších jazyků). Ustálila se tedy praxe, že všechny
použité jazyky musejí mít vzory dělení načteny v době generování formátu.
Když tedy chce uživatel použít další jazyk, který nemá vzory dělení načteny při
generování formátu, nestačí jazyk nějak vyznačit v dokumentu. Je třeba taky
upravit konfiguraci jazyků pro generování formátů a formát přegenerovat. Aby
distribuce TeXu zmírnily tuto komplikaci, načítají do formátu co nejvíce vzorů
dělení slov a dále nabízejí uživateli nějaké své rozhraní na generování formátů
(např. v TeXlive je na to skript fmtutil
).
formát | verze | engine | příkaz | komentář |
plainTeX | 3.141592653 | TeX | tex | základní makra (Donald Knuth) |
LaTeX | 2e | eTeX | latex | autorská tvorba dokumentů |
pdfLaTeX | 2e | pdfeTeX | pdflatex | LaTeX + PDF |
CSplain | Sep. 2013 | encTeX | csplain | plain + čeština, slovenština (Petr Olšák) |
pdfcsplain | Sep. 2013 | pdf+encTeX | pdfcsplain | CSplain + PDF |
eplain | 3.5 | eTeX | eplain | plain + tvorba dokumentů (Karl Berry) |
XeTeX | XeTeX | xetex | plain + XeTeX | |
JadeTeX | 3.13 | eTeX | jade | SGML dokumenty (Sebastian Rahtz) |
XeLaTeX | XeTeX | xelatex | LaTeX + XeTeX | |
LuaTeX | LuaTeX | luatex | plain + XeTeX | |
LuaLaTeX | LuaTeX | lualatex | LaTeX + LuaTeX | |
ConTeXt. | MKII | pdfeTeX | texexec | projekt Pragma ADE (Hans Hagen & all) |
ConTeXt. | MKIV | LuaTeX | context | ConTeXt + LuaTeX |
Sloupec „engine“ označuje použité rozšíření TeXu. O tom pojednává text následující sekce.
Sloupec „příkaz“ označuje příkaz, kterým se spustí odpovídající „engine“
s příslušným formátem. Např. tex document
spustí TeX s formátem
plain. Jak to je uděláno, řeší každá distribuce v závislosti na hostujícím
operačním systému po svém. Poznamenejme, že tex -ini soubor
spustí
iniTeX bez formátu a příkaz je určen k vygenerování formátu, zatímco
tex soubor
spustí virTeX s formátem plain.
Kromě formátů v tabulce existuje ještě mnoho dalších.
AMSTeX přidává k plainTeXu
makra a další fonty pro matematickou sazbu. Není ale nutné použít
speciální formát: stačí v plainTeXu psát \input amstex
přímo
v dokumentu nebo v LaTeXu použít balíček amsmath.sty
.
MeX je plain, který si vytvořili Poláci,
pTeX umožňuje sazbu japonštiny...
CSTUG dlouhou dobu udržoval českou verzi LaTeXu zvanou
CSLaTeX. Loni už přišli na to, že to nemá význam
a jen to komplikuje uživatelům život. Další vývoj i udržování CSLaTeXu
ukončili. Na jejich pokyn jsem do CSLaTeXu přidal hlášení, které TeX při
použití tohoto formátu vypíše na terminál, že je to zastaralá verze. Češtinu
a slovenštinu lze v klasickém LaTeXu použít prostřednictvím balíčku
babel.sty
.
V roce 1991, kdy Knuth zmrazil vývoj TeXu, zůstal jeho program
schopen pracovat jen s 8bitovými fonty a s výstupem do
DVI (device independent). To
je binární výstupní formát, na který je třeba navázat dalším programem (tzv.
ovladačem), který výstup zobrazí na obrazovce (např. xdvi
) nebo dokument
vytiskne na tiskárně (např. dvips
převede dokument do PostScriptu
pro tisk). Knuth ve své licenci dává TeX k volnému použití, ale ponechává
si „patent na název“. Nic se nesmí nazvat TeX, co se přesně nechová podle jeho
rozsáhlé dokumentace a co neprojde
náročnými testy trip. Pouze Knuth je
oprávněn opravovat chyby, což činí jednou za mnoho let. Tím patentem na název je
uživatel ochráněn před živelným vývojem programu. Je tu pevný základ, na který se
dá spoléhat, že bude fungovat stejně napořád.
Toto vypadá lákavě, ale má to stinné stránky: nové požadavky na program plynoucí z nových technologií nebudou zapracovány. Navíc TeX je napsán sice po dokumentační stránce zcela excelentně, ale je to monolit, do kterého opravdu může dloubnout jen jeden člověk: hemží se to tam např. mnoha globálními proměnnými, jejichž změna na jednom místě způsobí změněné chování desítek procedur na místě jiném. Pro týmovou práci se to naprosto nehodí. Pokusy o modifikaci TeXu či dokonce jeho přepsání do něčeho modernějšího tu sice byly, ale mnohdy nebyly moc úspěšné. V následujícím textu shrnu tedy jen ty pokusy, které úspěšné byly a přežívají v distribucích dodnes, nebo dokonce udávají další směr. Veškeré modifikace TeXu se z důvodu Knuthovy licence nesmí jmenovat TeX, ale typicky jsou označeny jako něcoTeX. Všechna níže uvedená rozšíření vycházejí z Knuthova kódu a co nejopatrněji do něj zapracovávají nový rys.
Program eTeX rozšiřuje TeX o další příkazy, které začaly některým uživatelům chybět záhy po zmrazení TeXu: více číslovaných registrů, možnost sazby zprava doleva (arabsky) a některé další fiškuntálie.
Program pdfTeX rozšiřuje TeX o možnost
výstupu do PDF při nastavení registru \pdfoutput=1
. Implicitně je
i v pdfTeXu nastaven výstup do DVI (\pdfoutput=0
), takže se
chová jako klasický TeX. Při výstupu do PDF přidává pdfTeX možnosti programovat
interaktivní vlastnosti dokumentu, které PDF formát přináší (např. hyperlinky)
a dále přidává některá jemná mikrotypografická rozšíření.
Rozšíření encTeX je můj příspěvek do TeXové
komunity, umožňující mimo jiné 8bitovému (pdf)TeXu číst UTF-8 vstup. Vstupní znaky
nebo sekvence znaků mapuje na řídicí sekvence tvaru \cosi
, které mohou
být v TeXu definovány jakkoli.
Dnes se v distribucích obvykle používá i pro emulaci klasického TeXu
binárka pdftex
, která obsahuje eTeX, encTeX a pdfTeX dohromady.
Rozšíření eTeX se zapne při generování formátu přepínačem -etex
nebo
hvězdičkou před názvem souboru a rozšíření encTeX probudíte k životu
přepínačem -enc
.
Výrazným posunem vpřed, kterému budu věnovat podrobněji některý z dalších dílů, jsou rozšíření umožňující pracovat se současnými fonty v UNICODE (OpenType fonty). Existují dvě různé vývojové větve: XeTeX a LuaTeX. Obě mají výstup do PDF.
Nejprve ale bylo nutno vyřešit interní reprezentaci znaků v TeXu v 16 bitech, což odstartoval projekt Omega. Toto rozšíření se v současné době moc nepoužívá, ale ze zdrojových kódů Omegy obě následující rozšíření vycházejí.
XeTeX [zítech] linkuje systémovou knihovnu na fonty (např. knihovnu fontconfig pro Linux) a umožňuje číst fonty instalované v systému. Klasický TeX totiž se systémovými fonty nespolupracuje: má své fonty přímo v instalaci a přidávání dalších fontů do TeXu může začátečníkovi činit i značné potíže. Interně XeTeX vystupuje do DVI (16bitové DVI) a na tento výstup přímo navazuje program xdvipdfmx, který bez nutnosti uživatelova zásahu výstup konvertuje do PDF.
LuaTeX linkuje knihovnu interpretačního jazyka Lua.
Pomocí příkazu \directlua{kód}
lze vkládat Lua kód, přitom některé
elementy jazyka Lua jsou přímo napojeny na algoritmy TeXu a umožňují tím změnu
jeho chování. Je tedy možné kombinovat programovací jazyk TeXu a Lua. Kódem
v \directlua
se typicky nejprve vyjmenují všechna rozšíření, která
LuaTeX má umět: eTeX, pdfTeX, Omega. Také je pomocí Lua kódu implementováno čtení
OpenType fontů.
Poznamenávám, že i 8bitový TeX (např. pdfTeX) umožňuje využít všechny znaky z OpenType fontu. Jak to udělat, bude popsáno v některém dalším dílu seriálu.
Od tohoto poněkud teoretičtějšího dílu si příště odpočineme a ukážeme motivační příklad.
this
se předává vždy, a efektivně tak trvale zabírá jeden registr procesoru. Vyhledání takové skoro globální proměnné v instanci nejvyššího nadřízeného objektu pak vždy bude komplikovanější, než prostá reference na pevné místo v paměti. A to i přes optimalizované ukládání mezivýsledků.
Takže vlastně vše kromě programování ve strojovém kódu je zde pouze pro pohodlí programátora, pro přenositelnost a znovupoužitelnost.
V objektovém přístupu bývají proměnné zabalené do struktur (objektů) a třebaže programátor úzkostlivě předává objekt přes parametry, tak na zásobníku nebude nic než ukazatel, takže až se funkce nakonec rozhodne přistoupit k proměnné, tak se krásný lokální ukazatel na zásobníku dereferencuje na globální proměnnou, která v keši nebude.
A stejně to dopadne i při neobjektovém paradigmatu, kdy nakonec programátor rezignuje na předávání každé proměnné argumentem (protože počet argumentů by vzrostl na nezvladatelný počet) a prostě je zabalí do struktury a bude předávat jen ukazatel na ni.
Jistě že dnešní překladače jsou jinde. Ale ty optimalizace jsou povětšinou jen lokální. Je jich moc. To ano. Ale stále jsou lokálního charakteru (tuhle funkci má smysl inlinovat, tady ušetřit tail-call, tuhle opakující se dereferenci lze nakešovat, tahle proměnná je ve skutečnosti konstanta, tahle podmínka nikdy nebude splněna). Představa, že překladač převede dereferenci objektu v desáté úrovni zanoření na globální proměnnou, „aby se zbytěčně netahaly ukazatele přes zásobník“, je naivní.
Complex
) je ale stejně interně uložena jako struktura s ukazateli, takže na zásobník se většinou uloží pouze pár odkazů do haldy.
Přímý odkaz na zásobník volajícího podprogramu je sice možný, ale aby fungoval, musí být funkce volaná vždy stejnou volací sekvencí funkcí mezí, a funkce musí být funkce statická (exportovaná funkce může být použita v předem neznámém kontextu, kde by tato přímá reference nefungovala). Nejsem si jist, zda to některý optimalizátor umí. Ve všech ostatních případech se musíte spolehnout buď na předaný ukazatel (jeden registr trvale obsazený), nebo na ukazatel zásobníkového rámce (frame pointer; ten sice nezabírá registr, ale každá reference na nadřízenou funkci znamená vystoupání po ukazatelích rámců, tedy jednu položku na zásobníku navíc na každou funkci, a jedno čtení navíc na každý stupeň vynoření).
Chápu, že nerozumíte tomu, že objekt lze celý uložit na zásobník. Takže předání ukazatele do dalšího podprogramu může třeba obsahovat ukazatel na data, která jsou o 10 bajtů dále za vrcholem zásobníku.
K čemu mi bude dobré ukládat na zásobník kopii objektu, když tam můžu chtít vidět data změněná jinde a hlavně měnit data daného objektu, tak aby byla změna vidět i jinde nebo po návratu z funkce?
tangle
), nebo tak, jak se to líbí TeXu (program weave
pro dokumentaci kódu), a dělá drobné záměny.
Statická deklarace polí v TeXu (zdrojový kód) zároveň znamená, že se TeX obejde bez ukazatelů a haldy (angl. heap), tedy bez alloc()
, malloc()
, free()
a jejich režie.
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.