Next: Page Motions, Previous: Conditionals and Loops, Up: GNU troff Reference [Contents][Index]
A macro is a stored collection of text and control lines that can be interpolated multiple times. Use macros to define common operations. Macros are called in the same way that requests are invoked. While requests exist for the purpose of creating macros, simply calling an undefined macro, or interpolating it as a string, will cause it to be defined as empty. See Identifiers.
Define a macro name, replacing the definition of any existing
request, macro, string, or diversion called name. If
name already exists as an alias, the target of the alias is
redefined; recall Strings. GNU troff
enters copy
mode,97 storing subsequent input lines as the
macro definition. If the optional second argument is not specified, the
definition ends with the control line ‘..’ (two dots).
Alternatively, end identifies a macro whose call syntax at the
start of a control line ends the definition of name; end is
then called normally. A macro definition must end in the same
conditional block (if any) in which it began (see Conditional Blocks). Spaces or tabs are permitted after the control character in
the line containing this ending token (either ‘.’ or
‘end’), but a tab immediately after the token prevents its
recognition as the end of a macro definition. The macro end can
be called with arguments.98
Here is a small example macro called ‘P’ that causes a break and inserts some vertical space. It could be used to separate paragraphs.
.de P . br . sp .8v ..
We can define one macro within another. Attempting to nest ‘..’ naïvely will end the outer definition because the inner definition isn’t interpreted as such until the outer macro is later interpolated. We can use an end macro instead. Each level of nesting should use a unique end macro.
An end macro need not be defined until it is called. This fact enables a nested macro definition to begin inside one macro and end inside another. Consider the following example.99
.de m1 . de m2 m3 you .. .de m3 Hello, Joe. .. .de m4 do .. .m1 know? . m3 What .m4 .m2 ⇒ Hello, Joe. What do you know?
A nested macro definition can be terminated with ‘..’ and nested macros can reuse end macros, but these control lines must be escaped multiple times for each level of nesting. The necessity of this escaping and the utility of nested macro definitions will become clearer when we employ macro parameters and consider the behavior of copy mode in detail.
de
defines a macro that inherits the compatibility mode
enablement status of its context (see Implementation Differences).
Often it is desirable to make a macro that uses groff
features
callable from contexts where compatibility mode is on; for instance,
when writing extensions to a historical macro package. To achieve this,
compatibility mode needs to be switched off while such a macro is
interpreted—without disturbing that state when it is finished.
The de1
request defines a macro to be interpreted with
compatibility mode disabled. When name is called, compatibility
mode enablement status is saved; it is restored when the call completes.
Observe the extra backlash before the interpolation of register
‘xxx’; we’ll explore this subject in Copy Mode.
.nr xxx 12345 .de aa The value of xxx is \\n[xxx]. . br .. .de1 bb The value of xxx is \\n[xxx]. .. .cp 1 .aa error→ warning: register '[' not defined ⇒ The value of xxx is 0xxx]. .bb ⇒ The value of xxx is 12345.
The dei
request defines a macro with its name and end
macro indirected through strings. That is, it interpolates strings
named name and end before performing the definition.
The following examples are equivalent.
.ds xx aa .ds yy bb .dei xx yy
.de aa bb
The dei1
request bears the same relationship to dei
as
de1
does to de
; it temporarily turns compatibility mode
off when name is called.
am
appends subsequent input lines to macro name, extending
its definition, and otherwise working as de
does.
To make the previously defined ‘P’ macro set indented instead of block paragraphs, add the necessary code to the existing macro.
.am P .ti +5n ..
The other requests are analogous to their ‘de’ counterparts. The
am1
request turns off compatibility mode during interpretation of
the appendment. The ami
request appends indirectly, meaning that
strings name and end are interpolated with the resulting
names used before appending. The ami1
request is similar to
ami
, disabling compatibility mode during interpretation of the
appended lines.
Using trace.tmac, you can trace calls to de
,
de1
, am
, and am1
. You can also use the
backtrace
request at any point desired to troubleshoot tricky
spots (see Debugging).
See Strings, for the als
, rm
, and rn
requests to
create an alias of, remove, and rename a macro, respectively.
Macro identifiers share their name space with requests, strings, and
diversions; see Identifiers. The am
, as
, da
,
de
, di
, and ds
requests (together with their
variants) create a new object only if the name of the macro, diversion,
or string is currently undefined or if it is defined as a request;
normally, they modify the value of an existing object. See the
description of the als
request, for pitfalls when redefining a
macro that is aliased.
Exit a macro, immediately returning to the caller. If called with an
argument anything, exit twice—the current macro and the macro
one level higher. This is used to define a wrapper macro for
return
in trace.tmac.
• Parameters | ||
• Copy Mode |
Next: Page Motions, Previous: Conditionals and Loops, Up: GNU troff Reference [Contents][Index]