home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / comp / text / tex / 15492 < prev    next >
Encoding:
Internet Message Format  |  1993-01-28  |  4.2 KB

  1. 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
  2. From: MJD@MATH.AMS.ORG (Michael Downes)
  3. Newsgroups: comp.text.tex
  4. Subject: Re:  Problems with false conditionals
  5. Message-ID: <728060965.802904.MJD@math.ams.org>
  6. Date: 26 Jan 93 15:09:25 GMT
  7. Organization: Info-Tex<==>Comp.Text.Tex Gateway
  8. Lines: 114
  9. X-Gateway-Source-Info: Mailing List
  10.  
  11. Michael Barr wrote:
  12.  
  13. > The following four lines cause an error:
  14. > \iffalse
  15. > \newif\iftest
  16. > \fi
  17. > \bye
  18. >
  19. > On the other hand, these four don't:
  20. > \iftrue
  21. > \newif\iftest
  22. > \fi
  23. > \bye
  24.  
  25. \newif is defined to be \outer in plain TeX. From the TeXbook, p. 206:
  26.  
  27.   An \outer macro cannot appear in an argument (not even when \par is
  28.   allowed), nor can it appear in the parameter text or the replacement
  29.   text of a definition, nor in the preamble to an alignment, nor in
  30.   conditional text that is being skipped over.  If an \outer macro
  31.   does show up in such places, TeX stops what it is doing and reports
  32.   either a ``runaway'' situation or an ``incomplete'' conditional.
  33.  
  34. > I am trying to do something with conditional compilation.  So I defined
  35. > a \newif that can be set true or false to determine which of two paths
  36. > to follow.  The problem is that the false path included the use of a
  37. > macro named \ifnnull (if non-null) that included an \if in its
  38. > definition and in use was to be complemented by a \fi.  Here is a
  39. > simplified version of what it all looked like:
  40. >
  41. > \newif\ifTotOnly
  42. > \TotOnlytrue
  43. >
  44. > \def\ifnnull#1{\def\next{#1}\ifx\next\empty\else}
  45. >
  46. > \ifTotOnly
  47. > %%%% Next line cases trouble when \TotOnlyfalse:
  48. > \newif\ifnnull
  49. >
  50. > %% stuff when \TotOnlytrue
  51. >
  52. > \else
  53. >
  54. >
  55. > %% stuff when \TotOnlyfalse that uses \ifnnull ... \fi
  56. >
  57. > \fi
  58. >
  59. > %% rest of file
  60.  
  61. ...
  62.  
  63. > I think the correct explanation is really the same
  64. > thing that led me to this kludge in the first place: the parser sees
  65. > \ifnnull as an \if, even when it is just being defined.
  66.  
  67. No, TeX is stopping at the \newif, it has not yet considered the
  68. \ifnnull. If you want to put a \newif inside a conditional,
  69. \csname newif\endcsname will work whether the condition is true or
  70. false.
  71.  
  72. > But it does not
  73. > see it as an \if when it is just a control sequence.
  74.  
  75. That's right, only the primitive \if's---or control sequences that are
  76. equated to one of them with \let---are recognized by TeX's conditional
  77. scanning. Conditionals created by \newif are always equal to either
  78. \iftrue or \iffalse.
  79.  
  80. If you want a conditional that includes non-expandable statements in
  81. its definition (such as "\def\next{#1}") there is a trick suggested by
  82. Knuth in TeXhax a few years ago (in response to a query of Stephan von
  83. Bechtolsheim):
  84.  
  85.   \def\nnull#1{TT\fi \def\next{#1}\ifx\next\empty\else}
  86.  
  87. Usage:
  88.  
  89.   \if\nnull{abc}...\fi
  90.  
  91. Explanation: This uses the primitive \if at the surface level to
  92. satisfy TeX's scanner. If the entire \if\nnull...\fi construction
  93. occurs on the false branch of an enclosing conditional, TeX sees only
  94. the \if and \fi and does not look inside \nnull. If the \if is
  95. actually executed, the TT\fi will match the \if and the \ifx will
  96. match the following \fi.
  97.  
  98. Or try the LaTeX-style construction \ifnonnull{...}{true case}{false
  99. case}.
  100.  
  101.   \def\ifnonnull#1#2#3{\def\truecase{#2}\def\falsecase{#3}%
  102.     \def\next{#1}%
  103.     \ifx\next\empty \let\next\truecase
  104.     \else \let\next\falsecase
  105.     \fi
  106.     \next
  107.   }
  108.  
  109. This has the advantage that the true or false case can end with
  110. a macro that requires arguments. (With the other style of conditional,
  111. such a macro would try to use the \else or \fi as an argument, with
  112. laughable results.)
  113.  
  114. The LaTeX convention of putting in an @ at the beginning (i.e.
  115. \@ifnonnull) is recommended for non-\newif-created macros like this
  116. since the lack of a \fi will otherwise make it impossible for a smart
  117. text editor to help you properly match up \if \else \fi for the
  118. standard kinds of conditionals. (Or some other distinguishing
  119. convention, perhaps \IFnonnull or \nonnullp.) And if you are starting
  120. to do more complex conditional programming as your example suggests, I
  121. suspect you will soon wish for such a matching ability in your text
  122. editor.
  123.  
  124. Michael Downes                              mjd@math.ams.org (Internet)
  125.