Warum tritt \@checkend nach dem Ausführen von \endenvironment auf?

Warum tritt \@checkend nach dem Ausführen von \endenvironment auf?

Weiß jemand, warum \endder \@checkendBefehl in der LaTeX-Definition von nach dem Ausführen des Endumgebungscodes auftritt? Es scheint, als wäre es zum Zwecke der Fehlererkennung am besten, den Benutzer so schnell wie möglich darüber zu informieren, dass etwas nicht stimmt.

Ich frage das, weil ich ein paar Umgebungen entwickle envaund envbversehentlich sage

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

löst innerhalb von einen Fehler auf niedriger Ebene aus \endenvb. Um dies zu verhindern, muss ich meine eigene \@checkendStilprüfung innerhalb von einfügen \endenvb, was Teil dessen zu sein scheint, was \beginund \endfür mich tun sollten.

Als einfaches Beispiel für dieses Problem betrachten Sie den folgenden Code:

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

Dies führt zu folgendem Fehler:

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

das ist weniger aufschlussreich, als ich es mir wünschen würde. Ich möchte verhindern, dass in meinem eigenen Code ähnliche nutzlose Fehler auftreten.

Zur Referenz: Um dies zu umgehen, habe ich den folgenden Befehl geschrieben und ihn an den Anfang des \endCodes für jede meiner Umgebungen gesetzt:

% #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
}

Antwort1

Eine Implementierung einer Umgebung kann andere Umgebungen enthalten:

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

Wenn \@checkendes direkt am Anfang des "End"-Codes aufgerufen würde, würde es centerhier innerhalb aufgerufen werden. Die\@checkend nachDer „End“-Teil ( \end<environment>) ermöglicht, dass andere im „Begin“-Teil geöffnete Umgebungen ordnungsgemäß geschlossen werden.

Antwort2

Zusätzlich zuHeikos AntwortBeachten Sie auch, dass es notwendig sein kann, dass der Code für das Ende der Umgebung durch Erweiterung funktioniert, wenn Tabellen beteiligt sind. Dies kann man sehen, ohne die (nicht erweiterbare) Definition zu verschieben, indem man ein \end...Makro schützt:

\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}

Dies ist zum Beispiel geschehen inxparseEntwicklung.

verwandte Informationen