為什麼運行\endenvironment後會出現\@checkend?

為什麼運行\endenvironment後會出現\@checkend?

有誰知道為什麼在 LaTeX 定義中\end,該\@checkend命令在運行結束環境程式碼後出現?出於錯誤捕獲的目的,最好盡快讓用戶知道出現了問題。

我問這個是因為我正在開發幾個環境enva並且envb不小心說

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

在 內部拋出一些低階錯誤\endenvb。為了防止這種情況,我必須將自己的\@checkend樣式檢查放在 裡面\endenvb,這似乎是\beginand\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此處將在 inside 調用。這\@checkend 「結束」部分 ( \end<environment>) 允許正確關閉「開始」部分中開啟的其他環境。

答案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發展

相關內容