6

Suppose I need to redefine the mdframed environment (from the mdframed package), using the old definition of mdframed. In the example here, perhaps the target (here, changing the color of the text) can be achieved by an other method more easily, but I need to know how to realize this with a \renewenvironment (if this is possible).

First try:

\renewenvironment{mdframed}[1][]{\begin{mdframed}[#1]\color{red}}{\end{mdframed}}

As the new environment (mdframed), with the same name as the old (mdframed), uses the old environment (mdframed) with the same name as the new, the TeX stack capacity is exceeded by infinite calls (the exact error is: TeX capacity exceeded, sorry [input stack size=10000].).

I tried to avoid this error by using \let\oldmdframed\mdframed and \let\endoldmdframed\endmdframed (see the code below), but this seems to still generate an infinite call in the \renewenvironment (because the definition of \oldmdframed seems not to be frozen with the original definition of \mdframed). Though the Wikibooks page TeX/let says that \let can be the solution at least for a 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}

A solution to prevent the error is obviously to rename the new environment with a new name, but can we keep the original name without having this stack overflow error?

2 Answers 2

13

you need a deep copy,

\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}

although it's usually better to use a env hook and avoid redefinition

1
4

In helpful documentclasses, the original definition of the environment is still accessible via \begin{original<env. name>}...\end{original<env. name>}. You can use the beamerarticle package to bring this feature to other classes as well:

\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}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .