在 LaTeX 中,我想知道文档类是否已加载,以及代码是否在 内
\begin{document}
。换句话说,是否有\ifpreamble
类似于\ifvmode
和 朋友?
部分原因是好奇,部分原因是为了让图表更容易编译为独立图表或包含在某个较大的文档中。过去,我让包含文档定义一个宏,然后图表对其进行测试,但如果图表可以自己弄清楚就好了。
不起作用的东西(因为它们没有被\documentclass
或改变\begin{document}
):
\ifvmode
立即生效\@currenvir
立即是“文件”\normalsize
立即定义
答案1
LaTeX 定义了许多宏,这些宏仅应在文档的前言中使用(例如\usepackage
,但也有一些内部内核宏)。它通过 来实现这一点\@onlypreamble\SomeMacro
。这通过添加\SomeMacro
到列表中来实现,其中\begin{document}
所有设置为\@notprerr
,这是一个生成错误的宏。特别是,内核声明\@onlypreamble\@onlypreamble
。这意味着我们可以通过执行以下操作来测试我们是否在前言中
\ifx\@onlypreamble\@notprerr (document)\else (preamble)\fi
如果我们在包中,想知道是在声明之前还是之后加载的\documentclass
,我们可以看看\documentclass
做了什么:除了其他许多事情之外,它还说\let\documentclass\@twoclasseserror
(这可以防止调用\documentclass
两次)。因此,测试 if\documentclass
是否等于 ifx-equal 可以\@twoclasseserror
解决这个问题。
\makeatletter
\def\MakeTest#1{%
\edef#1{%
\ifx\documentclass\@twoclasseserror % after \documentclass
\ifx\@onlypreamble\@notprerr % after \begin{document}
Hello
\else % before \begin{document}
Howdy
\fi
\else % before \documentclass
Hi!
\fi}}
\makeatother
\MakeTest\foo
\documentclass{minimal}
\MakeTest\bar
\begin{document}
\MakeTest\baz
foo says \foo; bar says \bar; baz says \baz
\end{document}
我认为这是非常强大的;我不认为任何包会发生改变\documentclass
或\@onlypreamble
在它们被改变之后会产生错误的含义。
电子工具箱添加\AfterEndPreamble
。中的代码\AfterEndPreamble{...}
将被检测为“之后\begin{document}
”(如艾哈迈德·穆萨在评论中)。
一方面,根据定义,\AfterEndPreamble
代码是在\begin{document}
,参见http://mirrors.ctan.org/macros/latex/contrib/etoolbox/etoolbox.pdf:
\AtEndPreamble
代码是序言的一部分;\AfterEndPreamble
代码是文档主体的一部分,可能包含要在文档最开始排版的可打印文本。总而言之,LaTeX 将在“内部”执行以下任务\begin{document}
:
- 执行任意
\AtEndPreamble
代码- 开始初始化文档主体(页面布局、默认字体等)
- 加载上一次 LaTeX 传递过程中编写的主要辅助文件
- 打开主辅助文件以在当前过程中进行写入
- 继续初始化文档主体
- 执行任意
\AtBeginDocument
代码- 完成文档主体的初始化
- 禁用所有
\@onlypreamble
命令- 执行任意
\AfterEndPreamble
代码
另一方面,它仍然在之后输入的任何代码之前执行\begin{document}
。
答案2
如果全部你需要这个来允许你从主文档中单独编译组件文件,那么你可以看看Martin Scharrer 的standalone
包裹,其设计目的正是实现这一目标。