groff-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[groff] 11/12: [docs]: Update material on conditionals.


From: G. Branden Robinson
Subject: [groff] 11/12: [docs]: Update material on conditionals.
Date: Mon, 24 May 2021 13:06:16 -0400 (EDT)

gbranden pushed a commit to branch master
in repository groff.

commit 356bc65dc012aac8f4a885068218347e8f2f8a3c
Author: G. Branden Robinson <g.branden.robinson@gmail.com>
AuthorDate: Tue May 25 02:00:53 2021 +1000

    [docs]: Update material on conditionals.
    
    * doc/groff.texi (Conditionals and Loops):
      - Say "groff" instead of "GNU troff" when referring to the system or
        accpted input language.
      - Introduce term "conditional expression" to refer to the extended
        expression syntax used by control structures.  Add concept index
        entries.
      - Capitalize "Boolean".
      - Tighten wording.
      - Coalesce discussion when spaces and tabs are valid (and behave
        intuititively) after conditional expression operators.
      - <if> Rewrite description of how the remainder of the input line
        after the conditional expression is interpreted.  Add example
        involving the notorious \c escape and the possibly surprising fact
        that an "empty" if body can put a newline on the input stream.
      - <nop> Rewrite description.  Supply use case as indentation mechanism
        for text lines inside macro definitions.  Replace example with a
        more practical one.
      - Replace "expr" metasyntactical variable with "cond-expr" to remind
        reader that the expression syntax in other contexts is more limited.
      - Say "GNU troff" instead of "gtroff".
    
    Sync groff(7) and groff_diff(7) with the above material.
    
    * man/groff.7.man (Numerical expressions): Recast colon-terminated
      sentence fragment as a real sentence.
      (Control structures): New section imports material on syntax from our
      Texinfo manual.
      (Conditional expressions): Renamed from "Conditions".  Reduce list of
      operators to only those that are actually conditional, removing plain
      numerical expressions and their logical complementation.  Fix
      description of "string" comparison operator to refer to formatted
      output.
      (Requests/Request short reference) <el, ie, if, nop, while>: Sync.
    
    * man/groff_diff.7.man (Language/New requests) <nop, while>: Sync.
---
 doc/groff.texi       | 120 +++++++++++++++-----------
 man/groff.7.man      | 233 ++++++++++++++++++++++++++++++++++++++-------------
 man/groff_diff.7.man |  85 +++++++++++++++----
 3 files changed, 314 insertions(+), 124 deletions(-)

diff --git a/doc/groff.texi b/doc/groff.texi
index bb13d0f..b706846 100644
--- a/doc/groff.texi
+++ b/doc/groff.texi
@@ -11532,7 +11532,7 @@ itself is not destroyed until it has no more names.
 @cindex conditionals and loops
 @cindex loops and conditionals
 
-GNU @code{troff} has @code{if} and @code{while} control structures like
+@code{groff} has @code{if} and @code{while} control structures like
 other languages.  However, the syntax for grouping multiple input lines
 in the branches or bodies of these structures is unusual.
 
@@ -11552,9 +11552,12 @@ in the branches or bodies of these structures is 
unusual.
 @cindex @code{if} request, operators to use with
 @cindex @code{ie} request, operators to use with
 @cindex @code{while} request, operators to use with
-In @code{if}, @code{ie}, and @code{while} requests, in addition to
-ordinary numeric expressions (@pxref{Expressions}), several boolean
-operators are available.
+@cindex conditional expressions
+@cindex expressions, conditional
+In @code{if}, @code{ie}, and @code{while} requests, in addition to the
+numeric expressions described in @ref{Expressions}, several Boolean
+operators are available; the members of this expanded class are termed
+@dfn{conditional expressions}.
 
 @table @code
 @item c @var{glyph}
@@ -11668,9 +11671,9 @@ false
 @endExample
 @end table
 
-These operators can't be combined with other operators like @samp{:} or
-@samp{&}; only a leading @samp{!} (without spaces or tabs between the
-exclamation mark and the operator) can be used to negate the result.
+These operators can't be combined with others like @samp{:} or @samp{&};
+only a leading @samp{!} (without spaces or tabs between the exclamation
+mark and the operator) can be used to negate the result.
 
 @Example
 .nr x 1
