Fonctionnement du traitement (DVI/PDF)

Prenez un document LaTeX d'une ligne — \documentclass{article}\begin{document}Hi\end{document} — et passez-le dans pdflatex : vous obtenez un PDF de 11 529 octets. Passez la source identique dans latex et le fichier DVI qui en sort pèse 248 octets. Un facteur quarante-six. Tous deux décrivent la même page unique portant le même mot « Hi » : où passe la différence ? La réponse explique toute la chaîne de traitement de TeX. Cette page suit le chemin de la source au résultat en passant par le moteur, montre ce que contient réellement un .dvi, et explique pourquoi l'ancienne route par DVI n'a pas disparu — chiffres mesurés à l'appui.

Pourquoi ce n'est pas du WYSIWYG : le choix du traitement par lots

Si TeX ne rafraîchit pas l'écran pendant la frappe, c'est qu'il optimise la coupure des lignes paragraphe par paragraphe. Il ne remplit pas une ligne après l'autre : il évalue le paragraphe entier en cherchant quelle combinaison de coupures est globalement la moins disgracieuse, puis retient la solution au coût total minimal. Conséquence : ajouter un seul caractère en fin de paragraphe peut déplacer la coupure de sa toute première ligne. Recalculer chaque paragraphe à chaque frappe ne serait pas rentable.

TeX a donc choisi le traitement par lots : lire le manuscrit jusqu'au bout, puis tout composer d'un seul tenant. On renonce au confort de voir la page évoluer sous les doigts. On gagne une composition globalement optimale, une mise en forme qui ne dérive pas sur un long document, et l'automatisation que permet le texte brut — engendrer la source depuis un script, la comparer sous Git, la construire sans surveillance sur un serveur. Le rythme de travail devient : écrire, compiler, regarder le PDF, recommencer. Rendre cette boucle rapide, c'est presque tout le propos de ce qui suit.

Les deux routes de la source à la sortie : PDF direct ou via DVI

Un moteur écrit soit directement du PDF, soit un fichier intermédiaire appelé DVI. pdflatex, xelatex et lualatex — respectivement les moteurs pdfTeX, XeTeX et LuaTeX — écrivent du PDF ; latex, ainsi que les japonais platex et uplatex, écrivent du DVI. Écrire un DVI ne clôt pas l'affaire : le fichier est confié à un programme distinct, un pilote dvi, qui le convertit au format voulu — dvipdfmx vers PDF, dvips vers PostScript, dvisvgm vers SVG. Un pilote qui dessine à l'écran s'appelle une visionneuse dvi.

terminal
# Direct to PDF, one step
lualatex  document.tex        # -> document.pdf
pdflatex  document.tex        # -> document.pdf

# Via DVI, two steps (the Japanese route)
uplatex   document.tex        # -> document.dvi
dvipdfmx  document.dvi        # -> document.pdf

# Other dvi drivers, same input
dvips     document.dvi        # -> document.ps
dvisvgm   document.dvi        # -> document.svg

Ce que l'on confond ici, c'est que « passe-t-il par DVI ? » et « sait-il gérer l'Unicode et les polices système ? » sont deux axes distincts. pdflatex contourne le DVI et écrit directement du PDF, mais son traitement de l'entrée reste à l'ancienne et on ne peut pas simplement lui désigner une police OpenType installée sur la machine. xelatex et lualatex, à l'inverse, lisent l'Unicode tel quel et permettent de nommer une police via fontspec. Gardez les deux axes séparés et la foule de noms s'ordonne d'elle-même.

CommandeSortieEntrée et policesFormats d'images
latexDVI (un pilote dvi est nécessaire)Surtout ASCII ; formats de fontes propres à TeXEPS, PS
pdflatexPDF (direct)Unicode limité ; pas de polices systèmePNG, JPEG, PDF (EPS converti automatiquement)
uplatexDVI (à passer à dvipdfmx)Moteur japonais compatible Unicode ; l'incorporation des fontes japonaises se configureEPS, PDF, PNG, JPEG
xelatexPDF (en interne via un .xdv)Unicode ; polices OpenType du système désignées via fontspecPNG, JPEG, PDF, EPS
lualatexPDF (direct)Unicode ; polices système ; les entrailles sont extensibles en LuaPNG, JPEG, PDF, EPS

Que contient vraiment un .dvi ? Ouvrons les 248 octets

DVI est l'abréviation de device independent, indépendant du périphérique, et son contenu n'est rien d'autre qu'un flux d'instructions indiquant quel caractère va à quelle position. dvitype, livré avec TeX Live, le déplie sous une forme lisible. Voici ce que contenait réellement le DVI de 248 octets issu du document d'une ligne ci-dessus.

