Duplicating Environments
When you define an environment with
\newenvironment{foo}[1]{start code with #1}{end code}
what happens internally (after some checking for optional arguments, testing if the environment exists, and taking care of a possible star argument to \newenvironment
) essentially boils down to
\newcommand\foo[1]{start code with #1}% actually \new@command
\def\endfoo{end code}
This means if the environment has no optional arguments
\let\myfoo\foo
\let\endmyfoo\endfoo
copies the environment {foo}
as environment {myfoo}
. (If it has an optional argument \LetLtxMacro
should be used instead of \let
, see When to use \LetLtxMacro?.)
In the article
class the {figure}
environment is defined as
\newenvironment{figure}
{\@float{figure}}
{\end@float}
so saying
\let\myfigure\figure
\let\endmyfigure\endfigure
works:
\documentclass{article}
\newenvironment{foo}[1]{start foo with (#1)}{end foo}
\let\myfoo\foo
\let\endmyfoo\endfoo
\let\myfigure\figure
\let\endmyfigure\endfigure
\begin{document}
\begin{myfoo}{arg}
bar
\end{myfoo}
\begin{myfigure}
copied figure
\caption{my figure}
\end{myfigure}
\end{document}
Some environments like {verbatim}
or AMSmath's {align}
cannot be copied this way since they need to find \end{verbatim}
or \end{align}
, respectively, exactly.
Patching \section
as you do is not an especially good way to proceed, because you lose all the flexibility of the original command; one always has to look how a command is defined, before patching it. You'll discover that \section
has no argument, for instance.
The same holds for environments; they are realized through a pair of commands: with
\newenvironment{foo}[1]
{something with #1 at the start}
{something at the end}
LaTeX defines \foo
and \endfoo
in a way basically equivalent to
\newcommand{\foo}[1]{something with #1 at the start}
\def\endfoo{something at the end}
In standard LaTeX the \end...
command is always parameterless (and \newcommand
wouldn't allow to define it).
It's also important to know when the commands are executed; here's the definition of \begin
:
% latex.ltx, line 3944:
\def\begin#1{%
\@ifundefined{#1}%
{\def\reserved@a{\@latex@error{Environment #1 undefined}\@eha}}%
{\def\reserved@a{\def\@currenvir{#1}%
\edef\@currenvline{\on@line}%
\csname #1\endcsname}}%
\@ignorefalse
\begingroup\@endpefalse\reserved@a}
Apart from some details, what happens with \begin{foo}
is that LaTeX essentially does
\begingroup<bookkeping stuff>\foo
with some bookkeeping for later checks in the \end
part. Similarly, \end{foo}
will do
\endfoo<checks>\endgroup
Thus the same method used for ordinary macros will work; however,
\let\svfigure\figure
\let\endsvfigure\endfigure
\renewenvironment{figure}
{\blahblah\begin{svfigure}}
{\end{svfigure}\moreblah}
wouldn't be a particularly good way to patch the figure
environment. For one thing, a typing mistake \end{fiugre}
in the input file would result in the puzzling message
! LaTeX Error: \begin{svfigure} on input line 11 ended by \end{fiugre}.
See the LaTeX manual or LaTeX Companion for explanation.
Type H <return> for immediate help.
...
l.13 \end{fiugre}
and users will not understand it because they have no idea about the svfigure
environment they have never started. The usual solution is to say
\let\svfigure\figure
\let\endsvfigure\endfigure
\renewenvironment{figure}
{\blahblah\svfigure}
{\endsvfigure\moreblah}
so that the <bookkeeping stuff>
will be done for figure
but not for the inner svfigure
.
However, not all environments are happily redefined this way.
Environments taking an optional argument should use \LetLtxMacro
(with \usepackage{letltxmacro}
) instead of \let
, but this is true also for macros. For the \end...
command \let
is always sufficient. More importantly, this way of doing might not work with environments defined with different tools, notably \NewEnviron
(environ
package) or \NewDocumentEnvironment
(xparse
package).
Some other environments have their own peculiarities: don't try redefining lrbox
(which wouldn't make sense anyway), nor verbatim
. Something like
\let\svverbatim\verbatim
\let\endsvverbatim\endverbatim
\renewenvironment{verbatim}
{<something>\svverbatim}
{\endsvverbatim<something>}
will simply not work and keep you in permanent verbatim mode unless you load the verbatim
package. But don't try this for changing the font size in verbatim
, it won't work.
Patching macros and environments is sometimes an arcane activity best suited for necromancers rather than even skilled LaTeX programmers.