更新

更新

NewEnviron我想使用用from定义的环境environ在另一个环境定义中:

\documentclass{article}

\usepackage{environ}

\NewEnviron{inner}[1]{%
  \textbf{#1:} \BODY
}

\newenvironment{out}{%
  \begin{inner}{Using outer}%
}{%
  \end{inner}%
}

\begin{document}
  \begin{inner}{Using inner}
    Lorem ipsum\ldots
  \end{inner}

  \begin{out}
    Lorem ipsum\ldots
  \end{out}
\end{document}

生成的 PDF 看起来符合要求:

在此处输入图片描述

但日志显示一些错误:

./test.tex:22: LaTeX Error: \begin{inner} on input line 20 ended by \end{out}.
 ...                                              
l.22 \end{out}

./test.tex:23: LaTeX Error: \begin{out} on input line 20 ended by \end{document
}.
 ...                                                  
l.23 \end{document}

...
(\end occurred inside a group at level 1)

### semi simple group (level 1) entered at line 20 (\begingroup)
### bottom level

如果我定义out使用NewEnviron,那就是

\NewEnviron{out}{%
  \begin{inner}{Using outer}%
    \BODY
  \end{inner}%
}

然后pdflatex不会终止。

显然,有些东西混淆了(以错误的顺序呈现给解析器)。出了什么问题?

答案1

可以使用环境的命令形式来规避导致错误的环境。因此,尝试

\newenvironment{out}
  {% \begin{out}
    \inner{Using outer}%
  }{% \end{out}
    \endinner%
  }

正如 egreg 在评论中提到的那样,嵌套\NewEnvirons 会导致对\BODY捕获的环境内容宏的循环引用。

答案2

嵌套问题是由于每个定义的(伪)环境都\NewEnviron用于\BODY存储内容。

实际上,控制序列名称是可以修改的,但不能在环境启动后修改。可以直接使用\collect@body\Collect@Body,但这会非常麻烦。

我的建议是定义同一环境的版本:

\newenvironment{innerx}[1]
 {\textbf{#1:}}
 {}

\NewEnviron{inner}[1]{%
  \innerx{#1} \BODY
}

\newenvironment{outx}
  {\innerx{Using outer}}
  {\endinnerx}

\NewEnviron{out}{\outx~\BODY\endoutx}

当然,在本例中,outx环境不是必需的,

\NewEnviron{out}{\innerx{Using outer} \BODY\endinnerx}

就足够了。

完整示例:

\documentclass{article}

\usepackage{environ}

\newenvironment{innerx}[1]
 {\textbf{#1:}}
 {}

\NewEnviron{inner}[1]{%
  \innerx{#1} \BODY
}

\newenvironment{outx}
  {\innerx{Using outer}}
  {\endinnerx}

\NewEnviron{out}{\outx~\BODY\endoutx}

\begin{document}
  \begin{inner}{Using inner}
    Lorem ipsum\ldots
  \end{inner}

  \begin{out}
    Lorem ipsum\ldots
  \end{out}
\end{document}

更新

使用environ2014 年 5 月 4 日发布的 0.3 版本,可以更轻松地定义嵌套环境\NewEnviron。当

\environbodyname<control sequence>

找到命令后,\NewEnviron从该点开始的每个命令都应使用<control sequence>而不是 来定义\BODY。以下是基于前面代码的示例。

\documentclass{article}
\usepackage{environ}

\NewEnviron{out}{%
  \begin{inner}{Using outer}%
    \BODY
  \end{inner}%
}

\environbodyname\innerBODY
\NewEnviron{inner}[1]{%
  \textbf{#1:} \innerBODY
}

\begin{document}

\begin{inner}{Using inner}
Lorem ipsum\ldots
\end{inner}

\begin{out}
Lorem ipsum\ldots
\end{out}

\end{document}

在此处输入图片描述

相关内容