LaTeX-Formate

Auf die Frage, was pdflatex sei, lautet die genaue Antwort nicht „ein Programm“. Es ist die Engine pdfTeX, gestartet mit vorgeladenem LaTeX-Format. Als Befehlsnamen nebeneinandergestellt, sehen pdflatex, lualatex und platex wie getrennte Software aus; tatsächlich ist jedes davon die Kombination zweier unabhängiger Achsen – einer Engine (dem laufenden Programm) und eines Formats (im Voraus kompilierter Makros). Sind diese Achsen erst sichtbar, erklärt sich mehreres von selbst: was eine .fmt-Datei ist, warum latex ein DVI und kein PDF liefert, und was aus LaTeX3 tatsächlich geworden ist.

Der Unterschied zwischen Engine und Format

Eine Engine ist eine ausführbare Datei, ein Format sind Daten. Die Engine ist das Programm, das eine .tex-Datei liest und setzt – tex, pdftex, xetex, luahbtex, euptex und andere. Ein Format ist eine große Sammlung von Makros wie \documentclass und \section, im Voraus expandiert und zu einem einzigen Dump eingefroren: einer .fmt-Datei. Die Engine lädt dieses .fmt beim Start augenblicklich und muss so nicht bei jedem Lauf Zehntausende Zeilen Makros neu definieren.

Also ist „LaTeX“ der Name eines Formats, nicht einer Engine. Dasselbe LaTeX-Format lässt sich auf verschiedenen Engines betreiben, und der eingetippte Befehl benennt ein bestimmtes Paar aus Engine und Format. Diese Zuordnung muss man nicht erraten: Sie existiert in TeX Live als eine einzige Konfigurationsdatei namens fmtutil.cnf. Ihre vier Spalten sind Formatname, Engine, Trennmusterdatei und Argumente; die Fassung von TeX Live 2024 enthält 54 Zeilen – 54 eingetragene Kombinationen.

terminal
$ grep -E '^(tex|latex|pdflatex|lualatex|xelatex|uplatex|amstex|pdfcsplain) ' \
      $(kpsewhich fmtutil.cnf)

# format      engine     hyphenation                 arguments
tex           tex        -                           tex.ini
latex         pdftex     language.dat                *latex.ini
pdflatex      pdftex     language.dat                *pdflatex.ini
xelatex       xetex      language.dat                -etex xelatex.ini
lualatex      luahbtex   language.dat,language.dat.lua lualatex.ini
uplatex       euptex     language.dat                *uplatex.ini
amstex        pdftex     -                           *amstex.ini
pdfcsplain    luatex     -                           csplain.ini
pdfcsplain    pdftex     -                           csplain-utf8.ini
pdfcsplain    xetex      -                           csplain.ini

Zweierlei folgt aus dieser Tabelle. Erstens kann ein Formatname bei mehreren Engines auftauchenpdfcsplain hat drei Zeilen, für luatex, pdftex und xetex. Einen besseren Beleg dafür, dass Format und Engine orthogonal sind, gibt es nicht. Zweitens das * vor den Argumenten: Es weist an, mit aktivierten e-TeX-Erweiterungen zu dumpen, und der Kommentarkopf der Datei erklärt, dass dies im Wesentlichen der Option -etex entspricht. Die Zeile latex trägt das *, die Zeile für Knuths tex nicht. In diesem einen Zeichen steckt die Abhängigkeit des modernen LaTeX von e-TeX.

Was tatsächlich in einer .fmt-Datei steckt

Es ist ein Speicherabbild des gesamten inneren Zustands der Engine. Kein Quelltext, kein Text. Makrodefinitionen, Kategoriecodes, Trennmuster, Zuordnungen der Mathematikschriften – was immer im Gedächtnis der Engine steht, sobald sie latex.ltx zu Ende gelesen hat, wird unmittelbar als Binärdatei herausgeschrieben. In TeX Live 2024 ist latex.fmt rund 8,2 MB groß. Der Unterschied zwischen dem erneuten Einlesen dieser 8,2 MB und dem jedes Mal neuen Auswerten von latex.ltx ist genau der Grund, warum LaTeX augenblicklich startet.

An einer Stelle wird das Verhältnis von Engine und Format im Dateisystem selbst sichtbar: Eine .fmt liegt nicht unter dem Namen des Formats, sondern in einem nach der Engine benannten Verzeichnis. Unter texmf-var/web2c/ finden sich in TeX Live 2024 die Verzeichnisse tex/, pdftex/, xetex/, luahbtex/, euptex/, jedes mit den von dieser Engine gedumpten Formaten. tex/tex.fmt ist plain TeX, pdftex/latex.fmt ist LaTeX, euptex/uplatex.fmt ist upLaTeX – dieselbe Endung .fmt, aber je nach erzeugender Engine etwas anderes.

