Formatos de LaTeX

Si preguntan qué es pdflatex, la respuesta exacta no es «un programa». Es el motor pdfTeX arrancado con el formato LaTeX precargado. Alineados como nombres de comando, pdflatex, lualatex y platex parecen programas distintos; en realidad, cada uno combina dos ejes independientes: un motor (el programa que se ejecuta) y un formato (un cuerpo de macros compilado de antemano). En cuanto se ven esos ejes, varias cosas se explican a la vez: qué es un archivo .fmt, por qué ejecutar latex da un DVI y no un PDF, y en qué quedó realmente LaTeX3.

La diferencia entre un motor y un formato

Un motor es un ejecutable; un formato son datos. El motor es el programa que lee un .tex y lo compone: tex, pdftex, xetex, luahbtex, euptex, etcétera. Un formato es una gran colección de macros como \documentclass y \section, expandida de antemano y congelada en un único volcado: un archivo .fmt. El motor carga ese .fmt en un instante al arrancar, de modo que nunca tiene que redefinir decenas de miles de líneas de macros en cada ejecución.

Por tanto, «LaTeX» es el nombre de un formato, no de un motor. El mismo formato LaTeX puede correr sobre motores distintos, y el comando que usted teclea designa una pareja motor + formato concreta. Esa correspondencia no hay que adivinarla: existe dentro de TeX Live como un único archivo de configuración llamado fmtutil.cnf. Sus cuatro columnas son nombre del formato, motor, archivo de patrones de partición y argumentos; la copia de TeX Live 2024 tiene 54 líneas, es decir, 54 combinaciones registradas.

terminal
$ grep -E '^(tex|latex|pdflatex|lualatex|xelatex|uplatex|amstex|pdfcsplain) ' \
      $(kpsewhich fmtutil.cnf)

# format      engine     hyphenation                 arguments
tex           tex        -                           tex.ini
latex         pdftex     language.dat                *latex.ini
pdflatex      pdftex     language.dat                *pdflatex.ini
xelatex       xetex      language.dat                -etex xelatex.ini
lualatex      luahbtex   language.dat,language.dat.lua lualatex.ini
uplatex       euptex     language.dat                *uplatex.ini
amstex        pdftex     -                           *amstex.ini
pdfcsplain    luatex     -                           csplain.ini
pdfcsplain    pdftex     -                           csplain-utf8.ini
pdfcsplain    xetex      -                           csplain.ini

De esa tabla se siguen dos cosas. Primero, un mismo nombre de formato puede aparecer frente a varios motores: pdfcsplain tiene tres filas, para luatex, pdftex y xetex. No hay mejor prueba de que formato y motor son ortogonales. Segundo, el * antepuesto a los argumentos: ordena volcar con las extensiones e-TeX activadas, y el propio encabezado de comentarios del archivo explica que equivale en lo esencial a la opción -etex. La fila latex lleva el *; la del tex de Knuth, no. La dependencia del LaTeX moderno respecto de e-TeX está comprimida en ese único carácter.

Qué contiene realmente un archivo .fmt

Es un volcado de memoria de todo el estado interno del motor. Ni código fuente ni texto. Definiciones de macros, códigos de categoría, patrones de partición, asignaciones de fuentes matemáticas: cuanto haya en la memoria del motor en el instante en que termina de leer latex.ltx se escribe tal cual en binario. En TeX Live 2024, latex.fmt ocupa unos 8,2 MB. La diferencia entre releer esos 8,2 MB y reinterpretar latex.ltx cada vez es justamente por lo que LaTeX arranca al instante.

Hay un lugar donde la relación entre motor y formato se ve en el propio sistema de archivos: un .fmt no se guarda bajo el nombre del formato, sino en un directorio con el nombre del motor. Bajo texmf-var/web2c/, TeX Live 2024 alinea los directorios tex/, pdftex/, xetex/, luahbtex/, euptex/, cada uno con los formatos volcados por ese motor. tex/tex.fmt es plain TeX, pdftex/latex.fmt es LaTeX, euptex/uplatex.fmt es upLaTeX: la misma extensión .fmt, pero objetos distintos según el motor que los construyó.

