How do I reset the current \AtBeginDocument?
\AtBeginDocument
just adds (appends) code to the 'hook' \@begindocumenthook
, at the beginning of the document the collected code is executed.
In theory you can clear the hook at any time with
\makeatletter
\let\@begindocumenthook\@empty
\makeatother
but that might be a bit risky since many packages expect \AtBeginDocument
to work properly.
If there are only a few \AtBeginDocument
s you want to skip over, it might be safer to disable the command temporarily with
\makeatletter
\let\AtBeginDocument\@gobble
\makeatother
Of course you can also save the contents of the hook
\makeatletter
\let\@masroor@saved@begindocumenthook\@begindocumenthook
\makeatother
and then after a few \AtBeginDocument
s you want to ignore restore it again
\makeatletter
\let\@begindocumenthook\@masroor@saved@begindocumenthook
\makeatother
I'm not sure I understand your use case precisely. Left to myself, I'd be hugely reluctant to fiddle with \AtBeginDocument
(or \@begindocumenthook
) directly, because lots of packages (and the internal workings of LaTeX itself) use them for various purposes, and I don't see how I could be sure that I wouldn't break something unintentionally.
Might it be better to define a separate accumulator macro of your own, and then to have that executed \AtBeginDocument
? You can then safely mess with that macro to your heart's content, without clobbering anything else that has been innocently making use of \AtBeginDocument
.
Something like:
\documentclass{memoir}
\makeatletter
\def\MyAtBeginDocument{\g@addto@macro\my@begindocumenthook}
\let\my@begindocumenthook\@empty
\def\MyResetBeginDocument{\global\let\my@begindocumenthook\@empty}
\AtBeginDocument{\my@begindocumenthook}
\makeatother
\AtBeginDocument{THAT\par}
\MyAtBeginDocument{NOT THIS\par}
\MyResetBeginDocument
\MyAtBeginDocument{THIS\par}
\begin{document}
We should see THIS then THAT!
\end{document}
Note that THIS comes before THAT because \my@begindocument
is executed as part of \@begindocumenthook
before the additional material added by \AtBeginDocument{THAT\par}
because it comes in via \my@begindocumenthook
which in turn got added to \@begindocumenthook
first. You might need to (and could) delay that addition until later.
This is similar to Paul Stanley's answer but with slightly different UI. This
defines \AllowAtBeginDocumentToBeResetable
which makes all subsequent uses of \AtBeginDocument
resetable. To reset these you invoke \ClearResetableAtBeginDocumentList
.
Thus your example code would look like:
\AllowAtBeginDocumentToBeResetable%% ALL EXTERNAL PACKAGES INCLUDED BEFORE HERE
\AtBeginDocument{First\par}
\AtBeginDocument{Second\par}
\AtBeginDocument{Third\par}
\ClearResetableAtBeginDocumentList% I want to cancel the above at this point
\AtBeginDocument{New First\par}
\AtBeginDocument{New Second\par}
\AtBeginDocument{New Third\par}
which produces:
Notes:
- Note that this requires that all external packages MUST be included before you issue
\AllowAtBeginDocumentToBeResetable
.
Code:
\documentclass{memoir}
\makeatletter
\let\@OldAtBeginDocument\AtBeginDocument
\newcommand{\@ResetableBegindDoumentItems}{}%
\newcommand{\AllowAtBeginDocumentToBeResetable}{%
\ifdefined\@AtBeginDocumentIncludesResetableList\else
\gdef\@AtBeginDocumentIncludesResetableList{}% Don't execute this again
\AtBeginDocument{\@ResetableBegindDoumentItems}%
\fi
\renewcommand{\AtBeginDocument}[1]{%
\g@addto@macro\@ResetableBegindDoumentItems{{##1}}%
}%
}
\newcommand*{\ClearResetableAtBeginDocumentList}{%
\gdef\@ResetableBegindDoumentItems{}%
}
\makeatother
\AllowAtBeginDocumentToBeResetable%% ALL EXTERNAL PACKAGES INCLUDED BEFORE HERE
\AtBeginDocument{First\par}
\AtBeginDocument{Second\par}
\AtBeginDocument{Third\par}
\ClearResetableAtBeginDocumentList% I want to cancel the above at this point
\AtBeginDocument{New First\par}
\AtBeginDocument{New Second\par}
\AtBeginDocument{New Third\par}
\begin{document}
\end{document}