回应这个问题我认为最明显的做法是:
\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?)。它不扩展宏。因此永远不会看到\fi
in ,后面只跟着标记, , ..., , 。然而,在逻辑真之后,标记会照常处理,而 TeX 只会记得将途中遇到的下一个标记作为当前处理的结束\end{foobar}
\end
{
f
r
}
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
是查看以下标记时,这才重要。)