@@ -11679,9 +11682,10 @@ exclamation mark and the operator) can be used to 
negate the result.
     @result{} register x is defined
 @endExample
 
-Spaces and tabs immediately after @samp{!} cause the condition to
-evaluate as zero (this bizarre behavior maintains compatibility with
-@acronym{AT&T} @code{troff}).
+Spaces and tabs are optional immediately after the @samp{r}, @samp{d},
+and @samp{c} operators, but immediately after @samp{!}, they cause the
+condition to evaluate false (this bizarre behavior maintains
+compatibility with @acronym{AT&T} @code{troff}).
 
 @Example
 .nr x 1
@@ -11691,12 +11695,9 @@ evaluate as zero (this bizarre behavior maintains 
compatibility with
 @endExample
 
 @noindent
-The unexpected appearance of @samp{r x} in the output is a clue that our
-conditional was not interpreted the way we planned, but matters may not
-always be so obvious.
-
-Spaces and tabs are optional before the arguments to the @samp{r},
-@samp{d}, and @samp{c} operators.
+The unexpected @samp{r x} in the output is a clue that our conditional
+was not interpreted as we planned, but matters may not always be so
+obvious.
 
 @c ---------------------------------------------------------------------
 
@@ -11704,24 +11705,48 @@ Spaces and tabs are optional before the arguments to 
the @samp{r},
 @subsection if-then
 @cindex if-then
 
-@Defreq {if, expr anything}
+@Defreq {if, cond-expr anything}
+Evaluate the conditional expression @var{cond-expr}, and if it evaluates
+true (that is, to a positive value), interpret the remainder of the line
+@var{anything} as if it were an input line.  Recall from @ref{Request
+and Macro Arguments} that any number of spaces between arguments to
+requests serves only to separate them; leading spaces in @var{anything}
+are thus not seen.  @var{anything} effectively @emph{cannot} be omitted;
+if @var{cond-expr} is true and @var{anything} is empty, the newline at
+the end of the control line is interpreted as a blank input line (and
+therefore a blank text line).
+
+@Example
+super\c
+tanker
+.nr force-word-break 1
+super\c
+.if ((\n[force-word-break] = 1) & \n[.int])
+tanker
+    @result{} supertanker super tanker
+@endExample
+@endDefreq
 
-Evaluate the expression @var{expr}, and execute @var{anything} (the
-remainder of the line) if @var{expr} evaluates true (that is, to a value
-greater than zero).  @var{anything} is interpreted as though it
-were on a line by itself (except that leading spaces are ignored).
-@xref{Operators in Conditionals}.
+@Defreq {nop, anything}
+Interpret @var{anything} as if it were an input line.  This is similar
+to @samp{.if@tie{}1}.  @code{nop} is not really ``no operation''; its
+argument @emph{is} processed---unconditionally.  It can be used to cause
+text lines to share indentation with surrounding control lines.
 
 @Example
-.nr xxx 1
-.nr yyy 2
-.if ((\n[xxx] == 1) & (\n[yyy] == 2)) true
-    @result{} true
+.als real-MAC MAC
+.de wrapped-MAC
+.  tm MAC: called with arguments \\$@@
+.  nop \\*[real-MAC]\\
+..
+.als MAC wrapped-MAC
+\# Later...
+.als MAC real-MAC
 @endExample
-@endDefreq
 
-@Defreq {nop, anything}
-Executes @var{anything}.  This is similar to @samp{.if@tie{}1}.
+In the above, we've used aliasing, @code{nop}, and the interpolation of
+a macro as a string to interpose a wrapper around the macro @samp{MAC}
+(perhaps to debug it).
 @endDefreq
 
 @c ---------------------------------------------------------------------
@@ -11730,19 +11755,17 @@ Executes @var{anything}.  This is similar to 
@samp{.if@tie{}1}.
 @subsection if-else
 @cindex if-else
 
-@DefreqList {ie, expr anything}
+@DefreqList {ie, cond-expr anything}
 @DefreqListEndx {el, anything}
 Use the @code{ie} and @code{el} requests to write an if-then-else.  The
 first request is the `if' part and the latter is the `else' part.
 
 @Example
-.ie n .ls 2 \" double-spacing in nroff
-.el   .ls 1 \" single-spacing in troff
+.ie n .ls 2 \" double-spacing in nroff mode
+.el   .ls 1 \" single-spacing in troff mode
 @endExample
 @endDefreq
 
-@xref{Expressions}.
-
 @c ---------------------------------------------------------------------
 
 @node Conditional Blocks, while, Operators in Conditionals, Conditionals and 
Loops
@@ -11780,7 +11803,8 @@ appear on a line with other occurrences of itself as 
necessary to match
 and tabs.  Input after an @code{\@}} escape on the same line
 is only processed if all the preceding conditions to which the escapes
 correspond are true.  Furthermore, a @code{\@}} closing the body of a
