这段代码片段有何用途?

这段代码片段有何用途?

查看包的代码ifxetex,我发现了以下内容:

\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname ProvidesPackage\endcsname\relax\else
  \ProvidesPackage{ifxetex}
    [2010/09/12 v0.6 Provides ifxetex conditional]
\fi

我完全理解有人可能想在调用 之前检查是否正在使用 LaTeX \ProvidesPackage,以便使文件也可以通过普通的 TeX 使用。但是,我看不出第一行的重点。为什么只包含三个\expandafters 的组似乎只用于\if在 之前完成\endgroup?为什么不直接删除该组?

答案1

组已启动,然后

\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname ProvidesPackage\endcsname\relax\else
  \ProvidesPackage{ifxetex}
    [2010/09/12 v0.6 Provides ifxetex conditional]
\fi

剩余。现在第一个\expandafter被扩展,这导致第三个起作用,这又扩展了第四个并最终\csname ProvidesPackage\endcsname形成了\ProvidesPackagetoken,使其等同于\relaxif not defined。

现在我们只剩下

\expandafter\endgroup
\ifx\ProvidesPackage\relax\else
  \ProvidesPackage{ifxetex}
    [2010/09/12 v0.6 Provides ifxetex conditional]
\fi

其余部分\expandafter将展开\ifx。如果\ProvidesPackage没有先前的定义,则测试返回 true,并且

\endgroup\else\ProvidesPackage{ifxetex}[2010/09/12 v0.6 Provides ifxetex conditional]\fi

剩余。该组关闭,取消对 的含义分配\ProvidesPackage。然后\else展开,这意味着 TeX 会跳过所有标记,直到匹配\fi最终消失。

如果先前存在 的定义\ProvidesPackage,TeX 会跳过 之前的所有标记,包括\else,因此我们保留

\endgroup\ProvidesPackage{ifxetex}[2010/09/12 v0.6 Provides ifxetex conditional]\fi

该组已关闭并\ProvidesPackage执行(带有必要的扩展步骤)。尾随部分\fi具有空扩展。

寓意是,如果\ProvidesPackage在找到代码时未定义,则它不会出现在流程的末尾。

如果没有这个\begingroup\expandafter\expandafter\expandafter\endgroup技巧,如果之前没有定义的话,代码最终会\ProvidesPackage等同于\relax

相关内容