Corrección (proofread)

Si alguna vez le han devuelto un comentario del tipo «página 12, tercer párrafo, cuarta línea», ya sabe qué necesita antes que nada la corrección en LaTeX: números de línea, del paquete lineno. Muchas revistas exigen un original con líneas numeradas ya en el envío, y con números al margen un comentario cuesta una sola palabra: «L412». Esta página recorre un ciclo de corrección completo: numerar las líneas, clavar tareas al margen, colorear por autor las intervenciones de cada coautor, usar latexdiff para enseñar qué ha cambiado desde el borrador anterior y soltar tres analizadores —chktex, lacheck y nag— sobre la fuente. Cada paso viene acompañado de la salida de una ejecución real.

Numerar las líneas de una copia de revisión: el paquete lineno

Cargue \usepackage{lineno}, escriba \linenumbers y, a partir de ahí, cada línea de texto corrido recibe un número en el margen izquierdo. Las opciones cambian la presentación: modulo numera solo una de cada cinco líneas, lo que calma el margen; pagewise reinicia la cuenta en 1 en cada página; switch coloca los números en el margen exterior en trabajos a doble cara. \nolinenumbers los desactiva y el entorno linenumbers numera un tramo. Numerar solo una parte del documento —el cuerpo pero no el apéndice, por ejemplo— es una exigencia cotidiana.

latex
\usepackage[modulo]{lineno}   % number every 5th line only
% \usepackage[pagewise]{lineno} % restart the count on each page
% \usepackage[switch]{lineno}   % outer margin, for twoside
\linenumbers
...
\nolinenumbers                % stop numbering (e.g. before the appendix)

He aquí la trampa que descarrila una conversación de revisión. Por defecto, las fórmulas aparte no se numeran. Medido en un documento con una equation y un align de amsmath, el texto corrido corrió 1, 2, 3, saltándose de largo las matemáticas. Añada \usepackage[mathlines]{lineno} al mismo documento y la cuenta va de 1 a 6, con número también en cada línea de cada fórmula. Dicho de otro modo, que mathlines esté puesto cambia adónde apunta «L4»; y si revisor y autor miran PDF compilados con ajustes distintos, la discusión no encajará. En un original cargado de fórmulas, activar mathlines es lo más seguro.

Opción u ordenEfecto
\linenumbersempezar a numerar el texto corrido desde aquí
\nolinenumbersdetener la numeración (justo antes del apéndice, por ejemplo)
moduloimprimir número solo cada cinco líneas
pagewisereiniciar la cuenta en 1 en cada página
switchcolocar los números en el margen exterior a doble cara
mathlinesnumerar también las líneas de las fórmulas aparte (desactivado por defecto)

lineno es una herramienta antigua, que se remonta a 1995; la versión incluida en TeX Live 2024 es la v5.3, del 20 de mayo de 2023. El aviso de copyright de la cabecera del paquete alinea tres generaciones de mantenedores: Stephan I. Böttcher para 1995–2003, Uwe Lück para la serie 4.x y Karl Wette, que tomó el relevo de la serie 5.x en 2021. Treinta años de trabajo de compatibilidad dejan huella, y el paquete no siempre encaja limpiamente con los demás. El orden de carga puede importar, así que si los números se niegan a aparecer, pruebe a cargar lineno en último lugar.

Cómo usar latexdiff: enseñarle a un coautor qué ha cambiado

Ejecute latexdiff old.tex new.tex > diff.tex y compile el diff.tex resultante con pdflatex como de costumbre. Ese es todo el procedimiento, y produce un PDF en el que lo añadido y lo suprimido se distinguen a la vista. En una ejecución real, latexdiff va enhebrando marcadores —\DIFaddbegin, \DIFadd{...}, \DIFdelbegin, \DIFdel{...}— por la prosa y añade al preámbulo \RequirePackage[normalem]{ulem} y definiciones de color. Lo que lo convierte en la herramienta más valiosa de todo el equipo de corrección es que le ahorra a su interlocutor la tarea de leer LaTeX: la diferencia se ve en una página compuesta, no en un diff de git.

terminal
# the whole workflow
latexdiff old.tex new.tex > diff.tex
pdflatex diff.tex

# one file made of many \input files: flatten first
latexdiff --flatten old/main.tex new/main.tex > diff.tex

# diff straight against a git revision (produces main-diffHEAD~1.tex)
latexdiff-vc --git --flatten -r HEAD~1 main.tex

