Previous: Parameters, Up: Writing Macros [Contents][Index]
GNU
troff
processes certain requests in
copy mode:
it copies ordinary,
special,
and indexed characters as-is;
interpolates the escape sequences
\n,
\g,
\$,
\*,
\V,
and
\?
normally;
discards comments
\"
and
\#;
interpolates
\a,
\e,
and
\t,
as the current
leader,
escape,
or
tab
character,
respectively;
represents
\RET,
\&,
\_,
\|,
\^,
\{,
\},
\`,
\',
\-,
\!,
\c,
\%,
\SPC,
\E,
\),
\~,
and
\:
in an encoded form,
and copies other escape sequences as-is.
The term “copy mode” reflects its most visible application
in requests that populate macros and strings,
but other requests also use it when interpreting arguments
that can’t meaningfully represent typesetting operations.
For example,
a font selection escape sequence has no meaning
in a hyphenation pattern file name
(hpf)
or a diagnostic message written to the terminal
(tm).
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)
when used before itself
quotes
an escape character for later interpreation
in an enclosing context.
Escape character quotation enables you to control
whether the formatter interprets a given
\n,
\g,
\$,
\*,
\V,
or
\?
escape sequence at the time the macro containing it is defined,
or later when the macro is called.157
.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 best considered an escape sequence,
but a quoted escape character.
In any escape sequence
‘\X’
that
GNU
troff does not recognize,
the formatter discards the escape character and outputs
X.
An unrecognized escape sequence causes a warning in category
‘escape’,
with two exceptions—‘\\’
is the first.
\.
quotes 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 quoting 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.
Outside of copy mode,
roff
documents should not use the
\\
or
\.
character sequences;
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.
As seen above,
the formatter interpets each escape character in multiple contexts;
once,
when populating the macro or string,
where the first
‘\’
serves its quotation function\[em]thus
only one
‘\’
is stored in the definition.
(Verify this fact with the
pm
request.)
The formatter interprets the second
‘\’
as an escape character
(assuming the escape character hasn’t been changed in the meantime)
each time it interpolates the macro or string definition.
This fact leads to exponential growth
in the quantity of escape characters
required to quote and thereby 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.158
.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]