以下代码有效:
\def \robble {robble}
\def \robbles {\robble\robble}
但以下却不行:
\def \robbles {robble}
\def \robbles {\robbles robble}
总体目标是变得robbles
robblerobble。我需要类似第二个示例的东西,其中我将附加到变量的当前值。现在的编写方式会导致堆栈溢出。有没有办法在 LaTeX 中附加到变量?
答案1
\robbles
您需要在第二个宏定义中扩展该宏,否则您将得到一个循环引用(\robbles
调用\robbles
,而调用又调用\robbles
)。您可以通过以下方式做到这一点:
\def\robbles{robble}
\edef\robbles{\robbles robble}
其中 代表\edef
。expanded definition
这将完全扩展定义中的宏,直到只剩下不可扩展的标记。在这种情况下,这没问题,因为 的内容一\robbles
开始就只是不可扩展的标记。
但是如果你最初定义\robbles
包含一个宏,那么你只需要\robbles
在新定义中展开一次。为此,你可以\unexpanded\expandafter{\robbles}
在宏定义中使用:
比较:
\documentclass{article}
\begin{document}
\def\robble{robble}
\def\robbles{\robble} % \robbles contains the macro \robble
\edef\robbles{\robbles robble}
\robbles % Will print "robblerobble"
\def\robble{ROBBLE} % We're redefining the macro used in the original definition
\robbles % Will still print "robblerobble", because we completely expanded \robble in the definition of \robbles
% Let's try again
\def\robble{robble}
\def\robbles{\robble} % \robbles contains the macro \robble
\edef\robbles{\unexpanded\expandafter{\robbles}robble}
\robbles % Will print "robblerobble"
\def\robble{ROBBLES} % We're redefining the macro used in the original definition
\robbles % Will print "ROBBLErobble", because we only expanded \robbles once in the definition of \robbles
\end{document}
答案2
如果它不必是本地的,您可以用来\g@addto@macro
附加到宏:
\g@addto@macro\robbles{robble}
如有必要,使用\makeatletter
和\makeatother
因为@
名字里的。
或者,如果您更改扩展顺序,则可以将其附加到宏,如果分组,它也可以在本地工作:
\expandafter\def\expandafter\robbles\expandafter{\robbles robble}
\expandafter
可以反转两个 token 的扩展。通过使用多个\expandafter
,您可以在这里实现第二个 token 的\robbles
扩展。进一步的解释在expandafter 教程由 Stephan v. Bechtolsheim 在 TUGboat 9-1 中撰写。
答案3
如果我们希望完全扩展宏,那么\edef\mymacro{\mymacro,3}
如上所述,效果会很好。
但是如果你只想扩展一次宏,那么我更喜欢\expanded{…}
更多(直观地讲,它会扩展其参数,除了以 为前缀的标记\noexpand
,然后扩展结果字符串)。由于我们想推迟对\def
和的评估,我们可以简单地在它们前面\mymacro
添加:\noexpand
\documentclass{article}
\begin{document}
\def\mymacro{1,2}
My macro is \mymacro
\expanded{\noexpand\def\noexpand\mymacro{\unexpanded\expandafter{\mymacro},3}}
My macro is \mymacro
\end{document}
请注意,如果我们加载 etoolbox,\unexpanded\expandafter{…}
则可以用 替换\expandonce{…}
,因为它实际上只扩展一次宏。