Запуск pdflatex
ОДИН РАЗ на
\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}
выдает следующий результат:
Как вы видите, метки обоих авторов — 1, а надстрочный индекс после Mr. Beethoven отсутствует. Вам нужен второй запуск, pdflatex
чтобы исправить эту проблему.
Однако запуск pdflatex
ВСЕГДА по крайней мере дважды — это не то, что вам нужно: это съедает ваше время, особенно на больших документах, тогда как запуск pdflatex
один раз может быть иногда достаточным, если нужные файлы .aux доступны с предыдущего запуска. Я заглянул в файл .log и консольный вывод в попытке обнаружить какие-либо подсказки о том, нужен ли второй повторный запуск, но не смог найти ничего полезного. Мой предыдущий подход к проверке того, нужен ли повторный запуск, заключается в том, чтобы сказать что-то вроде
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\.)'
в начале makefile и
for i in $(SOURCES); do \
$(PDFLATEX) $$i ; \
done
if (egrep $(MESSAGE_FOR_RERUN) $(OBJECTS)); then \
for i in $(SOURCES); do $(PDFLATEX) $$i ; done; \
fi
(где переменные определены соответствующим образом) в правиле makefile. (Конечно, в не-MWE вам также может потребоваться запустить какой-нибудь из sed, awk, rm, bibtex, bibtex8, biber, makeglossaries, makeindex, xindy, dvi2ps, zip, chmod или бог знает что еще в дополнение, но такие подробности о других программах здесь не по теме.)
Конечно, вы можете иметь latexmk
или \usepackage[mainaux]{rerunfilecheck}
выполнять эту работу, но мне интересно: можно ли продолжать делать это прежним способом через makefiles, и если да, то какую строку искать в файлах журнала?
решение1
Просто собираю свои комментарии в ответ.
Прямой .log
анализ файла не может гарантировать, что он будет достаточным для обнаружения необходимых повторных запусков. Предупреждения о повторных запусках .log
появляются только потому, что LaTeX настроил эвристику, чтобы предупредить вас, если \labels
и цитаты (и, возможно, несколько других вещей) выглядят так, как будто им требуется еще один запуск LaTeX. Но пакеты не обязаны использовать эти контролируемые механизмы и вполне могут делать свое дело.
Код в вопросе является ярким примером такого кода. Соответствующие метки выписываются с помощью пользовательской \Newlabel
команды (вместо \newlabel
), и нет кода для обнаружения изменений с ними.
На самом деле, единственные существенные различия между .log
файлами первого и второго запуска заключаются в следующем:
No file <jobname>.aux.
против
(<jobname>.aux)
<jobname>.spl
и загружен ли вызванный файл .
Теперь легко создать пример, в котором .log
файлы остаются прежними (за исключением информации о времени и памяти), но для вывода по-прежнему требуется еще один запуск LaTeX.
- Возьмите пример из вопроса и скомпилируйте его дважды.
- Добавить третьего автора:
\author[3]{Antonín Dvořák}
с адресом\address[3]{Vyšehrader Friedhof}
- Компилироватьодин разчтобы увидеть сноску «1» для Дворжака.
- Скомпилируйте еще раз, чтобы получить "с".
Между шагами 3 и 4 .log
файл остается тем же, за исключением информации о дате/времени, использовании памяти и номерах строк для информации о шрифтах. Однако ни одно из этих изменений не указывает на необходимость еще одного запуска LaTeX.
Таким образом, если используемые вами пакеты не имеют встроенной эвристики на стороне LaTeX, которая дважды проверяет необходимость повторного запуска и выводит предупреждение в файле .log
, то .log
одного файла недостаточно для принятия решения о необходимости повторного запуска LaTeX.
Это одна из причин, по которой latexmk
также отслеживаются вспомогательные файлы на предмет изменений. Если вспомогательные файлы стабильны между запусками, то, само собой разумеется, что вывод также должен быть стабильным. Действительно, в приведенном выше примере \Newlabel{3}{c}
добавляется в .aux
файл при запуске LaTeX на шаге 3. Таким образом, .aux
отличается до и после запуска на шаге 3, но запуск на шаге 4 не изменяет файл .aux
. (Конечно, есть ситуации, когда повторный запуск не требуется, даже если .aux
файлы изменяются, например, потому что новые \label
s не используются. Поэтому не гарантируется, что результирующий цикл сборки будет самым коротким для данного документа. Кроме того, есть ситуации, когда файл .aux
никогда не стабилизируется:Избежать бесконечных проходов компилятора с помощью стилей цитирования biblatex ibid?.)
Пакет rerunfilecheck
, который вы упомянули в вопросе, позволяет отслеживать файл .aux
между запусками LaTeX. В частности, сравниваются хэш файла .aux
до и после текущего запуска LaTeX. Если хэш изменился, это означает, что повторный запуск может быть полезен, и вы получаете предупреждение следующего вида
Package rerunfilecheck Warning: File `<jobname>.aux' has changed. Rerun.
Package rerunfilecheck Info: Checksums for `<jobname>.aux':
(rerunfilecheck) Before: AE406B0DDBF18055292F1343793AC8CB;63
(rerunfilecheck) After: ED9C2E0E40AE4680FD0E58AB745EA3BF;80.
Если, с другой стороны, он .aux
стабилен, он сообщает
Package rerunfilecheck Info: File `<jobname>.aux' has not changed.
(rerunfilecheck) Checksum: ED9C2E0E40AE4680FD0E58AB745EA3BF;80.
Таким образом, rerunfilecheck
ваша задача сводится к анализу предупреждений о повторном запуске этого пакета.
Возможно, удастся переделать то, что rerunfilecheck
делается внешне в вашем makefile.
- Хэшируем текущий хеш
.aux
и запоминаем его. - Запустите LaTeX.
- Сделайте хэш нового хеша
.aux
и сравните его со старым хешем. - Если хеши отличаются, повторите попытку.
Сомневаюсь, что это будет стоить усилий, но это может стать хорошим академическим упражнением по написанию скриптов bash (не то чтобы я имел представление о том, как на самом деле выполнить эту задачу).