\endenvironment を実行した後に \@checkend が発生するのはなぜですか?

\endenvironment を実行した後に \@checkend が発生するのはなぜですか?

の LaTeX 定義で\end\@checkend終了環境コードの実行後にコマンドが発生する理由を知っている人はいますか? エラーをキャッチするために、できるだけ早く何か問題があることをユーザーに知らせるのが最善のようです。

私がこの質問をしたのは、いくつかの環境を開発していてenvaenvbうっかりこう言ってしまったからです

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

は の内部で低レベルのエラーをスローします\endenvb。これを防ぐには、\@checkendの内部に独自のスタイル チェックを配置する必要があります。これは、とが行うはずの\endenvb機能の一部であると思われます。\begin\end

この問題の簡単な例として、次のコードを考えてみましょう。

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

次のエラーが発生します:

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

これは私が望んでいたほど明確ではありません。同様の役に立たないエラーが自分のコードに表示されないようにしたいのです。

\end参考までに、この問題を回避するために私が行ったことは、各環境のコードの先頭に次のコマンドを記述することです。

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

答え1

環境の実装には他の環境を含めることができます。

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

\@checkendが「終了」コードの先頭で呼び出される場合は、centerここでは 内で呼び出されます。\@checkend 「end」部分(\end<environment>)により、「begin」部分で開かれた他の環境が適切に閉じられるようになります。

答え2

に加えてハイコの答えまた、テーブルが関係する場合には、環境終了コードが展開によって動作する必要がある場合があることにも注意してください。マクロを\end...保護すれば、(展開不可能な)定義を移動せずにこれを確認できます。

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

これは例えばxparse発達

関連情報