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
\newenvironment
en 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
environ
crea 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
... \endmyenv
más bien que \begin{myenv}
... \end{myenv}
).
En términos generales, \NewEnviron{myenv}
crea una macro \myenv
que designa el inicio del entorno, y esta macro está buscandoexactamente \end{myenv}
... nada más.
El ejemplo falla al usarlo \input
ya que no hayexplícito \end{<something>}
que \myenv
esta buscando. Llega al final de secondary.tex
antes 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
\newenvironment
en lugar de\NewEnviron
Debería ser obvio por qué esto funciona.
\newenvironment{myenv}
define ambos\myenv
y\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
environ
deberí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.tex
directamente enmain.tex
en 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 deldocument
ambiente (debido a una llamada\begin{document}
). Entonces, su captura de fin de entorno en realidad se realiza\end{document}
de acuerdo connewenviron
la configuración de . Suambiente"comienza" con\myenv
y 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 , newenviron
utilice el alcance \begin{myenv}
.... \end{myenv}
Este alcance proporciona la agrupación necesaria que usted implementa a través de \begingroup
....\endgroup
Alternativamente, defina \myenv
capturar 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.