Alguém sabe por que na definição do LaTeX \end
o \@checkend
comando ocorre após a execução do código do ambiente final? Parece que, para fins de detecção de erros, seria melhor informar ao usuário que algo está errado o mais rápido possível.
Pergunto isso porque estou desenvolvendo alguns ambientes enva
e envb
acidentalmente digo
\begin{enva}
% some stuff
\end{envb}
lança algum erro de baixo nível dentro de \endenvb
. Para evitar isso, tenho que colocar minha própria \@checkend
verificação de estilo dentro de \endenvb
, o que parece ser parte do que \begin
deveria \end
fazer por mim.
Como um exemplo simples deste problema, considere o seguinte código:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\def\test{}
\begin{test}
\end{tikzpicture}
\end{document}
Isso dá o erro:
! Undefined control sequence.
\endtikzpicture ...r@layerlist@globally \endscope
\let \pgf@baseline =\pgf@s...
l.10 \end{tikzpicture}
o que é menos esclarecedor do que eu desejaria. Quero evitar que erros inúteis semelhantes apareçam em meu próprio código.
Para referência, o que fiz para contornar isso foi escrever o seguinte comando, que coloquei no início do \end
código para cada um dos meus ambientes:
% #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
}
Responder1
Uma implementação de um ambiente pode conter outros ambientes:
\newenvironment{foo}{\begin{center}}{\end{center}}
Se \@checkend
fosse chamado logo no início do código "final", seria chamado dentro center
, aqui. O\@checkend
depoisa parte “end” ( \end<environment>
) permite que outros ambientes abertos na parte “begin” sejam fechados corretamente.
Responder2
Além deA resposta de Heiko, observe também que pode ser necessário que o código de fim de ambiente funcione por expansão onde houver tabelas envolvidas. Pode-se ver isso sem mover a definição (não expansível), tornando uma \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}
Isto surgiu, por exemplo, emxparse
desenvolvimento.