terminal
# Formats are filed by ENGINE, not by format name.
$ ls /usr/local/texlive/2024/texmf-var/web2c/
aleph  euptex  hitex  luahbtex  luajittex  luatex  metafont  pdftex  tex  xetex

$ ls /usr/local/texlive/2024/texmf-var/web2c/euptex/
eptex.fmt  euptex.fmt  platex.fmt  ptex.fmt  uplatex.fmt  ...

# Ask kpathsea which .fmt a given engine would load.
$ kpsewhich -engine pdftex latex.fmt
/usr/local/texlive/2024/texmf-var/web2c/pdftex/latex.fmt

$ ls -l $(kpsewhich -engine pdftex latex.fmt)
-rw-r--r--  1 root  wheel  8221690 May  4  2024 .../pdftex/latex.fmt

Der Mechanismus auf der Erzeugerseite ist ebenso einfach. Startet man eine Engine mit -ini, gelangt sie in einen Initialisierungsmodus, in dem kein .fmt geladen wird. Lässt man sie in diesem Zustand eine Quelle wie latex.ltx lesen und schließt mit dem Primitiv \dump ab, wird der momentane innere Zustand als .fmt herausgeschrieben. initex, einst eine eigene ausführbare Datei, ist nichts anderes als ein Name für diesen -ini-Start und überlebt heute bloß als symbolischer Link auf tex.

Ein Format mit fmtutil neu bauen

Der Befehl, der eine .fmt neu baut, ist fmtutil. Er liest fmtutil.cnf und dumpt jedes Format mit der dort eingetragenen Engine und den Argumenten neu. Normalerweise läuft er beim Aktualisieren der Distribution automatisch, sodass man ihn selten von Hand aufruft – doch wenn eine ersetzte Kerndatei oder ein neues Trennmuster sich nicht auswirkt, ist meist ein veraltetes Format schuld. Die beiden Formen, die man wirklich braucht, sind fmtutil-sys --all (alles neu bauen) und fmtutil-sys --byfmt latex (nur eines).

terminal
# Rebuild one format (writes into the system tree; needs write permission).
$ fmtutil-sys --byfmt latex

# Rebuild every format listed in fmtutil.cnf.
$ fmtutil-sys --all

# Rebuild only the formats that use a given engine.
$ fmtutil-sys --byengine luahbtex

# Personal tree instead of the system tree (no root needed).
$ fmtutil-user --byfmt pdflatex

# Where did the format end up, and when was it built?
$ kpsewhich -engine pdftex latex.fmt

Der Unterschied zwischen -sys und -user liegt im Schreibziel: dem Systembaum (TEXMFSYSVAR) oder dem benutzereigenen Baum (TEXMFVAR). Mit Administratorrechten ist -sys die naheliegende Wahl; -user dient dazu, auf einer gemeinsam genutzten Maschine nur die eigene Kopie zu ersetzen. Beides zu mischen erzeugt zuverlässig das Phänomen „ich habe es doch repariert, und nichts ändert sich“ – daher im Projekt auf eines festlegen. Zudem steht fmtutil.cnf selbst unter der Kontrolle der Distribution; ihr einleitender Kommentar sagt ausdrücklich, dass manuelle Änderungen daran beim Update verloren gehen. Für dauerhafte Änderungen den vorgesehenen Weg nutzen, etwa fmtutil-sys --enablefmt.

LaTeX2e: das Format, das tatsächlich auf dem Rechner läuft

Heute meint „LaTeX“ fast ausnahmslos LaTeX2e. Es ist die aktuelle Fassung der von Leslie Lamport geschriebenen LaTeX-Makros, erschien 1994 und wird inzwischen vom LaTeX Project gepflegt. Das „2e“ stand für eine kleine Überarbeitung des früheren LaTeX 2.09 – damals als Zwischenschritt zum lange geplanten LaTeX3 gedacht. Welches Format man tatsächlich hat, lässt sich selbst nachsehen: Die Kerndatei latex.ltx bezeichnet sich mit \def\fmtname{LaTeX2e}, und in der mit TeX Live 2024 ausgelieferten Fassung ist \fmtversion gleich 2023-11-01 bei \patch@level 1.

