"¿Argumento desbocado?" error con \NewEnviron

"¿Argumento desbocado?" error con \NewEnviron

Tengo dos archivos. Básicamente, el archivo principal simplemente carga el paquete ambiental e ingresa el archivo secundario. El archivo secundario crea un entorno que básicamente no hace nada y crea una instancia de ese entorno:

principal.tex:

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

secundario.tex:

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

Recibo el siguiente mensaje de error:

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

El ejemplo funciona como se esperaba cuando hago cualquiera (!) de los siguientes cambios:

  • Usar \newenvironmenten lugar de\NewEnviron
  • Usar \begin{myenv}...\end{myenv}en lugar de\begingroup\myenv...\endmyenv\endgroup
  • Coloque el contenido de second.tex directamente en main.tex en lugar de ingresar second.tex

¿Por qué esto no funciona?

Respuesta1

environcrea un entorno que utiliza texto de parámetros TeX en definiciones para capturar el contenido del entorno. Esta definición de estilo de texto de parámetro permite que el paquete capture el contenido del entorno, pero también requiere un uso muy estricto de las macros/definiciones... algo a lo que no se adhiere cuando se utiliza un entorno de estilo de comando ( \myenv... \endmyenvmás bien que \begin{myenv}... \end{myenv}).

En términos generales, \NewEnviron{myenv}crea una macro \myenvque designa el inicio del entorno, y esta macro está buscandoexactamente \end{myenv}... nada más.

El ejemplo falla al usarlo \inputya que no hayexplícito \end{<something>}que \myenvesta buscando. Llega al final de secondary.texantes de encontrar algún parecido con \end. En realidad, está buscando \end{document}(ver más abajo).

Veamos las tres instancias que menciona que corrigieron el problema y veamos por qué es así:

  • Usar \newenvironmenten lugar de\NewEnviron

    Debería ser obvio por qué esto funciona. \newenvironment{myenv}define ambos \myenvy \endmyenv, por lo que usar la definición de comando del entorno debería funcionar sin problemas;

  • Usar \begin{myenv}...\end{myenv}en lugar de\begingroup\myenv...\endmyenv\endgroup

    Esto es exactamente lo que environdeberías usar cuando defines un entorno usando \NewEnviron. Entonces, esto funciona de inmediato, ya que hasexplícitamenteutilizó la terminación del entorno \end{myenv};

  • Coloque el contenido de secondary.texdirectamente en main.texen lugar de ingresarsecondary.tex

    Dado que está utilizando la forma de comando de un entorno, el "entorno actual" (conocido en LaTeX como \@currenvir) nunca cambia realmente. Es decir, queda como estando dentro del documentambiente (debido a una llamada \begin{document}). Entonces, su captura de fin de entorno en realidad se realiza \end{document}de acuerdo con newenvironla configuración de . Suambiente"comienza" con \myenvy termina con \end{document}. Es extraño, pero así es como funciona cuando no se utiliza el alcance del entorno esperado \begin{...}...\end{...}

Para que funcione correctamente dentro del contexto de , newenvironutilice el alcance \begin{myenv}.... \end{myenv}Este alcance proporciona la agrupación necesaria que usted implementa a través de \begingroup....\endgroup

Alternativamente, defina \myenvcapturar cosas hasta que llegue a \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}

Respuesta2

Lo hacenoFunciona si colocas el contenido en el archivo principal. Sólo no da error. Prueba esto:

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

World

\end{document}

Environ necesita encontrar \end{myenv} para detener el análisis.

información relacionada