Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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

share|improve this question
    
Compare also tex.stackexchange.com/questions/14538/… –  Caramdir Mar 30 '11 at 22:56
add comment

2 Answers

up vote 12 down vote accepted

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

share|improve this answer
    
Very well explained! –  Matthew Leingang Mar 30 '11 at 23:40
add comment

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

share|improve this answer
    
That package looks useful! –  Caramdir Mar 31 '11 at 3:45
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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