假设我需要使用 的旧定义重新定义mdframed
环境(来自包) 。在这里的例子中,也许目标(这里是更改文本的颜色)可以通过其他方法更轻松地实现,但我需要知道如何使用 来实现这一点(如果可能的话)。mdframed
mdframed
\renewenvironment
第一次尝试:
\renewenvironment{mdframed}[1][]{\begin{mdframed}[#1]\color{red}}{\end{mdframed}}
由于新环境 (mdframed) 与旧环境 (mdframed) 同名,而新环境又使用与新环境同名的旧环境 (mdframed),因此无限调用会导致 TeX 堆栈容量超出(具体错误为:TeX 容量超出,抱歉 [输入堆栈大小=10000]。)。
\let\oldmdframed\mdframed
我尝试使用和来避免此错误\let\endoldmdframed\endmdframed
(参见下面的代码),但这似乎仍然会在中产生无限调用\renewenvironment
(因为的定义\oldmdframed
似乎没有与的原始定义一起冻结\mdframed
)。尽管 Wikibooks 页面TeX/let他说这\let
至少对于 来说是一个解决方案renewcommand
。
\documentclass{article}
\usepackage{xcolor}
\usepackage{mdframed}
\let\oldmdframed\mdframed
\let\endoldmdframed\endmdframed
\renewenvironment{mdframed}[1][]{\oldmdframed[#1]\color{red}}{\endoldmdframed} % <-- stack exceeded
\begin{document}
\begin{mdframed}
test
\end{mdframed}
\end{document}
显然,防止该错误的解决方案是使用新名称重命名新环境,但是我们是否可以保留原始名称而不会出现此堆栈溢出错误?
答案1
您需要深层复制,
\documentclass{article}
\usepackage{xcolor}
\usepackage{mdframed}
\NewCommandCopy\oldmdframed\mdframed
\NewCommandCopy\endoldmdframed\endmdframed
\renewenvironment{mdframed}[1][]{\oldmdframed[#1]\color{red}}{\endoldmdframed} % <-- stack exceeded
\begin{document}
\begin{mdframed}
test
\end{mdframed}
\end{document}
尽管通常最好使用env
钩子并避免重新定义
答案2
在有用的文档类中,环境的原始定义仍然可以通过 访问\begin{original<env. name>}...\end{original<env. name>}
。您也可以使用该beamerarticle
包将此功能引入其他类:
\documentclass{article}
\usepackage{beamerarticle}
\usepackage{xcolor}
\usepackage{mdframed}
\renewenvironment<>{mdframed}[1][]{%
\begin{originalmdframed}[#1]\color{red}%
}{%
\end{originalmdframed}%
}
\begin{document}
\begin{mdframed}
test
\end{mdframed}
\end{document}