Previous: Conditional Blocks, Up: Conditionals and Loops [Contents][Index]
GNU
troff provides a looping construct:
the
while
request.
Its syntax matches the
if
request.
Evaluate the conditional expression
cond-expr,
and repeatedly execute
input
unless and until
cond-expr
evaluates false.
input,
which is often a conditional block,
is referred to as the
while
request’s
body.
.nr a 0 1
.while (\na < 9) \{\
\n+a,
.\}
\n+a
⇒ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
GNU
troff treats the body of a
while
request similarly to that of a
de
request
(albeit one not read in copy mode144),
but stores it under an internal name
and deletes it when the loop finishes.
The operation of a macro containing a
while
request can slow significantly if its body is large.
Each time
GNU
troff interpolates the macro,
it parses and stores the
while
body again.
.de xxx
. nr num 10
. while (\\n[num] > 0) \{\
. \" many lines of code
. nr num -1
. \}
..
An often better solution—and one that is more portable,
since AT&T
troff lacked the
while
request—is to instead write a recursive macro,
which is parsed only once.145
.de yy
. if (\\n(nm > 0) \{\
. \" many lines of code
. nr nm -1
. yy
. \}
..
.
.de xx
. nr nm 10
. yy
..
To prevent infinite loops,
GNU
troff limits the default number of available recursion levels
to 1,000 or somewhat less.146
You can disable this protective measure,
or alter the limit,
by setting the
slimit
register.
See Debugging.
As noted above,
if a
while
body begins with a conditional block,
its closing brace must end an input line.
.if 1 \{\
. nr a 0 1
. while (\n[a] < 10) \{\
. nop \n+[a]
.\}\}
error→ unbalanced brace escape sequences
Exit a while loop. Do not confuse this request with a
typographical break or the br request.
Skip the remainder of a while loop’s body, immediately retesting
its conditional expression.
Previous: Conditional Blocks, Up: Conditionals and Loops [Contents][Index]