File: groff.info, Node: Calling Macros, Next: Using Escape Sequences, Prev: Invoking Requests, Up: Formatter Instructions
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 (*note 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 '\' inserts a _fixed-width_, non-breaking
space. GNU 'troff''s '\~' escape sequence inserts an adjustable,
non-breaking space.(1) (*note Calling Macros-Footnote-1::)
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. *Note 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. *Note Using Escape
Sequences::. Otherwise, you must escape the escape character repeatedly
to a context-dependent extent. *Note 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.(2) (*note Calling Macros-Footnote-2::) 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. *Note
Implementation Differences::.