Когда и как оцениваются команды в аргументе \ AtBeginDocument?
Этот вопрос мотивирован как продолжение этого , где я столкнулся с проблемой с небольшими различиями в порядке выполнения между usepackageкомандой и AtBeginDocument. Чтобы упростить обсуждение, я воспроизведу здесь основной код:
\documentclass{report}
\AtBeginDocument{\listoffigures}
\usepackage{cleveref}
\begin{document}
\begin{figure} \caption{This caption cross-references \cref{eqn}.} \label{fig} \end{figure}
\begin{equation} F = ma \label{eqn}\end{equation}
\end{document}
Перефразируя комментарий, который я опубликовал в ответ на там ответ, я предполагал, что на основании именования я \AtBeginDocumentбуду вести себя как макрос препроцессора в C или что-то подобное, то есть он будет лениво расширяться и оцениваться при запуске (в начале документ). Однако проблема, с которой я столкнулся, была вызвана запуском \usepackageкоманды в преамбуле моего документа после того, как \AtBeginDocumentбыла вызвана в моем файле cls, и она была решена, когда я переместил usepackageвызов выше AtBeginDocument, указав, что он немедленно выполняет команды, но каким-то образом задерживает их действие. пока \begin{document}. В частности, этот порядок привел к тому, что мы cleverefне знали, как обращаться к уравнениям в подписях к рисункам, скопированным в lof:
\AtBeginDocument{...}
\usepackage{cleveref}
тогда как замена этих двух команд устранила эту проблему. Итак, мой вопрос: как это \AtBeginDocumentработает и какие предположения я могу на самом деле сделать, когда его аргументы оценены и когда их побочные эффекты станут очевидными?
Ответы
Токены, добавленные с помощью, \AtBeginDocumentпоявляются в том порядке, в котором они добавлены, поэтому изменение порядка заголовка имеет значение. Из последней версии LaTeX (2020-10-01) есть новый механизм крючка , который позволяет переупорядочивать основанный на правилах сортировки: \AddToHook{begindocument}. Однако, как \AtBeginDocumentуказано в комментариях, новый \AddToHook{begindocument}эквивалент не следует использовать ни для чего наборного текста. Для этого вы должны использовать \AddToHook{begindocument/end}новый формат LaTeX или загрузить etoolboxи использовать \AfterEndPreambleловушку.