我想在一个命令中定义多个新命令。它们的名称由参数参数化,但它们也应该能够在定义期间相互调用。以下是一个例子:
\documentclass{article}
\newcommand{\defFooAndBar}[2]{%
\expandafter\newcommand\csname foo#1\endcsname{#2}
\expandafter\newcommand\csname bar#1\endcsname{let us expand \foo#1 and show #2.}
}
\defFooAndBar{One}{the second argument}
\defFooAndBar{Two}{the second argument}
\begin{document}
\fooOne
\barOne
\fooTwo
\barTwo
\end{document}
但是,会产生一个错误:
! 未定义的控制序列。\barOne->让我们展开\foo One 并显示参数。
显然,Latex 在 \foo 后面放置了一个空格,因此 \foo#1 不被视为单个实体。是否可以向解析器表明它们属于同一类?
答案1
TeX 严格遵循代币. 在你的代码中
let us expand \foo#1 and show #2.
\foo
生成单个标记,并且#1
是参数标记,它将被宏调用时的实际参数替换。因此,当你这样做时
\defFooAndBar{One}{the second argument}
第二条命令定义为
let us expand \foo One and show the second argument
(空格只是为了显示一个标记在何处结束)。
\csname...\endcsname
解决方案:按照构建要定义的令牌的方式形成令牌:
\newcommand{\defFooAndBar}[2]{%
\expandafter\newcommand\csname foo#1\endcsname{#2}%
\expandafter\newcommand\csname bar#1\endcsname{let us expand \csname foo#1\endcsname and show #2.}%
}
这里不需要\expandafter
;而是需要形成令牌\fooOne
(或类似令牌)前 \newcommand
开始行动。