# How to define an environment inside which any undefined environment is “defined”?

I need to define an environment inside which I can simply do \begin{some string}some stuff\end{some string} with arbitrary strings, and have it process these as environments (which output e.g. \textbf{some string:} somestuff). The environments should also accept an optional parameter that modifies their behavior.

Preexisting environments like enumerate or itemize should still work inside my environment.

I can achieve most of this with the following code:

\makeatletter
\def\ifEqString#1#2{\def\csa{#1}\def\csb{#2}\ifx\csa\csb }
\def\ifUnDefinedCs#1{\expandafter \ifx\csname#1\endcsname\relax}
\let\old@begin=\begin
\def\new@begin{\ifx[\next \expandafter\newXX@begin \else \expandafter\newX@begin \fi}
\def\newX@begin#1{\ifUnDefinedCs{#1}\newZ@begin{#1}\else\old@begin{#1} \fi}
\newenvironment{myenvironment}{\begingroup%
\def\begin{\futurelet\next\new@begin}
}{\endgroup}
\makeatother


However, this breaks preexisting environments like tabular that require parameters to be given. Is there a better way to code this that doesn't break these?

I think you're going to have to do some heavy lifting here. A simple patching of \begin won't do the job because \begin has to be able to read optional and required arguments on occasion. You're much better off just declaring a custom environment for your needs. You can even keep your typing concise by giving it a nice short name, e.g., (assuming xparse is available):

\NewDocumentEnvironment{||}{ m o }{%
\IfNoValueTF{#2}{%
No optional argument
}%
{%
Optional argument #2
}%
\textbf{#1:}}%
{} % We don't need to do anything at the end

\begin{||}{some string} some stuff \end{||}


But if you don't want to do that, declare the command that will handle your special environment:

\NewDocumentCommand{\UndeclaredEnvironment}{ m o }{...}


This will take the name of the undeclared environment as its first required argument and then an optional argument and you can define it like we did the environment above.

Now comes surgery time. Before we go any further, let me emphasize that this is a bad idea. texdoc source2e will give you the annotated source code for LaTeX. The definition for \begin appears on page 473 in the D ltmiscen.dtx section:

\DeclareRobustCommand*\begin[1]{%
\UseHook{env/#1/before}%
\@ifundefined{#1}%
{\def\reserved@a{\@latex@error{Environment #1 undefined}\@eha}}% ❶
{\def\reserved@a{\def\@currenvir{#1}%
\edef\@currenvline{\on@line}%
\@execute@begin@hook{#1}%
\csname #1\endcsname}}%
\@ignorefalse
\begingroup\@endpefalse\reserved@a}


The line we're interested in is the one I've marked with ❶. You'll want to copy the above to a new command, say, \BadIdeaBegin (with \makeatletter active) and change that line to read:

    {\def\reserved@a{\def\@currenvir{#1}%
\edef\@currenvline{\on@line}%
\@execute@begin@hook{#1}%
\UndeclaredEnvironment{#1}}}%


Then you can have your environment be

\newenvironment{VeryBadIdea}{\let\begin\BadIdeaBegin}{}


And things will work the way you think you want them to work.

• +1 for \BadIdeaBegin – Dr. Manuel Kuehner May 15 at 3:56
• Maybe it's a bad idea, but I don't really see a way around it in my specific use case. – gmvh May 15 at 4:21
• @gmvh then you should probably explain what the use case actually is. I don't think anyone here have understood your need for such a construction – daleif May 15 at 5:47
• I have to be able to potentially \input blocks of LaTeX code written for various local adaptations of a private package, each of which contains various environments that all do basically the same thing (i.e. very little but print their name and contents). But the individual input files also have to continue working in their original context, so I can't change those environments. I don't see how to do that except in the way I asked about. – gmvh May 15 at 16:53