我编写了一个简单的宏,用特殊字体排版尖括号中的所有内容,并忽略反斜杠字符。
\catcode`\>=\active
\def>{\endgroup}
\catcode`\<=\active
\def<{\begingroup\tt\obeyspaces\frenchspacing\catcode`\\=12\relax}
\everymath{\catcode`\<=12\catcode`\>=12\relax}
\everydisplay{\catcode`\<=12\catcode`\>=12\relax}
直接输入时它可以正常工作,但传递到另一个宏时会失败,例如,
<\TeX> % correct
\def\identity#1{#1}
\identity{<\TeX>} % incorrect, does expand for some reason
\bye
有没有办法来解决这个问题?
答案1
您可以使用\scantokens
(也来自 e-tex)来重新标记而不是\detokenize
ing。然后它确实正确地添加了空格(连续的空格被忽略,您可以通过\catcode`\ =\active
在 之后执行来更改这\dospecials
一点)。而且由于它重新标记,您可以将其传递给宏。
\catcode`\<=\active
\def<#1>{{\tt\frenchspacing\def\do##1{\catcode`##1=12\relax}\dospecials\scantokens{#1}}}
<\TeX\TeX>
<\TeX \TeX>
\def\identity#1{#1}
\identity{<\TeX>}
答案2
catcode 的变化会影响文件中字符的标记方式,但对已经生成的标记没有影响。
在您的示例中#1
是单个标记\TeX
。
这就是为什么你不能\verb
在乳胶中使用参数的原因。
如果您不受经典 tex 的限制,您可以使用\detokenize
它,pdftex
但需要etex
dvi 版本。
\catcode`\<=\active
\def<#1>{\begingroup\tt\obeyspaces\frenchspacing\detokenize{#1}\endgroup}
\everymath{\catcode`\<=12\relax}
\everydisplay{\catcode`\<=12\relax}
It works just fine when typing direcly but fails when passed into another macro, e.g.,
<\TeX> % correct
\def\identity#1{#1}
\identity{<\TeX>} % incorrect, does expand for some reason
\bye
请注意,这里的字符标记后面有一个空格\TeX
,包括从 csname 重新构造的最后一个空格。