NewDocumentEnvironment 可选参数使用 \obeylines 改变行为

NewDocumentEnvironment 可选参数使用 \obeylines 改变行为

我注意到具有可选参数的环境的行为会\obeylines根据可选参数是否存在而改变。

我原本以为下面示例中的所有环境看起来都一样。但有一个环境不同。

发生了什么事?我是否可以在 的定义中添加一些内容,bbb以使其在存在可选参数时表现得像所有其他内容一样?

\documentclass{article}
\NewDocumentEnvironment{aaa}{}{\obeylines ENV:}{}
\NewDocumentEnvironment{bbb}{o}{\obeylines ENV:}{}
\NewDocumentEnvironment{ccc}{o}{ENV:}{}
\begin{document}
\begin{aaa}
  x
  y
\end{aaa}
\begin{bbb}
  x
  y
\end{bbb}
\begin{bbb}[arg]
  x
  y
\end{bbb}
\begin{ccc}\par
  x\par
  y\par
\end{ccc}
\begin{ccc}[arg]\par
  x\par
  y\par
\end{ccc}
\end{document}

输出

输出

答案1

问题“显然”是(*)可选参数抓取器尝试对换行符进行标记,该换行符在\obeylines执行之前通常具有 catcode 5(“行尾”),这会将其 catcode 更改为 13(活动)。

由于需要对以下标记进行标记以确定是否存在可选参数,因此这是不可避免的。

(理论上,可以使用scantokens它来“取消标记”。实际上,这会对性能造成影响,如果不设置,\everyeof用户可能会遇到更令人困惑的错误,甚至可能还会造成混淆\errorcontextlines

解决方法是设置\endlinechar 解析可选参数。目前最简洁的方法是(据我所知)定义辅助宏/环境。

%! TEX program = lualatex

\documentclass{article}
\NewDocumentEnvironment{aaa}{}{\obeylines ENV:}{}
\NewDocumentEnvironment{innerbbb}{o}{ENV:}{}
\NewDocumentEnvironment{bbb}{}{\obeylines\innerbbb}{\endinnerbbb}
\NewDocumentEnvironment{ccc}{o}{ENV:}{}
\begin{document}
\begin{aaa}
  x
  y
\end{aaa}
\begin{bbb}
  x
  y
\end{bbb}
\begin{bbb}[arg]
  x
  y
\end{bbb}
\begin{ccc}\par
  x\par
  y\par
\end{ccc}
\begin{ccc}[arg]\par
  x\par
  y\par
\end{ccc}
\end{document}

附注:使用简单形式\innerbbb是因为根据其他环境来定义环境:正确的方法是什么?

附注 2,这会使错误消息对于失控的可选参数(即你忘记输入])有点混乱,报告环境名称innerbbb而不是bbb

! File ended while scanning use of \environment innerbbb .

(*)如果你有丰富的 TeX 编程经验

相关内容