我有两个文件。基本上,主文件只是加载 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} 才能停止解析。