Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

\if \else \fi in new environment

1,431 views
Skip to first unread message

Anna Foeglein

unread,
Jun 2, 2010, 11:25:59 AM6/2/10
to
Hello,
I'm trying to make a template for problem sheets with problems &
solutions, and I'm running into a problem constructing an environment
for the solutions.

I'd like to have an environment
\begin{soln}
...
\end{soln}
which does the following:
If a certain variable is set to "true", then it includes its contents;
if the variable is set to "false", the environment's contents are just
skipped.
In a way, it should work like a kind of comment environment (yes, I
have seen the comment.sty package).

I thought that my problem would be solved by defining a custom
conditional (with \newif{\ifsoln} in the preamble) and then
reproducing the following structure:
\ifsoln
blah blah text
\else
\fi

This conditional structure works nicely. However, I'd like to put it
into an environment, using
\newenvironment{soln}{\ifsoln}{\else \fi}

This construction produces an error if \ifsoln evaluates to "false":

! Incomplete \iffalse; all text was ignored after line 55.
<inserted text>
\fi

As far as I could figure out from a LaTeX book (Kopka, 3rd volume) and
googling, the problem is that after "\ifsoln" is found to be false,
LaTeX seems to be looking for the "\else" or the "\fi" where it wants
to continue parsing the file. But since "\else" and "\fi" are still
abbreviated by "\end{soln}", they cannot be found, which leads to said
error.

Is there an acceptable way to get around this problem? Or is the whole
approach flawed?
(I've tried to figure out if some trickery with \def, \expandafter,
\let etc. could help, but so far no success, only confusion.)

Thanks for your attention,
Anna

Enrico Gregorio

unread,
Jun 2, 2010, 11:34:32 AM6/2/10
to
Anna Foeglein <anna.f...@googlemail.com> wrote:

Look at the "comment" package.

Ciao
Enrico

Anna Foeglein

unread,
Jun 2, 2010, 12:11:41 PM6/2/10
to
>
> Look at the "comment" package.
>
Thanks, I did that, but I'm afraid I need a somewhat more detailed
pointer...

"comment" seems to discard the commented-out stuff line by line (and
save it somewhere if necessary).
Unfortunately, I don't quite understand the details of how it does
that yet, especially how it finds beginning/end of the commented
part.

If all else fails I'll try and make a special comment environment with
the comment package, but it'd be really nice to find out about this if/
fi problem anyway.

Thanks again,
Anna

Enrico Gregorio

unread,
Jun 2, 2010, 1:11:20 PM6/2/10
to
Anna Foeglein <anna.f...@googlemail.com> wrote:

When TeX sees \if? (one of its conditional commands) it looks
whether the condition is true or false. Then it skips everything
up to \else if the condition is false /without/ expanding anything,
but keeping track of \if... \else \fi and then starts to expand
what comes after the corresponding \else.

If the condition is true, it throws away what comes between \else
and \fi, again keeping track of other conditionals, but starting to
expand right away the tokens it finds.

In your case, \ifsoln is either \iftrue or \iffalse; these have
no condition after them. So, let's look what happens with your
environment

\newenvironment{soln}{\ifsoln}{\else \fi}

When you write

\begin{soln}
xyz
\end{soln}

and \ifsoln is \iftrue, TeX executes essentially, apart from
minor things which are not important here

\begingroup\soln

where \soln has been defined by \def\soln{\ifsoln}. Now the condition
is true, so TeX expands tokens, until arriving at \end{soln} which
has been defined by \def\endsoln{\else \fi}. Its expansion is thus
"\else \fi", which happily balances the starting \ifsoln. The \else
is redundant, here.

When, instead, \ifsoln is \iffalse, TeX will look for a
closing \else (or \fi) /without/ expanding tokens. And here is
the problem: the intended closing \fi is buried inside a macro
and TeX cannot see it.

So the way out is either to use directly

\ifsoln
<solution>
\fi

or resorting to the comment package's strategy.

Ciao
Enrico

Philip Hirschhorn

unread,
Jun 2, 2010, 8:10:32 PM6/2/10
to
Anna Foeglein <anna.f...@googlemail.com> wrote:
> Hello,
> I'm trying to make a template for problem sheets with problems &
> solutions, and I'm running into a problem constructing an environment
> for the solutions.
>
> I'd like to have an environment
> \begin{soln}
> ...
> \end{soln}
> which does the following:
> If a certain variable is set to "true", then it includes its contents;
> if the variable is set to "false", the environment's contents are just
> skipped.


The following is a slight modification of the solution environment in
the exam documentclass:

--------------------------------------------------------------------
\newenvironment{solution}%
{%
\ifsoln
\else
\setbox0\vbox\bgroup
\fi
}{%
\ifsoln
\else
\egroup
\fi
}%
--------------------------------------------------------------------


