\begin{document} 命令到底触发了什么?

\begin{document} 命令到底触发了什么?

让我们首先考虑这两个文件。


\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}。没有成功。也许我没有找对地方。)

但是这个命令到底起什么作用呢?

请回答这两个问题,

  1. \begin{document} 命令究竟触发了什么?它启动了哪些东西?

  2. 为什么有些命令只允许在前导码中使用?

当然,其他相关问题也会随之给出答案。

答案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避免了@宏内问题。但是,有些软件包是使用命令编写的,而这些命令本身只能在前言部分使用。规避这一过程将是一个繁琐的过程,而且没有必要。

相关内容