terminal
$ dvitype -output-level=4 one.dvi
numerator/denominator=25400000/473628672
magnification=1000
' TeX output 2026.08.13:1233'
maxv=41484288, maxh=26673152, maxstackdepth=3, totalpages=1
Font 27: cmr10---loaded at size 655360 DVI units

42: beginning of page 1
117: down4 41484288       v:=0+41484288=41484288
140: right3 5046272       h:=0+5046272=5046272
144: fntdef1 27: cmr10
165: fntnum27             current font is cmr10
166: setchar72            h:=5046272+491521=5537793
167: setchar105           h:=5537793+182045=5719838
[Hi]
181: setchar49            h:=15204352+327681=15532033
[ 1]
185: eop

C'est tout le fichier. setchar72 dit « pose le code de caractère 72 (H) ici », setchar105 « pose 105 (i) », et setchar49 est le 1 du numéro de page imprimé en pied. right3 et down4 déplacent le point courant, et l'unité — un DVI unit vaut un sp, soit 1/65536 pt — explique que cmr10 à « 655360 DVI units » fasse exactement 10 pt. La ligne décisive est fntdef1 27: cmr10 : le DVI ne fait qu'appeler la fonte par son nom. Nulle part dans le fichier il n'est dit à quoi ressemble cmr10.

Le PDF est exactement l'inverse. Ouvrez le PDF de 11 529 octets produit par pdflatex : la fonte y est incorporée, sous le nom UNYBJV+CMR10. Le préfixe de six lettres signale un sous-ensemble — la preuve que seuls les glyphes réellement utilisés ont été extraits. L'objet qui contient cette fonte indique /Length1 1394 /Length2 8300 /Length3 0 /Length 9259 : 9 259 octets même après compression, soit quatre cinquièmes des 11 529 octets du fichier. C'est là, pour l'essentiel, qu'est passé le facteur quarante-six. Là où le DVI peut écrire « le H de cmr10 », le PDF doit transporter le contour de ce H. C'est le prix de la promesse du PDF : être identique partout où il va.

Une réserve toutefois. « Le DVI est petit parce qu'il ne contient pas de fonte » est exact ; « le PDF fait 11 529 octets parce qu'il en contient une » n'explique pas tout. Passez ce même DVI de 248 octets dans dvipdfmx et le PDF obtenu pèse 1 950 octets. Lui aussi incorpore la fonte, mais la convertit dans la forme bien plus compacte /Subtype/Type1C, où elle n'occupe que 546 octets. Une page portant un seul mot pèse donc 248, 1 950 ou 11 529 octets selon la seule manière dont elle est décrite. Quand la taille des fichiers compte, le choix de la route se voit réellement.

Pourquoi la route DVI est toujours vivante : le japonais et .xdv

La raison pratique la plus forte de la survie du DVI, c'est qu'il constitue la route standard de la composition japonaise. platex et uplatex produisent du DVI, et dvipdfmx en fait un PDF à la fin. Ce programme est né du dvipdfm de Mark A. Wicks et a été étendu pour répondre aux exigences japonaises ; l'exemplaire livré dans TeX Live 2024 date de mars 2024. Sa tâche : traduire les commandes de positionnement du DVI en opérations de dessin PDF, puis retrouver et incorporer les fontes que le DVI référence. Passez un document japonais d'une ligne dans upLaTeX et un DVI de 396 octets devient un PDF de 5 998 octets, avec la fonte japonaise HaranoAjiMincho incorporée comme fonte CID.

Et ce mécanisme est plus actuel qu'on ne croit. Vérifiez ce qu'est réellement dvipdfmx dans TeX Live 2024 : c'est un lien symbolique vers xdvipdfmx, le programme qui lit les fichiers .xdv produits par XeTeX. Autrement dit, XeTeX émet en interne un DVI légèrement étendu et le confie à un pilote pour le convertir en PDF : exactement la route DVI. On peut le prouver avec xelatex -no-pdf, qui s'arrête avant la conversion et laisse le .xdv. Pour le document d'une ligne, le .xdv fait 436 octets ; passé à xdvipdfmx, il donne un PDF de 2 329 octets, soit exactement la taille qu'obtient xelatex seul sur la même source. Découper le travail en deux à la main ne fait que rendre visible ce que xelatex faisait déjà en interne.

terminal
$ readlink $(which dvipdfmx)
xdvipdfmx

$ xelatex -no-pdf one.tex     # stop before the driver stage
$ ls -l one.xdv
-rw-r--r--  1 user  staff  436 one.xdv

$ xdvipdfmx one.xdv           # run the driver by hand
$ ls -l one.pdf
-rw-r--r--  1 user  staff  2329 one.pdf

