# Environments with conditionals in: why doesn't this work?

In response to this question I thought the obvious thing to do was the following:

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

This doesn't work: ! Incomplete \iffalse; all text was ignored after line 5.

If, however, I add a \footrue to the preamble it compiles fine. Adding \foofalse does not make it work.

Could someone explain this behaviour? This sort of thing is possible: the comment package does exactly this. I am not asking how to achieve this behaviour. My question is: why doesn't this thing work in LaTeX "out of the box"?

-
Compare also tex.stackexchange.com/questions/14538/… – Caramdir Mar 30 '11 at 22:56

TeX is skipping all input tokens (macros, characters, ...) after a conditional which is logical false but looks at every one to see if it is a \fi token (i.e. \fi or any macro \let to it; see also What is an if?). It doesn't expand macros. So the \fi in \end{foobar} is never seen, just \end followed by the tokens {, f, ..., r, }. However after a logical true if the tokens are processed as normal and TeX simply remembers to take the next \fi it encounters on the way as the end of the currently processed if-branch.

So:

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

would work, but there is no way to make that work with LaTeX style environments. The comment package skips everything verbatim to the \end{comment} marker (which is also read verbatim!).

-
Very well explained! – Matthew Leingang Mar 30 '11 at 23:40

Martin gave a very nice answer explaining why it doesn't work. Here's a way to get what you want (assuming your minimal example shows what you want and not just the problem) using Will's environ package.

\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}

Note that I replaced \newenvironment with \NewEnviron and that the body of the environment is stored in the \BODY macro. This way, the environment checks \iffoo before expanding \BODY. If \iffoo is false, then it skips tokens until it sees \fi which it can do without expanding anything else.

(The \expandafter is only important if the last thing in the foobar environment is going to be looking at following tokens.)

-
That package looks useful! – Caramdir Mar 31 '11 at 3:45