# Expanding the argument to \begin

I have some environments foo and bar that I would like to replace with the environments newfoo and newbar with the words "This is a modified foo/bar environment:" added before the environment. I am trying to do it in a loop, like so:

\documentclass{minimal}

\usepackage{amsthm}
\let\bar\relax

\newtheorem{foo}{Foo}
\newtheorem{bar}{Bar}
\newtheorem{newfoo}{New Foo}
\newtheorem{newbar}{New Bar}

\makeatletter
\@for\@env:=foo,bar\do{%
\renewenvironment{\@env}{%
This is a modified \@env environment:
\begin{new\@env}
}{%
\end{new\@env}
}%
}
\makeatother

\begin{document}
\begin{foo}
I want this to be New Foo.
\end{foo}

\begin{bar}
I want this to be New Bar.
\end{bar}
\end{document}


However, this does not work because \begin does not want to expand the command \@env. I have unsuccessfully tried to add \expandafters there, but I did not manage to make it work. I have also attempted to circumvent it by using

\renewenvironment{\@env}{%
This is a modified \@env environment:
\csname new\@env\endcsname
}{%
\csname endnew\@env\endcsname
}%


but apparently this does not work either (I'm not actually sure why).

Can someone suggest a working solution?

You need to use the expansion of \@env, not \@env. It's easier with expl3. In the second argument of \xfor, #1 denotes the current item in the list being processed.

\documentclass{article}
\usepackage{xparse}
\usepackage{amsthm}
\let\bar\relax

\newtheorem{foo}{Foo}
\newtheorem{bar}{Bar}
\newtheorem{newfoo}{New Foo}
\newtheorem{newbar}{New Bar}

\ExplSyntaxOn
\NewDocumentCommand{\xfor}{mm}
{
\clist_map_inline:nn { #1 } { #2 }
}
\ExplSyntaxOff

\xfor{foo,bar}{%
\renewenvironment{#1}{%
This is a modified #1 environment:
\begin{new#1}
}{%
\end{new#1}
}%
}

\begin{document}
\begin{foo}
I want this to be New Foo.
\end{foo}

\begin{bar}
I want this to be New Bar.
\end{bar}
\end{document}


Without the use of expl3 you might use:

\documentclass{minimal}

\usepackage{amsthm}
\let\bar\relax

% not necessary because we don't use \renewenvironment but define the macros used for the environment later
%\newtheorem{foo}{Foo}
%\newtheorem{bar}{Bar}

\newtheorem{newfoo}{New Foo}
\newtheorem{newbar}{New Bar}

\makeatletter
\@for\@env:=foo,bar\do{%
\expandafter\xdef\csname\@env\endcsname{%
This is a modified \@env\ environment:
\noexpand\begin{new\@env}}
\expandafter\xdef\csname end\@env\endcsname{\noexpand\end{new\@env}}
}
\makeatother

\begin{document}
\begin{foo}
I want this to be New Foo.
\end{foo}

\begin{bar}
I want this to be New Bar.
\end{bar}
\end{document}

• This might be very dangerous if the This is a modified... part contains commands. – egreg Aug 17 '17 at 9:01
• @egreg yes, in this case one would have to insert some \noexpands. I just wanted to show a way without expl3 for academic purposes. – Skillmon Aug 17 '17 at 9:08
• @egreg I'm curious, in what way is it dangerous? – Mereenie Aug 17 '17 at 12:36
• @Mereenie imagine you want to use a command inside of the definition which must not be expanded there (for any reason, e.g. being defined later). You'd have to mark it with \noexpand every time you use such a macro (because of \xdef expanding every expandable macro during the definition). That's what makes it not that user friendly and prone to errors. – Skillmon Aug 17 '17 at 12:39