为什么 LaTeX 内核定义 \usepackage *和* \RequirePackage?

为什么 LaTeX 内核定义 \usepackage *和* \RequirePackage?

ubiquitous\usepackage命令用于在文档的前言中加载包;命令语法为

\usepackage[<package-option-list>]{<package-list>}[<version>]

实际上,它\usepackage源自于\RequirePackage来源2e,第 69.3 节,可用于包或类文件中以加载其他包。与 相反\usepackage\RequirePackage也可以用于文档中 \documentclass或者在(LaTeX 2.09)兼容模式下:

\def\documentclass{%
  \let\documentclass\@twoclasseserror
  \if@compatibility\else\let\usepackage\RequirePackage\fi
  \@fileswithoptions\@clsextension}
\@onlypreamble\documentclass

但是如果\RequirePackage可以做到所有事情\usepackage甚至更多,为什么需要两个不同的命令呢?为什么 LaTeX 内核不简单地定义一个命令(无论如何命名)来加载包?

答案1

2e 的创建时间相当久远,所以这一切都有点模糊,但我记得的原因如下:

  • LaTeX 2.09 没有类/包/选项概念。选项是\documentstyle带有扩展名的外部文件.sty
  • 对于 LaTeX2e,我们希望采用一种结构化的方法来处理类/包及其选项。
  • 这个结构是为包和类编写者准备的,不是为用户准备的,我们决定将这部分的命令用 CamelCase 来命名,例如,\RequirePackage
  • 例如,该层包含更多\RequirePackageWithOptions在用户层上没有对应命令的命令。

现在 LaTeX2.09 的情况相当混乱,有大量不兼容的扩展,而 2e 的目标之一就是巩固这一局面。为此,2e 概念不会在 LaTeX2.09 之上使用非常重要,因为这会导致另一种不兼容的风格。相反,LaTeX2e 应该(实际上做得相当好)允许在兼容模式下运行旧文档。

但是,文档级别上不应该有任何新功能可用!

然而,由于旧内容已被重新实现(例如,使用包机制),因此 LaTeX2e 在底层应该能够使用其新功能,并且这应该适用于 2.09 中作为样式选项存在的包。

因此,我们决定只为以 开头的文档提供用户级别的 LaTeX2e 扩展,\documentclass但阻止它们用于以 开头的旧文档\documentstyle。因此,\usepackage除非您有命令,否则不可用\documentclass,而确保这一点的方法是等到您看到命令 :-)。另一方面,\documenstyle{article}现在将在内部加载 2e,article.cls因此\RequirePackage即使在那时,所有的类和包命令也必须可用。因此,您可以在\documentclass使用之前加载包\RequirePackage,并不是因为它被认为非常有用或重要(尽管在某些情况下确实如此),而是因为它必须同时适用于兼容性和本机模式。

综上所述,存在这两个命令

  • 因为我们希望类/包设计器层之间有明确的区分
  • 并且无法在兼容模式下提供新功能

当然,这两个目标都没有强制执行,因为没有什么可以阻止用户\RequirePackage在以 开头的旧文档上使用\documentstyle。但总体而言,效果很好。类/包命令是您在用户文档中找不到的东西(通常),而不允许在兼容模式下使用新的 2e 功能的决定在我看来是 2e 很快被采用的关键因素之一。

答案2

由于它们\let彼此相等,因此显然没有太大区别,但存在文档级别和包级别命令的不同命名方案的问题,请参阅

宏命名的最佳实践?

并且\usepackage犯错误有助于人们从 LaTeX 2.09 语法轻松升级到 LaTeX 2e 语法。

此外(现在很难记得)可能曾经有过\usepackage\RequirePackage不完全相同的时候。包加载方案是 2e 的主要创新之一,我们经历了很多原型:-)

答案3

\usepackage正如您已经指出的,和之间的唯一区别\RequirePackage在于,\usepackage最初被定义为错误消息,但后来被定义为 的别名\RequirePackage

对此的一个解释可能是阻止普通用户在课程开始前加载软件包。这可能是从 LaTeX2.09 时代开始的(我自己没有经历过),据我所知,那时没有课程,只有样式文件,现在更正确地称之为。人们可能有一个类似类的.sty文件,可能只是将加载宏更改为,\documentclass而不将其放在文件的开头。禁止在类之前加载包将是一种教育措施,并可防止由于错误的加载顺序而导致的许多潜在问题。更改 LaTeX 格式已经是一项艰巨的工作,但处理所有这些反馈将是一场支持噩梦。then 的存在\RequirePackage仍然允许例外。

其他可能性可能是某些兼容性原因,或者这是在从 LaTeX2.09 更改为 LaTeX2e 时意外导致的。还有一些其他宏显然应该被更改或删除,但一旦 LaTeX2e 冻结就会卡住。一个例子是\@empty\empty,它们也是相同的。

答案4

我想说 LaTeX\RequirePackage为包编写器定义的部分原因只是为了与其他类似的包编写器命令行\ProvidesClass和相比具有一致的语法\LoadClass。但也因为\usepackage正如您自己描述的那样,它不等同于\RequirePackage:包编写器被允许预先加载包\documentclass,而普通用户通常不应该这样做。

相关内容