"Discussão descontrolada?" erro com \NewEnviron

"Discussão descontrolada?" erro com \NewEnviron

Eu tenho dois arquivos. Basicamente, o arquivo principal apenas carrega o pacote ambiental e insere o arquivo secundário. O arquivo secundário cria um ambiente que basicamente não faz nada e cria uma instância desse ambiente:

principal.tex:

\documentclass{scrartcl}
\usepackage{environ}
\begin{document}
  \input{secondary.tex}
\end{document}

secundário.tex:

\NewEnviron{myenv}{\BODY}
\begingroup
  \myenv
    Hello
  \endmyenv
\endgroup

Eu recebi a seguinte mensagem de erro:

Runaway argument?
Hello \endmyenv \endgroup \par
! File ended while scanning use of \document.
<inserted text>
                \par
l.5 \input{secondary.tex}

O exemplo funciona conforme esperado quando faço qualquer (!) das seguintes alterações:

  • Use \newenvironmentem vez de\NewEnviron
  • Use \begin{myenv}...\end{myenv}em vez de\begingroup\myenv...\endmyenv\endgroup
  • Coloque o conteúdo de secundário.tex diretamente em main.tex em vez de inserir secundário.tex

Por que isso não funciona?

Responder1

environcria um ambiente que usa texto de parâmetro TeX em definições para capturar o conteúdo do ambiente. Esta definição de estilo de texto de parâmetro permite que o pacote capture o conteúdo do ambiente, mas também requer um uso muito estrito das macros/definições... algo que você não está aderindo ao usar um ambiente de estilo de comando ( \myenv... \endmyenvem vez que \begin{myenv}... \end{myenv}).

Em termos gerais, \NewEnviron{myenv}cria uma macro \myenvque designa o início do ambiente, e esta macro está à procura deexatamente \end{myenv}... nada mais.

O exemplo falha ao usar, \inputpois não háexplícito \end{<something>}que \myenvestá procurando. Chega ao fim secondary.texantes de encontrar qualquer semelhança com \end. Na verdade, está procurando \end{document}(veja abaixo).

Vejamos as três instâncias mencionadas que corrigiram o problema e vejamos por que isso acontece:

  • Use \newenvironmentem vez de\NewEnviron

    Deveria ser óbvio por que isso funciona. \newenvironment{myenv}define ambos \myenve \endmyenv, portanto, usar a definição de comando do ambiente deve funcionar sem problemas;

  • Use \begin{myenv}...\end{myenv}em vez de\begingroup\myenv...\endmyenv\endgroup

    Isso é exatamente o que environvocê espera usar ao definir um ambiente usando \NewEnviron. Então, isso funciona imediatamente, já que vocêexplicitamenteusou a terminação do ambiente \end{myenv};

  • Coloque o conteúdo secondary.texdiretamente main.texem vez de inserirsecondary.tex

    Como você está usando a forma de comando de um ambiente, o "ambiente atual" (conhecido no LaTeX como \@currenvir) nunca muda realmente. Ou seja, permanece como estando dentro do documentambiente (devido a uma chamada \begin{document}). Portanto, sua captura de fim de ambiente está \end{document}de acordo com newenvirona configuração de. Seuambiente"começa" com \myenve termina com \end{document}. Estranho, mas é assim que funciona quando você não usa o escopo do ambiente esperado \begin{...}....\end{...}

Para que funcione corretamente no contexto de newenviron, use o escopo \begin{myenv}... \end{myenv}. Esse escopo fornece o agrupamento necessário que você implementa por meio de \begingroup....\endgroup

Alternativamente, defina \myenvcapturar coisas até atingir \endmyenv:

\documentclass{scrartcl}
\usepackage{filecontents}
\begin{filecontents*}{secondary.tex}
\long\def\myenv #1\endmyenv{#1}% Fake myenv environment that captures its body
\begingroup
  \myenv
    Hello
  \endmyenv
\endgroup
\end{filecontents*}
\begin{document}
\input{secondary.tex}
\end{document}

Responder2

Isso acontecenãofuncionará se você colocar o conteúdo no arquivo principal. Só não dá erro. Experimente isto:

\documentclass{scrartcl}
\usepackage{environ}
\begin{document}
\NewEnviron{myenv}{BEGIN\BODY END}
\begingroup
  \myenv
    Hello
  \endmyenv
\endgroup

World

\end{document}

O Environ precisa encontrar \end{myenv} para interromper a análise.

informação relacionada