¿Por qué aparece \@checkend después de ejecutar \endenvironment?

¿Por qué aparece \@checkend después de ejecutar \endenvironment?

¿Alguien sabe por qué en la definición de LaTeX \end, el \@checkendcomando ocurre después de ejecutar el código del entorno final? Parece que para detectar errores, sería mejor informar al usuario que algo anda mal lo antes posible.

Pregunto esto porque estoy desarrollando un par de entornos envay envbaccidentalmente digo

\begin{enva}
% some stuff
\end{envb}

arroja algún error de bajo nivel dentro de \endenvb. Para evitar esto, tengo que poner mi propio \@checkendestilo dentro de \endenvb, lo que parece ser parte de lo que \beginse \endsuponía que debía hacer por mí.

Como ejemplo simple de este problema, considere el siguiente código:

\documentclass{article}
\usepackage{tikz}
\begin{document}
\def\test{}
\begin{test}
\end{tikzpicture}
\end{document}

Esto da el error:

! Undefined control sequence.
\endtikzpicture ...r@layerlist@globally \endscope 
                                                  \let \pgf@baseline =\pgf@s...
l.10 \end{tikzpicture}

lo cual es menos esclarecedor de lo que desearía. Quiero evitar que aparezcan errores inútiles similares en mi propio código.

Como referencia, lo que he hecho para solucionar este problema es escribir el siguiente comando, que puse al principio del \endcódigo para cada uno de mis entornos:

% #1 -- the name of the environment being ended
\def\mypkg@checkend#1{
    \def\mypkg@tempa{#1}
    \ifx\mypkg@tempa\@currenvir\else % mismatch
        \mypkg@error{endenv-mismatch}
        \csname end\@currenvir\endcsname % run the \end code for the correct environment
        \def\@currenvir{#1} % Prevent \@checkend from throwing a second redundant error
        \expandafter\mypkg@break % don't run the rest of \endthisenvironment
    \fi
}

Respuesta1

Una implementación de un entorno puede contener otros entornos:

\newenvironment{foo}{\begin{center}}{\end{center}}

Si \@checkendse llamara justo al comienzo del código "final", se llamaría dentro center, aquí. El\@checkend despuésla parte "final" ( \end<environment>) permite que otros entornos abiertos en la parte "inicio" se cierren correctamente.

Respuesta2

Además deLa respuesta de Heiko., tenga en cuenta también que puede ser necesario que el código de fin de entorno funcione mediante expansión cuando se trate de tablas. Se puede ver esto sin mover la definición (no ampliable) haciendo una \end...macro protegida:

\documentclass{article}
\newenvironment{foo}[1]
  {\begin{tabular}{#1}}{\end{tabular}}
\begin{document}
\fbox{%
  \begin{foo}{ccc}
    \hline
    Test & a & b \\
    \hline
  \end{foo}
}
\protected\edef\endfoo{\unexpanded\expandafter{\endfoo}}
\fbox{%
  \begin{foo}{ccc}
    \hline
    Test & a & b \\
    \hline
  \end{foo}
}
\end{document}

Esto ha surgido por ejemplo enxparsedesarrollo.

información relacionada