我最近想\jobname
与一个字符串进行比较(使用xstring
包),但令我惊讶的是字符串从未匹配。虽然互联网告诉我我必须\detokenize
在字符串上使用。\detokenize
是一个 e-TeX 命令,它
当后面跟着一个 时
<general text>
,会扩展为产生一个由 10 个(空格)或 12 个(其他)字符标记组成的序列,对应于未扩展的\catcode
的标记的分解;<balanced text>
<general text>
不幸的是,我没有 TeXbook 的副本,所以这里有三个问题:
- 什么是“平衡文本”?
- 为什么
\jobname
扩展到作业名称时会出现“错误”的 catcode? - 在 e-TeX 之前人们如何
\jobname
与字符串进行比较?
答案1
这里有 3 个问题,但我想你会被放过!
“平衡文本”意味着参数必须具有平衡的分组字符,通常{
是和}
对。这是因为\detokenize
需要一个以类别代码为 1 (begin-group) 的标记开头的参数,就像标记寄存器一样。事实上,您可以使用标记寄存器和 做非常相似的事情\detokenize
:
\newtoks\mytoks
\def\test{stuff}
\mytoks\expandafter{\test}% \mytoks holds 'stuff' as letters
\detokenize\expandafter{\test}% Ouputs 'stuff' as 'other' tokens
在 中的类别代码中\jobname
,有许多地方您可以从 TeX 获得“字符串”,其中除空格之外的所有内容都有类别代码 12。您在\the\<somedimen>
和\meaning
中也看到同样的情况(稍后会详细介绍)。您必须询问 DEK 以了解完整的故事,但我的理解是,使用这种“字符串”方法是为了避免将任何标记意外添加到控制序列名称中。有些地方如果它们是“字母”,那么可能会出现问题。
最后,关于 e-TeX 之前的方法。正如我所说,\jobname
并不是唯一可以看到“字符串”输出的地方。特别是,\meaning
它的作用相同。所以如果你这样做
\def\testa{<whatever>}
\edef\testa{\meaning\testa}
\edef\testb{\jobname}
\edef\testb{\meaning\testb}
\ifx\testa\testb
...
如果两个名称作为字符列表一致,则测试为真。此方法有多种变体,例如 LaTeX 的\strip@prefix
,可用于创建没有任何前缀的“字符串”:
\makeatletter
\def\testa{<whatever>}
\edef\testa{\expandafter\strip@prefix\meaning\testa}% Now a 'string'
(正如 Martin Scharrer 所指出的,LaTeX 的\@onelevel@sanitize
与上面的相同:\@onelevel@sanitize\testa
相当于上面的最后一行。为了显示正在发生的事情,更清楚地看到\meaning
但在使用中你会选择\@onelevel@sanitize
。)