Operators in Conditionals (The GNU Troff Manual)

#### 5.23.1 Operators in Conditionals

In `if`, `ie`, and `while` requests, in addition to the numeric expressions described in Numeric Expressions, several Boolean operators are available; the members of this expanded class are termed conditional expressions.

`c glyph`

  True if glyph is available, where glyph is an ordinary character, a special character ‘`\(xx`’ or ‘`\[xxx]`’, ‘`\N'xxx'`’, or has been defined by any of the `char`, `fchar`, `fschar`, or `schar` requests.

`d name`

  True if a string, macro, diversion, or request called name exists.

`e`

  True if the current page is even-numbered.

`F font`

  True if font exists. font is handled as if it were opened with the `ft` request (that is, font translation and styles are applied), without actually mounting it.

`m color`

  True if color is defined.

`n` ¶

  True if the document is being processed in `nroff` mode. See `troff` and `nroff` Modes.

`o`

  True if the current page is odd-numbered.

`r register`

  True if register exists.

`S style`

  True if style is available for the current font family. Font translation is applied.

`t`

  True if the document is being processed in `troff` mode. See `troff` and `nroff` Modes.

`v`

  Always false. This condition is recognized only for compatibility with certain other `troff` implementations.88

If the first argument to an `if`, `ie`, or `while` request begins with a non-alphanumeric character apart from `!` (see below); it performs an output comparison test. 89

``'`xxx`'`yyy`'``

  True if formatting the comparands xxx and yyy produces the same output commands. The delimiter need not be a neutral apostrophe: the output comparison operator accepts the same delimiters as most escape sequences; see Delimiters. This output comparison operator formats xxx and yyy in separate environments; after the comparison, the resulting data are discarded.

      .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.90 On the other hand, ‘`.if "\d"\v'0.5m'"`’ is true, because `\d` is defined as a downward motion of one-half em.91

  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 comparands protected with `\?` are read in copy mode (see Copy Mode), they need not even be valid `groff` syntax. 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
          ⇒ 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.92

    .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.