Previous: Parameters, Up: Writing Macros [Contents][Index]
When GNU troff
processes certain requests, most importantly those
which define or append to a macro or string, it does so in copy
mode: it copies the characters of the definition into a dedicated
storage region, interpolating the escape sequences \n
, \g
,
\$
, \*
, \V
, and \?
normally; interpreting
\RET
immediately; discarding comments \"
and
\#
; interpolating the current leader, escape, or tab character
with \a
, \e
, and \t
, respectively; and storing all
other escape sequences in an encoded form.
The complement of copy mode—a roff
formatter’s behavior when
not defining or appending to a macro, string, or diversion—where all
macros are interpolated, requests invoked, and valid escape sequences
processed immediately upon recognition, can be termed
interpretation mode.
The escape character, \
by default, can escape itself. This
enables you to control whether a given \n
, \g
, \$
,
\*
, \V
, or \?
escape sequence is interpreted at the
time the macro containing it is defined, or later when the macro is
called.101
.nr x 20 .de y .nr x 10 \&\nx \&\\nx .. .y ⇒ 20 10
You can think of \\
as a “delayed” backslash; it is the escape
character followed by a backslash from which the escape character has
removed its special meaning. Consequently, ‘\\’ is not an escape
sequence in the usual sense. In any escape sequence ‘\X’
that GNU troff
does not recognize, the escape character is
ignored and X is output. An unrecognized escape sequence causes
a warning in category ‘escape’, with two exceptions—‘\\’ is
the first.
\.
escapes the control character. It is similar to \\
in
that it isn’t a true escape sequence. It is used to permit nested macro
definitions to end without a named macro call to conclude them. Without
a syntax for escaping the control character, this would not be possible.
.de m1 foo . . de m2 bar \\.. . .. .m1 .m2 ⇒ foo bar
The first backslash is consumed while the macro is read, and the second
is interpreted when macro m1
is called.
roff
documents should not use the \\
or \.
character sequences outside of copy mode; they serve only to obfuscate
the input. Use \e
to represent the escape character,
\[rs]
to obtain a backslash glyph, and \&
before ‘.’
and ‘'’ where GNU troff
expects them as control characters
if you mean to use them literally (recall Requests and Macros).
Macro definitions can be nested to arbitrary depth. The mechanics of parsing the escape character have significant consequences for this practice.
.de M1 \\$1 . de M2 \\\\$1 . de M3 \\\\\\\\$1 \\\\.. . M3 hand. \\.. . M2 of .. This understeer is getting .M1 out ⇒ This understeer is getting out of hand.
Each escape character is interpreted twice—once in copy mode, when the
macro is defined, and once in interpretation mode, when the macro is
called. As seen above, this fact leads to exponential growth in the
quantity of escape characters required to delay interpolation of
\n
, \g
, \$
, \*
, \V
, and \?
at
each nesting level, which can be daunting. GNU troff
offers a
solution.
\E
represents an escape character that is not interpreted in copy
mode. You can use it to ease the writing of nested macro definitions.
.de M1 . nop \E$1 . de M2 . nop \E$1 . de M3 . nop \E$1 \\\\.. . M3 better. \\.. . M2 bit .. This vehicle handles .M1 a ⇒ This vehicle handles a bit better.
Observe that because \.
is not a true escape sequence, we can’t
use \E
to keep ‘..’ from ending a macro definition
prematurely. If the multiplicity of backslashes complicates
maintenance, use end macros.
\E
is also convenient to define strings containing escape
sequences that need to work when used in copy mode (for example, as
macro arguments), or which will be interpolated at varying macro nesting
depths. We might define strings to begin and end superscripting
as follows.102
.ds { \v'-.9m\s'\En[.s]*7u/10u'+.7m' .ds } \v'-.7m\s0+.9m'
When the ec
request is used to redefine the escape character,
\E
also makes it easier to distinguish the semantics of an escape
character from the other meaning(s) its character might have. Consider
the use of an unusual escape character, ‘-’.
.nr a 1 .ec - .de xx --na .. .xx ⇒ -na
This result may surprise you; some people expect ‘1’ to be output since register ‘a’ has clearly been defined with that value. What has happened? The robotic replacement of ‘\’ with ‘-’ has led us astray. You might recognize the sequence ‘--’ more readily with the default escape character as ‘\-’, the special character escape sequence for the minus sign glyph.
.nr a 1 .ec - .de xx -Ena .. .xx ⇒ 1
Previous: Parameters, Up: Writing Macros [Contents][Index]