Der Kernel wird inzwischen in einem regelmäßigen Rhythmus von etwa zwei Veröffentlichungen pro Jahr aktualisiert. „Die neueste Version“ als Zahl auswendig zu lernen bringt nichts – sie veraltet binnen Monaten. Zuverlässiger ist die Gewohnheit, in der eigenen Installation \fmtversion aus latex.ltx nachzulesen: Das ist das Datum des dort tatsächlich gedumpten Kernels. Wer die nächste Veröffentlichung vorab erproben will, findet in TeX Live daneben Entwicklungsformate. fmtutil.cnf führt Zeilen für latex-dev, pdflatex-dev, xelatex-dev, lualatex-dev und uplatex-dev; pdflatex-dev main.tex setzt also mit dem kommenden Kernel. Gedacht ist das für Kompatibilitätstests von Klassen und Paketen, nicht für produktive Manuskripte.

Was aus LaTeX3 wirklich wurde: die Antwort heißt expl3

Ein LaTeX3-Format ist nie erschienen. Erschienen ist die Programmiersprache von LaTeX3. Diese Schicht namens expl3 (L3 programming layer) kam nicht als eigener neuer Kernel, sondern im Inneren von LaTeX2e aufgenommen. Die Frage „Soll ich zu LaTeX3 wechseln?“ hat daher keine Antwort – nicht weil es kein Ziel gäbe, sondern weil man es bereits benutzt.

Der Wendepunkt ist dokumentiert. LaTeX News 31 (2. Februar 2020) hielt fest, expl3 habe sich im vorangegangenen Jahrzehnt von weitgehend experimentell zu breit stabil entwickelt, und berichtete, in dieser Veröffentlichung habe das Team den Kernel so angepasst, dass beim Bau des Formats ein erheblicher Teil von expl3 vorgeladen wird. Der Beweggrund war Geschwindigkeit: Dokumente, die unter XeLaTeX oder LuaLaTeX fontspec laden, zahlten bei jedem Lauf hohe Kosten für das Einlesen der Unicode-Daten.

expl3 ist heute Teil des Formats. Ein Blick in die Kerndatei latex.ltx zeigt die Logik: Ist expl3 bereits vorhanden, meldet sie Skipping: expl3 code already part of the format und fährt fort; andernfalls zieht sie es mit \input expl3.ltx herein; und lässt sich expl3.ltx überhaupt nicht finden, bricht sie mit \errmessage{LaTeX requires expl3} ab. Mit anderen Worten: expl3 ist kein optionales Paket mehr, sondern ein erforderlicher Bestandteil von LaTeX2e. \RequirePackage{expl3} in Dokument oder Paket bleibt mit Rücksicht auf ältere Formate empfohlen, bewirkt auf einem aktuellen aber praktisch nichts. Die Syntax von expl3 selbst – \ExplSyntaxOn, \cs_new:Npn, die typisierten Variablen von l3kernel – hat eine eigene Seite.

Andere Formate als LaTeX

LaTeX ist das meistgenutzte Format, aber nicht das einzige. Von den 54 Zeilen in fmtutil.cnf gehört nur eine Handvoll zu LaTeX; der Rest sind andere Makrosysteme. amstex verdient hier ein Wort. Als ausführbare Datei ist amstex bloß ein symbolischer Link auf pdftex, und die Zeile amstex pdftex - *amstex.ini in fmtutil.cnf benennt die pdfTeX-Engine mit geladenen AMS-TeX-Makros. AMS-TeX ist die auf plain TeX aufsetzende Makrosammlung der American Mathematical Society für den mathematischen Satz und wurde für LaTeX-Nutzende faktisch vom Paket amsmath abgelöst. Ein neues Dokument in AMS-TeX zu beginnen, hat kaum noch einen Grund.

FormatErzeugende EngineWas es ist
textexKnuths plain TeX – das einzige Format ohne die e-TeX-Erweiterungen
latexpdftexLaTeX2e, von pdfTeX im DVI-Modus ausgeführt; erzeugt eine .dvi
pdflatexpdftexDasselbe LaTeX2e, schreibt PDF direkt; De-facto-Standard für westlichen Text
xelatexxetexLaTeX2e auf der Engine XeTeX; Systemschriften und Unicode
lualatexluahbtexLaTeX2e auf LuaHBTeX; Lua-Skripting und HarfBuzz-Shaping verfügbar
platex / uplatexeuptexLaTeX2e für japanischen Satz; erzeugt DVI, das dvipdfmx in PDF wandelt
amstexpdftexAMS-TeX, Mathematikmakros über plain TeX; für LaTeX-Nutzende von amsmath abgelöst
cont-enpdftex / xetexConTeXt (MkII), ein von LaTeX unabhängiges Gesamtformat; für zwei Engines eingetragen
csplainpdftexEine plain-TeX-Ableitung für Tschechisch und Slowakisch; mit explizitem -etex gebaut

pLaTeX und upLaTeX: das LaTeX-Format für Japanisch

