如何重复使用一个命令名称两次或更多次?

如何重复使用一个命令名称两次或更多次?

我找到了如何重复使用命令名称

但是我如何才能多次重复使用一个命令,每次都使用以前的定义?如果我只是尝试类似

\newcommand{\aaa}{a}
\let\oldaaa\aaa
\renewcommand{\aaa}{\oldaaa b} % now \aaa is ab
\let\oldaaa\aaa
\renewcommand{\aaa}{\oldaaa c} % now \aaa should be abc

我明白了TeX 容量超出错误。

这是一个非常简单的例子。当我尝试编写一个可以完成类似任务的命令时,问题出现了,即在重复调用时连接其参数;因此,理想情况下,每次重复的代码都应该相似。

答案1

请记住,(La)TeX 是一种宏编程语言,它有一个称为“扩展”的奇怪东西。例如,如果

\newcommand{\aaa}{a}

然后\aaa 扩展a。换句话说,a是 的“替换文本” \aaa。在 的定义中

\let\oldaaa\aaa
\renewcommand{\aaa}{\oldaaa b} % now \aaa is ab

您正在将 的定义复制\aaa到 中\oldaaa(实际上类似于\def\oldaaa{<whatever \aaa is>},但是不是与 相同\def\oldaaa{\aaa}),随后将 重新定义为\aaa\oldaaa b扩张- 当你写 时\aaa,这将被 替换\oldaaa b,并且由于你\let\oldaaa\aaa,这将被 替换\aaa b,这是循环的。以下是分步展示:

\newcommand{\aaa}{a}
\let\oldaaa\aaa
\renewcommand{\aaa}{\oldaaa b}

> \aaa
> \oldaaa b % Expansion of \aaa
> \aaa b % Expansion of \oldaaa
> \oldaaa b b % Expansion of \aaa
> \aaa b b % Expansion of \oldaaa
> \oldaaa b b b % Expansion of \aaa
> ...

我认为您想要的是扩展重新定义时的内容,如下所示:

\newcommand{\aaa}{a}
\expandafter\renewcommand\expandafter\aaa\expandafter{\aaa b} % now \aaa is ab
\expandafter\renewcommand\expandafter\aaa\expandafter{\aaa c} % now \aaa should be abc

请注意,由于替换文本\aaa扩展在进行分配之前,因此无需使用额外的宏,例如\oldaaa。这也仅在重新定义的内容本身可扩展时才有效。

答案2

你可以避免\expandafter使用etoolbox包。这需要您的 TeX 可执行文件包含 e-TeX 扩展,但这很有可能是您的安装中的默认扩展。

\documentclass{article}
\usepackage{etoolbox}
\begin{document}
\newcommand{\aaa}{a}
\show\aaa
\apptocmd{\aaa}{b}{\message{aaa successfully patched}}{\message{aaa not successfully patched}}
\show\aaa
\apptocmd{\aaa}{c}{\message{aaa successfully patched}}{\message{aaa not successfully patched}}
\show\aaa
\end{document}

的参数\apptocmd是宏名称、要添加到定义中的内容,然后是成功或失败时要执行的操作。我使用最后一个参数只是为了向控制台/日志文件报告修补成功或失败。 \show将暂停编译并将宏的当前值写入控制台。每次都必须按 Enter 键才能继续。结果是:

...
> \aaa=\long macro:
->a.
l.6 \show\aaa

? [ENTER]
aaa successfully patched
> \aaa=macro:
->ab.
l.8 \show\aaa

? [ENTER]
aaa successfully patched
> \aaa=macro:
->abc.
l.10 \show\aaa

? [ENTER]
(./aaa.aux) )
No pages of output.
...

相关内容