terminal
# Formats are filed by ENGINE, not by format name.
$ ls /usr/local/texlive/2024/texmf-var/web2c/
aleph  euptex  hitex  luahbtex  luajittex  luatex  metafont  pdftex  tex  xetex

$ ls /usr/local/texlive/2024/texmf-var/web2c/euptex/
eptex.fmt  euptex.fmt  platex.fmt  ptex.fmt  uplatex.fmt  ...

# Ask kpathsea which .fmt a given engine would load.
$ kpsewhich -engine pdftex latex.fmt
/usr/local/texlive/2024/texmf-var/web2c/pdftex/latex.fmt

$ ls -l $(kpsewhich -engine pdftex latex.fmt)
-rw-r--r--  1 root  wheel  8221690 May  4  2024 .../pdftex/latex.fmt

El mecanismo del lado productor es igual de simple. Arranque un motor con -ini y entrará en un modo de inicialización en el que no se carga ningún .fmt. Déle en ese estado una fuente como latex.ltx y termine con la primitiva \dump: el estado interno de ese momento se escribe como un .fmt. initex, antaño un ejecutable aparte, no es más que un nombre para ese arranque con -ini, y hoy pervive solo como enlace simbólico a tex.

Reconstruir un formato con fmtutil

El comando que reconstruye un .fmt es fmtutil. Lee fmtutil.cnf y vuelve a volcar cada formato con el motor y los argumentos allí anotados. Normalmente se ejecuta solo al actualizar la distribución, así que rara vez se invoca a mano; pero cuando se ha sustituido un archivo del núcleo o un patrón de partición y nada cambia, la causa suele ser un formato obsoleto. Las dos formas que realmente se usan son fmtutil-sys --all (reconstruir todo) y fmtutil-sys --byfmt latex (solo uno).

terminal
# Rebuild one format (writes into the system tree; needs write permission).
$ fmtutil-sys --byfmt latex

# Rebuild every format listed in fmtutil.cnf.
$ fmtutil-sys --all

# Rebuild only the formats that use a given engine.
$ fmtutil-sys --byengine luahbtex

# Personal tree instead of the system tree (no root needed).
$ fmtutil-user --byfmt pdflatex

# Where did the format end up, and when was it built?
$ kpsewhich -engine pdftex latex.fmt

La diferencia entre -sys y -user está en dónde se escribe: el árbol del sistema (TEXMFSYSVAR) o el árbol propio del usuario (TEXMFVAR). Con permisos de administrador, -sys es la opción natural; -user sirve para sustituir solo la copia propia en una máquina compartida. Mezclar ambos es una manera segura de producir el clásico «pero si ya lo arreglé y no cambia nada»: conviene fijar uno para todo el proyecto. Además, fmtutil.cnf está bajo el control de la distribución: su comentario inicial advierte con claridad que las ediciones manuales se perderán en la actualización. Para un cambio permanente, use la vía prevista, como fmtutil-sys --enablefmt.

LaTeX2e: el formato que realmente corre en su máquina

Hoy «LaTeX» significa, casi sin excepción, LaTeX2e. Es la versión vigente de las macros LaTeX escritas por Leslie Lamport, apareció en 1994 y hoy la mantiene el LaTeX Project. El «2e» señalaba una revisión menor del anterior LaTeX 2.09; en su momento, un paso intermedio hacia el largamente planeado LaTeX3. Uno puede comprobar por sí mismo qué formato tiene: el archivo del núcleo latex.ltx se declara con \def\fmtname{LaTeX2e}, y en la copia incluida en TeX Live 2024 \fmtversion vale 2023-11-01 con \patch@level 1.

