Calling Macros (The GNU Troff Manual)

#### 5.6.3 Calling Macros

If a macro of the desired name does not exist when called, it is created, assigned an empty definition, and a warning in category ‘`mac`’ is emitted. Calling an undefined macro does end a macro definition naming it as its end macro (see Writing Macros).

To embed spaces within a macro argument, enclose the argument in neutral double quotes `"`. Horizontal motion escape sequences are sometimes a better choice for arguments to be formatted as text.

Consider calls to a hypothetical section heading macro ‘`uh`’.

    .uh The Mouse Problem
    .uh "The Mouse Problem"
    .uh The\~Mouse\~Problem
    .uh The\ Mouse\ Problem

The first line calls `uh` with three arguments: ‘`The`’, ‘`Mouse`’, and ‘`Problem`’. The remainder call the `uh` macro with one argument, ‘`The Mouse Problem`’. The last solution, using escaped spaces, can be found in documents prepared for AT&T `troff`. It can cause surprise when text is adjusted, because `\`SP`` inserts a fixed-width, non-breaking space. GNU `troff`’s `\~` escape sequence inserts an adjustable, non-breaking space.44

The foregoing raises the question of how to embed neutral double quotes or backslashes in macro arguments when those characters are desired as literals. In GNU `troff`, the special character escape sequence `\[rs]` produces a backslash and `\[dq]` a neutral double quote.

In GNU `troff`’s AT&T compatibility mode, these characters remain available as `\(rs` and `\(dq`, respectively. AT&T `troff` did not consistently define these special characters, but its descendants can be made to support them. See Device and Font Description Files.

If even that is not feasible, options remain. To obtain a literal escape character in a macro argument, you can simply type it if you change or disable the escape character first. See Using Escape Sequences. Otherwise, you must escape the escape character repeatedly to a context-dependent extent. See Copy Mode.

For the (neutral) double quote, you have recourse to an obscure syntactical feature of AT&T `troff`. Because a double quote can begin a macro argument, the formatter keeps track of whether the current argument was started thus, and doesn’t require a space after the double quote that ends it.45 In the argument list to a macro, a double quote that isn’t preceded by a space doesn’t start a macro argument. If not preceded by a double quote that began an argument, this double quote becomes part of the argument. Furthermore, within a quoted argument, a pair of adjacent double quotes becomes a literal double quote.

    .de eq
    .  tm arg1:\\$1 arg2:\\$2 arg3:\\$3
    .  tm arg4:\\$4 arg5:\\$5 arg6:\\$6
    .. \" 4 backslashes on the next line
    .eq a" "b c" "de"f\\\\g" h""i "j""k"
        error→ arg1:a" arg2:b c arg3:de
        error→ arg4:f\g" arg5:h""i arg6:j"k

Apart from the complexity of the rules, this traditional solution has the disadvantage that double quotes don’t survive repeated argument expansion in AT&T `troff` or GNU `troff`’s compatibility mode. This can frustrate efforts to pass such arguments intact through multiple macro calls.

    .cp 1
    .de eq
    .  tm arg1:\\$1 arg2:\\$2 arg3:\\$3
    .  tm arg4:\\$4 arg5:\\$5 arg6:\\$6
    ..
    .de xe
    .  eq \\$1 \\$2 \\$3 \\$4 \\$5 \\$6
    .. \" 8 backslashes on the next line
    .xe a" "b c" "de"f\\\\\\\\g" h""i "j""k"
        error→ arg1:a" arg2:b arg3:c
        error→ arg4:de arg5:f\g" arg6:h""i

Outside of compatibility mode, GNU `troff` doesn’t exhibit this problem because it tracks the nesting depth of interpolations. See Implementation Differences.