# Same environment with different names [duplicate]

A new environment can be made with:

\newenvironment{name}[1]{stuff at the beginning}{stuff at the end}


In the document the environment can be created with:

\begin{name} different stuff \end{name}


Now I want to call the same environment with different names. My solution is:

\newenvironment{name1}[1]{stuff1}{stuff2}
\newenvironment{name2}[1]{stuff1}{stuff2}
...
\newenvironment{nameN}[1]{stuff1}{stuff2}


This is pretty dirty and makes my code confusing. Do you know a better solution? Something like this would be great:

\newenvironment{name1, name2,  ... , nameN}[1]{stuff1}{stuff2}

• why use a different name not an argument? \begin{name2} looks weird, why not have \begin{name}[type=2]... or some other argument form to distinguish them? – David Carlisle Jul 28 at 10:33
• @campa I don't think, that this is what I mean. – Titanlord Jul 28 at 10:40
• @DavidCarlisle I'm working on Templates, that produce differen styled PDFs. But a TeX code with one template should work with all other templates. When doing math i often use \begin{theorem} etc. but when I do Pen and Paper I use \begin{MonsterBox} etc. The point is, that the TeX for math should work with Pen and Paper, too – Titanlord Jul 28 at 10:42
• why change the environment name, the latex model would normally be you use the same name with different definitions – David Carlisle Jul 28 at 12:08
• I still don't understand. What makes name1 different from name2? From what you've shown, they would have the same output. How is theorem different from MonsterBox? – Teepeemm Jul 28 at 13:14

The code below defines a new command \NewEnvironments that will define multiple copies of an environment using a comma separated list of names for the environments. The syntax is:

\NewEnvironments[#args]{comma separated list of names}{env beginning}{env end}


So the syntax is similar to \newenvironment except that the optional argument for the number of arguments must be first. For example, you can define a series of environments, name1, name2, name3, name4, that accept one argument using:

\NewEnvironments[1]{name1,name2,name3,name4}
{\textbf{Environment with one arg: ##1}\newline\itshape}% begin
{\newline\textbf{End of 1 environment}\par}             % end


Note the use of ##1, rather than #1, for the parameter inside the environment definition. Of course, since all of these environments are the name you could only use name1. On the other hand, the code supports defining environments that depend on their name such as:

\NewEnvironments[1]{name1,name2,name3,name4}
{\textbf{Environment #1 with one arg: ##1}\newline\itshape}% begin
{\newline\textbf{End of 1 environment}\par}                % end


Here is the MWE showing how to use the code:

\documentclass{article}
\usepackage{etoolbox,xparse}

% usage: \NewEnvironments[#args]{comma separated list of names}{env beginning}{env end}
\newcommand\NewEnvironments[4][0]{%
\renewcommand*\do[1]{\newenvironment{##1}[#1]{#3}{#4}}
\docsvlist{#2}
}

% examples

% environments with no arguments
\NewEnvironments{none1,none2,none3,none4}
{\textbf{Environment with no args}\newline\itshape}% begin
{\newline\textbf{End of 0 environment}\par}        % end

% environments with one arguments
\NewEnvironments[1]{name1,name2,name3,name4}
{\textbf{Environment with one arg: ##1}\newline\itshape} %  begin
{\newline\textbf{End of 1 environment}\par}              % end

\begin{document}

\begin{none1}stuff\end{none1}
\begin{none2}stuff\end{none2}
\begin{none1}stuff\end{none1}
\begin{none3}stuff\end{none3}
\begin{none4}stuff\end{none4}
\begin{none1}stuff\end{none1}

\begin{name1}{one}stuff\end{name1}
\begin{name2}{two}stuff\end{name2}
\begin{name1}{three}stuff\end{name1}
\begin{name3}{four}stuff\end{name3}
\begin{name4}{five}stuff\end{name4}
\begin{name1}{six}stuff\end{name1}

\end{document}


It seems unusual to me that the name environments are all exactly the same, but I accept that there may be good reasons for this. One way to do what you want without duplicating code is to have a "template" environment that contains the main code and then have the other environments use this. That is, a structure like:

\newenvironment{nametemplate}[1]{stuff1}{stuff2}
\newenvironment{name1}[1]{\nametemplate{#1}...}{...\endnametemplate}
\newenvironment{name2}[1]{\nametemplate{#1}...}{...\endnametemplate}
...


The dots ... inside the \newenvironment definitions allow you to include extra code if you want but, as described in the OP, these dots should be omitted.

• This is a bit better, but still needs a lot of code. So there is no better way in doing that? E.g. using lists and for-loops, so that a list contains all the names, and the for-loop makes the newenvironment defines (for-loop as a sujective function)? – Titanlord Jul 28 at 13:21
• @Titanlord See my update – Andrew Jul 29 at 1:15
• This is a pretty good answer! Thank you very much! – Titanlord Jul 29 at 9:09