Some syntactical and behavioral differences between GNU and
AT&T
troffs
are thought too important to neglect;
GNU
troff therefore makes available a
compatibility mode
in an effort to keep documents prepared for AT&T
troff rendering well.
Identifier names of arbitrary length may be
GNU
troff’s most obvious innovation.
AT&T
troff interprets
‘.dsabcd’
as defining a string
‘ab’
with contents
‘cd’.
Normally,
GNU
troff interprets this input as calling a macro named
dsabcd.
AT&T
troff also interprets
‘\*[’
and
‘\n[’
as interpolating a string or register,
respectively,
named
‘[’.
GNU
troff, however,
normally interprets
‘[’
as bracketing a long name
(with
‘]’
at the distal end).
In compatibility mode,
GNU
troff interprets names in the traditional way;
they thus can be two characters long at most.
.cp [b] ¶\n[.C] ¶Enable or disable AT&T troff compatibility mode per Boolean
expression b. It is disabled by default, and enabled if b
is omitted. In compatibility mode, long names are not recognized, and
the incompatibilities they cause do not arise.
The read-only register .C interpolates 1 if compatibility
mode is enabled, 0 otherwise.
Compatibility mode is also enabled by the -C command-line option.
.do name [argument …] ¶\n[.cp] ¶Interpret the string,
request,
diversion,
or macro
name
(along with any further arguments)
with compatibility mode disabled.
Compatibility mode is restored
(only if it was active)
when the interpolation
of
name
is interpreted;
that is,
the restored compatibility state applies to the request or
contents of the macro,
string,
or diversion
name,
its arguments,
and data read from files or pipes if
name
is the
so,
soquiet,
mso,
msoquiet,
or
pso
request.
The following example illustrates several aspects of do behavior.
.de mac1
FOO
..
.de1 mac2
groff
.mac1
..
.de mac3
compatibility
.mac1
..
.de ma
\\$1
..
.cp 1
.do mac1
.do mac2 \" mac2, defined with .de1, calls "mac1"
.do mac3 \" mac3 calls "ma" with argument "c1"
.do mac3 \[ti] \" groff syntax accepted in .do arguments
⇒ FOO groff FOO compatibility c1 ~
The read-only register .cp, meaningful only when dereferenced
from a do request, is 1 if compatibility mode was on when
the do request was encountered, and 0 if it was not. This
register is specialized and may require a statement of rationale.
When writing macro packages or documents that use GNU troff
features and which may be mixed with other packages or documents that do
not—common scenarios include serial processing of man pages or use of
the so or mso requests—you may desire correct operation
regardless of compatibility mode enablement in the surrounding context.
It may occur to you to save the existing value of ‘\n(.C’ into a
register, say, ‘_C’, at the beginning of your file, turn
compatibility mode off with ‘.cp 0’, then restore it from that
register at the end with ‘.cp \n(_C’. At the same time, a modular
design of a document or macro package may lead you to multiple layers of
inclusion. You cannot use the same register name everywhere lest you
“clobber” the value from a preceding or enclosing context.
The two-character register name space of AT&T
troff is confining,
but employing
GNU
troff’s more capacious one,
as with
‘.nr _my_saved_C \n(.C’,
does not work in compatibility mode;
the register name is too long.
Employing the
do
request is no help:
‘.do nr _my_saved_C \n(.C’
always saves zero to the register,
because
do
turns compatibility mode
off
while it interprets its argument list.
To robustly save compatibility mode before switching it off, use
.do nr _my_saved_C \n[.cp] .cp 0
at the beginning of your file, followed by
.cp \n[_my_saved_C] .do rr _my_saved_C
at the end.
As the C language exposes application programs’ symbols
to those defined by libraries,
roff documents share a name space with macro packages;
choose a register name that is unlikely to collide with other uses.
In compatibility mode,
GNU
troff accepts several characters as delimiters that it ordinarily rejects
because they can begin numeric expressions and therefore
may be ambiguous to the document maintainer.
This set of additional delimiters comprises
‘0123456789+-(.|’.
Normally,
GNU
troff tracks the nesting depth of interpolations.
In compatibility mode,
it does not.
.ds xx '
\w'abc\*(xxdef'
⇒ 168 (normal mode on a terminal device)
⇒ 72def' (compatibility mode on a terminal device)
The escape sequences
\f,
\H,
\m,
\M,
\R,
\s,
and
\S
are transparent at the beginning of a line,
or after the conditional expression of an
if
or
ie
request,
only in compatibility mode.
That is,
upon interpreting them,
GNU
troff no longer recognizes a control character on the input line;
AT&T
troff does.
Thus the next example produces bold output in both modes,
but the text differs.
.de xx
Hello!
..
\fB.xx\fP
⇒ .xx (normal mode)
⇒ Hello! (compatibility mode)
Normally, the syntax form \sn accepts only a single
character (a digit) for n, consistently with other forms that
originated in AT&T troff, like \*, \$,
\f, \g, \k, \n, and \z. In
compatibility mode only, a non-zero n must be in the range
4–39. Legacy documents relying upon this quirk of parsing150 should migrate to another
\s form.
In compatibility mode,
the
de,
am,
ds,
and
as
requests behave as
de1,
am1,
ds1,
and
as1,
respectively:
GNU
troff inserts a
compatibility save
token at the beginning of the macro,
string,
or appendment thereto as applicable
and a
compatibility restore
token at its end,
enabling compatibility mode during its interpolation.151
Thus they work as expected
even if the interpolation context disables compatibility mode.