Al mirar dentro de una instalación de TeX Live 2024 aparece algo extraño: latex, pdflatex y etex no son programas, sino enlaces simbólicos a pdftex. Solo el TeX de Knuth —el comando tex— sobrevive como ejecutable independiente. Entender eso disuelve buena parte de la confusión que rodea a LaTeX, porque saca a la luz la distinción sobre la que se apoya todo el sistema: un motor (el programa) y un formato (un cuerpo de macros precargado) son cosas distintas. Esta página recorre el programa congelado que está en la base y las extensiones e-TeX añadidas en los años noventa: el suelo sobre el que hoy trabaja todo el mundo sin darse cuenta.
Qué ejecuta realmente el comando tex
tex lanza un programa que coloca caracteres y cajas en líneas y párrafos, optimiza los cortes de línea y escribe el resultado en un archivo, y prácticamente nada más. La confusión nace de que la palabra TeX nombra a la vez ese programa y el sistema de comandos que el programa interpreta. De la división en secciones, las referencias cruzadas o la bibliografía, el programa mismo no sabe nada.
Knuth empezó el primer TeX en 1978, empujado por las galeradas del segundo volumen de su The Art of Computer Programming, cuya composición matemática le resultó insoportable. Aquella primera versión fue un prototipo exploratorio y se reescribió por completo en 1982; esa reescritura es TeX82, y «TeX» hoy significa en la práctica ese linaje. El conjunto mínimo de comandos que Knuth incorporó al programa mismo son las primitivas: \def (definir un comando), \hbox (una caja horizontal), \vbox (una caja vertical) y afines.
Escribir un documento con primitivas desnudas no es practicable. En la práctica se usa por eso un formato: una capa de macros apilada encima. Cargar plain.tex da plain TeX; cargar un juego de macros mucho mayor da LaTeX. Un formato no se vuelve a leer en cada ejecución: se expande de antemano, se guarda como archivo .fmt y se restaura en un instante al arrancar. El detalle de ese mecanismo —qué contiene un .fmt, cómo lo reconstruye fmtutil, qué relación hay entre LaTeX2e y LaTeX3— corresponde a la página «Los formatos LaTeX».
De tex, initex y etex, cuál es un programa de verdad
Solo tex. initex es un enlace simbólico a tex, y etex lo es a pdftex: es decir, e-TeX como programa independiente ya no existe en las distribuciones actuales. No es una opinión, sino algo que readlink confirma en segundos en la propia máquina. En TeX Live 2024, tex --version responde 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 -> pdftex¿Por qué es así? Porque las extensiones de e-TeX fueron absorbidas por completo en los demás motores. El archivo doc/etex/base/README que acompaña a TeX Live (Karl Berry, 2024) lo dice sin rodeos: el ejecutable etex que ofrecen la mayoría de las distribuciones es una encarnación de pdfTeX funcionando en modo DVI, justamente para que también estén disponibles las extensiones que van más allá de e-TeX. Por la misma lógica, latex no es «el TeX antiguo» sino pdfTeX en modo DVI: al ejecutarlo, el banner anuncia This is pdfTeX, .... Sustituciones así solo funcionan porque motor y formato son ejes independientes.
Plain TeX: un mundo sin \documentclass ni \begin{document}
Plain TeX es el formato estándar que Knuth presenta en The TeXbook. Reúne un utillaje mínimo —configuración de fuentes, símbolos matemáticos básicos, macros cómodas como \bye— en plain.tex, que se distribuye junto con TeX. Antes de LaTeX, esta era la única vía practicable para usar TeX. En TeX Live 2024 el motor tex vuelca este formato desde tex.ini y lo guarda como tex.fmt.
La notación difiere bastante de LaTeX. Las matemáticas en línea son $...$ en ambos, pero una caja horizontal es \hbox{...}, una vertical \vbox{...}, la alineación tabular se hace con \halign, un comando se define con \def, el ancho del texto es \hsize y un documento termina con \bye. No hay \documentclass ni \begin{document}: LaTeX los construye con macros. Dado la vuelta, esto dice algo importante: las comodidades de LaTeX son prestaciones del formato, no del motor.
% 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$.
\byeProcesado con tex hello.tex, esto produce un archivo DVI, no un PDF; enseguida volvemos sobre ello. Las macros de logotipo como \TeX y las de espaciado como \medskip (un salto vertical medio) también las define plain TeX. Puesto junto a un documento LaTeX con \documentclass, deja ver lo delgada que es la piel que plain TeX pone sobre el motor desnudo.
Programación literaria y WEB: cómo está escrito el código de TeX
El propio TeX está escrito en WEB, el sistema ideado por Knuth y la práctica fundacional de la programación literaria. Una fuente WEB es un documento único en el que la explicación para humanos y el código Pascal se entretejen. Dos herramientas extraen de ahí productos distintos: tangle genera Pascal compilable y weave genera el comentario compuesto: el libro TeX: The Program.
El lenguaje de destino inicial fue Pascal; en las distribuciones modernas, una herramienta llamada web2c traduce el WEB (pasando por Pascal) a C para compilarlo. Es decir: el pdfTeX, el XeTeX o el LuaTeX que corren hoy en su máquina se remontan, en último término, a aquella única fuente literaria. Por eso el nombre web2c reaparece una y otra vez en la estructura de directorios de TeX Live.
Un número de versión que converge a π y un programa congelado
La numeración de versiones de TeX es peculiar. Desde la versión 3, cada actualización añade un dígito más, de modo que el número se aproxima asintóticamente a π. En la copia que acompaña a TeX Live 2024, tex --version responde TeX 3.141592653. Su compañero METAFONT hace lo mismo hacia e, la base de los logaritmos naturales; solo viendo ambas cosas se aprecia la broma.
Y Knuth ha declarado que el «cambio absolutamente final», realizado tras su muerte, fijará la versión en π exacto, momento en el cual todos los errores restantes pasarán a ser, en sus propias palabras, características (Donald E. Knuth, «The future of TeX and METAFONT», revista NTG MAPS, 1990; reimpreso como capítulo 30 de Digital Typography). Esta congelación fue una decisión de diseño, no una rendición. Justamente porque los cimientos no se mueven, los formatos y controladores apilados encima pueden evolucionar sin miedo. Que un archivo .tex de hace décadas siga produciendo hoy la misma salida es consecuencia directa de ello.
METAFONT y DVI: por qué TeX no emite PDF directamente
TeX tiene un compañero gemelo, METAFONT (el comando mf): un sistema que describe una tipografía no como formas fijas sino como un programa para dibujar los glifos. Knuth diseñó con él toda la familia Computer Modern para TeX. El reparto de tareas es limpio: TeX decide dónde van los caracteres y METAFONT produce la forma misma de los caracteres.
Y lo que el TeX de Knuth emite directamente no es PDF sino un archivo DVI (DeVice Independent). Un DVI contiene solo instrucciones independientes del dispositivo —«pon este carácter en esta posición»—, que dvips convierte luego en PostScript o dvipdfmx en PDF. En 1982 el PDF no existía, así que el diseño era el evidente; leído al revés, significaba que el formato de salida podía cambiar sin reescribir TeX. La gran diferencia de los hoy extendidos pdfTeX, XeTeX y LuaTeX es que han absorbido ese paso y pueden escribir PDF directamente.
Qué es e-TeX: extender un programa congelado sin romperlo
e-TeX es una extensión que añade nuevas primitivas al TeX congelado como superconjunto estricto. Una vez que Knuth congeló TeX, las novedades tenían que venir de otras manos. Bajo el auspicio de DANTE e.V., la asociación de usuarios de TeX del ámbito germanohablante, se creó en 1992 el proyecto NTS (New Typesetting System), y e-TeX fue su primer resultado concreto. Lo implementó Peter Breitenlohner, del Instituto Max Planck de Física de Múnich (fallecido en 2015), con Philip Taylor como coordinador del proyecto. La página de manual etex.1 incluida en TeX Live formula el objetivo así: perpetuar y desarrollar el espíritu y la filosofía de TeX, respetando a la vez el deseo de Knuth de que TeX siga congelado.
«Superconjunto estricto» significa que la entrada existente se ejecuta sin cambios y produce una salida idéntica. Para garantizarlo, e-TeX tiene dos modos. En modo de compatibilidad se comporta exactamente como el TeX desnudo; solo en modo extendido quedan disponibles las primitivas añadidas. Lo que decide cuál rige no es la ejecución sino la construcción del formato: anteponer un * al nombre del archivo fuente del formato al volcarlo selecciona el modo extendido. Como muestra la sección siguiente, todo el LaTeX moderno descansa sobre esa convención de un solo carácter.
Por qué ya está usando e-TeX sin saberlo
Porque el formato LaTeX se vuelca en modo extendido. No es una conjetura: está escrito en un archivo de configuración. Abra fmtutil.cnf en TeX Live 2024 y encontrará la línea latex pdftex language.dat -translate-file=cp227.tcx *latex.ini, donde el * de *latex.ini solicita el modo extendido; y el encabezado de comentarios de ese mismo archivo afirma que ese * equivale en lo esencial a la opción -etex. En cambio, la línea de plain TeX es tex tex - tex.ini: motor tex, sin *. El TeX desnudo es lo único que ha quedado sin las extensiones e-TeX.
Lo mismo puede comprobarse desde el lado de LaTeX. Cerca del comienzo del archivo del núcleo latex.ltx hay un centinela: \ifx\eTeXversion\undefined \errmessage{LaTeX requires e-TeX}; sin las extensiones, la construcción del formato se detiene en seco. También está documentado el momento en que esto se hizo oficial: LaTeX News 16 (diciembre de 2003) anunció que en unos dos años las versiones pasarían a suponer e-TeX, y LaTeX News 26 declaró que desde la versión de enero de 2017 e-TeX es obligatorio para construir el formato. La línea entering extended mode, tercera de una ejecución de latex, es el rastro visible de esa decisión.
# 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 modeEse último banner comprime en una línea el asunto de esta página. La cadena de versión 3.141592653-2.6-1.40.26 tiene tres capas: el TeX de Knuth está en 3.141592653, e-TeX en 2.6, pdfTeX en 1.40.26, y (preloaded format=latex) nombra el formato. Una sola línea registra, pues, tanto la ascendencia del motor como la elección del formato. Adquirir el hábito de leer la primera línea del registro resuelve en segundos el clásico enigma del trabajo en equipo: «mismo comando, resultado distinto».
Las primitivas que añadió e-TeX
Los añadidos de e-TeX benefician sobre todo a quien escribe macros. El mayor es la aritmética con enteros, dimensiones y muelle (glue). En TeX desnudo había que hacer malabares con registros auxiliares en cada cálculo; e-TeX aporta \numexpr, \dimexpr y \glueexpr, que evalúan en el acto una expresión como (a+b)*c/d y, lo decisivo, de forma expandible: el valor aparece directamente dentro de \edef o \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}\fiEl segundo pilar son las condicionales y la manipulación de tokens. \ifdefined comprueba si una secuencia de control está definida; \ifcsname...\endcsname comprueba la existencia de una ensamblada a partir de un nombre. Lo importante en ambos casos es que no tienen efectos secundarios: el viejo truco con \ifx usado en TeX desnudo podía convertir en silencio una secuencia no definida en \relax. \unless invierte cualquier condicional y ahorra el trabajo rutinario de intercambiar las dos ramas, y \detokenize convierte una lista de tokens en su forma de cadena: caracteres de código de categoría 12.
| Primitiva | Qué hace |
|---|---|
\numexpr | Evalúa en el acto una expresión entera, de forma expandible: \numexpr (3+4)*2/7 \relax |
\dimexpr / \glueexpr | Lo mismo para dimensiones y muelle: \dimexpr \textwidth/3 \relax |
\ifdefined | Comprueba si una secuencia de control está definida, sin efecto secundario |
\ifcsname | Comprueba la existencia de una secuencia de control formada desde un nombre, sin crearla |
\unless | Invierte el sentido de la condicional siguiente: \unless\ifnum ... |
\protected | Define una macro que no se expande por sí sola dentro de \edef o \write |
\detokenize / \unexpanded | Convierte una lista de tokens en cadena / deja una lista de tokens sin expandir |
\scantokens / \readline | Vuelve a leer una cadena como si fuera entrada / lee una línea de entrada literalmente |
\middle | Coloca un delimitador extensible en medio de \left … \right |
\currentgrouplevel | Devuelve la profundidad de grupo actual (\interactionmode lee y fija el modo de interacción) |
También se reforzó el control de la expansión. \unexpanded deja su contenido tal cual, sin expandirlo, y \protected define una macro que no se expande por sí sola en un contexto de expansión. Esto último es la clave para implementar correctamente, a bajo nivel, el \protect de LaTeX, de modo que los comandos frágiles sobrevivan a un \edef o un \write. En matemáticas, \middle se gana el sueldo: escriba \left( … \middle| … \right) y la barra vertical central crecerá hasta la altura de los paréntesis de ambos lados. El TeX desnudo no tenía siquiera la noción de delimitador en mitad de una fórmula.
Discreto pero decisivo es el gran aumento de registros. El TeX desnudo solo tenía 256 de cada uno —\count, \dimen, \skip, \toks y afines—, que es justo lo que tex rechazaba arriba con ! Bad register code (300). e-TeX elevó el techo a 32768 y los asigna como arreglos dispersos, de modo que los no usados no consumen memoria. Que los documentos LaTeX actuales, que cargan decenas de clases y paquetes grandes, no se queden sin registros se debe a esta extensión.
e-TeX trajo además maquinaria para la composición bidireccional: sistemas de escritura que corren de derecha a izquierda. Esa parte desciende del TeX--XeT de Breitenlohner y alimentó el trabajo posterior en XeTeX, LuaTeX y el procesamiento del japonés. Y muchos paquetes modernos sencillamente no podrían existir sin estas primitivas. expl3, la capa de programación de LaTeX, es el ejemplo evidente: sin \ifcsname ni \protected ese enorme sistema de macros no se habría podido escribir.
Qué permite leer el conocimiento de esta capa
Se ve el fondo de los mensajes de error. Buena parte de lo que LaTeX advierte está redactado en el vocabulario de la capa inferior. Overfull \hbox (12.3pt too wide) dice que el material sobresale 12,3 pt de la caja horizontal que es una línea; saber que \hbox es una caja reduce la causa a una URL larga o una palabra indivisible. ! Missing number, treated as zero. dice que TeX esperaba algo legible como número o dimensión y no lo halló: casi siempre una longitud mal escrita.
Ahora bien, leer esta capa y escribir en ella son cosas distintas. Deje los títulos, las listas, las referencias cruzadas y los entornos de teorema a los comandos estructurales de LaTeX, y reserve los de bajo nivel para leer por qué algo se rompió o para retocar puntualmente una clase. Incluso al definir un comando nuevo, un documento corriente sale ganando con \newcommand o \NewDocumentCommand antes que con un \def crudo, porque comprueban el número de argumentos y avisan de colisiones con comandos existentes.
- Al redactar — use los comandos estructurales de LaTeX y reserve las primitivas de bajo nivel para casos contados.
- Al arreglar una clase o un paquete — herramientas de e-TeX como
\ifdefinedy\numexprson más seguras y legibles que los viejos trucos de TeX. - Al leer un registro — traduzca los avisos al vocabulario de TeX (cajas, muelle y registros) y la causa aparece.
- Cuando hace falta reproducibilidad — el motor está congelado, así que los documentos antiguos siguen dando el mismo resultado. Lo que sí se mueve es la versión del formato y de los paquetes, y eso es lo que conviene fijar.