例如,有一个命令\x
和另一个\y
。我想重新定义,\x
以便它变成原来的自己,然后是\y
。我发现直接使用\renewcommand\x{\x\y}
不起作用,因为它会让 LaTeX 陷入某种无限的递归循环,导致
TeX capacity exceeded, sorry [input stack size=10000]
所以也许我需要一些可以容纳旧的定义\x
但不会扩展到它的东西。
答案1
保存定义的基本原语是,\let
但是这必须小心使用(或者更好地说,不要使用)与更高级别的乳胶命令一起使用,因为通常命令\x
只有定义\def\x{\protect\xinternal}
并且\let
只保存顶层,因此您的 renewcommand 会\xinternal
根据其自身进行定义。
LaTeX 具有对\NewCommandCopy
组成由任何标准 Latex 定义形式定义的命令的内部宏进行“深度复制”的功能:
\documentclass{article}
\newcommand\x[1][hmm]{#1!}
\begin{document}
\x[A]
%\let\originalx\x % this would loop
\NewCommandCopy\originalx\x
\renewcommand\x[1][oops]{\originalx[#1] ??}
\x[B]
\end{document}
然而,以允许多个包调整同一命令的方式修改功能的更可控的方法是使用通用命令挂钩:
\documentclass{article}
\newcommand\x[1][hmm]{#1!}
\begin{document}
\x[A]
\AddToHook{cmd/x/after}{???}
\x[B]
\end{document}
答案2
如果您使用有用的类,它将为您存储原始定义:
\documentclass{beamer}
\newcommand{\x}{x}
\newcommand{\y}{y}
\renewcommand<>{\x}{\beameroriginal{\x}\y}
\begin{document}
\begin{frame}
\x
\end{frame}
\end{document}
如果您不使用如此优秀且行为良好的类,您可以使用该beamerarticle
包使其在其他类中也可用:
\documentclass{article}
\usepackage{beamerarticle}
\newcommand{\x}{x}
\newcommand{\y}{y}
\renewcommand<>{\x}{\beameroriginal{\x}\y}
\begin{document}
\begin{frame}
\x
\end{frame}
\end{document}