I have two files. Basically, the main file just loads the environ package and inputs the secondary file. The secondary file creates an environment that basically does nothing, and creates one instance of that environment:
main.tex:
\documentclass{scrartcl}
\usepackage{environ}
\begin{document}
\input{secondary.tex}
\end{document}
secondary.tex:
\NewEnviron{myenv}{\BODY}
\begingroup
\myenv
Hello
\endmyenv
\endgroup
I get the following error message:
Runaway argument?
Hello \endmyenv \endgroup \par
! File ended while scanning use of \document.
<inserted text>
\par
l.5 \input{secondary.tex}
The example works as expected when I make any (!) of the following changes:
- Use
\newenvironment
instead of\NewEnviron
- Use
\begin{myenv}...\end{myenv}
instead of\begingroup\myenv...\endmyenv\endgroup
- Place the contents of secondary.tex directly in main.tex instead of inputting secondary.tex
Why does this not work?
Best Answer
environ
creates an environment that uses TeX parameter text in definitions to capture the environment contents. This parameter-text style definition allows the package to capture the environment contents, but it also requires a very strict usage of the macros/definitions... something you're not adhering to when using a command-style environment (\myenv
...\endmyenv
rather than\begin{myenv}
...\end{myenv}
).Broadly speaking,
\NewEnviron{myenv}
creates a macro\myenv
which designates the start of the environment, and this macro is on the lookout for exactly\end{myenv}
... nothing else.The example fails when using
\input
since there's no explicit\end{<something>}
that\myenv
is searching for. It reaches the end ofsecondary.tex
before it ever finds any resemblance of\end
. It's actually looking for\end{document}
(see below).Let's look at the three instances you mention that corrected the problem and see why that's the case:
Use
\newenvironment
instead of\NewEnviron
It should be obvious why this works.
\newenvironment{myenv}
defines both\myenv
and\endmyenv
, so using the command-definition of the environment should work without problem;Use
\begin{myenv}...\end{myenv}
instead of\begingroup\myenv...\endmyenv\endgroup
This is exactly what
environ
expects you should use when you define an environment using\NewEnviron
. So, this works out-of-the-box, since you've explicitly used the environment termination\end{myenv}
;Place the contents of
secondary.tex
directly inmain.tex
instead of inputtingsecondary.tex
Since you're using the command-form of an environment, the "current environment" (known to LaTeX as
\@currenvir
) never really changes. That is, it remains as being inside thedocument
environment (due to a call\begin{document}
). So, your end-of-environment capture is actually\end{document}
according tonewenviron
's setup. Your environment "starts" with\myenv
and ends with\end{document}
. Weird, but that's how it works when you don't use the expected environment scoping\begin{...}
...\end{...}
.For it to work properly within the context of
newenviron
, use the scoping\begin{myenv}
...\end{myenv}
. This scoping provides the necessary grouping you implement through\begingroup
...\endgroup
.Alternatively, define
\myenv
to capture stuff until it reaches\endmyenv
: