Conditionally displaying/hiding parts of document using macros

I'm currently using the following approach to conditionally display/hide parts of my document:

% PREAMBLE

\def\MyVersion{1}

% BODY

\ifnum\MyVersion=1
This is version one.
% possibly other paragraphs, math blocks, tables, figures, etc
\fi

\ifnum\MyVersion=2
This is version two.
% possibly other paragraphs, math blocks, tables, figures, etc
\fi

To tidy up a bit, I tried to define macros for the \ifnum and \fi statements in the preamble:

\def\StartVersionOne{\ifnum\MyVersion=1}
\def\StopVersionOne{\fi}
\def\StartVersionTwo{\ifnum\MyVersion=2}
\def\StopVersionTwo{\fi}

However, this produces the following error:

! Incomplete \ifnum; all text was ignored after line ...

Strangely, everything works if I only use the \StartXXX macros and not the \StopXXX macros. Can anyone explain what is going on? Am I defining the macros wrongly for \fi?

-
For LaTeX, you can use the comment package. For ConTeXt, you can use Modes. Perhaps you can look at the implementation of these solution to see how to implement the same in plain TeX. –  Aditya Feb 16 '11 at 22:33
See also this Q&A which discusses something very similar, just for different languages instead of versions. –  Martin Scharrer Feb 16 '11 at 22:59
Take a look at this question and answer: [tex.stackexchange.com/questions/10069/… which (I think) does what you want. –  Phil Hirschhorn Feb 16 '11 at 23:05

Replace

\def\StopVersionOne{\fi}

with

\let\StopVersionOne=\fi

Then it should work. Explanation: TeX scans ahead for finding a \fi that matches the \ifnum, but it scans without expanding if the test turns out false, so with \def it doesn't find the \fi.

If in any case you're using nested conditionals, please read Martin's answer (and the comments to my answer).

-
No, that's not enough in the general case. See my answer. –  Martin Scharrer Feb 16 '11 at 22:38
@Martin: I'm not exactly sure what you mean; in the context of the OP my answer should work. –  Hendrik Vogt Feb 16 '11 at 22:40
The if-switches are not matched, e.g.: \iffalse \StartVersionOne \StopVersionOne \fi breaks because \StartVersionOne is not expanded. A simple solution works if there are no other conditionals, but as soon there are one it breaks. –  Martin Scharrer Feb 16 '11 at 22:44
@Martin: I see no \iffalse or \iftrue in the OP. (I see them in your answer, but I don't think they're needed to solve the OP's problem. And I do see that my answer breaks for nested conditionals; I'll add that to my answer.) –  Hendrik Vogt Feb 16 '11 at 22:52
Fun-fact: I spent the last three hours to make my new collcell package to work with conditionals in tabular cells, without much success. Especially because the first cell token is expanded before I can read it and therefore in a last but empty cell the \\ is expanded, which contains some \iffalse{\fi\ifnum0}\fi which really freaks my parser out! :-) –  Martin Scharrer Feb 16 '11 at 23:07

This doesn't work because the \StopVersionOne is never expanded when it is in the \else path and therefore the containing \fi is never seen by TeX. Inside an false path TeX skips ahead without expanding macros until it finds one which is identical to \fi, e.g. \fi itself or a macro which was \let to it. However, other including \if... and their closing \fi are also counted.

In order for this to work you need to \let these macros to \iffalse/\iftrue and \fi respectively, e.g. everytime you change \MyVersion you \let the corresponding macro to \iftrue and all others to \iffalse. All \Stop... macros are \let to \fi.

However this still doesn't work if your text includes unmatch \if../\fis.

Another way to do it is the comments package which skips everything verbatim to avoid these issues.

-

If you count your versions 1,2,3,.. then use \ifcase

\documentclass{minimal}
\def\MyVersion{1}
\begin{document}

\ifcase\MyVersion\or
This is version one.
% possibly other paragraphs, math blocks, tables, figures, etc
\or
This is version two.
% possibly other paragraphs, math blocks, tables, figures, etc
\fi

\end{document}
-