You type latex and no PDF appears. Nothing is broken: the oldest LaTeX command writes DVI, not PDF, and everything after that is the job of a DVI converter — dvipdfmx, dvips, dvisvgm. The format itself goes back a long way; Knuth’s DVItype source records that the first DVItype program was designed by David Fuchs in 1979, more than a decade before PDF existed. Yet the two-step route survives in an age when pdflatex writes PDF directly, and it survives for concrete reasons. This page covers what each converter in TeX Live 2024 consumes and emits, why the Japanese uplatex → dvipdfmx pipeline is still the standard one, and how to read the errors that appear at the conversion step.
Why go through DVI at all when pdflatex exists
DVI — device independent — is an intermediate format that carries nothing but instructions: put this character of this font at this position on this page. It embeds no font files, knows no colour and no images. That lightness is the whole point. TeX itself concentrates on typesetting and hands everything about the output device to a converter; a design decision from 1979 is what still gives you an exit toward PostScript, PDF and SVG today. So DVI is not kept alive purely for compatibility. pdflatex can only write PDF, whereas one DVI file can branch three ways. On top of that, the PSTricks family of packages works through \special commands that assume a PostScript interpreter somewhere in the chain, and latex → dvips is the direct way to give it one. And the Japanese pTeX-family engines have no direct-to-PDF implementation at all.
dvipdfmx, xdvipdfmx and extractbb are one single program
Look inside the TeX Live 2024 bin directory and dvipdfmx, dvipdfm, extractbb and ebb all turn out to be symlinks to xdvipdfmx. That is one executable under five names, and the program checks which name invoked it before deciding how to behave. dvipdfmx --version announces itself as “This is dvipdfmx Version 20240305”; xdvipdfmx --version gives the same date under the name xdvipdfmx. Same file. Once you know that, the XeTeX side of the story falls into place too: xelatex -no-pdf writes not a PDF but an .xdv (extended DVI), and xdvipdfmx turns that into PDF — and because it is the same binary, dvipdfmx sample.xdv works just as well. The ancestor dvipdfm was written by Mark A. Wicks; the extension into dvipdfmx, with CJK support, font embedding and object streams, is the work of Jin-Hwan Cho, Shunsaku Hirata and others.
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 | What it does (defaults from TeX Live 2024) |
|---|---|
-o FILE | Output filename; - means stdout. Defaults to the input name with .pdf |
-p a4 | Paper size by name; the default is a4. List them with dvipdfmx --showpaper |
-V 5 | PDF version; the default 5 means PDF 1.5. Use -V 4 when a journal demands 1.4 |
-s 1-3,5 | Restrict the physical page ranges processed; several may be given, comma separated |
-l | Landscape: swap the width and height of the paper |
-z 9 | zlib compression level 0 to 9; the default is 9. Use -z 0 when debugging the raw PDF |
-f FILE.map | Load an extra font map file; the hook for substituting which fonts get embedded |
When you see ! LaTeX Error: Cannot determine size of graphic, suspect the driver option
Put a figure into a DVI-route document and this is the first error most people hit: ! LaTeX Error: Cannot determine size of graphic in fig.pdf (no BoundingBox). The cause is not the image file but which driver graphicx is set up for. In TeX Live 2024, graphics.cfg selects dvips.def by default for any run that writes DVI, and dvips can only embed PostScript, so it has no way to read the size of a PDF or a PNG. Say \usepackage[dvipdfmx]{graphicx} in the preamble and, on this installation, both PDF and PNG go straight through with no extra files. Tested here, latex picked up the figures without a single .xbb file and without shell escape, and dvipdfmx embedded them. For an older image whose size still cannot be determined, run extractbb fig.pdf; the .xbb it writes is a few lines of text such as %%BoundingBox: 0 0 612 792 — and, per the symlink above, the program producing it is dvipdfmx itself.
% name the driver explicitly on the DVI route
\documentclass{article}
\usepackage[dvipdfmx]{graphicx}
\begin{document}
\includegraphics[width=3cm]{fig.pdf}
\end{document}dvips: the route that survives for what only PostScript can do
dvips -o paper.ps paper.dvi turns DVI into PostScript. It is Tomas Rokicki’s program, but the author line of its man page reads “extended to virtual fonts by Don Knuth”, with path searching and configuration by Karl Berry — a genuinely shared piece of work. Today there are three reasons to reach for it: figures that depend on PostScript arithmetic, PSTricks above all; a print shop that wants a .ps; and cutting a single figure out with dvips -E, which writes an EPS whose bounding box hugs the actual content (in the run here, %%BoundingBox: 148 88 326 668). If you want a PDF at the end, the standard finish is to pass the file through ps2pdf, which ships with 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 | What it does |
|---|---|
-o FILE | Name of the PostScript file to write; without it, dvips may try to print |
-t a4 | Paper type: a4, letter, legal, and also landscape |
-E | Write a single page as EPS; one-page files only, and included graphics do not count toward the box |
-P NAME | Read the printer configuration config.NAME, which switches resolution and font handling |
-p 3 -l 7 | Output only pages 3 through 7 |
Here is the trap that eats a whole day if you have not met it. Do not send bitmap images down the dvips route. With the driver left at dvips, \includegraphics{dot.png} stops at the no BoundingBox error above; force it through — by supplying an .xbb by hand, say — and now neither LaTeX nor dvips says a word, and a .ps file is duly written. The breakage is further downstream. Feeding that .ps to ps2pdf here made Ghostscript print Error: /syntaxerror in (binary token, type=137) and die with GPL Ghostscript 10.03.0: Unrecoverable error, exit code 1. PostScript simply does not know what a PNG is, which is reasonable enough — what hurts is that nothing complains until the very last step. So: if you use dvips, keep every figure in EPS. If you want to mix PNG, JPEG and PDF, take the dvipdfmx route. That one line is the whole decision.
dvisvgm: math as SVG, and how the font format changes the file size
Putting mathematics on the web is a choice between a raster image that blurs when zoomed and MathML that renders differently everywhere. dvisvgm — by Martin Gieseking, in development since 2005 — converts DVI straight to SVG, so TeX’s typesetting survives as vectors. The version in TeX Live 2024 here is dvisvgm 3.2.2, and it also accepts EPS with --eps and PDF with --pdf. The option that matters most is --font-format. Converting the same single page and measuring the result: 13,156 bytes with the default embedded SVG fonts, 8,361 bytes with --font-format=woff2, and — going the other way — 23,563 bytes with --no-fonts, which turns every glyph into a path. The outlined file also contains not one <text> element, so the result cannot be searched or copied. “Outlines are smaller” does not hold here.
| Setting | Measured size and character of the same page |
|---|---|
(default) | 13,156 bytes; SVG fonts embedded, 14 <text> elements survive |
--font-format=woff2 | 8,361 bytes; the smallest, and the text survives. First choice for the web |
--no-fonts | 23,563 bytes; everything becomes paths and zero <text> remains — no search, no copy |
-z | 5,383 bytes; a gzip-compressed .svgz, the smallest of all if the server supports it |
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 usedOne more message generates a steady stream of reports: processing of PostScript specials is disabled (Ghostscript not found) — on a machine where Ghostscript is installed. That is exactly the case here: gs sits in /usr/local/bin/gs, and dvisvgm still says this. The reason is that it looks for something else. dvisvgm does not run the gs executable; it loads the shared library libgs at run time. The Ghostscript that comes with MacTeX installs only the executable, so the library is nowhere to be found. If you need to convert figures that use \special — PSTricks, some TikZ output — install a Ghostscript that ships the shared library, or point at it with --libgs=. For a DVI holding only mathematics and \includegraphics, the warning is safe to ignore.
The Japanese uplatex → dvipdfmx route, and ptex2pdf
The DVI route survives in Japanese typesetting out of necessity, not nostalgia. The pTeX-family engines — ptex, eptex, uptex, uplatex — have no ability to write PDF directly. Vertical writing, line-breaking prohibitions, the spacing between Japanese and Latin script: pTeX owns all of that, while dvipdfmx owns making the PDF and embedding the Japanese fonts. Forty years of work have accumulated on both sides of that division. So the procedure is always two steps: uplatex paper.tex produces the .dvi, and dvipdfmx paper.dvi produces the PDF. Naming the driver in the document as well, as in \documentclass[uplatex,dvipdfmx]{jsarticle}, is what makes graphicx and color emit the right \special commands.
Folding those two steps into one command is what ptex2pdf does. The version in TeX Live 2024 is 20200520.0, a texlua script by texjporg — the Japanese TeX development community — and Norbert Preining; the command itself is a symlink to texmf-dist/scripts/ptex2pdf/ptex2pdf.lua, and it calls dvipdfmx automatically after the engine finishes. You choose the engine by combining flags, and upLaTeX, the standard for Japanese papers, is -l -u. Fine-grained options go to the TeX side with -ot and to dvipdfmx with -od. What ptex2pdf will not do is count compilation passes, so for a document with cross-references or a bibliography it is safer to hand the job to latexmk, which does.
| Flags | Engine invoked |
|---|---|
(none) | ptex — the pTeX flavour of plain TeX |
-l | platex — pLaTeX, the traditional engine limited to the JIS X 0208 range |
-u | uptex — the internally Unicode version of pTeX |
-l -u | uplatex — upLaTeX, today’s default choice for Japanese papers |
# 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.The errors the conversion step produces, and what they mean
| Message | What is actually happening |
|---|---|
dvipdfmx:fatal: Could not open specified DVI | No .dvi exists — usually because the document was built with pdflatex. Exit status 1 |
dvips: DVI file can't be opened | The input is missing as well; dvips will not guess a name, so check the spelling and extension |
dvips: ! Bad DVI file: id byte not 2 | An .xdv written by XeTeX was handed to dvips; only xdvipdfmx reads XDV |
no BoundingBox | graphicx is set up for dvips; try \usepackage[dvipdfmx]{graphicx} instead |
Ghostscript not found | dvisvgm cannot find libgs; having the gs executable is a different matter |
The pre-submission checks also differ by route. If you are handing in a PDF, then after dvipdfmx open it in the viewer your reader will use and confirm embedded fonts, paper size, bookmarks and links. If it is going to a printer, compare the .ps from dvips before and after ps2pdf to see that the EPS files and PostScript \special commands survived. And if you rely on forward and inverse search from your editor, latex -synctex=1 produces a .synctex.gz on the DVI route too — here it came out at 860 bytes and was still there after dvipdfmx ran. The .dvi, .pdf and .synctex.gz all share the job name, so if outputs go to a separate directory, have the build tool specify that path consistently.
That said, you will rarely type these commands in sequence by hand. latexmk covers the latex → dvipdfmx and (u)platex → dvipdfmx routes with nothing more than a change of $pdf_mode, and it works out for itself whether the .dvi is stale. Typing by hand is for the moments when you suspect the route itself — which is to say, the moments this page is for. Put the other way round: learn the converters’ names and arguments once, and you can also read what your build tool is doing.