The reason I got told to use the "plain form" for inner environments was, as already quoted in the question, that if the normal \begin
/\end
form is used and the last \end{<outer env>}
is missing or misplaced the error message includes the name of the last inner \begin{<env>}
. A user might not be aware that the outer environment uses this environment internally and can get confused. Because it can be part of several used environments the error doesn't give that much information where to look (except the line number, which might be all what you need if you stick with one \begin
per line).
Let us look at the definitions of \begin
and \end
to see what the exact differences between the two forms are:
\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}
So \begin
checks for if #1
(the environment name) exists as macro and reports an error if not. Otherwise the current list and the name is saved. The latter as \@currenvir
. This is done inside a group opened with \begingroup
. The @ignore
switch is for ignoring spaces afterwards and the @endpe
is "to suppress the paragraph indentation in text immediately following a paragraphmaking environment" (source2e).
\def\end#1{%
\csname end#1\endcsname\@checkend{#1}%
\expandafter\endgroup\if@endpe\@doendpe\fi
\if@ignore\@ignorefalse\ignorespaces\fi}
The \end
macro executes \end<envname>
. It then checks using \@checkend
if the given name is equal to the one used by the last opened \begin
. If both aren't equal an error message is printed. It then executes the \@doendpe
code to suppress paragraph indentation if enabled and closes the group. Spaces might then be ignored if that was enabled.
Let's look at the differences: As seen in the above code description the things which are done in addition if the normal LaTeX form is used are:
- The existence is checked.
- A group is added.
- The environment name is saved.
- The number of the line where the environment starts is saved.
- Spaces can be ignored afterwards.
- A paragraph indention can be avoided.
Do we need these things for inner environments?:
- Not really, it should be known if the inner environment exists or not.
- There is already a group added by the outer environment and almost never an extra group is needed. One exception are verbatim and other special environments which can't be nested without extra precaution anyway. There might be some non-verbatim environments which require an inner group for themselves, but these should not rely on the one added by
\begin
/\end
, but add it explicitly. Anyway, the group could be added manually if required.
- That's the one thing which should be directly avoided.
- Already saved by the outer environment.
- Can be done by the outer environment and is needed because
\end{xxx}
ends with }
so it doesn't removes spaces. The plain form \endxxx
however does and therefore doesn't require that. An explicit \ignorespaces
could be added if someone insists.
- This point is one of the main important ones, which I just found out about while writing this answer: the fact that the paragraph should be indented or not. This seems to be set to true in the begin-code of some environments and is executed and set back to false inside
\end
. So if the plain version is used it will move to the outer \end
which might or might not be the right thing. I would recommend to set the switch @endpe
manually at the end to the proper value to avoid issues.
Conclusion:
There should be no issues with using the plain form for inner environments as long as the expected paragraph indention is handled. They have the benefit of generating meaningful error messages and are also slightly faster and do not generate (normally) unnecessary subgroups. Special care might be required for special inner environments.
@
notification doesn't work in questions and answers, only in comments and chat messages.