带有条件的环境:为什么这不起作用?

带有条件的环境:为什么这不起作用?

回应这个问题我认为最明显的做法是:

\documentclass{article}
\newif\iffoo
\newenvironment{foobar}{\iffoo}{\fi}
\begin{document}
\begin{foobar}
  Here is text
\end{foobar}
Here is more text
\end{document}

这不起作用:! Incomplete \iffalse; all text was ignored after line 5.

但是,如果我\footrue在前言中添加一个,它就可以编译成功。添加并\foofalse不能使它工作。

有人能解释一下这种行为吗?这种事情是可能的:这个comment包就是这样做的。我不是在问如何实现这种行为。我的问题是:为什么这个东西不能在 LaTeX 中“开箱即用”?

答案1

TeX 跳过符合逻辑的条件后的所有输入标记(宏、字符等)错误的但会查看每一个以查看它是否是一个\fi标记(即\fi或其任何宏\let;另请参阅什么是 if?)。它不扩展宏。因此永远不会看到\fiin ,后面只跟着标记, , ..., , 。然而,在逻辑真之后,标记会照常处理,而 TeX 只会记得将途中遇到的下一个标记作为当前处理的结束\end{foobar}\end{fr}if\fi如果-分支。

所以:

\documentclass{article}
\newif\iffoo
\let\foobar=\iffalse
\let\endfoobar=\fi
\begin{document}
\foobar
  Here is text
\endfoobar
Here is more text
\end{document}

可以工作,但是没有办法让它在 LaTeX 样式环境中工作。该comment包会逐字跳过所有内容到\end{comment}标记(也是逐字读取的!)。

答案2

Martin 给出了一个很好的答案,解释了为什么它不起作用。这里有一种方法可以使用 Will 的environ包来获得您想要的东西(假设您的最小示例显示了您想要的东西,而不仅仅是问题)。

\documentclass{article}
\usepackage{environ}
\newif\iffoo
\NewEnviron{foobar}{\iffoo\expandafter\BODY\fi}
\begin{document}
\begin{foobar}
Here is some foobar text 1.
\end{foobar}
\footrue
\begin{foobar}
Here is some foobar text 2.
\end{foobar}
\end{document}

请注意,我用 替换了\newenvironment\NewEnviron并且环境主体存储在\BODY宏中。这样,环境会\iffoo在扩展 之前进行检查\BODY。如果\iffoo为假,则它会跳过标记,直到看到\fi它可以在不扩展任何其他内容的情况下执行哪些操作。

\expandafter只有当环境中的最后一件事foobar是查看以下标记时,这才重要。)

相关内容