可变参数宏

可变参数宏

我正在尝试使用可变参数创建宏,并对其进行迭代。最终结果应该是:

\foreach[x]((var = \x )){foo}{bar}{baz}\null

评估为

var = foo var = bar var = baz

我的天真猜测是这样的:

\def\Macro#1{\if \null#1 . \else ,\noexpand\Macro \fi}
\Macro foogg\null

我期望它评估为,,,,,.,但它评估为,oogg。我理解\noexpand行为有误吗?

答案1

更改\noexpand\expandafter,这就是你需要“跳过”的\fi。同样,埃格尔指出,\if\null不会起作用。要么使用\ifx,要么更改\null\relax,并希望它不包含在您的文本中。之所以\relax会起作用,是因为它不可扩展并\if接受它,而不是扩展。由于\relax\null可能被其他人使用,更安全的选择是使用不存在的命令,例如\thisIStoheczSdelimiter

\def\Macro#1{\ifx\thisIStoheczSdelimiter#1 . \else ,\expandafter\Macro \fi}
\Macro foogg\thisIStoheczSdelimiter

至于工作foreach周期,请查看pgffor包。你的代码,如果我没记错的话,可以重写为

\foreach \x in {foo, bar, baz}{ var = \x, }

答案2

\def\Macro#1{\if \null#1 . \else ,\noexpand\Macro \fi}
\Macro foogg\null

\def\xnull{\null}
\def\Macro#1{\def\tmp{#1}\ifx\tmp\xnull\else ,#1\expandafter\Macro \fi}
\Macro foogg\null

\bye

,foogg从原始版本生成,然后,f,o,o,g,g从修改后的版本生成,在原始版本中,使其\noexpand表现\Macro得像\relax,因此在第一次调用后不执行任何操作,因此只f被视为参数。

以上是纯 TeX,但如果你打算将其用于 LaTeX,你应该使用不同的语法,LaTeX 的主要目的之一是提供统一的语法结构,LaTeX 命令绝不接受可变数量的{}参数。LaTeX 语法是单个{}参数内的逗号分隔列表。

相关内容