\jobname、字符代码和 \detokenize

\jobname、字符代码和 \detokenize

我最近想\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。)

相关内容