En regardant dans une installation de TeX Live 2024, on découvre une bizarrerie : latex, pdflatex et etex ne sont pas des programmes mais des liens symboliques vers pdftex. Seul le TeX de Knuth lui-même — la commande tex — subsiste comme exécutable distinct. Une fois ce point acquis, l’essentiel de la confusion autour de LaTeX se dissipe, car il met au jour la distinction sur laquelle repose tout l’édifice : un moteur (le programme) et un format (un ensemble de macros préchargées) sont deux choses différentes. Cette page traite du programme gelé qui se trouve tout en bas, puis des extensions e-TeX ajoutées dans les années 1990 — le socle sur lequel chacun travaille aujourd’hui sans le savoir.
Ce que la commande tex exécute réellement
tex lance un programme qui range les caractères et les boîtes en lignes et en paragraphes, optimise les coupures de ligne et écrit le résultat dans un fichier — et à peu près rien d’autre. La confusion naît de ce que le mot TeX désigne à la fois ce programme et le système de commandes que le programme interprète. La structure en sections, les renvois, la bibliographie : le programme lui-même n’en sait rien.
Knuth entreprit le premier TeX en 1978, poussé par les épreuves du deuxième volume de son The Art of Computer Programming, dont la composition mathématique lui parut insupportable. Cette première version était un prototype exploratoire ; elle fut entièrement réécrite en 1982, et cette réécriture est TeX82 — c’est de cette lignée qu’on parle aujourd’hui quand on dit « TeX ». L’ensemble minimal de commandes que Knuth a intégrées au programme lui-même constitue les primitives : \def (définir une commande), \hbox (une boîte horizontale), \vbox (une boîte verticale) et leurs proches.
Rédiger un document en primitives nues n’est pas praticable. En pratique on utilise donc un format : une couche de macros posée par-dessus. Charger plain.tex donne plain TeX ; charger un jeu de macros bien plus vaste donne LaTeX. Un format n’est pas relu à chaque exécution : il est développé à l’avance, enregistré dans un fichier .fmt, puis restauré en un instant au démarrage. Le détail de ce mécanisme — ce que contient un .fmt, comment fmtutil le reconstruit, ce qui lie LaTeX2e à LaTeX3 — relève de la page « Les formats LaTeX ».
De tex, initex et etex, lequel est un vrai programme
Seul tex. initex est un lien symbolique vers tex, et etex est un lien vers pdftex — autrement dit, e-TeX en tant que programme distinct n’existe plus du tout dans les distributions actuelles. Ce n’est pas une opinion : readlink le confirme en quelques secondes sur votre propre machine. Sous TeX Live 2024, tex --version répond TeX 3.141592653 (TeX Live 2024).
$ tex --version | head -1
TeX 3.141592653 (TeX Live 2024)
# Which of these are real binaries, and which are links?
$ cd $(dirname $(which tex))
$ readlink tex initex etex latex pdflatex amstex csplain
# tex prints nothing: it is a real executable
tex # initex -> tex
pdftex # etex -> pdftex
pdftex # latex -> pdftex
pdftex # pdflatex -> pdftex
pdftex # amstex -> pdftex
pdftex # csplain -> pdftexPourquoi cela ? Parce que les extensions d’e-TeX ont été absorbées en bloc par les autres moteurs. Le fichier doc/etex/base/README livré avec TeX Live (Karl Berry, 2024) le dit sans détour : l’exécutable etex fourni par la plupart des distributions est une incarnation de pdfTeX tournant en mode DVI, précisément pour que les extensions allant au-delà d’e-TeX soient elles aussi disponibles. Par la même logique, latex n’est pas « l’ancien TeX » mais pdfTeX en mode DVI : à l’exécution, la bannière annonce This is pdfTeX, .... De telles substitutions ne tiennent que parce que moteur et format sont deux axes indépendants.
Plain TeX : un monde sans \documentclass ni \begin{document}
Plain TeX est le format standard que Knuth présente dans The TeXbook. Il rassemble un outillage minimal — réglage des fontes, symboles mathématiques de base, macros commodes comme \bye — dans plain.tex, livré avec TeX lui-même. Avant LaTeX, c’était l’unique manière praticable d’utiliser TeX. Dans TeX Live 2024, le moteur tex produit ce format à partir de tex.ini et l’enregistre sous tex.fmt.
La notation diffère nettement de LaTeX. Les mathématiques en ligne s’écrivent $...$ des deux côtés, mais une boîte horizontale est \hbox{...}, une boîte verticale \vbox{...}, l’alignement tabulaire se fait avec \halign, une commande se définit avec \def, la largeur du texte est \hsize, et un document se termine par \bye. Point de \documentclass ni de \begin{document} : LaTeX les fabrique avec des macros. Retournée, cette observation dit quelque chose d’important : les commodités de LaTeX sont des propriétés du format, non du moteur.
% plain TeX — process with: tex hello.tex (produces hello.dvi)
\hsize=10cm
\font\big=cmr10 at 17pt
{\big Hello, plain \TeX!}
\medskip
This paragraph is set in the default font.
Inline math works too: $E = mc^2$.
\byeTraité par tex hello.tex, cela produit un fichier DVI — pas un PDF ; on y vient. Les macros de logo comme \TeX et les macros d’espacement comme \medskip (un saut vertical moyen) sont elles aussi définies par plain TeX. Placé à côté d’un document LaTeX avec \documentclass, il montre à quel point la pellicule que plain TeX pose sur le moteur nu est mince.
Programmation lettrée et WEB : comment est écrit le source de TeX
TeX lui-même est écrit en WEB, le système propre à Knuth et la pratique fondatrice de la programmation lettrée. Une source WEB est un document unique où l’explication destinée aux humains et le code Pascal sont tissés ensemble. Deux outils en tirent ensuite des dérivés distincts : tangle produit du Pascal compilable, et weave produit le commentaire composé — le livre TeX: The Program.
La langue cible initiale était Pascal ; dans les distributions modernes, un outil nommé web2c traduit le WEB (en passant par Pascal) en C pour la compilation. Ainsi, le pdfTeX, le XeTeX ou le LuaTeX qui tournent aujourd’hui sur votre machine remontent en dernier ressort à cette unique source lettrée. C’est pourquoi le nom web2c revient sans cesse dans l’arborescence de TeX Live.
Un numéro de version convergeant vers π, et un programme gelé
La numérotation des versions de TeX est singulière. Depuis la version 3, chaque mise à jour ajoute un chiffre de plus, si bien que le nombre tend asymptotiquement vers π. Sur l’exemplaire livré avec TeX Live 2024, tex --version répond TeX 3.141592653. Son compagnon METAFONT fait de même vers e, la base des logarithmes népériens : c’est la réunion des deux qui rend la plaisanterie visible.
Et Knuth a déclaré que le « changement absolument final », effectué après sa mort, fixera la version à π exactement — moment où tous les bogues restants deviendront, selon ses propres termes, des fonctionnalités (Donald E. Knuth, « The future of TeX and METAFONT », revue NTG MAPS, 1990 ; repris comme chapitre 30 de Digital Typography). Ce gel relève d’une décision de conception, non d’un renoncement. C’est précisément parce que le socle ne bouge pas que les formats et pilotes empilés dessus peuvent évoluer sans crainte. Qu’un fichier .tex vieux de plusieurs décennies produise encore la même sortie en découle directement.
METAFONT et DVI : pourquoi TeX n’émet pas directement de PDF
TeX a un compagnon jumeau, METAFONT (commande mf) : un système qui décrit une police non comme des formes figées mais comme un programme de tracé des glyphes. Knuth a conçu avec lui toute la famille Computer Modern destinée à TeX. La répartition des rôles est nette : TeX décide où vont les caractères, METAFONT produit la forme même des caractères.
Et ce que le TeX de Knuth émet directement n’est pas du PDF mais un fichier DVI (DeVice Independent). Un DVI ne contient que des instructions indépendantes du périphérique — « place ce caractère à cette position » —, que dvips convertit ensuite en PostScript ou dvipdfmx en PDF. En 1982 le PDF n’existait pas : la conception allait de soi ; lue à l’envers, elle signifie que le format de sortie pouvait changer sans réécrire TeX lui-même. La grande différence des pdfTeX, XeTeX et LuaTeX largement utilisés aujourd’hui est qu’ils ont intégré cette étape et savent écrire le PDF directement.
Ce qu’est e-TeX : étendre un programme gelé sans le casser
e-TeX est une extension qui ajoute de nouvelles primitives au TeX gelé, en sur-ensemble strict. Knuth ayant gelé TeX, les nouveautés devaient venir d’ailleurs. Sous l’égide de DANTE e.V., l’association germanophone des utilisateurs de TeX, le projet NTS (New Typesetting System) fut créé en 1992, et e-TeX en fut le premier résultat concret. Il a été mis en œuvre par Peter Breitenlohner, de l’Institut Max-Planck de physique de Munich (mort en 2015), avec Philip Taylor comme coordinateur du projet. La page de manuel etex.1 livrée avec TeX Live formule l’objectif ainsi : perpétuer et développer l’esprit et la philosophie de TeX, tout en respectant le vœu de Knuth que TeX demeure gelé.
« Sur-ensemble strict » signifie que les entrées existantes tournent sans modification et produisent une sortie identique. Pour le garantir, e-TeX a deux modes. En mode de compatibilité, il se comporte exactement comme TeX nu ; ce n’est qu’en mode étendu que les primitives ajoutées deviennent disponibles. Ce n’est pas l’exécution qui tranche, mais la construction du format : préfixer d’un * le nom du fichier source du format au moment du dump sélectionne le mode étendu. Comme le montre la section suivante, tout le LaTeX moderne repose sur cette convention d’un seul caractère.
Pourquoi vous utilisez déjà e-TeX sans le savoir
Parce que le format LaTeX est produit en mode étendu. Ce n’est pas une supposition : c’est écrit dans un fichier de configuration. Ouvrez fmtutil.cnf dans TeX Live 2024 et vous y lisez la ligne latex pdftex language.dat -translate-file=cp227.tcx *latex.ini, où le * devant latex.ini demande le mode étendu — et l’en-tête de commentaire du même fichier précise que ce * équivaut pour l’essentiel à l’option -etex. La ligne de plain TeX, elle, est tex tex - tex.ini : moteur tex, pas de *. Seul TeX nu est resté sans les extensions e-TeX.
On peut le vérifier aussi du côté de LaTeX. Près du début du fichier noyau latex.ltx se trouve la sentinelle \ifx\eTeXversion\undefined \errmessage{LaTeX requires e-TeX} : sans les extensions, la construction du format s’arrête net. La date à laquelle cela est devenu officiel est également documentée — LaTeX News 16 (décembre 2003) annonçait qu’en deux ans environ les versions supposeraient e-TeX, et LaTeX News 26 a déclaré qu’à partir de la version de janvier 2017, e-TeX est requis pour construire le format. La ligne entering extended mode, troisième ligne d’une exécution de latex, est la trace visible de cette décision.
# Ask each engine whether the e-TeX primitives exist.
$ cat > probe.tex <<'EOF'
\message{[eTeX=\ifx\eTeXversion\undefined none\else\number\eTeXversion\eTeXrevision\fi]}
\count300=7 % register 300 does not exist in Knuth's TeX
\end
EOF
$ tex probe.tex # Knuth's TeX: no extensions
[eTeX=none]
! Bad register code (300).
$ pdftex probe.tex # pdfTeX: e-TeX 2.6 built in, 32768 registers
[eTeX=2.6]
$ latex probe.tex | head -3
This is pdfTeX, Version 3.141592653-2.6-1.40.26 (TeX Live 2024) (preloaded format=latex)
restricted \write18 enabled.
entering extended modeCette dernière bannière condense en une ligne le sujet de cette page. La chaîne de version 3.141592653-2.6-1.40.26 comporte trois couches : le TeX de Knuth est en 3.141592653, e-TeX en 2.6, pdfTeX en 1.40.26 — et (preloaded format=latex) nomme le format. Une seule ligne consigne donc à la fois la filiation du moteur et le choix du format. Prendre l’habitude de lire la première ligne du journal, et l’énigme classique du travail à plusieurs — « même commande, résultat différent » — se tranche en quelques secondes.
Les primitives ajoutées par e-TeX
Les ajouts d’e-TeX profitent surtout à ceux qui écrivent des macros. Le plus important est l’arithmétique sur les entiers, les dimensions et le ressort (glue). Avec TeX nu, il fallait jongler avec des registres de travail à chaque calcul ; e-TeX fournit \numexpr, \dimexpr et \glueexpr, qui évaluent sur place une expression comme (a+b)*c/d — et de façon développable, si bien que la valeur apparaît directement dans un \edef ou un \write.
% On any e-TeX engine in extended mode (pdftex, xetex, luatex, euptex).
\count0=\numexpr (3+4)*2/7 \relax % yields 2
% Branch safely on whether a name is defined.
\ifdefined\foo \message{foo exists}\else \message{no foo}\fi
% Test a control sequence without creating it.
\ifcsname chapter\endcsname \message{chapter is defined}\fi
% Negate a conditional directly, instead of swapping the branches.
\unless\ifnum\count0>10 \message{count0 is not greater than 10}\fiLe deuxième pilier, ce sont les conditionnelles et la manipulation de tokens. \ifdefined teste si une séquence de contrôle est définie ; \ifcsname...\endcsname teste l’existence de celle qu’on assemble à partir d’un nom. L’essentiel, pour les deux, est l’absence d’effet de bord : l’ancienne astuce à base de \ifx, utilisée avec TeX nu, pouvait transformer silencieusement une séquence non définie en \relax. \unless inverse n’importe quelle conditionnelle et supprime la corvée d’échanger les deux branches ; \detokenize convertit une liste de tokens en chaîne de caractères, de code de catégorie 12.
| Primitive | Rôle |
|---|---|
\numexpr | Évalue sur place une expression entière, de façon développable : \numexpr (3+4)*2/7 \relax |
\dimexpr / \glueexpr | Idem pour les dimensions et le ressort : \dimexpr \textwidth/3 \relax |
\ifdefined | Teste si une séquence de contrôle est définie, sans effet de bord |
\ifcsname | Teste l’existence d’une séquence de contrôle formée depuis un nom, sans la créer |
\unless | Inverse le sens de la conditionnelle qui suit : \unless\ifnum ... |
\protected | Définit une macro qui ne se développe pas d’elle-même dans \edef ou \write |
\detokenize / \unexpanded | Transforme une liste de tokens en chaîne / laisse une liste de tokens non développée |
\scantokens / \readline | Relit une chaîne comme si c’était de l’entrée / lit une ligne d’entrée verbatim |
\middle | Place un délimiteur extensible au milieu de \left … \right |
\currentgrouplevel | Donne la profondeur de groupe courante (\interactionmode lit et fixe le mode d’interaction) |
Le contrôle du développement a lui aussi été renforcé. \unexpanded laisse son contenu en place sans le développer, et \protected définit une macro qui ne se développe pas d’elle-même dans un contexte de développement. Ce dernier est la clé d’une implémentation correcte, au bas niveau, du \protect de LaTeX : les commandes fragiles survivent alors à un \edef ou à un \write. En mathématiques, \middle fait son office : écrivez \left( … \middle| … \right) et la barre verticale du milieu s’élève à la même hauteur que les parenthèses qui l’encadrent. TeX nu ignorait tout bonnement la notion de délimiteur au milieu d’une formule.
Discrète mais décisive : la forte augmentation du nombre de registres. TeX nu n’avait que 256 exemplaires de chacun — \count, \dimen, \skip, \toks et consorts —, ce que refusait précisément tex plus haut avec ! Bad register code (300). e-TeX a porté le plafond à 32768, en les allouant comme des tableaux creux : les registres inutilisés ne coûtent aucune mémoire. Si les documents LaTeX d’aujourd’hui, qui chargent des dizaines de grandes classes et packages, ne butent pas sur une pénurie de registres, c’est grâce à cette extension.
e-TeX a aussi apporté des mécanismes pour la composition bidirectionnelle — les écritures allant de droite à gauche. Cette partie descend du TeX--XeT de Breitenlohner et a nourri les travaux ultérieurs sur XeTeX, LuaTeX et le traitement du japonais. Et bien des packages modernes ne pourraient tout simplement pas exister sans ces primitives. expl3, la couche de programmation de LaTeX, en est l’exemple évident : sans \ifcsname ni \protected, cet immense système de macros n’aurait pas pu être écrit.
Ce que la connaissance de cette couche permet de lire
On voit le fond des messages d’erreur. Une bonne part de ce dont LaTeX avertit est rédigée dans le vocabulaire de la couche inférieure. Overfull \hbox (12.3pt too wide) dit que la matière dépasse de 12,3 pt la boîte horizontale qu’est une ligne ; savoir que \hbox est une boîte réduit la cause à une longue URL ou à un mot insécable. ! Missing number, treated as zero. dit que TeX attendait quelque chose de lisible comme nombre ou dimension et n’a rien trouvé — le plus souvent une longueur mal orthographiée.
Mais lire cette couche et y écrire sont deux choses distinctes. Laissez les titres, les listes, les renvois et les environnements de théorème aux commandes structurantes de LaTeX, et réservez les commandes de bas niveau à la lecture des pannes ou à de menues retouches d’une classe. Même pour définir une nouvelle commande, un document ordinaire gagne à employer \newcommand ou \NewDocumentCommand plutôt qu’un \def brut : celles-ci vérifient le nombre d’arguments et signalent les collisions avec les commandes existantes.
- En rédigeant — employer les commandes structurantes de LaTeX et n’user des primitives de bas niveau qu’avec parcimonie.
- En réparant une classe ou un package — les outils e-TeX comme
\ifdefinedet\numexprsont plus sûrs et plus lisibles que les vieilles astuces de TeX. - En lisant un journal — traduire les avertissements dans le vocabulaire TeX des boîtes, du ressort et des registres, et la cause apparaît.
- Quand la reproductibilité importe — le moteur est gelé, les anciens documents rendent le même résultat. Ce qui bouge vraiment, c’est la version du format et des packages : c’est cela qu’il faut figer.