Next: while, Previous: if-else, Up: Conditionals and Loops [Contents][Index]
It is frequently desirable for a control structure to govern more than
one request,
macro call,
text line,
or combination of the foregoing.
The opening and closing brace escape sequences
\{
and
\}
define such groups.
These
conditional blocks
can furthermore be nested.
Brace escape sequences outside of control structures have no meaning (but can be used as delimiters) and produce no output.254
\{
begins a conditional block;
it must appear
(after optional spaces and tabs)
immediately subsequent to the conditional expression of an
if,
ie,
or
while
request,255
or as the argument to an
el
request.
\}
ends a conditional block and should appear on an input line
with other occurrences of itself as necessary to match
\{
sequences.
It can be preceded by a control character,
spaces,
and tabs.
Input after any quantity of opening brace escape sequences
\}
on the same line is processed
only if all of the preceding conditions to which they correspond
are true.
Further,
a closing brace escape sequence
\}
closing the body of a
while
request must be the last such escape sequence on an input line.
Caution:
Input lines using
\{
often end with
\RET,
especially in macros that consist primarily of control lines.
Forgetting to use
\RET
on an input line after
\{
is a common source of error.
We might write the following in a page header macro. If we delete
\RET, the header will carry an unwanted extra empty line (except
on page 1).
.if (\\n[%] != 1) \{\
. ie ((\\n[%] % 2) = 0) .tl \\*[even-numbered-page-title]
. el .tl \\*[odd-numbered-page-title]
.\}
Let us take a closer look at how conditional blocks nest.
A
.if 0 \{ B
C
D
\}E
F
⇒ A F
N
.if 1 \{ O
. if 0 \{ P
Q
R\} S\} T
U
⇒ N O U
.ie 1 \{\
. ds a abc\}def
a="\*a"
.el ghi
⇒ a="abcdef"
The above behavior may challenge the intuition;
it was implemented to retain compatibility with AT&T
troff.
A right-brace escape sequence governs flow of control this way:
if a branch is
not
taken,
then the closing brace that closes a conditional block
causes the formatter to ignore the entire input line
on which it appears for all purposes except matching braces.
For clarity, it
is idiomatic to end input lines with \{ (followed by
\RET if appropriate), and to precede \} on an input
line with nothing more than a control character, spaces, tabs, and other
instances of itself.
We can use ie, el, and conditional blocks to simulate the
multi-way “switch” or “case” control structures of other languages.
The following example is adapted from the groff man
package. Indentation is used to clarify the logic.
.\" Simulate switch/case in roff.
. ie '\\$2'1' .ds title General Commands\"
.el \{.ie '\\$2'2' .ds title System Calls\"
.el \{.ie '\\$2'3' .ds title Library Functions\"
.el \{.ie '\\$2'4' .ds title Kernel Interfaces\"
.el \{.ie '\\$2'5' .ds title File Formats\"
.el \{.ie '\\$2'6' .ds title Games\"
.el \{.ie '\\$2'7' .ds title Miscellaneous Information\"
.el \{.ie '\\$2'8' .ds title System Management\"
.el \{.ie '\\$2'9' .ds title Kernel Development\"
.el .ds title \" empty
.\}\}\}\}\}\}\}\}
Next: while, Previous: if-else, Up: Conditionals and Loops [Contents][Index]