If \ifsoln is true, then the \begin{solution} and \end{solution} both
do nothing, and so the contents of the environment are printed.

If \ifsoln is false, though, then you essentially have

\setbox0=\bgroup
...All the stuff you've typed...
\egroup

which puts the stuff you've typed into box0 and then totally ignores
box0, so it's not printed. As you leave the environment, you also
leave a group, and so that contents of box0 are thrown away.


Hope this helps,
Phil


--
----------------------------------------------------------------------
Philip Hirschhorn p...@math.mit.edu
p...@poincare.wellesley.edu
----------------------------------------------------------------------

Heiko Oberdiek

unread,
Jun 3, 2010, 6:05:13 AM6/3/10
to
Philip Hirschhorn <p...@math.mit.edu> wrote:

> The following is a slight modification of the solution environment in
> the exam documentclass:
>
> --------------------------------------------------------------------
> \newenvironment{solution}%
> {%
> \ifsoln
> \else
> \setbox0\vbox\bgroup
> \fi
> }{%
> \ifsoln
> \else
> \egroup
> \fi
> }%
> --------------------------------------------------------------------
>
>
> If \ifsoln is true, then the \begin{solution} and \end{solution} both
> do nothing, and so the contents of the environment are printed.
>
> If \ifsoln is false, though, then you essentially have
>
> \setbox0=\bgroup
> ...All the stuff you've typed...
> \egroup

However, color specials escape, it is fixed by using
LaTeX's internal color interface (a group):

\setbox0=\vbox\bgroup\color@begingroup
...
\color@endgroup\egroup

--
Heiko Oberdiek

GL

unread,
Jun 3, 2010, 6:07:25 AM6/3/10
to

It's weird to take time to built such an environment,
and, in the same time, to say that no time's left to
understand the comment package...
... that's weird ...
... in my opinion

A simple solution is to use the Environ package :

\newif\ifsoln
\NewEnviron{soln}
{\ifsoln\else\BODY\fi}

Yours sincerely


Philip Hirschhorn

unread,
Jun 3, 2010, 5:21:03 PM6/3/10
to

Heiko,

I've only rarely used color, and so I suspect that I'm
misunderstanding something, but a small experiment suggests that
\color@begingroup and \color@endgroup aren't needed in this simple
situation. (However, when I experimented with the exam class's
solution environment, I found that unconfined \color commands do cause
the trouble you're describing. I'll need to add those things to
exam.cls to guard against such problems.)

Anyway, if you process the file

--------------------------------------------------------------------
\documentclass[12pt]{article}
\usepackage{color}

\newif\ifsoln
\solnfalse
\newenvironment{mysolution}%
{%
\ifsoln
\else
\setbox0=\vbox\bgroup


\fi
}{%
\ifsoln
\else
\egroup
\fi
}%

\begin{document}

1. Why is there air?

\begin{mysolution}
\color{red}
There is air so that we can inflate volleyballs and footballs.
\end{mysolution}

2. What was the color of George Washington's white horse?

\begin{mysolution}
\color{blue}
Blue. (No; yellow!)
\end{mysolution}

3. Define the universe. Give three examples.

\end{document}
--------------------------------------------------------------------

there's no problem with the \color commands affecting anything,
presumably because of the group created by the \being{whatever}
\end{whatever}. If you change \solnfalse to \solntrue, you get the
solutions, with color, but the color isn't in anything but the
solutions.

Am I missing something, or am I just confused about what you were
suggesting?

Thanks,

Heiko Oberdiek

unread,
Jun 3, 2010, 5:43:55 PM6/3/10
to
Philip Hirschhorn <p...@math.mit.edu> wrote:

> Heiko Oberdiek <heiko.o...@googlemail.com> wrote:
> > However, color specials escape, it is fixed by using
> > LaTeX's internal color interface (a group):
> >
> > \setbox0=\vbox\bgroup\color@begingroup
> > ...
> > \color@endgroup\egroup
>

> I've only rarely used color, and so I suspect that I'm
> misunderstanding something, but a small experiment suggests that
> \color@begingroup and \color@endgroup aren't needed in this simple
> situation.

They are!

Then the color stack of pdfTeX is out of sync, because the pop color
actions leak out of the discarded \vbox:

pdfTeX warning: pdflatex: pop empty color page stack 0

> there's no problem with the \color commands affecting anything,
> presumably because of the group created by the \being{whatever}
> \end{whatever}.

No. Inside the box the color is set. Then *after* the current group
the color is reset. If the current group is the box, then the reset is
done at the place of \setbox *outside* the discarded box.

\documentclass[12pt]{article}
\usepackage{color}