La règle pratique est simple. Pour un nouveau texte en anglais ou dans une autre langue à écriture latine, prenez la route PDF direct (pdflatex ou lualatex) : une étape de moins, c'est une source d'ennuis de moins. Pour travailler en japonais avec un existant ou un usage de laboratoire derrière soi, la route DVI (uplatex puis dvipdfmx) reste un choix solide, avec un long acquis en composition verticale et en règles de coupure japonaises. L'argumentaire complet revient à la page sur le choix du moteur ; en tout cas, rien n'oblige à fuir le DVI sous prétexte qu'il est ancien.

Fichiers auxiliaires et nombre de passes : le tableau avec BibTeX et makeindex

« Lancer le moteur une fois et c'est fini » ne vaut que pour un document sans renvoi, sans table des matières, sans bibliographie et sans index. Au cours d'un passage, le moteur écrit .aux (numéros et pages) et .toc (la table) ; le passage suivant les relit. Répéter jusqu'à stabilisation est la forme de base, et dès qu'un seul \ref apparaît il faut au moins deux passes. Bibliographies et index insèrent dans la boucle des programmes autres que le moteur : BibTeX lit le .aux et écrit un .bbl (ou biber lit un .bcf), et makeindex lit le .idx et écrit un .ind. Le moteur doit ensuite lire ces sorties, d'où l'ordre d'exécution ci-dessous.

terminal
# A document with cross-references, a bibliography and an index
pdflatex   thesis      # writes .aux, .idx; references still print as ??
bibtex     thesis      # reads .aux  -> writes .bbl
makeindex  thesis      # reads .idx  -> writes .ind
pdflatex   thesis      # pulls .bbl and .ind in; numbering shifts again
pdflatex   thesis      # everything settles

# Or simply
latexmk -pdf thesis    # figures out the order and the count on its own

Cesser de compter les passes : latexmk, éditeurs et SyncTeX

latexmk surveille les fichiers auxiliaires et relance le moteur exactement autant de fois que le document l'exige. Lorsque le contenu de .aux et consorts ressort identique à la fois précédente, il considère la construction stabilisée et s'arrête, en appelant au passage BibTeX/biber ou makeindex si besoin. Par défaut il répète au plus cinq fois ($max_repeat = 5) avant de conclure à une boucle. Les documents réels n'atteignent pour ainsi dire jamais ce plafond. Pour la route DVI, il suffit d'inscrire le parcours dans un fichier de configuration latexmk : la même commande unique fait l'affaire.

terminal
latexmk -pdf      document.tex   # pdfLaTeX, as many passes as needed
latexmk -lualatex document.tex   # LuaLaTeX
latexmk -pv       document.tex   # build, then open the viewer
latexmk -c                       # remove .aux, .log, .toc and friends
latexmk -C                       # the same, and remove the PDF too

LaTeX Workshop dans VS Code, TeXShop, TeXstudio et Overleaf appellent en général latexmk en coulisses : appuyer sur « compiler » a donc déjà réglé la question du nombre de passes. L'autre chose à activer est SyncTeX, qui consigne dans un fichier .synctex.gz de quelle ligne source provient chaque endroit du PDF. Une fois activé, un clic dans le PDF mène à la ligne correspondante de la source, et inversement. Plus le document est long, plus cela paie.

Quand la compilation s'arrête, quelle étape soupçonner

L'étape d'où provient un message indique où chercher. Une erreur du moteur dans le .log signifie que le problème est dans la source ; une plainte du pilote dvi désigne une image ou une fonte ; une sortie de BibTeX ou biber pointe vers le .bib. Le symptôme le plus déroutant est « mon image n'apparaît pas », et c'est la différence de route qui transparaît directement : la route DVI accueille volontiers l'EPS, la route PDF direct accueille PDF, PNG et JPEG. Vouloir inclure un PNG dans un document compilé avec latex est donc une entrée très fréquente dans ce problème. La lecture du journal elle-même est traitée en détail sur la page consacrée à la traque des erreurs.

  • Quand seuls les renvois sont faux, ne supprimez pas les fichiers auxiliaires : laissez latexmk relancer autant de fois qu'il le faut.
  • Quand seules les images manquent, vérifiez si la route en cours est le PDF direct ou le DVI, et convertissez le fichier dans un format que cette route accepte.
  • Quand un symptôme persiste sans explication, et seulement alors, supprimez .aux, .toc et .out et reconstruisez (latexmk -c). Si des auxiliaires périmés étaient en cause, c'est réglé.
  • Quand les fontes changent dans un PDF japonais, soupçonnez la configuration d'incorporation de dvipdfmx. C'est une affaire de pilote, pas de moteur.