home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!charon.amdahl.com!amdahl!rtech!decwrl!hal.com!olivea!spool.mu.edu!howland.reston.ans.net!usc!news.service.uci.edu!unogate!mvb.saic.com!info-tex
- From: MJD@MATH.AMS.ORG (Michael Downes)
- Newsgroups: comp.text.tex
- Subject: Re: Problems with false conditionals
- Message-ID: <728060965.802904.MJD@math.ams.org>
- Date: 26 Jan 93 15:09:25 GMT
- Organization: Info-Tex<==>Comp.Text.Tex Gateway
- Lines: 114
- X-Gateway-Source-Info: Mailing List
-
- Michael Barr wrote:
-
- > The following four lines cause an error:
- > \iffalse
- > \newif\iftest
- > \fi
- > \bye
- >
- > On the other hand, these four don't:
- > \iftrue
- > \newif\iftest
- > \fi
- > \bye
-
- \newif is defined to be \outer in plain TeX. From the TeXbook, p. 206:
-
- An \outer macro cannot appear in an argument (not even when \par is
- allowed), nor can it appear in the parameter text or the replacement
- text of a definition, nor in the preamble to an alignment, nor in
- conditional text that is being skipped over. If an \outer macro
- does show up in such places, TeX stops what it is doing and reports
- either a ``runaway'' situation or an ``incomplete'' conditional.
-
- > 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. Here is a
- > simplified version of what it all looked like:
- >
- > \newif\ifTotOnly
- > \TotOnlytrue
- >
- > \def\ifnnull#1{\def\next{#1}\ifx\next\empty\else}
- >
- > \ifTotOnly
- > %%%% Next line cases trouble when \TotOnlyfalse:
- > \newif\ifnnull
- >
- > %% stuff when \TotOnlytrue
- >
- > \else
- >
- >
- > %% stuff when \TotOnlyfalse that uses \ifnnull ... \fi
- >
- > \fi
- >
- > %% rest of file
-
- ...
-
- > I think the correct explanation is really the same
- > thing that led me to this kludge in the first place: the parser sees
- > \ifnnull as an \if, even when it is just being defined.
-
- No, TeX is stopping at the \newif, it has not yet considered the
- \ifnnull. If you want to put a \newif inside a conditional,
- \csname newif\endcsname will work whether the condition is true or
- false.
-
- > But it does not
- > see it as an \if when it is just a control sequence.
-
- That's right, only the primitive \if's---or control sequences that are
- equated to one of them with \let---are recognized by TeX's conditional
- scanning. Conditionals created by \newif are always equal to either
- \iftrue or \iffalse.
-
- If you want a conditional that includes non-expandable statements in
- its definition (such as "\def\next{#1}") there is a trick suggested by
- Knuth in TeXhax a few years ago (in response to a query of Stephan von
- Bechtolsheim):
-
- \def\nnull#1{TT\fi \def\next{#1}\ifx\next\empty\else}
-
- Usage:
-
- \if\nnull{abc}...\fi
-
- Explanation: This uses the primitive \if at the surface level to
- satisfy TeX's scanner. If the entire \if\nnull...\fi construction
- occurs on the false branch of an enclosing conditional, TeX sees only
- the \if and \fi and does not look inside \nnull. If the \if is
- actually executed, the TT\fi will match the \if and the \ifx will
- match the following \fi.
-
- Or try the LaTeX-style construction \ifnonnull{...}{true case}{false
- case}.
-
- \def\ifnonnull#1#2#3{\def\truecase{#2}\def\falsecase{#3}%
- \def\next{#1}%
- \ifx\next\empty \let\next\truecase
- \else \let\next\falsecase
- \fi
- \next
- }
-
- This has the advantage that the true or false case can end with
- a macro that requires arguments. (With the other style of conditional,
- such a macro would try to use the \else or \fi as an argument, with
- laughable results.)
-
- The LaTeX convention of putting in an @ at the beginning (i.e.
- \@ifnonnull) is recommended for non-\newif-created macros like this
- since the lack of a \fi will otherwise make it impossible for a smart
- text editor to help you properly match up \if \else \fi for the
- standard kinds of conditionals. (Or some other distinguishing
- convention, perhaps \IFnonnull or \nonnullp.) And if you are starting
- to do more complex conditional programming as your example suggests, I
- suspect you will soon wish for such a matching ability in your text
- editor.
-
- Michael Downes mjd@math.ams.org (Internet)
-