Basta un ls -l dentro de una instalación de TeX Live 2024 para llevarse la primera sorpresa: latex, el comando de compilación de LaTeX que todo el mundo aprende primero, no es un programa. Es un enlace simbólico a pdftex, y otros diecinueve nombres —entre ellos pdflatex, etex, xmltex y amstex— apuntan a ese mismo archivo. Qué comando se escribe sigue importando muchísimo, pero no por la razón que casi todos suponen: el nombre no elige un programa distinto, elige un archivo de formato distinto, y a veces toda la diferencia entre dos comandos se reduce a un único número entero. Esta página recorre los comandos que de verdad se teclean —pdflatex, xelatex, lualatex, latex con dvipdfmx y las rutas CJK platex y uplatex—, además del puñado de opciones que conviene memorizar y de cómo leer la consola cuando una compilación falla.
Cómo compilar un archivo .tex y qué deja tras de sí la compilación
Basta una línea: pdflatex document.tex produce document.pdf. La extensión .tex es opcional y las opciones van siempre antes del nombre del archivo. Ahora bien, lo que se obtiene no es solo el PDF. Junto a él aparecen dos archivos más: document.aux, un libro de cuentas que acumula datos de referencias cruzadas y del índice, y document.log, una transcripción completa con todo lo que pasó por la pantalla y bastante más. Ambos son intermedios prescindibles, pero el primero es el que decide qué ocurre a continuación.
pdflatex document.tex # -> document.pdf, document.aux, document.log
lualatex document # the .tex extension is optional
xelatex -synctex=1 document.tex # options come before the file namePor culpa de ese archivo .aux, un comando de compilación normalmente hay que ejecutarlo dos veces. LaTeX lee el documento una sola vez, de principio a fin, así que cuando compone el índice en la página uno todavía no sabe en qué página caerá la sección 7. La primera pasada escribe en .aux los números que ha averiguado; la segunda los lee de vuelta y los coloca en el texto. La bibliografía y el índice alargan aún más ese ida y vuelta. Cómo decide LaTeX que el bucle ya se ha estabilizado, y cómo lo automatiza latexmk, corresponde a la página de compilación automática. Aquí tratamos los comandos que se invocan dentro de ese bucle.
latex frente a pdflatex: la diferencia es un entero
latex produce .dvi y pdflatex produce .pdf, pero el binario que se ejecuta por debajo es el mismo archivo. En TeX Live 2024 ambos enlaces resuelven a pdftex, y latex --version se presenta sin ningún reparo como pdfTeX 3.141592653-2.6-1.40.26 (TeX Live 2024). La diferencia no está en el programa, sino en el archivo de formato que carga cada nombre. pdflatex.ini incluye pdftexconfig.tex, donde se fija \pdfoutput = 1. latex.ini incluye ese mismísimo archivo y acto seguido lo sobrescribe con \pdfoutput=0. Reducido al hueso, ese único entero es lo que separa a los dos comandos.
# TeX Live 2024: four commands, three binaries
readlink $(which latex) $(which pdflatex) $(which xelatex) $(which lualatex)
# pdftex
# pdftex
# xetex
# luahbtex
latex --version
# pdfTeX 3.141592653-2.6-1.40.26 (TeX Live 2024)¿Cómo sabe entonces un mismo binario qué formato cargar? Mira el nombre con el que se le ha invocado. El texto de ayuda de pdfTeX lo dice sin rodeos: busca NAME.fmt, donde NAME es el nombre de invocación del programa. Basta renombrar el enlace para arrancar un LaTeX distinto. Para anular esa suposición se pasa -fmt=NAME o -progname=NAME, o se coloca una línea %&format justo al principio del archivo fuente. Ese mismo truco es lo que permite colgar veinte nombres distintos de un único ejecutable pdftex.
\pdfoutput no es solo un ajuste del momento de construir el formato: es una primitiva de pdfTeX viva durante la ejecución. Basta poner \pdfoutput=0 en la primerísima línea del archivo, antes de \documentclass, para que incluso una ejecución de pdflatex devuelva un .dvi. En la práctica la vía limpia es la línea de comandos: -output-format=dvi o -output-format=pdf, aceptadas tanto por pdfTeX como por LuaTeX (solo XeTeX carece de ellas y usa -no-pdf en su lugar). El propio LaTeX lee además ese valor y cambia en consecuencia el tratamiento de las figuras: en modo DVI carga l3backend-dvips.def y en modo PDF l3backend-pdftex.def. Esa es exactamente la razón de que una ruta acepte figuras .eps y la otra .pdf y .png.
pdflatex, xelatex o lualatex: elegir por fuentes y Unicode
Basta un criterio. Si el documento es de escritura latina y se busca velocidad y la máxima compatibilidad de paquetes, pdflatex. En cuanto haga falta nombrar una fuente ya instalada en el sistema operativo, o componer caracteres fuera del ámbito latino, se pasa a xelatex o lualatex. Los tres emiten PDF y aceptan el mismo .tex; lo que cambia por completo es la puerta por la que entran las fuentes.
¿Por qué se multiplicaron así los comandos? La historia lo explica en línea recta. Knuth empezó a escribir TeX en 1978, y su formato de salida era DVI —device-independent— porque el PDF, que Adobe presentó en 1993, todavía no existía. pdfTeX es la extensión que cerró esa brecha. Su autor, Hàn Thế Thành, trabajaba en su doctorado sobre microtipografía: dejar que los caracteres sobresalgan mínimamente del margen derecho y estirar los anchos de los glifos de forma imperceptible para igualar el gris de la página. De ese mismo trabajo salió la escritura directa de PDF, sin DVI de por medio. Que pdflatex sea hoy el más rápido y el que la mayoría de paquetes da por supuesto se debe simplemente a que lleva más tiempo en uso.
xelatex ejecuta XeTeX, desarrollado por Jonathan Kew hacia 2004. Con el paquete fontspec basta nombrar una fuente OpenType instalada en el sistema operativo para usarla. XeTeX, sin embargo, no escribe PDF directamente: produce .xdv, una forma extendida de DVI, y se lo entrega a xdvipdfmx, que genera el PDF. -no-pdf detiene la ejecución en la etapa .xdv, y -output-driver=CMD permite sustituir el propio conversor. Que XeTeX sea el único de los tres sin opción -output-format se sigue directamente de esta arquitectura.
En lualatex hay un giro. En TeX Live 2024 el enlace no lleva a luatex, sino a luahbtex: LuaTeX con la biblioteca de conformado HarfBuzz incorporada, que es justo lo que permite componer correctamente sistemas de escritura con reglas de conformado complejas, entre ellos el árabe y las escrituras índicas. El luatex a secas sigue existiendo; es al que apunta el dvilualatex del que se habla más abajo. El rasgo estrella de LuaTeX está en su nombre: un intérprete Lua integrado que permite al documento intervenir en el corte de líneas, la carga de fuentes y otros mecanismos internos del compositor. Al alinear aquí los números de versión aparece algo curioso. tex --version informa TeX 3.141592653: Knuth numera TeX añadiendo una cifra más de pi en cada actualización, y tanto pdfTeX como XeTeX heredan ese prefijo tal cual. Solo LuaTeX se apeó de la tradición y se llama Version 1.18.0.
| Comando | Binario (TeX Live 2024) | Salida | Fuentes y caracteres |
|---|---|---|---|
pdflatex | pdftex | Fuentes TeX; el más rápido y compatible | |
xelatex | xetex | PDF (vía .xdv internamente) | Fuentes OpenType del sistema con fontspec |
lualatex | luahbtex | Fuentes del sistema + conformado HarfBuzz + scripts Lua | |
latex | pdftex | DVI | Fuentes TeX; la vía para figuras EPS y PSTricks |
dvilualatex | luatex | DVI | Funciones de LuaTeX cuando se exige salida DVI |
platex | euptex | DVI | Japonés; internos EUC, limitado a JIS X 0208 |
uplatex | euptex | DVI | Japonés; internos Unicode, incluidos caracteres raros |
latex y luego dvipdfmx: por qué sobrevive la ruta DVI
Siguen valiendo dos razones. La primera: hay maquinaria que solo habla DVI; los paquetes que dibujan a través de PostScript, con PSTricks a la cabeza, rinden al máximo en la ruta de latex a dvips. La segunda: la composición japonesa, tema de la sección siguiente, ha viajado tradicionalmente por aquí. latex document.tex escribe document.dvi, y dvipdfmx document.dvi lo convierte en PDF; si hace falta PostScript, se recurre a dvips. Para el deseo menos frecuente de usar funciones de LuaTeX y obtener aun así DVI existe dvilualatex, que apunta al luatex simple, sin HarfBuzz.
latex document.tex # -> document.dvi
dvipdfmx document.dvi # -> document.pdf
dvips document.dvi # -> document.ps (for PSTricks and friends)Comandos CJK: platex, uplatex y las alternativas
El japonés tiene comandos propios porque su composición tiene reglas propias: escritura vertical, las prohibiciones kinsoku sobre qué caracteres pueden abrir o cerrar una línea, y el hueco fijo que corresponde entre texto japonés y latino. pTeX incorporó esas reglas al propio motor en lugar de a las macros, y LaTeX ejecutándose encima es pLaTeX, el comando platex. La primera línea del archivo de formato platex.ini sigue diciendo “for pLaTeX (ASCII Nihongo LaTeX)”, huella de su origen en ASCII. upTeX, de Takuji Tanaka, extiende pTeX para que su código interno de caracteres sea Unicode completo; LaTeX sobre eso es upLaTeX, el comando uplatex. Ambos escriben siempre DVI y nunca PDF directamente.
La misma sorpresa se repite aquí. En TeX Live 2024, platex y uplatex son ambos enlaces a un único binario, euptex, y ptex, eptex y uptex confluyen igualmente en él. Lo que los separa es la codificación interna de kanji. platex --version imprime e-upTeX 3.141592653-p4.1.1-u1.30-230214-2.6 (utf8.euc), mientras que uplatex --version termina en (utf8.uptex). Es decir, un solo ejecutable que conmuta -kanji-internal según el nombre con el que se le llama. pLaTeX se comporta como el pTeX clásico con internos EUC, de modo que los caracteres que maneja se quedan en general dentro de JIS X 0208; upLaTeX es Unicode por dentro y deja pasar sin más los kanji raros de nombres propios y el conjunto completo de ideogramas unificados CJK. Esa única diferencia explica que uplatex sea la opción por defecto para un documento japonés nuevo. La unificación es bastante reciente y está fechada con precisión: la guía oficial de pTeX que se distribuye con TeX Live consigna que platex funcionó sobre e-pTeX desde TeX Live 2012 hasta 2022 y que el 2023-06-01 pasó a e-upTeX en lo que la guía llama legacy-encoding-compatibility mode. Las primitivas adicionales de upTeX quedaron así al alcance de pLaTeX, mientras que el código interno de los caracteres japoneses se dejó a propósito sin pasar a Unicode para conservar la compatibilidad hacia atrás.
La codificación interna y la del archivo de entrada son dos cosas distintas. La entrada se fija con -kanji=STRING, que admite euc, jis, sjis, utf8 o uptex. Las versiones recientes de TeX Live usan UTF-8 por defecto, así que a menudo puede omitirse, pero declararlo mantiene estable la compilación cuando cambia el entorno. Para que el UTF-8 sin BOM pase de forma fiable, se añade -no-guess-input-enc, que desactiva por completo la adivinación de la codificación. La salida es DVI, de modo que dvipdfmx remata el trabajo.
# Japanese, the traditional route: typeset -> DVI -> PDF
uplatex -kanji=utf8 -no-guess-input-enc document.tex # -> document.dvi
dvipdfmx document.dvi # -> document.pdfEl chino y el coreano no usan esa ruta en absoluto. Ambos se confían normalmente a un motor nativo en Unicode: para el chino, xelatex o lualatex con el paquete ctex (que por debajo llama a xeCJK y compañía); para el coreano, esos mismos motores con kotex. El japonés dispone de la misma opción: al cargar luatexja bajo lualatex, el PDF sale directamente. Por ese camino -kanji deja de hacer falta, porque un motor que es Unicode de principio a fin no tiene codificación interna que conmutar.
Las opciones que merece la pena escribir: -interaction=nonstopmode, -halt-on-error, -output-directory
Las opciones van siempre delante del nombre del archivo, y las siguientes valen para cualquiera de los comandos de pdfTeX, XeTeX y LuaTeX. Cuatro se ganan el sueldo a diario: -synctex=1 para la integración con el editor, -interaction=nonstopmode para que una ejecución no se quede parada, -halt-on-error para lo contrario, abandonar al primer problema, y -file-line-error para dejar el mensaje en una forma que una máquina pueda analizar.
| Opción | Qué hace |
|---|---|
-synctex=1 | Escribe document.synctex.gz y habilita los saltos entre editor y PDF |
-interaction=nonstopmode | Llega hasta el final en vez de esperar entrada ante un error; batchmode además silencia la terminal |
-halt-on-error | Abandona al primerísimo error; no se produce PDF |
-file-line-error | Reescribe la cabecera del mensaje como ./document.tex:3:, que IDE y CI pueden analizar |
-output-directory=DIR | Escribe la salida y los archivos auxiliares en DIR; DIR debe existir de antemano |
-jobname=NAME | Fija el nombre base, antes de la extensión, de todos los archivos de salida |
-draftmode | Se ejecuta sin escribir el PDF (pdfTeX / LuaTeX); útil para pasadas intermedias que solo fijan referencias |
-output-format=FORMAT | Elige dvi o pdf (solo pdfTeX y LuaTeX; XeTeX usa -no-pdf) |
-shell-escape | Levanta toda restricción sobre la ejecución de comandos externos mediante \write18 (leer la advertencia siguiente) |
pdflatex -synctex=1 -interaction=nonstopmode -halt-on-error -file-line-error document.tex
mkdir -p build # -output-directory will NOT create it for you
pdflatex -output-directory=build document.tex-output-directory esconde una trampa con la que tropiezan constantemente las tuberías de CI: el directorio que se indica tiene que existir ya. El propio texto de ayuda de pdfTeX lo dice: usa un DIR existente. Si falta, la ejecución anuncia “Please type another transcript file name” y acaba con ! Emergency stop y “Fatal error occurred, no output PDF file produced!”. Como la causa no tiene nada que ver con la composición, hasta quien lee logs de LaTeX con soltura pierde un instante ahí. Un mkdir -p en la línea anterior lo resuelve todo.
-shell-escape: por qué lo necesita minted y por qué es peligroso
Esta opción concede al documento el derecho a ejecutar comandos de shell arbitrarios en tu máquina. Aun así, los comandos externos no están del todo cerrados por defecto. TeX Live funciona en un modo restringido y cada ejecución imprime la línea restricted \write18 enabled.. En ese estado, \write18 solo puede llamar a programas incluidos en una lista de permitidos dentro de texmf.cnf, y en TeX Live 2024 esa lista es corta: bibtex, bibtex8, extractbb, gregorio, kpsewhich, makeindex, memoize-extract.pl, memoize-extract.py, repstopdf, r-mpost, texosquery-jre8. Que la bibliografía y el índice funcionen sin opción alguna se debe precisamente a que esas dos entradas están permitidas de origen.
pygmentize no está en esa lista. texmf.cnf lo deja fuera a propósito, con un comentario que cuestiona si su función de filtro es segura. minted, que colorea listados de código, llama justamente a ese programa: no funciona en modo restringido y la única salida es -shell-escape completo. Y completo es literal: un .tex recibido de otra persona puede, en esa única compilación, borrar archivos, enviar fuera datos locales o instalar algo. La regla puede quedarse simple — activarlo solo para documentos escritos por uno mismo, en un directorio bajo control propio. Nunca para una plantilla descargada ni para un envío llegado para revisión.
# minted calls pygmentize, which the restricted allow-list does not include
pdflatex -shell-escape document.tex
# turn it off explicitly when compiling a file you did not write
pdflatex -no-shell-escape untrusted.texLeer la salida de consola cuando falla una compilación
Hay que leer desde la primera línea que empieza por !, no desde el final. Los errores de LaTeX se encadenan, así que lo que queda en pantalla al final suele ser daño colateral provocado por el primero; la causa está más arriba. Todo informe de error tiene la misma forma: la línea con ! nombra el síntoma y la línea de debajo que empieza por l. señala el lugar.
! Missing $ inserted.
<inserted text>
$
l.3 Some text with a bare x^
2 here.
?La línea que importa es l.3. Significa línea 3 del fuente, pero se imprime partida en dos justo en el punto hasta el que TeX había leído. Todo lo anterior al corte quedó consumido; todo lo posterior aún no se ha leído. Aquí el corte cae inmediatamente después de x^, así que el carácter de superíndice queda señalado como culpable a simple vista. ! Undefined control sequence. sigue el mismo patrón, y el comando mal escrito que queda justo antes del corte es ya la respuesta. El ? final es un indicador de entrada: la ejecución se ha detenido en el errorstopmode por defecto y espera. Enter continúa; escribir x aborta.
Ese diálogo es justo lo que scripts y CI no quieren, y para eso están los modos de interacción. -interaction=nonstopmode imprime todo sin detenerse, batchmode además silencia la terminal y scrollmode solo pregunta cuando no encuentra un archivo. Si en cambio se quiere ver únicamente el primer problema, -halt-on-error cierra la ejecución con ! Emergency stop. y “Fatal error occurred, no output PDF file produced!”. Añadir -file-line-error reescribe la cabecera como ./document.tex:3: Missing $ inserted., que editores y CI convierten en un enlace pulsable. Se elija lo que se elija, la transcripción completa acaba siempre en .log: si se pasa por alto en la terminal, el mismo texto espera en ese archivo.
Qué comando de compilación conviene usar
- Un documento en escritura latina —
pdflatex. El más rápido y el valor por defecto que la mayoría de paquetes da por hecho. - Quieres nombrar una fuente del sistema operativo —
xelatexolualatex; ambos lo hacen a través defontspec. - Escrituras de conformado complejo, o programar el propio compositor —
lualatex(en realidadluahbtex, con HarfBuzz incluido). - Un documento japonés nuevo —
uplatexy luegodvipdfmx, olualatexconluatexja. - Chino o coreano —
xelatexolualatexconctexokotex; sin ninguna etapa DVI. - PSTricks y demás maquinaria que solo entiende DVI —
latexy luegodvipsodvipdfmx.
Una última costumbre de diagnóstico. Cuando falla el botón de compilar del editor, escribe primero el mismo comando a mano en una terminal. Si allí funciona, el problema está en la configuración del editor y no en el documento. Antes de entregar un archivo a alguien o meterlo en CI, conviene una ejecución con -halt-on-error -file-line-error -interaction=nonstopmode para que la posición del primer error real quede legible. Y en el día a día casi nadie escribe estos comandos dos veces a mano: el trabajo se delega en latexmk, que cuenta las pasadas y llama a dvipdfmx por ti. Cómo sabe cuándo parar es el tema de la página de compilación automática.