Next: , Up: Conditionals and Loops   [Contents][Index]


5.23.1 Operators in Conditionals

The if, ie, and while requests test the truth values of numeric expressions. They also support several additional Boolean operators. The members of this expanded class are termed conditional expressions; their truth values are as shown below.

c chr

True if a character chr is available; chr is an ordinary, special or indexed character, whether defined by a font description file or a request.

d nam

True if a string, macro, diversion, or request named nam is defined.

e

True if the current page is even-numbered.

F fnt

True if a font fnt is available; fnt can be an abstract style or a font name. GNU troff handles fnt as if it were an argument to the ft request (that is, it combines the default family with an abstract style and applies any applicable font translation), but fnt cannot be a mounting position, and it does not become mounted.

m col

True if a color col is defined.

n

True if the document is being processed in nroff mode.

o

True if the current page is odd-numbered.

r reg

True if a register reg is defined.

S sty

True if an abstract style sty is registered. Font translation applies.

t

True if the document is being processed in troff mode.

v

Always false. This condition exists for compatibility with certain other troff implementations.248

If the first argument to an if, ie, or while request begins with a non-alphanumeric character apart from ! (see below) and is not a numeric expression, the formatter performs an output comparison test. 249

'xxx'yyy'

This output comparison expression interpolates a true value if formatting the comparands xxx and yyy produces the same output commands. Other delimiters can be used in place of the neutral apostrophes; recall Delimiters. troff formats xxx and yyy in separate scratch buffers; after comparison, it discards the resulting data.

.ie "|"\fR|\fP" true
.el false
    ⇒ true

The resulting glyph properties, including font family, style, size, and slant, must match, but not necessarily the requests and/or escape sequences used to obtain them. In the previous example, ‘|’ and ‘\fR|\fP’ result in ‘|’ glyphs in the same typefaces at the same positions, so the comparands are equal. If ‘.ft I’ had been added before the ‘.ie’, they would differ: the first ‘|’ would produce an italic ‘|’, not a roman one. Motions must match in orientation and magnitude to within the applicable horizontal and vertical motion quanta of the device, after rounding. ‘.if "\u\d"\v'0'"’ is false even though both comparands result in zero net motion, because motions are not interpreted or optimized but sent as-is to the output.250 On the other hand, ‘.if "\d"\v'0.5m'"’ is true, because \d is defined as a downward motion of one-half em.251

Surround the comparands with \? to avoid formatting them; this causes them to be compared character by character, as with string comparisons in other programming languages.

.ie "\?|\?"\?\fR|\fP\?" true
.el false
    ⇒ false

Since GNU troff reads comparands protected with \? in copy mode,252 they need not even be syntactically valid. The escape character is still lexically recognized, however, and consumes the next character.

.ds a \[
.ds b \[
.if '\?\*a\?'\?\*b\?' a and b equivalent
.if '\?\\?'\?\\?' backslashes equivalent
.if '\?\P\?'\?P\?' backslash-P and P equivalent
    ⇒ a and b equivalent

The above operators can’t be combined with most others, but a leading ‘!’, not followed immediately by spaces or tabs, complements an expression.

.nr x 1
.ie !r x register x is not defined
.el      register x is defined
    ⇒ register x is defined

Spaces and tabs are optional immediately after the ‘c’, ‘d’, ‘F’, ‘m’, ‘r’, and ‘S’ operators, but right after ‘!’, they end the predicate and the conditional evaluates true.253

.nr x 1
.ie ! r x register x is not defined
.el       register x is defined
    ⇒ r x register x is not defined

The unexpected ‘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.

Conditional operators do not create roff language objects as interpolations with \n and \* escape sequences do.


Next: , Up: Conditionals and Loops   [Contents][Index]