El núcleo se actualiza ahora con una cadencia regular de unas dos publicaciones al año. Memorizar «la última versión» como número no sirve de nada: caduca en meses. Adquiera en cambio el hábito de leer \fmtversion en el latex.ltx de su propia instalación: esa es la fecha del núcleo realmente volcado allí. Para quien quiera probar antes la próxima versión, TeX Live incluye en paralelo formatos de desarrollo. fmtutil.cnf tiene filas para latex-dev, pdflatex-dev, xelatex-dev, lualatex-dev y uplatex-dev, de modo que pdflatex-dev main.tex compone con el núcleo venidero. Sirve para probar la compatibilidad de clases y paquetes, no para manuscritos definitivos.

En qué quedó realmente LaTeX3: la respuesta es expl3

Un formato LaTeX3 nunca llegó a publicarse. Lo que se publicó fue el lenguaje de programación de LaTeX3. Esa capa, llamada expl3 (L3 programming layer), no llegó como un núcleo nuevo e independiente sino absorbida dentro de LaTeX2e. Así que la pregunta «¿debo migrar a LaTeX3?» no tiene respuesta: no porque no haya adónde migrar, sino porque ya lo está usando.

El punto de inflexión está documentado. LaTeX News 31 (2 de febrero de 2020) señalaba que expl3 había pasado, en la década anterior, de ser en buena medida experimental a ser ampliamente estable, e informaba de que en esa versión el equipo ajustó el núcleo para precargar una parte importante de expl3 al construir el formato. El motivo era la velocidad: los documentos que cargan fontspec bajo XeLaTeX o LuaLaTeX pagaban en cada ejecución un coste alto por leer los datos Unicode.

expl3 forma hoy parte del formato. Al leer el archivo del núcleo latex.ltx se ve la lógica: si expl3 ya está presente, anuncia Skipping: expl3 code already part of the format y sigue; si no, lo carga con \input expl3.ltx; y si expl3.ltx no aparece por ninguna parte, se detiene con \errmessage{LaTeX requires expl3}. Dicho de otro modo, expl3 ya no es un paquete opcional sino un componente obligatorio de LaTeX2e. Escribir \RequirePackage{expl3} en un documento o paquete sigue recomendándose por consideración a quienes usan formatos antiguos, pero en uno actual no hace prácticamente nada. La sintaxis de expl3 en sí —\ExplSyntaxOn, \cs_new:Npn, las variables tipadas de l3kernel— tiene página propia.

Formatos distintos de LaTeX

LaTeX es el formato más extendido, pero no el único. De las 54 filas de fmtutil.cnf, solo unas pocas son de LaTeX; el resto son otros sistemas de macros. amstex merece aquí una mención. Como ejecutable, amstex no es más que un enlace simbólico a pdftex, y la línea amstex pdftex - *amstex.ini de fmtutil.cnf designa el motor pdfTeX cargado con las macros de AMS-TeX. AMS-TeX es el juego de macros de la American Mathematical Society para composición matemática, construido sobre plain TeX, y para quien usa LaTeX ha quedado sustituido en la práctica por el paquete amsmath. Empezar un documento nuevo en AMS-TeX apenas tiene sentido.

FormatoMotor que lo vuelcaQué es
textexEl plain TeX de Knuth: el único formato sin las extensiones e-TeX
latexpdftexLaTeX2e ejecutado por pdfTeX en modo DVI; emite un .dvi
pdflatexpdftexEl mismo LaTeX2e escribiendo PDF directamente; el estándar de facto para texto occidental
xelatexxetexLaTeX2e sobre el motor XeTeX; fuentes del sistema y Unicode
lualatexluahbtexLaTeX2e sobre LuaHBTeX; con scripting en Lua y modelado HarfBuzz
platex / uplatexeuptexLaTeX2e para composición japonesa; emite DVI, convertido a PDF por dvipdfmx
amstexpdftexAMS-TeX, macros matemáticas sobre plain TeX; sustituido por amsmath para usuarios de LaTeX
cont-enpdftex / xetexConTeXt (MkII), formato completo independiente de LaTeX; registrado para dos motores
csplainpdftexDerivado de plain TeX para checo y eslovaco; construido con un -etex explícito

pLaTeX y upLaTeX: el formato LaTeX para japonés