pLaTeX und upLaTeX setzen das LaTeX-Format auf Engines für den japanischen Satz. Vertikalsatz, Ruby (Furigana) und der japanische Zeilenumbruch werden von der pTeX-Engine-Familie erledigt, ursprünglich bei ASCII Corporation erweitert. In fmtutil.cnf von TeX Live 2024 sind sowohl platex als auch uplatex der Engine euptex zugeordnet; unterschieden werden sie durch die Initialisierungsdatei des Formats (*platex.ini bzw. *uplatex.ini). Der Unterschied liegt also nicht in der ausführbaren Datei, sondern in der Zeichenbehandlung des Formats: platex bewahrt das herkömmliche pTeX-kompatible Verhalten, uplatex setzt intern Unicode voraus. Für ein neues japanisches Dokument ist uplatex die übliche Wahl.

Diese Familie gibt stets DVI aus; das japanische DVI wird mit dvipdfmx in PDF gewandelt – eine zweistufige Kette (uplatex file.tex, dann dvipdfmx file.dvi). Für das Register kommt upmendex hinzu. Als Dokumentklassen sind Haruhiko Okumuras jsarticle und jsbook (für pLaTeX) samt ihren Unicode-Gegenstücken wie ujarticle verbreitet, ebenso das jüngere jlreq, das den Anforderungen von JIS X 4051 an den japanischen Satz folgt. Das Innenleben der Engines – JFM-Metriken, Kinsoku-Umbruchregeln, die Umsetzung des Vertikalsatzes – gehört auf die Seite „pTeX-Familie“.

Welcher Befehl welche Paarung bedeutet

Auch bei gleichem LaTeX-Format legt der Befehlsname die dahinterstehende Engine, das Ausgabeformat und die Schriftbehandlung fest. Die folgende Tabelle vom Befehlsnamen ausgehend von links nach rechts lesen. In der Praxis zählt die rechte Spalte am meisten: Ob fontspec verfügbar ist, entspricht unmittelbar der Wahl der Engine.

BefehlEngineAusgabeUnicode / Systemschriften
latexpdfTeX im DVI-ModusDVI – braucht einen separaten WandlungsschrittNein; stützt sich auf inputenc und Verwandtes
pdflatexpdfTeXPDF direktNein; stützt sich auf inputenc und Verwandtes
platexe-upTeX mit pLaTeX-kompatibler EinstellungDVI, dann dvipdfmxJapanisch über die herkömmliche Schrifteinrichtung
uplatexe-upTeXDVI, dann dvipdfmxIntern Unicode; japanische Schriften weiterhin herkömmlich eingerichtet
lualatexLuaHBTeXPDF direktJa – fontspec und luatexja
xelatexXeTeXPDF, intern über xdvipdfmxJa – fontspec
terminal
# Engines that write PDF finish in one step.
$ pdflatex main.tex      # -> main.pdf
$ lualatex main.tex      # -> main.pdf
$ xelatex  main.tex      # -> main.pdf

# DVI-based routes add a conversion step.
$ latex    main.tex      # -> main.dvi   (pdfTeX in DVI mode)
$ uplatex  main.tex      # -> main.dvi   (Japanese)
$ dvipdfmx main.dvi      # -> main.pdf

Die erste Zeile des Logs lesen – und die Paarung festschreiben

Die erste Zeile des Logs nennt sowohl Engine als auch Format. Zerlegt man This is pdfTeX, Version 3.141592653-2.6-1.40.26 (TeX Live 2024) (preloaded format=latex), so ist die erste Hälfte die Engine samt Version und (preloaded format=...) das geladene Format. This is LuaHBTeX ..., This is XeTeX ... und This is e-upTeX ... liest man genauso. Meldet jemand im Team „gleicher Befehl, andere Ausgabe“, trennt der Abgleich dieser einen Zeile sofort ein Problem der Editorkonfiguration von einem Unterschied im TeX-Live-Jahrgang oder im Format.

Und sobald die Paarung feststeht, im Projekt festhalten und einfrieren. Bei einer Abschlussarbeit: Sobald Titelseite, Inhaltsverzeichnis, Abbildungen, Tabellen und Literaturverzeichnis durchlaufen, den Befehl in die README oder in .latexmkrc schreiben. Ein Wechsel von lualatex zu uplatex mitten im Projekt ändert Schriftwahl, Japanischbehandlung, den Weg zum PDF und oft auch die Literaturverarbeitung auf einen Schlag. Muss doch gewechselt werden, alle Funktionen zuerst an einer kleinen Testdatei prüfen, bevor es zurück ans eigentliche Manuskript geht. Die Kriterien für die Wahl – Geschwindigkeit, Paketkompatibilität, die japanische Lage – stehen gesammelt auf der Seite „Die Wahl der Engine“.