-@code{while} request must be the last such escape on an input line.
+@code{while} request (discussed below) must be the last such escape on
+an input line.
 
 @Example
 A
@@ -11830,9 +11854,8 @@ version
 Try omitting the @code{\@key{RET}}s from the foregoing example and see
 how the output changes.  Remember that, as noted above, after a true
 conditional (or after the @code{el} request if its counterpart @code{ie}
-condition was false) any spaces or tabs on the same input line are
-interpreted @emph{as if they were on an input line by themselves}.
-
+condition was false) the remainder of the input line is interpreted
+@emph{as if it were on an input line by itself}.
 @endDefesc
 
 @c ---------------------------------------------------------------------
@@ -11841,13 +11864,12 @@ interpreted @emph{as if they were on an input line by 
themselves}.
 @subsection while
 @cindex while
 
-GNU @code{troff} provides a looping construct using the @code{while}
+@code{groff} provides a looping construct using the @code{while}
 request, which is used much like the @code{if} request.
 
-@Defreq {while, expr anything}
-Evaluate the expression @var{expr}, and repeatedly execute
-@var{anything} (the remainder of the line) until @var{expr} evaluates
-false.
+@Defreq {while, cond-expr anything}
+Evaluate the conditional expression @var{cond-expr}, and repeatedly
+execute @var{anything} unless and until @var{cond-expr} evaluates false.
 
 @Example
 .nr a 0 1
@@ -11864,11 +11886,11 @@ Some remarks.
 @itemize @bullet
 @item
 The body of a @code{while} request is treated like the body of a
-@code{de} request: @code{gtroff} temporarily stores it in a macro that
-is deleted after the loop has been exited.  It can considerably slow
-down a macro if the body of the @code{while} request (within the macro)
-is large.  Each time the macro is executed, the @code{while} body is
-parsed and stored again as a temporary macro.
+@code{de} request: GNU @code{troff} temporarily stores it in a macro
+that is deleted after the loop exits.  It can considerably slow down a
+macro if the body of the @code{while} request (within the macro) is
+large.  Each time the macro is executed, the @code{while} body is parsed
+and stored again as a temporary macro.
 
 @Example
 .de xxx
@@ -11904,7 +11926,7 @@ that is parsed only once during its definition.
 
 @noindent
 The number of available recursion levels is set to@tie{}1000
-(this is a compile-time constant value of @code{gtroff}).
+(this is a compile-time constant value of GNU @code{troff}).
 
 @item
 The closing brace of a @code{while} body must end a line.
diff --git a/man/groff.7.man b/man/groff.7.man
index ed0dc0a..3718f55 100644
--- a/man/groff.7.man
+++ b/man/groff.7.man
@@ -907,7 +907,7 @@ Close current grouping
 .P
 Moreover,
 .I groff
-added the following operators for numerical expressions:
+provides the following additional operators for numerical expressions.
 .
 .
 .P
@@ -947,51 +947,136 @@ Texinfo manual.
 .
 .
 .\" ====================================================================
-.SH Conditions
+.SH "Control structures"
 .\" ====================================================================
 .
