5.30 Punning Names

Macros, strings, and diversions share a name space; recall Identifiers. Internally, the same mechanism is used to store them. You can thus call a macro with string interpolation syntax and vice versa.

.de subject
Typesetting
..
.de predicate
rewards attention to detail
..
\*[subject] \*[predicate].
Truly.
    ⇒ Typesetting
    ⇒  rewards attention to detail Truly.

What went wrong? Strings don’t contain newlines, but macros do. String interpolation placed a newline at the end of ‘\*[subject]’, and the next thing on the input was a space. Then when ‘\*[predicate]’ was interpolated, it was followed by the empty request ‘.’ on a line by itself. If we want to use macros as strings, we must take interpolation behavior into account.

.de subject
Typesetting\\
..
.de predicate
rewards attention to detail\\
..
\*[subject] \*[predicate].
Truly.
    ⇒ Typesetting rewards attention to detail.  Truly.

By ending each text line of the macros with an escaped \RET, we get the desired effect (see Line Continuation).114 What would have happened if we had used only one backslash at a time instead?

Interpolating a string does not hide existing macro arguments. We can also place the escaped newline outside the string interpolation instead of within the string definition. Thus, in a macro, a more efficient way of doing

.xx \\$@

is

\\*[xx]\\

The latter calling syntax doesn’t change the value of \$0, which is then inherited from the calling macro (see Parameters).

Diversions can be also called with string syntax. It is sometimes convenient to copy one-line diversions to a string.

.di xx
the
.ft I
interpolation system
.ft
.br
.di
.ds yy This is a test of \*(xx\c
\*(yy.
    ⇒ This is a test of the interpolation system.

As the previous example shows, it is possible to store formatted output in strings. The \c escape sequence prevents the subsequent newline from being interpreted as a break (again, see Line Continuation).

Copying multi-output line diversions produces unexpected results.

.di xxx
a funny
.br
test
.br
.di
.ds yyy This is \*[xxx]\c
\*[yyy].
    ⇒ test This is a funny.

Usually, it is not predictable whether a diversion contains one or more output lines, so this mechanism should be avoided. With AT&T troff, this was the only solution to strip off a final newline from a diversion. Another disadvantage is that the spaces in the copied string are already formatted, preventing their adjustment. This can cause ugly results.

A clean solution to this problem is available in GNU troff, using the requests chop to remove the final newline of a diversion, and unformat to make the horizontal spaces adjustable again.

.box xxx
a funny
.br
test
.br
.box
.chop xxx
.unformat xxx
This is \*[xxx].
    ⇒ This is a funny test.

See gtroff Internals.