A macro is a collection of text and embedded commands which can be invoked multiple times. Use macros to define common operations. See Strings, for a (limited) alternative syntax to call macros.
Although the following requests can be used to create macros, simply using an undefined macro will cause it to be defined as empty. See Identifiers.
Define a new macro named name.
gtroffcopies subsequent lines (starting with the next one) into an internal buffer until it encounters the line ‘..’ (two dots). If the optional second argument to
deis present it is used as the macro closure request instead of ‘..’.
There can be whitespace after the first dot in the line containing the ending token (either ‘.’ or macro ‘end’). Don't insert a tab character immediately after the ‘..’, otherwise it isn't recognized as the end-of-macro symbol.1
Here a small example macro called ‘P’ which causes a break and inserts some vertical space. It could be used to separate paragraphs..de P . br . sp .8v ..
The following example defines a macro within another. Remember that expansion must be protected twice; once for reading the macro and once for executing.\# a dummy macro to avoid a warning .de end .. . .de foo . de bar end . nop \f[B]Hallo \\\\$1!\f . end .. . .foo .bar Joe ⇒ Hallo Joe!
\fhas no expansion, it isn't necessary to protect its backslash. Had we defined another macro within
barwhich takes a parameter, eight backslashes would be necessary before ‘$1’.
de1request turns off compatibility mode while executing the macro. On entry, the current compatibility mode is saved and restored at exit..nr xxx 12345 . .de aa The value of xxx is \\n[xxx]. .. .de1 bb The value of xxx ix \\n[xxx]. .. . .cp 1 . .aa ⇒ warning: number register `[' not defined ⇒ The value of xxx is 0xxx]. .bb ⇒ The value of xxx ix 12345.
deirequest defines a macro indirectly. That is, it expands strings whose names are name or end before performing the append.
This:.ds xx aa .ds yy bb .dei xx yy
is equivalent to:.de aa bb
dei1request is similar to
deibut with compatibility mode switched off during execution of the defined macro.
If compatibility mode is on,
dei) behave similar to
dei1): A `compatibility save' token is inserted at the beginning, and a `compatibility restore' token at the end, with compatibility mode switched on during execution. See Gtroff Internals, for more information on switching compatibility mode on and off in a single document.
Note that macro identifiers are shared with identifiers for strings and diversions.
See the description of the
alsrequest, for possible pitfalls if redefining a macro which has been aliased.
Works similarly to
deexcept it appends onto the macro named name. So, to make the previously defined ‘P’ macro actually do indented instead of block paragraphs, add the necessary code to the existing macro like this:.am P .ti +5n ..
am1request turns off compatibility mode while executing the appended macro piece. To be more precise, a compatibility save input token is inserted at the beginning of the appended code, and a compatibility restore input token at the end.
amirequest appends indirectly, meaning that
gtroffexpands strings whose names are name or end before performing the append.
ami1request is similar to
amibut compatibility mode is switched off during execution of the defined macro.
See Strings, for the
rn request to create an
alias and rename a macro, respectively.
requests (together with its variants) only create a new object if the
name of the macro, diversion or string diversion is currently undefined
or if it is defined to be a request; normally they modify the value of
an existing object.
If called with an argument, exit twice, namely the current macro and the macro one level higher. This is used to define a wrapper macro for
 While it is possible to define and call a macro ‘.’ with
.de . . tm foo .. . .. \" This calls macro `.'!
you can't use this as the end-of-macro macro: during a macro definition, ‘..’ is never handled as a call to ‘.’, even if you say ‘.de foo .’ explicitly.