查看包的代码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 使用。但是,我看不出第一行的重点。为什么只包含三个\expandafter
s 的组似乎只用于\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
形成了\ProvidesPackage
token,使其等同于\relax
if 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
。