From: Donald Arseneau <ASND%TRIUMFRG.BITNET@SHSU.edu>
Newsgroups: comp.text.tex
Subject: Re: Problems with false conditionals
Date: Tue, 26 Jan 1993 02:20 PDT
Organization: Info-Tex<==>Comp.Text.Tex Gateway
X-Gateway-Source-Info: Mailing List

Michael Barr wrote in info-TeX:
% The following lines cause an error:
% \iffalse
% \newif\iftest
% \fi

% I am trying to do something with conditional compilation.  So I defined
% a \newif that can be set true or false to determine which of two paths
% to follow.  The problem is that the false path included the use of a
% macro named \ifnnull (if non-null) that included an \if in its
% definition and in use was to be complemented by a \fi.

There are two problems here.  The second is the well-known problem of
macros that act as conditionals, but are not recognized as such by TeX.
You need to include an \if in the visible syntax of the macro so the
\else and \fi will be balanced when skipping.  Here are some examples:

% ================================================================
% There are many ways to check if a field is blank.  The clearest is:
%
% \long\def\@tempa{#1}\ifx\@tempa\@empty ... \else ... \fi
%
% (use \empty for plain TeX)
%
% There are a few deficiencies with this approach: it is not "expandable"
% so it can't be executed in an \edef or a \write; it redefines some
% command (\@tempa here); there are many parameter texts that will break
% it.  Below are my versions which are expandable and safe.  There are
% two versions for the syntax:  \ifnull{#1}\then... and \if\naught{#1}...
% [I hear this syntax comes from DEK].   Choose your favorite.
%
%========================================================================
%  \ifblank --- checks if parameter is blank (Spaces count as blank)
%  \ifgiven --- checks if parameter is not blank: like \ifblank...\else
%  \ifnull  --- checks if parameter is null (spaces are NOT null)
%     use \ifgiven{#1}\then   ...  \else  ...  \fi   etc
\let\then\iftrue
{\catcode`\!=8 % funny catcode so ! will be a delimiter
\long\gdef\ifgiven#1\then{\Ifbl@nk#1@@@\empty!}% negative of \ifblank
\long\gdef\ifblank#1\then{\Ifbl@nk#1@@..!}% if null or spaces
\long\gdef\Ifbl@nk#1#2@#3#4!{\ifx#3#4}
\long\gdef\ifnull#1\then{\IfN@LL#1* {#1}!}% if null
\long\gdef\IfN@LL#1 #2!{\ifblank{#2}\then}
}
%
%---------------------------------------------------------------------
%  or.... use \if\given, \if\blank, \if\naught (\null already exists)
%  without \then.
%
{\catcode`\!=8 % funny catcode so ! will be a delimiter
\long\gdef\given#1{88\fi\Ifbl@nk#1@@@\empty!}
\long\gdef\blank#1{88\fi\Ifbl@nk#1@@..!}% if null or spaces
\long\gdef\naught#1{\IfN@Ught#1* {#1}!}% if null
\long\gdef\IfN@Ught#1 #2!{\blank{#2}}
\long\gdef\Ifbl@nk#1#2@#3#4!{\ifx#3#4}% same as above
}
%---------------------------------------------------------------------
%  \ifsame --- checks if its two parameters are the same,
%          use \ifsame{#1}{#2}\then  ...  \else  ...  \fi
\def\ifsame#1#2\then{\begingroup\def\fiRst{#1}\def\seCon{#2}\expandafter
  \endgroup\ifx\fiRst\seCon }
%
\def\same#1#2{88\fi % match the bogus \if
  \begingroup \def\first{#1}\def\second{#2}%
  \expandafter\endgroup %test macros outside group but before forgetting them
  \ifx\first\second}
%
%=========================================================================


The other (first) problem was that \newif\ifwhatever produces an unbalanced
\ifwhatever if it is already defined and the initialization is skipped
over.  \newif is not allowed to be skipped in any case because it is \outer!
Of course you want to skip the \newif when the \if is already defined
Here is how I solved that problem (exerpt from ulem.sty):

%=========================================================================
% Allow plain TeX to use this style:
\ifx\@ifundefined\@underfined
  ...
% Do non-outer \newif and balance \if's and \fi's when skipping
  \csname newif\endcsname\if@ignore   \ifx\fi\relax\fi
\fi
%=========================================================================

Donald Arseneau      asnd@reg.triumf.ca
                     asnd@triumfrg
Newsgroups: comp.text.tex