\NewEnviron 出现“参数失控?”错误

\NewEnviron 出现“参数失控?”错误

我有两个文件。基本上,主文件只是加载 environ 包并输入辅助文件。辅助文件创建一个基本上不执行任何操作的环境,并创建该环境的一个实例:

主要.tex:

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

次要.tex:

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

我收到以下错误消息:

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

当我进行以下任何更改时,示例都会按预期工作:

  • 使用\newenvironment而不是\NewEnviron
  • 使用\begin{myenv}...\end{myenv}而不是\begingroup\myenv...\endmyenv\endgroup
  • 将secondary.tex的内容直接放在main.tex中,而不是输入secondary.tex

为什么这不起作用?

答案1

environ创建一个使用定义中的 TeX 参数文本来捕获环境内容的环境。此参数文本样式定义允许包捕获环境内容,但它还要求非常严格地使用宏/定义……使用命令样式环境时您不需要遵守这一点(\myenv...\endmyenv而不是\begin{myenv}... \end{myenv})。

广义上讲,\NewEnviron{myenv}创建一个宏\myenv来指定环境的开始,这个宏会寻找确切地 \end{myenv}... 没有其他的。

该示例在使用时失败,\input因为没有明确的 \end{<something>}正在搜索。它在找到任何与 相似的东西之前就\myenv到达了 的末尾。它实际上是在寻找(见下文)。secondary.tex\end\end{document}

让我们看看您提到的三个解决问题的实例,看看为什么会出现这种情况:

  • 使用\newenvironment而不是\NewEnviron

    为什么这样做显而易见。\newenvironment{myenv}定义了\myenv\endmyenv,因此使用环境的命令定义应该可以毫无问题地工作;

  • 使用\begin{myenv}...\end{myenv}而不是\begingroup\myenv...\endmyenv\endgroup

    这正是environ您在使用 定义环境时应该使用的期望\NewEnviron。因此,这是开箱即用的,因为您已经明确地使用环境终止\end{myenv}

  • 将内容secondary.tex直接放入,main.tex而不是输入secondary.tex

    由于您使用的是环境的命令形式,因此“当前环境”(LaTeX 称为\@currenvir)实际上从未改变。也就是说,它仍然位于环境内部document(由于调用\begin{document})。因此,您的环境结束捕获实际上是\end{document}根据 的newenviron设置进行的。您的环境“开始”于\myenv并以 结束\end{document}。很奇怪,但是当你不使用预期的环境范围时,它就是这样工作的\begin{...}...。\end{...}

为了使其在上下文中正常工作newenviron,请使用范围\begin{myenv}...。此范围提供了您通过...\end{myenv}实现的必要分组。\begingroup\endgroup

或者,定义\myenv捕获内容直到达到\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}

答案2

确实如此不是如果您将内容放在主文件中,则可行。它只是不会给出错误。试试这个:

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

World

\end{document}

Environ 需要找到 \end{myenv} 才能停止解析。

相关内容