La mayoría de las órdenes de TeX Live no componen un documento. Lo leen. texdef muestra cómo está definida realmente una orden; chktex y lacheck señalan los tics del archivo fuente; texfot reduce un registro de mil líneas a un puñado; texcount cuenta palabras; texloganalyser extrae de un .log justo las líneas que hacen falta. Lo que de verdad consume tiempo al trabajar con LaTeX no es la composición sino averiguar por qué algo no funcionó, así que este rincón de la distribución compensa con creces la hora que cuesta aprenderlo. Abrir el manual de un paquete con texdoc corresponde a otra página; aquí va todo lo demás, y se cierra con Ghostscript para operar sobre el PDF terminado.
texdef: cómo está definida realmente esta orden
Cuando las redefiniciones chocan, lo más rápido para saber qué definición está vigente es preguntárselo al motor. Escribe latexdef \section y llega \long macro:->\@startsection {section}{1}{\z@ }{-3.5ex \@plus -1ex \@minus -.2ex}{2.3ex \@plus .2ex}{\normalfont \Large \bfseries }: el valor real, en tu instalación real. Para verlo con un paquete cargado, añade -p: latexdef -p amsmath \tfrac devuelve \genfrac {}{}{}1, y se ve al instante que \tfrac no es más que una envoltura fina alrededor de \genfrac. Dale un nombre que no existe y la respuesta es un seco undefined. El autor es Martin Scharrer; la versión incluida en TeX Live 2024 es la 1.9, con fecha 2020/09/27.
Aquí reaparece el mismo truco que en dvipdfmx. latexdef es un enlace simbólico a texdef, y el programa decide qué formato cargar según el nombre con el que lo invocaron: texdef significa plain TeX y latexdef significa LaTeX. Por eso un texdef \LaTeX pelado responde undefined, y no es un defecto. Lo mismo se puede decir explícitamente con -t latex o -t lualatex. Más útiles todavía son las opciones de localización. -F indica dónde se definió una orden: latexdef -p booktabs -F \toprule responde \toprule first defined in "/usr/local/texlive/2024/texmf-dist/tex/latex/booktabs/booktabs.sty". Y -l enumera las órdenes de usuario que ofrece un paquete, cómodo cuando quieres ver qué hay antes de abrir el manual.
latexdef \section # the definition in force right now
latexdef -p amsmath \tfrac # with a package loaded
latexdef -p booktabs -F \toprule # which file defined it
latexdef -p geometry -l # the user-level commands a package adds
latexdef -c beamer \frametitle # inside a different document classchktex y lacheck: dos analizadores que miran cosas distintas
Ambos atrapan la clase de problema en que el documento compila pero la página sale mal, y se especializan de forma distinta. chktex mira los hábitos tipográficos. El mismo archivo da reproches numerados como Warning 26 in lint.tex line 4: You ought to remove spaces in front of punctuation. y Warning 44 in lint.tex line 5: User Regex: 1:Capitalize before references., cada uno con un ^ bajo la columna culpable. Numerado significa silenciable: si estorba la regla 18, que pide sustituir la comilla doble recta por comillas propias de TeX, chktex -n18. lacheck mira la correspondencia estructural. Cuando entornos, llaves o delimitadores matemáticos no casan, muestra ambos extremos con sus números de línea, emparejados como <- y ->. Con un archivo roto a propósito imprimió "broken.tex", line 5: <- unmatched "\end{enumerate}" seguido de inmediato por "broken.tex", line 3: -> unmatched "\begin{itemize}": antes que el motor, y en una forma mucho más legible.
Si los metes en integración continua, una diferencia es decisiva. lacheck devuelve código de salida 0 sea lo que sea que encuentre. El archivo roto de arriba —dos entornos descuadrados y una fórmula sin cerrar— dio igualmente 0. No sirve para condicionar una compilación: hay que capturar su salida estándar y juzgar por cuenta propia. chktex -q, en cambio, devolvió 2 en cada ejecución que imprimió advertencias y 0 con un archivo limpio. Ese sí sirve de barrera. Una nota más: el chktex de esta compilación de TeX Live 2024 para macOS está construido con expresiones regulares extendidas POSIX, y una de sus reglas por omisión usa una anticipación al estilo Perl, así que cada ejecución empieza con una línea que arranca por chktex: WARNING -- Compilation of regular expression. No hace daño, pero enseñar a tu registro de CI a ignorarla mantiene la calma.
chktex -q paper.tex # exit 2 when it prints warnings, 0 when clean
chktex -q -n18 -n26 paper.tex # mute the quotation-mark and punctuation rules
lacheck paper.tex # unmatched groups, shown as a <- and -> pair
lacheck paper.tex | tee lacheck.out # its exit code is always 0, so read thisPara captar el carácter de estas herramientas, merece la pena leer la sección BUGS de la página de manual de lacheck. Admite que el programa se confunde con las macros avanzadas y lo engañan las sencillas, que no le gusta TeX y que no ofrece modo alguno de desactivar avisos concretos, y se describe a sí mismo como «at best a crude approximation». Quizá sea esa franqueza la razón de que una herramienta pequeña, escrita por Kresten Krab Thorup a principios de los noventa y modificada por Per Abrahamsen, siga distribuyéndose hoy con TeX Live. chktex también sigue arrancando con el cartel Copyright 1995-96 Jens T. Berger Thielemann. Herramientas de casi treinta años que aún hacen observaciones útiles sobre un manuscrito escrito hoy: esa es también la velocidad del mundo LaTeX.
texfot: convertir 24 líneas de registro en 4
La razón de que nadie lea la salida de TeX es simple: hay demasiada. texfot lanza el motor en tu lugar y deja pasar solo las líneas que merecen atención. Aquí, un documento de una página con lipsum hizo desfilar 24 líneas bajo pdflatex pelado; la misma ejecución bajo texfot pdflatex produjo 4. Sobrevivieron la línea de versión del motor, Overfull \hbox (122.18651pt too wide) detected at line 4 y Output written on over.pdf (1 page, 19010 bytes). Tampoco se descarta nada: la salida completa sin filtrar se duplica a un archivo temporal, así que se puede leer después si hace falta —--tee= cambia el destino y --tee=/dev/null lo desactiva—. El código de salida se transmite tal cual desde el motor, de modo que colarlo en latexmk o en CI no rompe nada: en un documento con error devolvió 1, exactamente como el pdflatex pelado. El autor es Karl Berry.
texfot pdflatex paper.tex
# texfot: invoking: pdflatex paper.tex
# This is pdfTeX, Version 3.141592653-2.6-1.40.26 (TeX Live 2024)
# Overfull \hbox (122.18651pt too wide) detected at line 4
# Output written on paper.pdf (1 page, 19010 bytes).
texfot --tee=/dev/null lualatex paper.tex # do not keep the full copy
# .latexmkrc: wrap the engine
$pdflatex = 'texfot pdflatex %O %S';texcount y texloganalyser: contar palabras, excavar el registro
Cuando una convocatoria dice «no más de 8.000 palabras de texto», wc -w no sirve: cuenta \usepackage y cada nombre de macro. texcount —TeXcount 3.1.1, de octubre de 2018— entiende la sintaxis de LaTeX y cuenta en consecuencia, informando por separado del cuerpo, los títulos y los pies, hasta llegar al número de fórmulas. Con -brief todo se reduce a una línea como 2+0+0 (0/0/0/0) File: over.tex. La otra herramienta, texloganalyser (Thomas van Oudenhove, version 0.11, licencia BSD), excava un .log ya escrito: -o extrae solo las cajas overfull, -r solo los avisos de referencias cruzadas, -i las imágenes cargadas, -s los archivos .sty y .cls empleados. Donde texfot filtra mientras el motor corre, este cava en el registro terminado; no se solapan, así que tener ambos no cuesta nada.
texcount -brief paper.tex # words in text + headers + captions
texcount -inc -sum paper.tex # follow \input and \include, one total
texloganalyser -o paper.log # only the overfull boxes
texloganalyser -r paper.log # only the reference warnings
texloganalyser -s paper.log # which .sty and .cls were actually loadedGhostscript: unir PDF y cuándo la «compresión» no hace nada
gs es el intérprete de PostScript y PDF, y también es lo que ps2pdf ejecuta por debajo. Dale -sDEVICE=pdfwrite y escribirá PDF, lo que resuelve en una línea la conversión desde PostScript, la unión de varios PDF y la extracción de páginas. Unir es lo más sencillo: basta con enumerar las entradas en orden. Aquí, un PDF de 7.940 bytes y otro de 6.865 se convirtieron en un solo volumen de 12.543 bytes. Ten en cuenta que gs no forma parte de TeX Live; es el Ghostscript que MacTeX y similares instalan aparte, y aquí en la versión 10.03.0.
gs -q -sDEVICE=pdfwrite -dNOPAUSE -dBATCH \
-sOutputFile=merged.pdf front.pdf body.pdf
gs -q -sDEVICE=pdfwrite -dNOPAUSE -dBATCH \
-dFirstPage=3 -dLastPage=8 -sOutputFile=extract.pdf paper.pdf
gs -q -sDEVICE=pdfwrite -dPDFSETTINGS=/ebook -dNOPAUSE -dBATCH \
-sOutputFile=small.pdf big.pdfConviene corregir aquí una afirmación muy extendida. -dPDFSETTINGS no es un interruptor que comprima un PDF. Lo que esos preajustes gobiernan sobre todo es la política de remuestreo de imágenes, con el suelo de resolución subiendo de /screen a /ebook, /printer y /prepress. Un documento sin imágenes de mapa de bits no tiene, por tanto, nada que encoger. En la prueba de aquí, un PDF de solo texto de 6.865 bytes salió con 7.310 usando /screen, 7.309 con /ebook, 7.302 con /prepress y hasta 9.869 con /printer: los cuatro mayores que el original, porque lo único que queda es el sobrecoste de reconstruir el archivo. La opción se gana el sueldo en documentos repletos de fotografías y escaneos. Y en todos los casos, comprueba con la vista antes y después: fuentes incrustadas, enlaces, marcadores y tamaño de página. pdfwrite reconstruye el PDF, y en el proceso puede perderse información invisible.
Qué orden responde a cada pregunta
| Orden | La pregunta que responde |
|---|---|
latexdef NAME | Cómo está definida ahora esta orden y, con -F, qué archivo la definió |
chktex -q | ¿Tiene el fuente malas costumbres tipográficas? Devuelve un estado apto para condicionar la CI |
lacheck | ¿Casan bien entornos y llaves? Pero el código de salida es siempre 0 |
texfot ENGINE FILE | De todo el registro de esta ejecución, qué puñado de líneas importa de verdad |
texcount -brief | Cuántas palabras de texto hay, sin contar macros ni \usepackage |
texloganalyser -o | Extraer de un .log existente solo las cajas overfull o los avisos de referencias |
gs -sDEVICE=pdfwrite | Unir PDF, extraer páginas o aligerar un PDF cargado de imágenes |