在宏中调用 \end{document}

在宏中调用 \end{document}

我有一个文件,旨在用作更大文档内的片段文件:

\include{boilerplate}
content
\include{boilerplate}

目标是使片段文件可编译。因此,在 boilerplate.tex 中,我有:

\ifx\maindocument\undefined
    \documentclass{article}
    \def\maindocument{}
    \begin{document}
    fragment is now standalone
\else 
    fragment is finished
    \end{document}
\fi

当我编译该片段时,我得到:

(\end occurred when \ifx on line 1 was incomplete)

造成这种情况的“原因”是,我在 \ifx 中结束了文档,因此 \ifx 永远不会结束。但是,一切似乎都编译正确。我怎样才能保留这种通用格式,但让错误消息消失?我尝试放置 \expandafter{\end{document}},但这没有帮助。


在采纳了有关 \enddocument (或其他宏) 的建议后,我能够消除错误。但是,仍存在一些错误:

(\end occurred when \iftrue on line 3 was incomplete)
(\end occurred when \ifnum on line 3 was incomplete)

这是我现在的boilerplate.tex:

\def\prestuff{%
    \documentclass{article}
    \def\maindocument{}
    \begin{document}
    fragment is now standalone
}

\def\poststuff{%
    fragment is finished
    \end{document}
}

\ifx\maindocument\undefined
    \expandafter\prestuff
\else 
    \expandafter\poststuff
\fi

那么这些错误该怎么办呢?

答案1

避免过多开放条件的另一种策略(顺便说一句,所有这些技术都有超出给定范围的用途,只要您不想不必要地执行下一个条件)是定义一个在条件内设置的“执行后”命令。因此在这种情况下,

\ifx\maindocument\undefined
    \documentclass{article}
    \def\maindocument{}
    \begin{document}
    fragment is now standalone
    \def\donext{}
\else 
    fragment is finished
    \end{document}
    \def\donext{\end{document}}
\fi
\donext

显然,您可以在宏中添加更多内容\donext

更新:这是对您收到的新错误的响应。这些错误来自命令\include。基本上,通过结束包含文件中的文档,您没有给命令\include机会完成其正常操作。由于这涉及一些条件和其他内容(例如写入aux文件),TeX 会对此发出警告。

如果您不需要所有花哨的额外功能,\include那么您可以将其替换为。提供的\input主要功能之一是每个包含的文件都有单独的文件。 由于您两次包含文件,我担心第二个文件可能会覆盖第一个文件,因此在使用之前会犹豫不决。 如果您的“现实生活”情况与问题中的示例相似,那么我认为使用over没有任何好处,因此这种替换应该是安全的。\include\inputaux\include\include\input

如果您仍然需要使用,那么您可以通过查看命令并将行后的所有内容放入宏中\include来解决问题。以下方法对我有用,但我不能保证我没有忽略其他内容!\include@include\@input@\poststuff

\def\prestuff{%
    \documentclass{article}
    \def\maindocument{}
    \begin{document}
    fragment is now standalone
}

\makeatletter
\def\poststuff{%
    fragment is finished
    \clearpage
    \@writeckpt{boilerplate}%
    \if@filesw
      \immediate\closeout\@partaux
    \fi
  \else
    \deadcycles\z@
    \@nameuse{cp@boilerplate}%
  \fi
  \let\@auxout\@mainaux
    \fi
    \end{document}
}
\makeatother

\ifx\maindocument\undefined
    \expandafter\prestuff
\else 
    \expandafter\poststuff
\fi

(但正如我所说,使用\input可以避免这种麻烦。)

答案2

当 TeX 读取您的输入时,它会\end{document}在 之前执行\fi。里面\end{document}有 TeX\end原语,在关闭所有条件之前,切勿使用它。因此,您可以使用低级\endocument宏(如 mhp 所建议的):

  ...
  \expandafter\enddocument
\fi

或者对于更通用的解决方案,使用你自己的宏来处理条件材料

  ...
  \def\mymacro{\end{document}}
  \expandafter\mymacro
\fi

后一种方法允许您包含要在 之后插入的多个项目\fi

答案3

不要使用\includeexcept 来在正文中包含独立章节。改用原始包含命令\input,然后其余警告将消失。

答案4

standalone包可以实现你想要的。

%boilerplate.tex
\documentclass{standalone}
\begin{document}
Content of boilerplate
\end{document}

%main.tex

\documentclass{article} %or whatever
\usepackage{standalone}

\begin{document}
\include{boilerplate} % Perhaps input would be better?
Other text
\include{boilerplate}
\end{document}

确保在样板中使用的所有包都包含在主文档中。standalone自动删除所包含文件的前言。

相关内容