2

Say that we have an environment that is used like this:

\begin{foo}
... code in here
\end{foo}

And, without changing the above syntax in our document, we would like to redefine what the foo environment does.

For example, say we want to wrap foo in a bar, so that the effect of the above code would be like this:

\begin{bar}
    \begin{foo}
... code in here
    \end{foo}
\end{bar}

For example, as suggested in this post we can do the following:

\let\OldFoo\foo

% in the minimal redefinition case
\renewcommand{\foo}[1]{\OldFoo#1\endfoo}

% in the wrapping w/ bar case
\renewcommand{\foo}[1]{\begin{bar}\OldFoo#1\endfoo}\end{bar}}

And this would allow us to do the following:

\foo{ ... code in here }

However, that's not the syntax we want - it's essentially a new \foo command, not redefining \begin{foo}...\end{foo}


My attempt is the following:

\let\origfoo\foo
\let\origendfoo\endfoo

\renewcommand{\foo}[1]{
  \begin{bar}
  \origfoo{#1}
}

\renewcommand{\endfoo}[0]{
  \origendfoo
  \end{bar}
}

... but it doesn't seem to work.

Any thoughts on how to do this?

P.S. Bonus Q: I don't understand where \endfoo is coming from. Is \end{foo} a syntax shorthand for \endfoo in LaTeX?

3

In LaTeX an environment consists of two macros (plus some more code added by \begin and \end). \newenvironment and \renewenvironment define both of these commands. The following saves the values of \Foo and \endFoo and uses those to define another version of the environment Foo which also incorporates the \begin and \end code of Bar.

\documentclass[]{article}

\newenvironment{Foo}
  {%
    \itshape
    \ignorespaces
  }
  {%
    \ifhmode\unskip\fi
  }

\newenvironment{Bar}
  {%
    \bfseries
    \ignorespaces
  }
  {%
    \ifhmode\unskip\fi
  }

\begin{document}
\begin{Bar}
  Test this
\end{Bar}
\begin{Foo}
  Test this
\end{Foo}
\begin{Bar}
  \begin{Foo}
    Test this
  \end{Foo}
\end{Bar}

\let\FooOrig\Foo
\let\endFooOrig\endFoo
\renewenvironment{Foo}
  {%
    \Bar
    \FooOrig
  }
  {%
    \endFooOrig
    \endBar
  }%
\begin{Foo}
  Test this
\end{Foo}

\end{document}

enter image description here

| improve this answer | |
  • You should consider \ignorespacesafterend. – egreg Sep 5 '18 at 21:14
  • @egreg I don't see any difference when using it. What should be its effect? – Skillmon likes topanswers.xyz Sep 5 '18 at 21:18
  • It should be used instead of \ifhmode\unskip\fi. It's much cleaner. – egreg Sep 5 '18 at 21:19
  • 1
    @egreg but it does something completely different (I just tested). The \ifhmode\unskip\fi removes a trailing space from the contents of the environment, while the \ignorespacesafterend removes the space after the environment. I think the former is better (while being less clean), as one is used to this behaviour (compare e.g. tabular the space after \end is the one you'd have to comment). – Skillmon likes topanswers.xyz Sep 5 '18 at 21:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.