当环境以相同的名称重新定义时,如何使用环境的旧定义?(为了避免堆栈溢出)

当环境以相同的名称重新定义时,如何使用环境的旧定义?(为了避免堆栈溢出)

假设我需要使用 的旧定义重新定义mdframed环境(来自包) 。在这里的例子中,也许目标(这里是更改文本的颜色)可以通过其他方法更轻松地实现,但我需要知道如何使用 来实现这一点(如果可能的话)。mdframedmdframed\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}

相关内容