-.B Conditions
-are expressions tested by the
+.I groff
+has \[lq]if\[rq] and \[lq]while\[rq] control structures like other
+languages.
+.
+However,
+the syntax for grouping multiple input lines in the branches or bodies
+of these structures is unusual.
+.
+.
+.P
+They have a common form:
+the request name is
+(except for
+.request .el
+\[lq]else\[rq])
+followed by a conditional expression
+.IR cond-expr ,
+and then the remainder of the line
+.I anything
+is interpreted as if it were an input line.
+.
+Any number of spaces between arguments to requests serves only to
+separate them;
+leading spaces in
+.I anything
+are therefore not seen.
+.
+.I anything
+effectively
+.I cannot
+be omitted;
+if
+.I cond-expr
+is true and
+.I anything
+is empty,
+the newline at the end of the control line is interpreted as a blank
+line
+(and therefore a blank text line).
+.
+.
+.P
+It is frequently desirable for a control structure to govern more than
+one request,
+call more than one macro,
+span more than one input line of text,
+or mix the foregoing.
+.
+The opening and closing brace escapes
+.esc {
+and
+.esc }
+perform such grouping.
+.
+Brace escapes can be used outside of control structures,
+but when they are they have no meaning and produce no output.
+.
+.
+.P
+.esc {
+should appear
+(after optional spaces and tabs)
+immediately subsequent to the request's conditional expression.
+.
+.esc }
+should appear on a line with other occurrences of itself as necessary to
+match
+.esc {
+escapes.
+.
+It can be preceded by a control character,
+spaces,
+and tabs.
+.
+Input after a
+.esc }
+escape on the same line is only processed if all the preceding
+conditions to which the escapes correspond are true.
+.
+Furthermore,
+a
+.esc }
+closing the body of a
+.request .while
+request must be the last such escape on an input line.
+.
+.
+.\" ====================================================================
+.SH "Conditional expressions"
+.\" ====================================================================
+.
+In
 .request .if ,
 .request .ie ,
-and the
+and
 .request .while
-requests.
+requests,
+in addition to the numeric expressions described above,
+several Boolean operators are available;
+the members of this expanded class are termed
+.IR "conditional expressions" .
 .
-The following table characterizes the different types of conditions.
 .
 .P
-.
-.PD 0
-.RS
-.
-.TPx
-.I N
 A numerical expression
 .I N
-yields true if its value is greater than\~0.
+yields true if its value is positive.
+.
+In
+.I roff
+languages,
+negative values are false,
+not true.
 .
-.TPx
-.BI ! N
-True if the value of
-.I N
-is \[<=]\~0
-(see below).
+.
+.P
+.
+.PD 0
+.RS
 .
 .TPx
 .BI \[aq] s1 \[aq] s2 \[aq]
-True if string\~\c
-.I s1
-is identical to string\~\c
-.IR s2 .
+True
+.RI if\~ s1
+produces the same formatted output
+.RI as\~ s2 .
 .
-.TPx
-.BI !\[aq] s1 \[aq] s2 \[aq]
-True if string\~\c
-.I s1
-is not identical to string\~\c
-.I s2
-(see below).
 .
 .TPx
 .BI c\~ g
@@ -1059,12 +1144,28 @@ implementations).
 .
 .
 .P
-Note that the
-.B !\&
-operator may only appear at the beginning of an expression,
-and negates the entire expression.
-This maintains bug-compatibility with AT&T
-.IR troff .
+These operators can't be combined with others like
+.RB \[lq] : \[rq]
+or
+.RB \[lq] & \[rq];
+only a leading
+.RB \[lq] ! \[rq]
+(without spaces or tabs between the exclamation mark and the operator)
+can be used to negate the result.
+.
+.
+.P
+Spaces and tabs are optional immediately after the
+.RB \[lq] r \[rq],
+.RB \[lq] d \[rq],
+and
+.RB \[lq] c \[rq]
+operators,
+but immediately after
+.RB \[lq] ! \[rq],
+they cause the condition to evaluate false
+(this bizarre behavior maintains compatibility with AT&T
+.IR troff ).
 .
 .
 .\" ====================================================================
@@ -1726,9 +1827,12 @@ Save current escape character.
 .
 .TPx
 .REQ .el "anything"
-Else part for if-else (\c
-.request .ie )
-request.
+Interpret
+.I anything
+as if it were an input line if the conditional expression of the
+corresponding
+.request .ie
+request was false.
 .
 .
 .TPx