# a different visual style, e.g. bold instead of underline
latexdiff --type=CFONT old.tex new.tex > diff.tex

El aspecto por defecto es algo más concreto que la descripción habitual de «adiciones subrayadas, supresiones tachadas». La versión de TeX Live 2024 es la v1.3.3latexdiff --version se presenta como «(c) 2004-2022 F J Tilmann»— y el preámbulo que inyecta define \DIFadd como {\protect\color{blue}\uwave{#1}} y \DIFdel como {\protect\color{red}\sout{#1}}. Es decir: las adiciones son un subrayado ondulado azul y las supresiones, un tachado rojo. Ese ajuste tiene nombre, --type=UNDERLINE, y las alternativas son CTRADITIONAL, TRADITIONAL, CFONT, FONTSTRIKE, INVISIBLE, CHANGEBAR, CCHANGEBAR, CULINECHBAR, CFONTCHBAR, BOLD y PDFCOMMENT. Para un revisor que imprimirá en blanco y negro, FONTSTRIKE o BOLD se lee mucho mejor.

latex
% What latexdiff actually writes into diff.tex (excerpt of a real run):
\RequirePackage[normalem]{ulem}
\providecommand{\DIFadd}[1]{{\protect\color{blue}\uwave{#1}}}
\providecommand{\DIFdel}[1]{{\protect\color{red}\sout{#1}}}
...
The measured value was \DIFdelbegin \DIFdel{3.2}\DIFdelend
  \DIFaddbegin \DIFadd{3.4}\DIFaddend \,mm.

Hay dos situaciones en las que se gana el sueldo. Una es el envío revisado: muchas revistas piden, junto a la versión limpia, una versión marcada, y la salida de latexdiff es precisamente ese entregable. La otra es mandar borradores a los coautores. Para un documento repartido en varios ficheros, --flatten expande los \input antes de comparar, y latexdiff-vc --git --flatten -r HEAD~1 main.tex compara el árbol de trabajo directamente con un commit anterior y escribe main-diffHEAD~1.tex. Una advertencia: latexdiff trata el LaTeX como texto, no como sintaxis, de modo que los cambios dentro de tablas y figuras pueden romper el marcado. Cuando ocurra, añada la orden problemática a la lista segura con --append-safecmd o excluya el entorno con --exclude-textcmd.

Un color por coautor: el paquete changes

Mientras latexdiff compara dos versiones desde fuera, changes registra las ediciones dentro de la propia fuente. Se declaran los autores —\definechangesauthor[name={Ada Lovelace}, color=blue]{AL}— y luego se anota con \added[id=AL]{...}, \deleted[id=AL]{...}, \replaced[id=AT]{nuevo}{viejo} y \comment[id=AT]{...}. Añada \listofchanges y obtendrá una «List of changes»; en una ejecución real aparecieron Added (AL): ..., Replaced (AT): ..., Deleted (AL): ... y Commented (AT): ..., cada uno atribuido a su autor. La versión de TeX Live 2024 es la v4.2.1 (2021/07/15).

latex
\usepackage[markup=underlined]{changes}   % draft look; the default
\definechangesauthor[name={Ada Lovelace}, color=blue]{AL}
\definechangesauthor[name={Alan Turing},  color=orange]{AT}
\begin{document}
\listofchanges
The engine \added[id=AL]{weaves algebraical patterns} and
\replaced[id=AT]{computes}{calculates} the numbers.
\deleted[id=AL]{This sentence is redundant.}
\comment[id=AT]{Check the citation here.}

El gesto final importa. Cambie a \usepackage[final]{changes} y el paquete no se limita a ocultar el marcado: aplica las ediciones. En una ejecución real, el texto de \added se mantuvo, \replaced conservó solo la versión nueva y tanto la frase \deleted como el \comment desaparecieron, dejando la frase limpia «The engine weaves algebraical patterns and computes the numbers. Ordinary text.» Nunca hace falta, pues, borrar las órdenes a mano para producir una versión final. El corolario es que el PDF de antes y el de después no dicen lo mismo: recompile siempre en modo final y relea antes de enviar.

Clavar tareas al margen: todonotes y \todo

Un comentario escrito con % desaparece al compilar, así que su coautor nunca lo verá. todonotes existe para mantener las tareas en la salida. \todo{check this number} dibuja una nota adhesiva al margen, \todo[inline]{...} coloca una banda en el hilo del texto y \missingfigure{plot of the residuals} traza un recuadro que avisa de que aquí falta una figura. \listoftodos genera una «Todo list» al principio; en una ejecución real cada elemento aparecía allí con su número de página, de modo que se ve de un vistazo qué queda pendiente.

latex
\usepackage[textwidth=3cm]{todonotes}
% \usepackage[disable]{todonotes}   % final version: hides notes AND the list
\begin{document}
\listoftodos
Some text.\todo{check this number}
More text.\todo[inline,color=green!30]{rewrite this paragraph}
\missingfigure{plot of the residuals}

Para la versión final, sustituya por \usepackage[disable]{todonotes}. Medido, eso elimina las notas al margen, los recuadros \missingfigure y también la «Todo list» inicial, mientras las órdenes siguen en la fuente, de modo que quitar disable en la siguiente revisión devuelve todas las tareas. Esa es la diferencia decisiva con un comentario %: la nota se oculta, no se destruye. El riesgo es enviar con disable todavía puesto y que nadie advierta que quedan asuntos abiertos. Convierta «quitar disable una vez y leer \listoftodos» en un paso fijo justo antes del envío.

chktex y lacheck: cazar lo que pdflatex nunca menciona

Estos dos cazan errores tipográficamente malos pero perfectamente compilables, porque a pdflatex solo le importa que la pasada termine bien. Un caso concreto: pase la línea As shown in Fig. 1 and in Table \ref{tab:one}, see also \cite{knuth1984}. por pdflatex y lo único que obtendrá es LaTeX Warning: Reference 'tab:one' on page 1 undefined, un comentario sobre referencias cruzadas. Pase esa misma línea por chktex y este aviso salta dos veces:

terminal
$ chktex -q ref.tex
Warning 2 in ref.tex line 3: Non-breaking space (`~') should have been used.
As shown in Fig. 1 and in Table \ref{tab:one}, see also \cite{knuth1984}.
                               ^
Warning 2 in ref.tex line 3: Non-breaking space (`~') should have been used.
As shown in Fig. 1 and in Table \ref{tab:one}, see also \cite{knuth1984}.
                                                       ^

Aquí toca una rectificación. Suele decirse que chktex regaña por el ~ que falta en Fig. 1. Con la configuración de fábrica no lo hace. La comprobación del ~ —el aviso 2— vigila solo lo que figura bajo Linker en chktexrc: \ref, \vref, \pageref, \eqref y \cite. Una cadena desnuda como Fig. 1 queda fuera. Para que Fig. se detecte hay que añadirlo uno mismo a la lista Abbrev. Hecho eso y repetida la pasada sobre el mismo fichero, Warning 12 in ref.tex line 3: Interword spacing should perhaps be used. señala ahora a Fig.: la queja es que, si no, el punto recibirá el espacio ancho de fin de frase.

AvisoQué objetaQué lo dispara
2Non-breaking space (~) should have been used.un espacio normal ante Table \ref{...} o see \cite{...}
8Wrong length of dash may have been used.un solo - donde iba un intervalo o una raya
11You should use \ldots to achieve an ellipsis.teclear ... en vez de una orden de puntos suspensivos
12Interword spacing should perhaps be used.tras el punto de una abreviatura listada en Abbrev
18Use TeX quotes as an alternative to the straight double quote.usar la comilla recta "
26You ought to remove spaces in front of punctuation.un espacio dejado ante un signo de puntuación
29$\times$ may look prettier here.x usado como signo de multiplicación, como en 5x10^3
9'itemize' expected, found 'enumerate'.un entorno cerrado con otro nombre
terminal
# The messages exactly as chktex prints them (one run, one bad file):
Warning 18 in bad.tex line 4: Use either `` or '' as an alternative to `"'.
Warning 11 in bad.tex line 4: You should use \ldots to achieve an ellipsis.
Warning 26 in bad.tex line 4: You ought to remove spaces in front of punctuation.
Warning 29 in bad.tex line 5: $\times$ may look prettier here.
Warning  8 in bad.tex line 7: Wrong length of dash may have been used.
Warning  9 in mm.tex  line 5: `itemize' expected, found `enumerate'.

lacheck es mucho más parco y su papel resulta, por eso mismo, más nítido. Donde chktex vigila hábitos de escritura a golpe de expresiones regulares, lacheck comprueba la coherencia estructural del documento. Dele un fichero que cierre \begin{itemize} con \end{enumerate} y señalará ambos extremos por parejas: "mm.tex", line 5: <- unmatched "\end{enumerate}" y "mm.tex", line 3: -> unmatched "\begin{itemize}". chktex caza el mismo fallo como Warning 9, pero apunta solo al cierre. En un documento largo, cuando la pregunta es dónde se torció el anidamiento por primera vez, lacheck llega antes. La respuesta correcta es ejecutar los dos.

terminal
$ lacheck mm.tex
"mm.tex", line 5: <- unmatched "\end{enumerate}"
"mm.tex", line 3: -> unmatched "\begin{itemize}"

# chktex exits with the number of warnings, so CI can gate on it
$ chktex -q ref.tex >/dev/null; echo $?
2
# mute one check by number and it passes
$ chktex -q -n2 ref.tex >/dev/null; echo $?
0
# teach it your abbreviations via a local rc file
$ printf 'Abbrev { Fig. Eq. Sec. }\n' > my.chktexrc
$ chktex -q -l my.chktexrc ref.tex

Que chktex termine con el número de avisos en sí es lo que lo hace útil en integración continua. En la ejecución anterior, chktex -q ref.tex salió con 2 —dos avisos— y silenciar la comprobación número 2 con -n2 lo dejó en 0. Así, una política del tipo «toleramos exactamente esta comprobación» puede escribirse como configuración del repositorio. Los ajustes por proyecto van en un fichero cargado con -l my.chktexrc; en local se suprime con directivas dentro de la fuente como % chktex-file 26.

Reprender órdenes obsoletas y etiquetas sin usar: nag y refcheck

nag señala construcciones que todavía funcionan pero llevan décadas caducadas, y lo hace en tiempo de compilación. Coloque \RequirePackage[l2tabu,orthodox]{nag} antes de \documentclass, compile y el registro se llenará de quejas: Package nag Warning: Command \bf is an old LaTeX 2.09 command. seguido de Use \bfseries or \textbf instead on input line 5., luego $$...$$ is obsolete. Use \[...\] et al. instead, Command \centerline is TeX. Use \centering or center environment instead, Package epsf is obsolete. Use the graphicx package instead. y, para cerrar, Package nag Warning: 5 complaints in total. Se amortiza en cuanto hereda un original construido sobre una plantilla de hace décadas.

Otra herramienta que merece una pasada antes del envío es refcheck (v1.9.1 en TeX Live 2024). Añada \usepackage{refcheck}, compile dos veces y enumerará las etiquetas que nadie invoca: en una ejecución real produjo Package refcheck Warning: Unused label 'sec:unused' on input line 5. y Package refcheck Warning: Unused label 'eq:never' on input line 7. Una ecuación que lleva número pero nunca se cita suele ser una ecuación que no debería numerarse, y es lo primero que puede recortar cuando le piden acortar el artículo.

latex
\RequirePackage[l2tabu,orthodox]{nag}   % MUST come before \documentclass
\documentclass{article}
\usepackage{refcheck}                   % lists labels nobody refers to
% Then: pdflatex paper.tex && grep -E "nag Warning|refcheck Warning" paper.log

Recorrer el ciclo de corrección de principio a fin

Qué herramienta usar lo decide quién va a ver qué. Las tareas que solo les incumben a usted y a sus coautores: todonotes. Las ediciones que deben llevar un nombre: changes. Enseñarle a un revisor qué se ha movido desde la versión anterior: latexdiff. Y la caza de fallos que puede hacer una máquina: chktex, lacheck y nag. Los cuatro no compiten. Encadenarlos en este orden evita pasar dos veces por el mismo original.

  • Mientras escribe, deje tareas con todonotes\todo{...}, \missingfigure{...}— y cuente lo pendiente con \listoftodos.
  • Antes de hacerlo circular, ejecute chktex, lacheck y nag para que los fallos detectables por máquina ya no estén. No gaste atención humana en eso.
  • Para enviarlo, compile una versión con lineno y \linenumbers activados. Añada mathlines si el artículo va cargado de fórmulas.
  • Reincorpore las anotaciones con changes\added, \replaced, \deleted— y use \listofchanges para que nada quede sin tramitar.
  • Con cada versión que entregue, acompañe una compilación de latexdiff --flatten old.tex new.tex > diff.tex. Al lector le basta con abrir el diff.
  • Justo antes del envío, limpie las etiquetas sin usar con refcheck y recompile con todonotes en disable y changes en final.