# [Tex/LaTex] \AtBeginDocument and \AtEndDocument for standalone

hooksstandalone

Using the commands \AtBeginDocument and \AtEndDocument with the standalone documentclass yields unexpected effects.

I have the following three files.

% main.tex
\documentclass{scrartcl}
\usepackage[subpreambles]{standalone}
\AtBeginDocument{begin main \\}
\AtEndDocument{end main \\}
\begin{document}%
before
\input{sub1}
between
\input{sub2}
after
\end{document}


and

% sub1.tex
\documentclass{standalone}
\AtBeginDocument{begin sub1 \\}
\AtEndDocument{end sub1 \\}
\begin{document}%
\end{document}


sub2.tex looks like sub1.tex except for the numbers. Compiling main.tex results in a document that orders the text fragments like this. (I inserted some indentation here just to point out the structure.)

begin sub1
begin sub2
begin main
before
between
after
end main
end sub1
end sub2


But I would expect this.

begin main
before
begin sub1
end sub1
between
end sub2
begin sub2
after
end main


How can I instead get the second result?

I am sure there are better ways of doing this, but my approach is to patch the \AtBeginDocument and \AtEndDocument macros during the loading of the subpreambles such that they append their arguments to temporary macros. I then patch the input (or more specifically \@iinput) macro to use the temporary macros in the document body. I do the patching with the etoolbox package, but you can do it however you want. In order to get the patching done during the loading of the subpreambles I write directly into the \jobname.sta file. My patching of \@iinput isn't particularly robust and requires you to use \input{sub1.tex} instead of \input{sub1}.

By the way this type of patching of the \AtBeginDocument and \AtEndDocument macros is going to cause havoc if you load any packages in your sub files that depend on \AtBeginDocument and \AtEndDocument being expanded where they are supposed to be expanded.

% main.tex
\documentclass{scrartcl}
\usepackage{etoolbox}
\usepackage[subpreambles]{standalone}
\AtBeginDocument{begin main \\}
\AtEndDocument{end main \\}

\makeatletter
\pretocmd{\@iinput}{\csuse{AtBeginDocument#1}}{}{}
\apptocmd{\@iinput}{\csuse{AtEndDocument#1}}{}{}
{\@makeother\#%
\AtBeginDocument{\immediate\write\sa@out{\unexpanded{%
\renewcommand{\subpreamble}[1]{%
\expandafter\def\csname AtBeginDocument#1\endcsname{}%
\expandafter\def\csname AtEndDocument#1\endcsname{}%
\renewcommand{\AtBeginDocument}[1]{\expandafter\apptocmd\expandafter{\csname AtBeginDocument#1\endcsname}{##1}{}{}}
\renewcommand{\AtEndDocument}[1]{\expandafter\apptocmd\expandafter{\csname AtEndDocument#1\endcsname}{##1}{}{}}
}
}}}
}
\makeatother

\setlength{\parindent}{0pt}
\begin{document}%

before

\input{sub1.tex}

between

\input{sub2.tex}

after

\end{document}
`