@@ -2009,22 +2113,29 @@ extra space to each inter-word space
 (default scaling indicator\~\c
 .scaleindicator m ).
 .
+.
 .TPx
-.REQ .ie "cond anything"
+.REQ .ie "cond-expr anything"
 If
-.I cond
-then
-.IR anything ,
-otherwise skip to
-.request .el .
+.I cond-expr
+is true,
+interpret
+.I anything
+as if it were an input line,
+otherwise skip to a corresponding
+.request .el
+request.
+.
 .
 .TPx
-.REQ .if "cond anything"
+.REQ .if "cond-expr anything"
 If
-.I cond
-then
-.IR anything ;
-otherwise do nothing.
+.I cond-expr
+is true,
+then interpret
+.I anything
+as if it were an input line.
+.
 .
 .TPx
 .REQ .ig
@@ -2264,10 +2375,13 @@ Do not number next
 .I N
 lines.
 .
+.
 .TPx
 .REQ .nop "anything"
-Always process
-.IR anything .
+Interpret
+.I anything
+as if it were an input line.
+.
 .
 .TPx
 .REQ .nr "register \[+-]N \fR[\fPM\fR]\fP"
@@ -2885,12 +2999,15 @@ is replaced.
 .
 .
 .TPx
-.REQ .while "cond anything"
-While condition
-.I cond
-is true, accept
+.REQ .while "cond-expr anything"
+Evaluate
+.IR cond-expr ,
+and repeatedly execute
 .I anything
-as input.
+unless and until
+.I cond-expr
+evaluates false.
+.
 .
 .TPx
 .REQ .write "stream anything"
diff --git a/man/groff_diff.7.man b/man/groff_diff.7.man
index f9725a4..40ab5ec 100644
--- a/man/groff_diff.7.man
+++ b/man/groff_diff.7.man
@@ -2598,9 +2598,22 @@ does not exist.
 .
 .TP
 .BI .nop \~anything
-Execute
-.IR anything .
-This is similar to \[oq].if\~1\[cq].
+Interpret
+.I anything
+as if it were an input line.
+.
+This is similar to
+.RB \[lq] ".if 1" \[rq].
+.
+.B .nop
+is not really \[lq]no operation\[rq];
+its argument
+.I is
+processed\[em]unconditionally.
+.
+It can be used to cause text lines to share indentation with surrounding
+control lines.
+.
 .
 .TP
 .B .nroff
@@ -3309,28 +3322,66 @@ and\~\c
 At startup, it is set to\~\c
 .BR i .
 .
+.
 .TP
-.BI .while \~c\~anything
-While condition\~\c
-.I c
-is true, accept
+.BI .while \~cond-expr\~anything
+Evaluate the conditional expression
+.IR cond-expr ,
+and repeatedly execute
 .I anything
-as input;
-.IR c \~\c
-can be any condition acceptable to an
-.B if
-request;
-.I anything
-can comprise multiple lines if the first line starts with
-.B \[rs]{
-and the last line ends with
-.BR \[rs]} .
+unless and until
+.I cond-expr
+evaluates false.
+.
 See also the
 .B break
 and
 .B continue
 requests.
 .
+.
+.IP
+The body of a
+.B while
+request is treated like the body of a
+.B de
+request:
+.I \%@g@troff
+temporarily stores it in a macro that is deleted after the loop exits.
+.
+It can considerably slow down a macro if the body of the
+.B while
+request
+(within the macro)
+is large.
+.
+Each time the macro is executed,
+the
+.B while
+body is parsed and stored again as a temporary macro.
+.
+.
+.IP
+The traditional and often better solution
+(AT&T
+.I troff \" AT&T
+lacked the
+.B while
+request)
+is to use a recursive macro instead that is parsed only once during its
+definition.
+.
+The number of available recursion levels is set to\~1000
+(this is a compile-time constant value of
+.IR \%@g@troff .
+.
+.
+.IP
+The closing brace of a
+.B while
+body must end a line.
+.
+.
 .TP
 .BI .write\~ stream\~anything
 Write



reply via email to

[Prev in Thread] Current Thread [Next in Thread]