Next: , Previous: , Up: Implementation Differences   [Contents][Index]


5.39.2 Compatibility Mode

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.

Identifiers 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.

Request: .cp [b]
Register: \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.

Request: .do name [argument ]
Register: \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.

Normally, GNU troff tracks the nesting depth of interpolations. In compatibility mode, it does not.

.ds xx '
\w'abc\*(xxdef'
    ⇒ 168 (not in compatibility 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 to control charcter recognition 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 normally no longer recognizes a control character on the input line; but in compatibility mode, it does, just like AT&T troff. Thus the next example produces bold output in both modes, but the text differs.

.de xx
Hello!
..
\fB.xx\fP
    ⇒ .xx (not in compatibility mode)
    ⇒ Hello! (in 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 parsing187 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.188 Thus they work as expected even if the interpolation context disables compatibility mode.

AT&T troff recognized slightly varying sets of delimiters when expecting numerical expressions (as with the \h escape sequence), string expressions (as with the \w escape sequence and tl request), and output comparisons (as in ‘.if #foo#bar# .tm match’). GNU troff, when not in compatibility mode, recognizes a single consistent set of delimiters. Compatibility mode emulates AT&T troff only up to a point. GNU troff accepts leaders and tabs as delimiters, as well as Control+D (EOT or EOF), Control+H (BS or backspace), and Control+L (FF or form feed), all of which, when used as delimiters, cause AT&T troff to behave in ways difficult to predict.


Next: , Previous: , Up: Implementation Differences   [Contents][Index]