[Tex/LaTex] Environments with conditionals in: why doesn’t this work

conditionalsenvironments

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"?

Best Answer

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!).

Related Question