Executando o pdflatex o número mínimo de vezes necessário para o elsarticle

Executando o pdflatex o número mínimo de vezes necessário para o elsarticle

Executando pdflatexUMA VEZ em

\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}

produz a seguinte saída:

saída da primeira execução

Como você pode ver, os rótulos de ambos os autores são 1 e a estrela sobrescrita após o Sr. Beethoven está faltando. Você precisa da segunda execução pdflatexpara corrigir esse problema.

No entanto, executar pdflatexSEMPRE pelo menos duas vezes não é o que você deseja: consome seu tempo, especialmente em papéis grandes, enquanto executar pdflatexuma vez às vezes pode ser suficiente se os arquivos .aux corretos estiverem disponíveis em uma execução anterior. Examinei o arquivo .log e a saída do console na tentativa de descobrir algumas dicas sobre se uma segunda execução é necessária, mas não consegui encontrar nada utilizável. Minha abordagem anterior para verificar se uma nova execução é necessária é dizer 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\.)'

no início de um makefile e

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

(onde as variáveis ​​são definidas apropriadamente) em uma regra do makefile. (Claro, em um não-MWE, você também pode precisar executar alguma opção de sed, awk, rm, bibtex, bibtex8, biber, makeglossaries, makeindex, xindy, dvi2ps, zip, chmod ou Deus sabe o que além disso , mas esses detalhes sobre outros programas estão fora do assunto aqui.)

Claro, você pode ter latexmkou \usepackage[mainaux]{rerunfilecheck}fazer o trabalho, mas eu me pergunto: você pode continuar fazendo da maneira anterior via makefiles e, em caso afirmativo, qual string procurar nos arquivos de log?

Responder1

Apenas reunindo meus comentários em uma resposta.

Não é possível garantir que a análise direta .logde arquivos seja suficiente para detectar as reexecuções necessárias. Os avisos de reexecução .logaparecem apenas porque o LaTeX configurou uma heurística para avisá-lo se \labelsas citações (e talvez algumas outras coisas) parecerem que precisam de outra execução do LaTeX. Mas os pacotes não são obrigados a usar esses mecanismos monitorados e podem muito bem fazer o que quiserem.

O código em questão é um excelente exemplo desse código. Os rótulos relevantes são escritos com o \Newlabelcomando personalizado (em vez de \newlabel) e não há código para detectar alterações neles.

Na verdade, as únicas diferenças relevantes entre os .logficheiros da primeira e da segunda execução são

No file <jobname>.aux.

contra

(<jobname>.aux)

e se um arquivo chamado está carregado ou não <jobname>.spl.

Agora é fácil construir um exemplo onde os .logarquivos permanecem os mesmos (exceto as informações de tempo e memória), mas a saída ainda precisa de outra execução do LaTeX.

  1. Pegue o exemplo da pergunta e compile-o duas vezes.
  2. Adicione um terceiro autor: \author[3]{Antonín Dvořák}com endereço\address[3]{Vyšehrader Friedhof}
  3. Compilaruma vezpara ver a nota de rodapé "1" para Dvořák.
  4. Compile novamente para obter "c".

Entre as etapas 3 e 4, o .logarquivo permanece o mesmo, exceto pelas informações de data/hora, uso de memória e números de linha para as informações da fonte. Nenhuma dessas alterações, entretanto, indica que outra execução do LaTeX seja necessária.

Portanto, a menos que os pacotes que você usa tenham algum tipo de heurística incorporada no lado do LaTeX que verifique se uma nova execução é necessária e avise no arquivo .log, o .logarquivo por si só não é suficiente para decidir se deve executar novamente o LaTeX.

Essa é uma das razões pelas quais latexmktambém monitora alterações nos arquivos auxiliares. Se os arquivos auxiliares estiverem estáveis ​​entre as execuções, é lógico que a saída também deverá ser estável. Na verdade, no exemplo acima \Newlabel{3}{c}é adicionado ao .auxarquivo na execução do LaTeX da etapa 3. Portanto, .auxé diferente antes e depois da execução na etapa 3, mas a execução na etapa 4 não altera o .auxarquivo. (É claro que há situações em que uma nova execução não é necessária, mesmo que os .auxarquivos sejam alterados, por exemplo, porque novos \labels não são usados. Portanto, não é garantido que o ciclo de construção resultante seja o mais curto para um determinado documento. Além disso, há situações onde o .auxarquivo nunca se estabiliza:Evite passagens infinitas do compilador com estilos de citação biblatex ibid?.)

O package rerunfilecheck, que você menciona na pergunta, permite monitorar o .auxarquivo entre as execuções do LaTeX. Em particular, o hash do .auxarquivo antes e depois da execução atual do LaTeX é comparado. Se o hash for alterado, isso indica que uma nova execução pode ser útil e você receberá um aviso no seguinte 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.

Se, por outro lado, .auxestiver estável, ele reporta

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

Portanto, rerunfilechecksua tarefa se reduz apenas à análise dos avisos de reexecução desse pacote.

Pode ser possível refazer o que rerunfilechecké feito externamente no seu makefile.

  • Faça hash do atual .auxe lembre-se do hash.
  • Execute o LaTeX.
  • Faça hash do novo .auxe compare com o hash antigo.
  • Se os hashes forem diferentes, execute novamente.

Duvido que valha a pena o esforço, mas pode ser um bom exercício acadêmico em scripts bash (não que eu tenha alguma ideia de como realmente realizar essa tarefa).

informação relacionada