21

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

16

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

14

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
  • This doesn't seem to work if BODY contains a verbatim environment... – Alec Jacobson Oct 19 '18 at 15:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.