定义时 \edef 的参数值是什么?

定义时 \edef 的参数值是什么?

假设我们有以下简短的文档

\documentclass{article}

\def\foo#1{\if#1XX\else not X\fi}

\edef\bar#1{\if#1XX\else not X\fi}

\begin{document}
foo: X = \foo{X}, Y = \foo{Y}

bar: X = \bar{X}, Y = \bar{Y}
\end{document}

结果是

foo:X = X,Y = 非 X
bar:X = 非 X,Y = 非 X

第一种情况很容易理解,的扩展\foo发生在调用宏时,#1X或替换Y,并且\if用这两个字符中的任一个执行 。

不太清楚的是 的结果\bar。我理解 的扩展\if发生在定义宏时,因此 的具体值#1尚不可用;TeX 在扩展的替换文本中为参数留下了“空洞”,以便在实际调用宏时稍后填充。但要正确扩展\if一些#1需要的值。

参数似乎不能留空,否则\bar不应该给出not X,因为\if XX总是为真。它们似乎也没有被\relax编辑,因为

\edef\baz#1{\ifx#1\relax yes\else no\fi}

总是给予no

那么定义的时候参数采用的是什么值呢?

答案1

当 TeX 执行\edef<macro><parameter text>{1 <replacement text>}2<macro>时,它会将替换文本和{1放在一边,然后进行完全扩展,<replacement text>直到找到匹配的}2。最后它执行

\def<macro><parameter text>{<full expansion of the replacement text>}

的完整展开\if#1XX\else not X\finot X,因为#1是不同的字符标记(按字符代码)。

因此你的\edef变得和

\def\bar#1{not X}

再举一个例子,

\edef\rightbracestring{\string}}

是完全合法的,即使它看起来括号不匹配,因为在进行扩展时,遇到的第一个括号}已经被标记为}12。这证明 TeX 不会先吸收整个<replacement text>,而是像在正常情况下一样执行扩展,不同之处在于匹配的}2会停止该过程并恢复赋值。

答案2

我想说的是,它#1hance 进行比较,总是选择错误的分支。(比较第二个测试,它 #与正确的分支进行比较#并选择正确的分支)

\edef\bar#1{\if#1#1 (TRUE)\else #1 (FALSE)\fi}

\show\bar


\edef\bar#1{\if##1 (TRUE)\else (FALSE)\fi}

\show\bar

\bye

给予

> \bar=macro:
#1->#1 (FALSE).
l.3 \show\bar

> \bar=macro:
#1->1 (TRUE).
l.8 \show\bar

相关内容