\newif\ifsoln
\solnfalse
\newenvironment{mysolution}%
{%
\ifsoln
\else
\setbox0=\vbox\bgroup
\fi
}{%
\ifsoln
\else
\egroup
\fi
}%

\begin{document}

1. Why is there air?

\color{cyan}

CYAN

\begin{mysolution}
\color{red}
There is air so that we can inflate volleyballs and footballs.
\end{mysolution}

This should be CYAN.

2. What was the color of George Washington's white horse?

\begin{mysolution}
\color{blue}
Blue. (No; yellow!)
\end{mysolution}

3. Define the universe. Give three examples.

\end{document}

--
Heiko Oberdiek

Philip Hirschhorn

unread,
Jun 3, 2010, 6:02:32 PM6/3/10
to
Heiko Oberdiek <heiko.o...@googlemail.com> wrote:
> Philip Hirschhorn <p...@math.mit.edu> wrote:
>
>> Heiko Oberdiek <heiko.o...@googlemail.com> wrote:
>> > However, color specials escape, it is fixed by using
>> > LaTeX's internal color interface (a group):
>> >
>> > \setbox0=\vbox\bgroup\color@begingroup
>> > ...
>> > \color@endgroup\egroup
>>
>> I've only rarely used color, and so I suspect that I'm
>> misunderstanding something, but a small experiment suggests that
>> \color@begingroup and \color@endgroup aren't needed in this simple
>> situation.
>
> They are!
>> .............

>
> Then the color stack of pdfTeX is out of sync, because the pop color
> actions leak out of the discarded \vbox:
>
> pdfTeX warning: pdflatex: pop empty color page stack 0
>
>> there's no problem with the \color commands affecting anything,
>> presumably because of the group created by the \being{whatever}
>> \end{whatever}.
>
> No. Inside the box the color is set. Then *after* the current group
> the color is reset. If the current group is the box, then the reset is
> done at the place of \setbox *outside* the discarded box.

Heiko,

Thank you. I suspect this hasn't come up for anyone using the exam
class because no one's used color in quite this way, but I should
clearly add \color@begingroup and \color@endgroup commands to the
various solution environments in exam.cls to guard against this
problem.

Donald Arseneau

unread,
Jun 3, 2010, 8:44:54 PM6/3/10
to
On Jun 2, 9:11 am, Anna Foeglein <anna.foegl...@googlemail.com> wrote:
> > Look at the "comment" package.
>
> Thanks, I did that, but I'm afraid I need a somewhat more detailed
> pointer...

Then read:

http://www.tex.ac.uk/cgi-bin/texfaq2html?label=conditional

> "comment" seems to discard the commented-out stuff line by line (and
> save it somewhere if necessary).

Then try the other packages like version/versions.

Anna Foeglein

unread,
Jun 4, 2010, 5:49:13 AM6/4/10
to
Hi,

> The following is a slight modification of the solutionenvironmentin
> the exam documentclass:
>

[...]

Sounds absolutely helpful, I'll try this right away! (and have a look
at the "exam" class, too.)

Thanks,
Anna

Anna Foeglein

unread,
Jun 4, 2010, 5:50:52 AM6/4/10
to
Hi Enrico,

On 2 Jun., 19:11, Enrico Gregorio <grego...@math.unipd.it> wrote:
> When, instead, \ifsoln is \iffalse, TeX will look for a
> closing \else (or \fi) /without/ expanding tokens. And here is
> the problem: the intended closing \fi is buried inside a macro
> and TeX cannot see it.

Thanks for the detailed explanation (and confirming why what I was
doing didn't work)!

Ciao,
Anna

Anna Foeglein

unread,
Jun 4, 2010, 5:53:02 AM6/4/10
to
On 3 Jun., 12:07, GL <gouail...@gmail.com> wrote:
> It's weird to take time to built such anenvironment,
> and, in the same time, to say that no time's left to
> understand the comment package...
>                                 ... that's weird ...
>                                    ... in my opinion
>
> A simple solution is to use the Environ package :
>
> \newif\ifsoln
> \NewEnviron{soln}
>         {\ifsoln\else\BODY\fi}
>
> Yours sincerely

Don't worry, I do have the time to understand how to use the comment
package, I just need more time to understand its internal
workings. :-) Luckily, the problem's not time-critical.

But thanks for the hint with the Environ package.

Ciao,
Anna

Anna Foeglein

unread,
Jun 15, 2010, 2:29:41 PM6/15/10
to
On 3 Jun., 02:10, Philip Hirschhorn <p...@math.mit.edu> wrote:
> The following is a slight modification of the solution environment in
> the exam documentclass:
[...]

Just a quick follow-up:
Thanks again for the solution, and even more for the pointer to the
exam document class -- it's great and has everything I was looking
for. :-)

Anna

0 new messages