让我们首先考虑这两个文件。
\documentclass{article}
\parindent 0.0mm
\hyphenpenalty 500
\tolerance 700
\usepackage{lipsum}
\begin{document}
\lipsum[1-10]
\end{document}
\documentclass{article}
\usepackage{lipsum}
\begin{document}
\parindent 0.0mm
\hyphenpenalty 500
\tolerance 700
\lipsum[1-10]
\end{document}
这两个文件除了前后使用了一些命令之外,内容完全相同\begin{document}
。然而,它们产生的输出完全相同。
现在,如果我们想添加一个\baselineskip
命令,只要在 之后使用它就会起作用\begin{document}
。
同样,有些命令只允许在序言中使用。\usepackage
是其中最常见的。
我们当然明白,\begin{document}
启动一个环境,可能是最高或最重要的环境,你明白我的意思。
(尝试在 latex.ltx 中搜索类似内容\newenvironment{document}
。没有成功。也许我没有找对地方。)
但是这个命令到底起什么作用呢?
请回答这两个问题,
\begin{document} 命令究竟触发了什么?它启动了哪些东西?
为什么有些命令只允许在前导码中使用?
当然,其他相关问题也会随之给出答案。
答案1
您应该在里面搜索\document
(and/or \enddocument
)latex.ltx
,因为环境env
由宏对\env
和组成\endenv
:
\def\document{\endgroup
\ifx\@unusedoptionlist\@empty\else
\@latex@warning@no@line{Unused global option(s):^^J%
\@spaces[\@unusedoptionlist]}%
\fi
\@colht\textheight
\@colroom\textheight \vsize\textheight
\columnwidth\textwidth
\@clubpenalty\clubpenalty
\if@twocolumn
\advance\columnwidth -\columnsep
\divide\columnwidth\tw@ \hsize\columnwidth \@firstcolumntrue
\fi
\hsize\columnwidth \linewidth\hsize
\begingroup\@floatplacement\@dblfloatplacement
\makeatletter\let\@writefile\@gobbletwo
\global \let \@multiplelabels \relax
\@input{\jobname.aux}%
\endgroup
\if@filesw
\immediate\openout\@mainaux\jobname.aux
\immediate\write\@mainaux{\relax}%
\fi
\process@table
\let\glb@currsize\@empty %% Force math initialization.
\normalsize
\everypar{}%
\ifx\normalsfcodes\@empty
\ifnum\sfcode`\.=\@m
\let\normalsfcodes\frenchspacing
\else
\let\normalsfcodes\nonfrenchspacing
\fi
\fi
\@noskipsecfalse
\let \@refundefined \relax
\let\AtBeginDocument\@firstofone
\@begindocumenthook
\ifdim\topskip<1sp\global\topskip 1sp\relax\fi
\global\@maxdepth\maxdepth
\global\let\@begindocumenthook\@undefined
\ifx\@listfiles\@undefined
\global\let\@filelist\relax
\global\let\@addtofilelist\@gobble
\fi
\gdef\do##1{\global\let ##1\@notprerr}%
\@preamblecmds
\global\let \@nodocument \relax
\global\let\do\noexpand
\ignorespaces}
在许多事情中,document
环境引发了以下现象:
- 报告未使用的
\documentclass
选项; - 设置页面布局;
- 读取文件
.aux
; - 打开一个流以开始(覆盖)写入
.aux
; - 启动文档的字体大小(
\normalsize
); \AtBeginDocument
执行通过( )收集到的所有信息\@begindocumenthook
;- 禁用仅限前导命令(通过
\@preamblecmds
,它收集定义为仅可通过前导使用的命令\@onlypreamble
)。
请注意,这是 LaTeX 中使用的默认定义。某些文档可能会根据需要更改或附加此定义。
从根本上讲,软件包旨在做很多事情,包括干预在环境启动期间完成的事情document
(如上所述)。显然,geometry
就是其中之一,因为它需要设置页面布局和尺寸,然后才能开始编写某些内容。但是,作为更一般的规则,最好将结构与内容分开,并且由于包提供了结构接口,因此它们更适合前言。您可以在环境mypackage
中加载一个相当简单的包(例如)document
,使用
\makeatletter
\input{mypackage.sty}% Load mypackage.sty
\makeatother
\makeatletter
...对\makeatother
避免了@
宏内问题。但是,有些软件包是使用命令编写的,而这些命令本身只能在前言部分使用。规避这一过程将是一个繁琐的过程,而且没有必要。