Ejecute un comando simple en el envío, dependiendo del valor de un booleano

Ejecute un comando simple en el envío, dependiendo del valor de un booleano

Solo uso lualatex, pero quizás esta sea una pregunta general sobre LaTeX. Supongamos que se utiliza TeXlive 2023 o posterior, ya que no es necesaria la compatibilidad con versiones anteriores.

He mirado atbegshialgunos otros documentos, pero no hacen lo que necesito o son mucho más complejos de lo necesario. También veo que, no hace mucho, alguien hizo una pregunta similar, pero sin una respuesta útil: Utilice ganchos de envío para manipular el estado global

Situación: tengo dos comandos, a los que llamaré \fooy \unfoo. El \foocomando incluye \clearpageen la parte superior, por lo que no necesito preocuparme por dónde \fooaparece al escribirlo. El \unfoocomando termina con \clearpage.

Si una página tiene \foo, entonces la misma página debe tener \unfoo. Si el usuario no escribe \unfooantes de que se envíe la \foopágina, se trata de un error. Sé cómo escribir un mensaje de error adecuado, deteniendo la compilación. No necesito almacenar, editar, descartar ni manipular de otro modo el contenido de la página.

Mi pregunta: ¿Existe una forma sencilla de utilizar el \shipoutgancho (o algo similar) para hacer esto? Aunque atbegshiparece que debería ser capaz, están sucediendo muchas cosas con ese paquete, lo que me pone nervioso.

MWE:

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

Además: no deseo utilizar un auxarchivo para esto. El código no aparece dentro de nada complicado (como bibliografía, índice, etc.). Justo dentro del texto en ejecución.

EDITAR: Dejó en claro que el problema debe detectarse rápidamente, no más adelante en el documento.

EDIT2: La solución aceptada funciona enmi situación específicapero puede que no funcione en la situación general. Ver comentarios.

Respuesta1

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

Esto escribe el mensaje para las dos últimas páginas, ya que ambas aparecen sin \unfoo. Si desea evitar lo segundo, deberá administrar la lógica condicional de manera adecuada.

información relacionada