Man tippt latex, und es erscheint kein PDF. Nichts ist kaputt: Der älteste LaTeX-Befehl schreibt DVI und kein PDF, und alles Weitere ist Sache eines DVI-Konverters – dvipdfmx, dvips, dvisvgm. Das Format reicht weit zurück; Knuths DVItype-Quelltext hält fest, dass das erste DVItype-Programm 1979 von David Fuchs entworfen wurde, mehr als ein Jahrzehnt vor PDF. Trotzdem überlebt der zweistufige Weg in einer Zeit, in der pdflatex direkt PDF erzeugt, und das aus handfesten Gründen. Diese Seite zeigt, was jeder Konverter aus TeX Live 2024 liest und schreibt, warum die japanische Kette uplatex → dvipdfmx weiterhin der Standard ist und wie sich die Fehler im Konvertierungsschritt lesen lassen.
Warum überhaupt über DVI, wenn es pdflatex gibt
DVI – device independent – ist ein Zwischenformat, das nichts als Anweisungen enthält: Setze dieses Zeichen dieser Schrift an diese Position auf dieser Seite. Es bettet keine Schriftdateien ein und kennt weder Farbe noch Bilder. Genau diese Leichtigkeit ist der Punkt. TeX konzentriert sich auf den Satz und überlässt alles Gerätebezogene einem Konverter; eine Entwurfsentscheidung von 1979 eröffnet bis heute den Weg zu PostScript, PDF und SVG. DVI lebt also nicht nur aus Kompatibilitätsgründen weiter. pdflatex kann ausschließlich PDF schreiben, eine DVI-Datei dagegen verzweigt in drei Richtungen. Hinzu kommt: Die PSTricks-Familie arbeitet über \special-Anweisungen, die irgendwo in der Kette einen PostScript-Interpreter voraussetzen, und latex → dvips ist der direkte Weg, ihr einen zu geben. Und die japanischen Engines der pTeX-Familie besitzen überhaupt keine direkte PDF-Ausgabe.
dvipdfmx, xdvipdfmx und extractbb sind ein einziges Programm
Ein Blick in das bin-Verzeichnis von TeX Live 2024 zeigt: dvipdfmx, dvipdfm, extractbb und ebb sind allesamt Symlinks auf xdvipdfmx. Das ist eine ausführbare Datei unter fünf Namen, und das Programm prüft, unter welchem Namen es aufgerufen wurde, bevor es sich entscheidet. dvipdfmx --version meldet sich als „This is dvipdfmx Version 20240305“, xdvipdfmx --version nennt dasselbe Datum unter dem Namen xdvipdfmx. Dieselbe Datei. Damit ordnet sich auch die XeTeX-Seite: xelatex -no-pdf schreibt kein PDF, sondern ein .xdv (erweitertes DVI), und xdvipdfmx macht daraus ein PDF – weil es dasselbe Binärprogramm ist, funktioniert dvipdfmx sample.xdv genauso. Der Vorfahr dvipdfm stammt von Mark A. Wicks; die Erweiterung zu dvipdfmx mit CJK-Unterstützung, Font-Einbettung und Objektstreams geht auf Jin-Hwan Cho, Shunsaku Hirata und andere zurück.
ls -l $(dirname $(which dvipdfmx))/dvipdfmx
# dvipdfmx -> xdvipdfmx
dvipdfmx sample.dvi # sample.dvi -> sample.pdf
dvipdfmx -p a4 -o out.pdf sample.dvi
xelatex -no-pdf paper.tex # writes paper.xdv, not paper.pdf
xdvipdfmx paper.xdv # paper.xdv -> paper.pdf| Option | Wirkung (Standardwerte aus TeX Live 2024) |
|---|---|
-o FILE | Name der Ausgabedatei; - bedeutet stdout. Standard ist der Eingabename mit .pdf |
-p a4 | Papierformat nach Name; Standard ist a4. Liste über dvipdfmx --showpaper |
-V 5 | PDF-Version; der Standard 5 bedeutet PDF 1.5. -V 4, wenn eine Zeitschrift 1.4 verlangt |
-s 1-3,5 | Beschränkt die verarbeiteten Seitenbereiche; mehrere durch Komma getrennt möglich |
-l | Querformat: Breite und Höhe des Papiers tauschen |
-z 9 | zlib-Kompressionsstufe 0 bis 9; Standard ist 9. -z 0 beim Debuggen des rohen PDF |
-f FILE.map | Lädt eine zusätzliche Font-Map-Datei; der Ansatzpunkt zum Austauschen eingebetteter Schriften |
Bei ! LaTeX Error: Cannot determine size of graphic zuerst die Treiberoption prüfen
Wer im DVI-Weg eine Abbildung einbindet, stößt meist zuerst auf diesen Fehler: ! LaTeX Error: Cannot determine size of graphic in fig.pdf (no BoundingBox). Die Ursache ist nicht die Bilddatei, sondern für welchen Treiber graphicx eingerichtet ist. In TeX Live 2024 wählt graphics.cfg bei jedem Lauf, der DVI schreibt, standardmäßig dvips.def, und dvips kann nur PostScript einbetten, hat also keine Möglichkeit, die Größe einer PDF- oder PNG-Datei zu lesen. Mit \usepackage[dvipdfmx]{graphicx} in der Präambel gehen auf dieser Installation sowohl PDF als auch PNG ohne Zusatzdateien glatt durch. Im Test hier las latex die Abbildungen ohne eine einzige .xbb-Datei und ohne Shell-Escape ein, und dvipdfmx bettete sie ein. Lässt sich bei einem älteren Bild die Größe dennoch nicht ermitteln, hilft extractbb fig.pdf; die erzeugte .xbb ist ein kurzer Text wie %%BoundingBox: 0 0 612 792 – und gemäß dem obigen Symlink stammt sie von dvipdfmx selbst.
% name the driver explicitly on the DVI route
\documentclass{article}
\usepackage[dvipdfmx]{graphicx}
\begin{document}
\includegraphics[width=3cm]{fig.pdf}
\end{document}dvips – der Weg, der bleibt, weil nur PostScript manches kann
dvips -o paper.ps paper.dvi macht aus DVI PostScript. Es ist Tomas Rokickis Programm, doch die Autorenzeile der Manpage vermerkt „extended to virtual fonts by Don Knuth“, dazu Pfadsuche und Konfiguration von Karl Berry – echte Gemeinschaftsarbeit. Heute bleiben drei Gründe, danach zu greifen: Grafiken, die auf PostScript-Arithmetik beruhen, allen voran PSTricks; eine Druckerei, die eine .ps verlangt; und das Herausschneiden einer einzelnen Abbildung mit dvips -E, das ein EPS schreibt, dessen Bounding Box eng am tatsächlichen Inhalt liegt (im Lauf hier %%BoundingBox: 148 88 326 668). Soll am Ende ein PDF stehen, führt der übliche Abschluss über ps2pdf aus Ghostscript.
dvips -t a4 -o paper.ps paper.dvi # DVI -> PostScript
ps2pdf paper.ps # PostScript -> PDF (Ghostscript)
dvips -E -o figure.eps figure.dvi # one tightly cropped EPS| Option | Wirkung |
|---|---|
-o FILE | Name der zu schreibenden PostScript-Datei; ohne sie versucht dvips womöglich zu drucken |
-t a4 | Papiertyp: a4, letter, legal und auch landscape |
-E | Schreibt eine Seite als EPS; nur für einseitige Dateien, eingebundene Grafiken zählen nicht zur Box |
-P NAME | Liest die Druckerkonfiguration config.NAME, die Auflösung und Fontbehandlung umschaltet |
-p 3 -l 7 | Gibt nur die Seiten 3 bis 7 aus |
Hier lauert die Falle, die einen ganzen Tag kostet, wenn man sie nicht kennt. Keine Bitmap-Bilder auf den dvips-Weg schicken. Bleibt der Treiber bei dvips, endet \includegraphics{dot.png} mit dem obigen no BoundingBox-Fehler; erzwingt man den Durchgang, etwa durch eine von Hand angelegte .xbb, sagen weder LaTeX noch dvips ein Wort, und eine .ps-Datei entsteht ordnungsgemäß. Kaputt ist es weiter hinten. Übergibt man diese .ps an ps2pdf, gibt Ghostscript hier Error: /syntaxerror in (binary token, type=137) aus und bricht mit GPL Ghostscript 10.03.0: Unrecoverable error, exit code 1 ab. PostScript kennt kein PNG, was nachvollziehbar ist – schmerzhaft ist, dass bis zum allerletzten Schritt niemand widerspricht. Also: Wer dvips nutzt, hält alle Abbildungen in EPS. Wer PNG, JPEG und PDF mischen will, nimmt den dvipdfmx-Weg. Diese eine Zeile genügt als Entscheidung.
dvisvgm – Formeln als SVG, und wie das Fontformat die Dateigröße ändert
Mathematik ins Web zu stellen heißt sonst: ein Rasterbild, das beim Zoomen verschwimmt, oder MathML, das überall anders aussieht. dvisvgm – von Martin Gieseking, seit 2005 in Entwicklung – wandelt DVI direkt in SVG um, sodass TeX’ Satz als Vektorgrafik erhalten bleibt. Die Fassung in TeX Live 2024 ist hier dvisvgm 3.2.2; mit --eps nimmt sie auch EPS, mit --pdf auch PDF entgegen. Entscheidend ist die Option --font-format. Dieselbe einzelne Seite konvertiert und gemessen: 13.156 Bytes mit den standardmäßig eingebetteten SVG-Schriften, 8.361 Bytes mit --font-format=woff2 und – umgekehrt – 23.563 Bytes mit --no-fonts, das jede Glyphe in einen Pfad verwandelt. Die konturierte Datei enthält zudem kein einziges <text>-Element, ist also weder durchsuchbar noch kopierbar. „Outlines sind kleiner“ trifft hier nicht zu.
| Einstellung | Gemessene Größe und Eigenschaft derselben Seite |
|---|---|
(default) | 13.156 Bytes; SVG-Schriften eingebettet, 14 <text>-Elemente bleiben erhalten |
--font-format=woff2 | 8.361 Bytes; am kleinsten, Text bleibt erhalten. Erste Wahl fürs Web |
--no-fonts | 23.563 Bytes; alles wird zu Pfaden, kein <text> bleibt – keine Suche, kein Kopieren |
-z | 5.383 Bytes; ein gzip-komprimiertes .svgz, das kleinste, sofern der Server es unterstützt |
latex equation.tex # -> equation.dvi
dvisvgm --font-format=woff2 equation.dvi # -> equation.svg
dvisvgm --pdf figure.pdf # PDF input
dvisvgm --libgs=/path/to/libgs.dylib f.dvi # only if PS specials are usedEine weitere Meldung sorgt für einen stetigen Strom von Rückfragen: processing of PostScript specials is disabled (Ghostscript not found) – auf einem Rechner, auf dem Ghostscript installiert ist. Genau so liegt der Fall hier: gs steht in /usr/local/bin/gs, und dvisvgm sagt es trotzdem. Der Grund ist, dass es nach etwas anderem sucht. dvisvgm startet nicht die ausführbare Datei gs, sondern lädt zur Laufzeit die gemeinsam genutzte Bibliothek libgs. Das mit MacTeX gelieferte Ghostscript legt nur die ausführbare Datei ab, also ist die Bibliothek nirgends zu finden. Wer Grafiken mit \special umwandeln muss – PSTricks, manche TikZ-Ausgabe –, installiert ein Ghostscript mit gemeinsam genutzter Bibliothek oder verweist mit --libgs= darauf. Bei einer DVI mit nur Mathematik und \includegraphics kann die Warnung ignoriert werden.
Die japanische Kette uplatex → dvipdfmx und ptex2pdf
Dass der DVI-Weg im japanischen Satz überlebt, ist Notwendigkeit, nicht Nostalgie. Die Engines der pTeX-Familie – ptex, eptex, uptex, uplatex – können kein PDF direkt schreiben. Vertikalsatz, Umbruchverbote, der Abstand zwischen japanischer und lateinischer Schrift: All das gehört pTeX, während dvipdfmx die PDF-Erzeugung und das Einbetten der japanischen Schriften übernimmt. Auf beiden Seiten dieser Arbeitsteilung haben sich vierzig Jahre angesammelt. Der Ablauf besteht deshalb immer aus zwei Schritten: uplatex paper.tex erzeugt die .dvi, dvipdfmx paper.dvi das PDF. Wird der Treiber zusätzlich im Dokument genannt, etwa \documentclass[uplatex,dvipdfmx]{jsarticle}, schreiben graphicx und color die passenden \special-Anweisungen.
Diese zwei Schritte zu einem Befehl zu bündeln, ist die Aufgabe von ptex2pdf. In TeX Live 2024 steckt Version 20200520.0, ein texlua-Skript von texjporg – der japanischen TeX-Entwicklergemeinschaft – und Norbert Preining; der Befehl selbst ist ein Symlink auf texmf-dist/scripts/ptex2pdf/ptex2pdf.lua und ruft nach dem Engine-Lauf automatisch dvipdfmx auf. Die Engine wählt man durch Kombination von Flags; upLaTeX, der Standard für japanische Arbeiten, ist -l -u. Feinere Optionen gehen mit -ot an die TeX-Seite und mit -od an dvipdfmx. Was ptex2pdf nicht tut, ist Kompilierläufe zu zählen; bei Dokumenten mit Querverweisen oder Literaturverzeichnis übergibt man die Aufgabe deshalb besser latexmk.
| Flags | Aufgerufene Engine |
|---|---|
(none) | ptex – die pTeX-Variante von plain TeX |
-l | platex – pLaTeX, die traditionelle Engine für den Bereich JIS X 0208 |
-u | uptex – die intern Unicode-basierte Fassung von pTeX |
-l -u | uplatex – upLaTeX, heute die Standardwahl für japanische Arbeiten |
# the two steps, written out
uplatex paper.tex # -> paper.dvi
dvipdfmx paper.dvi # -> paper.pdf
# the same thing in one command
ptex2pdf -l -u -ot '-kanji=utf8 -synctex=1' paper.tex
ptex2pdf -l -u -s paper.tex # stop at the DVI
# what to check when the converter fails
dvipdfmx nosuch.dvi
# dvipdfmx:fatal: Could not open specified DVI (or XDV) file: nosuch.dvi
# No output PDF file written.Die Fehler des Konvertierungsschritts und was sie bedeuten
| Meldung | Was tatsächlich passiert |
|---|---|
dvipdfmx:fatal: Could not open specified DVI | Keine .dvi vorhanden – meist, weil mit pdflatex übersetzt wurde. Exit-Status 1 |
dvips: DVI file can't be opened | Auch hier fehlt die Eingabe; dvips rät keinen Namen, also Schreibweise und Endung prüfen |
dvips: ! Bad DVI file: id byte not 2 | Eine von XeTeX geschriebene .xdv wurde an dvips übergeben; XDV liest nur xdvipdfmx |
no BoundingBox | graphicx ist für dvips eingerichtet; stattdessen \usepackage[dvipdfmx]{graphicx} versuchen |
Ghostscript not found | dvisvgm findet libgs nicht; die vorhandene gs-Datei ist eine andere Sache |
Auch die Kontrollen vor der Abgabe unterscheiden sich je nach Weg. Wird ein PDF eingereicht, öffnet man es nach dvipdfmx in dem Betrachter, den die Lesenden verwenden werden, und prüft eingebettete Schriften, Papierformat, Lesezeichen und Links. Geht es zur Druckerei, vergleicht man die .ps von dvips vor und nach ps2pdf daraufhin, ob EPS-Dateien und PostScript-\special-Anweisungen überlebt haben. Und wer auf Vorwärts- und Rückwärtssuche aus dem Editor angewiesen ist: latex -synctex=1 erzeugt auch auf dem DVI-Weg eine .synctex.gz – hier 860 Bytes groß und nach dem Lauf von dvipdfmx weiterhin vorhanden. .dvi, .pdf und .synctex.gz teilen sich den Jobnamen; landen die Ausgaben in einem eigenen Verzeichnis, sollte das Build-Werkzeug diesen Pfad konsequent vorgeben.
Von Hand tippt man diese Befehle allerdings selten nacheinander. latexmk deckt die Wege latex → dvipdfmx und (u)platex → dvipdfmx allein durch eine Änderung von $pdf_mode ab und entscheidet selbst, ob die .dvi veraltet ist. Von Hand tippt man dann, wenn man den Weg selbst in Verdacht hat – also genau in den Momenten, für die diese Seite gedacht ist. Umgekehrt gilt: Wer die Namen und Argumente der Konverter einmal kennt, kann auch lesen, was das Build-Werkzeug tut.