\AtBeginDocument 和 \AtEndDocument 独立版

\AtBeginDocument 和 \AtEndDocument 独立版

使用命令\AtBeginDocument\AtEndDocumentdocumentclassstandalone会产生意想不到的效果。

我有以下三个文件。

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

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

sub2.texsub1.tex除了数字之外,看起来都一样。编译main.tex后会生成一个按如下顺序排列文本片段的文档。(我在这里插入了一些缩进,只是为了指出结构。)

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

但我预料到这一点。

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

我怎样才能获得第二个结果?

答案1

我相信有更好的方法可以做到这一点,但我的方法是在加载子前言期间修补\AtBeginDocument和宏,以便它们将其参数附加到临时宏中。然后我修补(或更具体地说)宏以在文档主体中使用临时宏。我使用\AtEndDocumentinput\@iinputetoolbox包,但您可以按照自己的意愿进行操作。为了在加载子前言时完成修补,我直接写入文件\jobname.sta。我的修补\@iinput不是特别强大,需要您使用\input{sub1.tex}而不是`\input{sub1}。

顺便说一下,如果您在子文件中加载任何依赖于并在应该扩展的位置扩展的包,则这种对\AtBeginDocument\AtEndDocument宏的修补将造成严重破坏。\AtBeginDocument\AtEndDocument

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

在此处输入图片描述

答案2

因为有人给出了一个棘手的答案(+1),所以我并不介意建议一个简单的答案,这可能有用,也可能没用,这取决于你真的希望发生在‘边缘’或子文件附近。

\documentclass{scrartcl}
\parindent 0pt
\usepackage[subpreambles]{standalone}
\AtBeginDocument{main.tex: begin main\par}
\AtEndDocument{main.tex:   end main\par}

\usepackage{xparse}
\NewDocumentCommand{\myinput}{omo}
{\IfNoValueTF{#3}%
  {\IfNoValueTF{#1}%
    {\input{#2}}%
    {#1\par\input{#2}}}%
  {\IfNoValueTF{#1}%
    {\input{#2}\par#3\par}%
    {#1\par\input{#2}\par#3\par}}%
}

\begin{document}%

before

\myinput{sub1}

between

\myinput[sub1: before (no after)]{sub1}

between

\myinput{sub1}[sub1: after (no before) ]

between

\myinput[sub2: before]{sub2}[sub2: after]

\end{document}

\At<etc.>然后从子文件中删除所有参数:

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

% sub1.tex
\documentclass{standalone}
% \AtBeginDocument{begin sub2 \\}
% \AtEndDocument{end sub2 \\}
\begin{document}%
sub2 -- main text
\end{document}

相关内容