Ejecutar pdflatex la cantidad mínima de veces necesaria para elsarticle

Ejecutar pdflatex la cantidad mínima de veces necesaria para elsarticle

Ejecutando pdflatexUNA VEZ

\documentclass{elsarticle}%%% version 3.1 from CTAN
\begin{document}
\begin{frontmatter}
\author[1]{Johann Sebastian Bach}
\author[2]{Ludwig van Beethoven\corref{cor2}}
\cortext[cor2]{Corresponding author}%
\address[1]{Thomaskirche, Leipzig}
\address[2]{Zentralfriedhof Wien}
\end{frontmatter}
\end{document}

produce el siguiente resultado:

salida de la primera ejecución

Como puede ver, las etiquetas de ambos autores son 1 y falta la estrella en superíndice después del Sr. Beethoven. Necesita una segunda ejecución pdflatexpara corregir este problema.

Sin embargo, ejecutar pdflatexSIEMPRE al menos dos veces no es lo que desea: consume tiempo, especialmente en papeles grandes, mientras que ejecutar pdflatexuna vez a veces puede ser suficiente si los archivos .aux correctos están disponibles en una ejecución anterior. Miré el archivo .log y la salida de la consola en un intento de descubrir algunas pistas sobre si es necesaria una segunda ejecución, pero no pude encontrar nada utilizable. Mi enfoque anterior para comprobar si es necesaria una repetición es decir algo como

MESSAGE_FOR_RERUN := '(LaTeX Warning: Label\(s\) may have changed\. Rerun to get cross\-references right\.)|(LaTeX Warning: There were undefined references\.)|(LaTeX Warning: Citation [^[:cntrl:]]* on page [0-9]* undefined on)|(Package natbib Warning: There were undefined citations\.)|(\(mparhack\) *Rerun to get them right\.)'

al comienzo de un archivo MAKE y

for i in $(SOURCES); do \
  $(PDFLATEX) $$i ; \
done
if (egrep $(MESSAGE_FOR_RERUN) $(OBJECTS)); then \
  for i in $(SOURCES); do $(PDFLATEX) $$i ; done; \
fi

(donde las variables se definen apropiadamente) en una regla del archivo MAKE. (Por supuesto, en un entorno que no sea MWE, es posible que también necesite ejecutar alguna opción de sed, awk, rm, bibtex, bibtex8, biber, makeglossaries, makeindex, xindy, dvi2ps, zip, chmod o dios-sabe-qué además , pero esos detalles sobre otros programas están fuera de tema aquí).

Por supuesto, puede tener latexmko \usepackage[mainaux]{rerunfilecheck}hacer el trabajo, pero me pregunto: ¿puede continuar haciéndolo de la manera anterior a través de archivos MAKE y, de ser así, qué cadena buscar en los archivos de registro?

Respuesta1

Simplemente recopilando mis comentarios en una respuesta.

No se puede garantizar que el análisis sencillo .logde archivos sea suficiente para detectar las reejecuciones necesarias. Las advertencias de repetición en el .logúnico aparecen porque LaTeX ha configurado una heurística para advertirle si \labelslas citas (y tal vez algunas otras cosas) parecen necesitar otra ejecución de LaTeX. Pero los paquetes no están obligados a utilizar esos mecanismos monitoreados y bien pueden hacer lo suyo.

El código de la pregunta es un excelente ejemplo de dicho código. Las etiquetas relevantes se escriben con el \Newlabelcomando personalizado (en lugar de \newlabel) y no hay ningún código para detectar cambios en ellas.

De hecho, las únicas diferencias relevantes entre los .logarchivos de la primera y segunda ejecución son

No file <jobname>.aux.

vs

(<jobname>.aux)

<jobname>.sply si un archivo llamado está cargado o no .

Ahora es fácil construir un ejemplo donde los .logarchivos siguen siendo los mismos (excepto la información de tiempo y memoria), pero la salida aún necesita otra ejecución de LaTeX.

  1. Tome el ejemplo de la pregunta y compílelo dos veces.
  2. Añadir un tercer autor: \author[3]{Antonín Dvořák}con dirección\address[3]{Vyšehrader Friedhof}
  3. Compilaruna vezpara ver la nota a pie de página "1" de Dvořák.
  4. Compile nuevamente para obtener "C".

Entre los pasos 3 y 4, el .logarchivo permanece igual excepto la información de fecha/hora, el uso de memoria y los números de línea para la información de fuente. Sin embargo, ninguno de estos cambios indica que sea necesaria otra ejecución de LaTeX.

Entonces, a menos que los paquetes que utilice tengan algún tipo de heurística incorporada en el lado de LaTeX que verifique si es necesario volver a ejecutar y advierta en el archivo .log, el .logarchivo por sí solo no es suficiente para decidir si se debe volver a ejecutar LaTeX.

Esa es una de las razones por las que latexmktambién monitorea los archivos auxiliares en busca de cambios. Si los archivos auxiliares son estables entre ejecuciones, es lógico que la salida también sea estable. De hecho, en el ejemplo anterior \Newlabel{3}{c}se agrega al .auxarchivo en la ejecución de LaTeX del paso 3. Por lo tanto, .auxes diferente antes y después de la ejecución del paso 3, pero la ejecución del paso 4 no cambia el .auxarchivo. (Por supuesto, hay situaciones en las que no es necesario volver a ejecutar incluso si los .auxarchivos cambian, por ejemplo, porque \labelno se utilizan nuevos correos electrónicos. Por lo tanto, no se garantiza que el ciclo de compilación resultante sea el más corto para un documento determinado. Además, hay situaciones donde el .auxarchivo nunca se estabiliza:¿Evitar pases infinitos del compilador con estilos de citas biblatex ibid?.)

El paquete rerunfilecheck, que menciona en la pregunta, permite monitorear el .auxarchivo entre ejecuciones de LaTeX. En particular .aux, se compara el hash del archivo antes y después de la ejecución actual de LaTeX. Si el hash cambió, eso indica que una nueva ejecución podría ser útil y recibirá una advertencia del siguiente formato

Package rerunfilecheck Warning: File `<jobname>.aux' has changed. Rerun.

Package rerunfilecheck Info: Checksums for `<jobname>.aux':
(rerunfilecheck)             Before: AE406B0DDBF18055292F1343793AC8CB;63
(rerunfilecheck)             After:  ED9C2E0E40AE4680FD0E58AB745EA3BF;80.

Si, por el contrario, .auxes estable, informa

Package rerunfilecheck Info: File `<jobname>.aux' has not changed.
(rerunfilecheck)             Checksum: ED9C2E0E40AE4680FD0E58AB745EA3BF;80.

Entonces, rerunfilechecksu tarea simplemente se reduce a analizar las advertencias de repetición de ese paquete.

Podría ser posible rehacer lo rerunfilecheckque hace externamente en su archivo MAKE.

  • Hash el actual .auxy recuerda el hash.
  • Ejecute látex.
  • Hash el nuevo .auxy compárelo con el hash antiguo.
  • Si los hashes son diferentes, vuelva a ejecutar.

Dudo que valga la pena el esfuerzo, pero podría ser un buen ejercicio académico en scripting bash (no es que tenga idea de cómo lograr esta tarea).

información relacionada