pLaTeX y upLaTeX colocan el formato LaTeX sobre motores creados para la composición japonesa. La escritura vertical, los ruby (furigana) y la composición de líneas japonesas corren a cargo de la familia de motores pTeX, extendida originalmente en ASCII Corporation. En el fmtutil.cnf de TeX Live 2024, tanto platex como uplatex están registrados frente al motor euptex; lo que los separa es el archivo de inicialización del formato (*platex.ini frente a *uplatex.ini). La diferencia, pues, no está en el ejecutable sino en cómo el formato trata los caracteres: platex conserva el comportamiento tradicional compatible con pTeX, mientras que uplatex supone Unicode internamente. Para un documento japonés nuevo, uplatex es la elección estándar.

Esta familia siempre emite DVI, y el DVI con japonés se convierte a PDF con dvipdfmx: una cadena en dos pasos (uplatex file.tex y luego dvipdfmx file.dvi). Para el índice se le suma upmendex. Como clases de documento son habituales jsarticle y jsbook de Haruhiko Okumura (para pLaTeX) y sus equivalentes Unicode como ujarticle, así como el más reciente jlreq, conforme a los requisitos de composición japonesa de la norma JIS X 4051. Los detalles internos de los motores —métricas JFM, reglas de corte kinsoku, implementación de la escritura vertical— corresponden a la página «familia pTeX».

Qué comando corresponde a qué combinación

Aun con el mismo formato LaTeX, el nombre del comando fija el motor subyacente, el formato de salida y el tratamiento de las fuentes. Lea la tabla siguiente partiendo del nombre del comando, de izquierda a derecha. En la práctica, la columna de la derecha es la que más pesa: que fontspec esté disponible o no coincide directamente con la elección del motor.

ComandoMotorSalidaUnicode / fuentes del sistema
latexpdfTeX en modo DVIDVI — requiere un paso de conversión aparteNo; se apoya en inputenc y afines
pdflatexpdfTeXPDF directamenteNo; se apoya en inputenc y afines
platexe-upTeX con ajustes compatibles con pLaTeXDVI y luego dvipdfmxJaponés mediante la configuración de fuentes tradicional
uplatexe-upTeXDVI y luego dvipdfmxUnicode internamente; fuentes japonesas aún a la manera tradicional
lualatexLuaHBTeXPDF directamenteSí — fontspec y luatexja
xelatexXeTeXPDF, internamente a través de xdvipdfmxSí — fontspec
terminal
# Engines that write PDF finish in one step.
$ pdflatex main.tex      # -> main.pdf
$ lualatex main.tex      # -> main.pdf
$ xelatex  main.tex      # -> main.pdf

# DVI-based routes add a conversion step.
$ latex    main.tex      # -> main.dvi   (pdfTeX in DVI mode)
$ uplatex  main.tex      # -> main.dvi   (Japanese)
$ dvipdfmx main.dvi      # -> main.pdf

Leer la primera línea del registro y fijar la combinación

La primera línea del registro nombra a la vez el motor y el formato. Descomponga This is pdfTeX, Version 3.141592653-2.6-1.40.26 (TeX Live 2024) (preloaded format=latex): la primera mitad es el motor y su versión, y (preloaded format=...) es el formato cargado. This is LuaHBTeX ..., This is XeTeX ... y This is e-upTeX ... se leen igual. Cuando un colaborador informa de «mismo comando, salida distinta», comparar esa única línea separa de inmediato un problema de configuración del editor de una diferencia de año de TeX Live o de formato.

Y una vez fijada la combinación, anótela en el proyecto y congélela. En una tesis, en cuanto portada, índice, figuras, tablas y bibliografía compilen bien, registre el comando en el README o en .latexmkrc. Pasar un documento de lualatex a uplatex a mitad de camino cambia de golpe la selección de fuentes, el tratamiento del japonés, la ruta hacia el PDF y a menudo el procesamiento bibliográfico. Si hay que cambiar, verifique todas las funciones en un pequeño archivo de prueba antes de volver al manuscrito real. Los criterios de elección —velocidad, compatibilidad de paquetes, la situación del japonés— están reunidos en la página «Elegir un motor».