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 of secondary.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 in main.tex
instead of inputting secondary.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 the document
environment (due to a call \begin{document}
). So, your end-of-environment capture is actually \end{document}
according to newenviron
'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
:
\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}