我正在阅读的代码miniltx
以了解 LaTeX 加载包文件的方式。我知道它被简化了,但有一个方面让我感到困惑。根据source2e
,\RequirePackage
有以下模板:
\RequirePackage[options]{name}[version]
这意味着它应该接受三个或更少的参数。但是,在简化定义\RequirePackage
和完整版本中source2e
,以下内容大致相同:
\def\RequirePackage{%
\@fileswithoptions\@pkgextension}
\def\@fileswithoptions#1{% Nice
\@ifnextchar[%]
{\@fileswith@ptions#1}%
{\@fileswith@ptions#1[]}}
\def\@fileswith@ptions#1[#2]#3{% Nice
\@ifnextchar[%]
{\@fileswith@pti@ns#1[#2]#3}%
{\@fileswith@pti@ns#1[#2]#3[]}}
我被困在这里了。为什么会出现第四个参数,并且为什么它被方括号括起来?(我省略了一些行)
\def\@fileswith@pti@ns#1[#2]#3[#4]{% ???
\def\reserved@b##1,{%
\ifx\@nil##1\relax\else
\ifx\relax##1\relax\else
\noexpand\@onefilewithoptions##1[#2][#4]\noexpand\@pkgextension
\fi
\expandafter\reserved@b
\fi}%
\edef\reserved@a{\zap@space#3 \@empty}%
\edef\reserved@a{\expandafter\reserved@b\reserved@a,\@nil,}%
\reserved@a}
\def\@pkgextension{sty}
\def\@onefilewithoptions#1[#2][#3]#4{%
\input #1.#4 }
我猜想它与后缀有关.sty
,但我仍然不明白,特别是因为第四个参数中的方括号。
答案1
宏\@fileswithoptions
还用于加载班级文件。事实上,你会发现
\def\LoadClass{%
\ifx\@currext\@pkgextension
\@latex@error
{\noexpand\LoadClass in package file}%
{You may only use \noexpand\LoadClass in a class file.}%
\fi
\@fileswithoptions\@clsextension}
与带有可选参数的宏一样,参数通过使用不同的宏来获取。在这种情况下,宏\@fileswithoptions
会存储其单个参数并检查是否[
跟有。如果有[
,\@fileswith@ptions#1
则调用,否则\@fileswith@ptions#1[]
(因此会提供一个空的可选参数)。
请注意,#1
将是\@pkgextension
或\@clsextension
必须结转。
接下来扫描常规参数,仍然继续扫描前两个参数;然后是另一个可选参数。因此,最后一个宏,即执行实际工作的宏,将需要四參數。
在latex.ltx
我们看到
\def\@fileswith@pti@ns#1[#2]#3[#4]{%
\ifx#1\@clsextension
\ifx\@classoptionslist\relax
\xdef\@classoptionslist{\zap@space#2 \@empty}%
\def\reserved@a{%
\@onefilewithoptions#3[{#2}][{#4}]#1%
\@documentclasshook}%
\else
\def\reserved@a{%
\@onefilewithoptions#3[{#2}][{#4}]#1}%
\fi
[...]
你会发现这个论点是使用。在 的简化形式 used 中miniltx.tex
,参数#1
实际上并未使用,因为加载类毫无意义。因此,代码作者决定不使用,#1
并在拾取参数时坚持使用标准定义:仅精简了少数部分。
答案2
第一个参数将是\@pkgextension
有趣的,除非您删除了定义中的某些行\@fileswith@pti@ns
,否则第一个参数实际上不会在任何地方使用。