在 Heiko Oberdiek 的许多包装中,我们都能看到这种类型的结构:
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname pdf@filesize\endcsname\relax
\ifxetex
...
\expandafter
将命令包含在内的目的是什么begingroup...\endgroup
?这种方法有什么优点?
答案1
哦,鬼鬼祟祟的 Heiko:-)
它测试 csname 是否未定义(或放宽),但如果它之前未定义,则它保持未定义状态,因为隐式定义会\relax
在组内部发生。
纯 TeX:
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname aaaa\endcsname\relax
\show\aaaa
\fi
\expandafter\ifx\csname bbbb\endcsname\relax
\show\bbbb
\fi
\bye
生成:
(./heiko.tex
> \aaaa=undefined.
l.3 \show\aaaa
?
> \bbbb=\relax.
l.7 \show\bbbb
?
)
答案2
实际上,这与避免哈希表的过度填充有关。
问题在于
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname pdf@filesize\endcsname\relax
...
\else
...
\fi
是它不可扩展。使用 eTeX,你可以改用\ifcsname
。如果你测试的是控制序列而不是名称,你可以改用\ifdefined
。但 Heiko 会创建独立于平台的包。
你也可以考虑电子工具箱packages 的定义\csletcs
:
\newrobustcmd*{\csletcs}[2]{% [2011/01/03]
\ifcsdef{#2}{\expandafter\let
\csname#1\expandafter\endcsname
\csname#2\endcsname}{\csundef{#1}}%
}
这期权包将其定义为(此处使用假名):
\def\letnames#1#2{%
\begingroup\expandafter\endgroup
\expandafter\let\csname#1\expandafter
\endcsname\csname#2\endcsname
}
因为无论如何都是不可扩展的。如果最初未定义,\let
则#1
和#2
未定义。#2