
Я использую только lualatex
, но, возможно, это общий вопрос LaTeX. Предположим, что используется TeXlive 2023 или более поздняя версия, поскольку нет необходимости в обратной совместимости.
Я посмотрел atbegshi
и некоторые другие документы, но они не делают то, что мне нужно, или намного сложнее, чем нужно. Я также вижу, что не так давно кто-то задал похожий вопрос, но без полезного ответа:
Используйте хуки shipout для управления глобальным состоянием
Ситуация: У меня есть две команды, которые я назову \foo
и \unfoo
. \foo
Команда включает в себя \clearpage
в верхней части, поэтому мне не нужно беспокоиться о том, где \foo
она появится при наборе. \unfoo
Команда заканчивается на \clearpage
.
Если страница имеет \foo
, то эта же страница должна иметь \unfoo
. Если пользователь не пишет \unfoo
до \foo
отправки страницы, это ошибка. Я знаю, как написать подходящее сообщение об ошибке, останавливающее компиляцию. Мне не нужно хранить, редактировать, удалять или иным образом манипулировать содержимым страницы.
Мой вопрос: есть ли простой способ использовать \shipout
хук (или что-то подобное), чтобы сделать это? Хотя, atbegshi
похоже, что это должно быть возможно, с этим пакетом происходит много всего, что заставляет меня нервничать.
МВЭ:
\documentclass{article} % Compile with lualatex.
\usepackage{fontspec}
\newif\ifusedfoo
\def\foo{\clearpage Hello.\par\usedfootrue}
\def\unfoo{Goodbye.\par\usedfoofalse\clearpage}
% \WhenPageShips{ % This is what I need. I know how to create an error, instead of typeout.
% \ifusedfoo
% \typeout{EEEEK. The page with \string\foo\space did not have \string\unfoo.}
% \fi
% }
\begin{document}
Welcome.\par
\foo
No problem here.\par
\unfoo
\foo % With too many lines on that page, causes problem:
x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\
x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\
x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\
x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\par
% Whether or not there is a later \unfoo, does not matter.
Moving right along\par
\clearpage
This is too late.\par
\unfoo
I cannot wait until this far in the document.\par
\end{document}
Также: я не хочу использовать aux
файл для этого. Код не появляется внутри чего-то сложного (например, библиографии, оглавления и т. д.). Только внутри бегущего текста.
ПРАВКА: Ясно указано, что проблему следует обнаружить быстро, а не позже в документе.
EDIT2: Принятое решение работает вмоя конкретная ситуацияно может не работать в общей ситуации. Смотрите комментарии.
решение1
\documentclass{article} % Compile with lualatex.
\usepackage{fontspec}
\newif\ifusedfoo
\def\foo{\clearpage Hello.\par\usedfootrue}
\def\unfoo{Goodbye.\par\usedfoofalse\clearpage}
\AddToHook{shipout/before}[rallg]{%
% \WhenPageShips{ % This is what I need. I know how to create an error, instead of typeout.
\ifusedfoo
\typeout{EEEEK. The page with \string\foo did not have \string\unfoo.}
\fi
}
\begin{document}
Welcome.\par
\foo
No problem here.\par
\unfoo
\foo % With too many lines on that page, causes problem:
x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\
x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\
x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\
x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\\x\par
% Whether or not there is a later \unfoo, does not matter.
\end{document}
Это выводит сообщение для последних двух страниц, поскольку оба происходят без \unfoo
. Если вы хотите избежать второго, вам нужно будет соответствующим образом управлять условной логикой.