5.38.3 Other Differences

groff request names unrecognized by other troff implementations will likely be ignored by them; escape sequences that are groff extensions are liable to be interpreted as if the escape character were not present. For example, the adjustable, non-breaking escape sequence \~ is also supported by Heirloom Doctools troff 050915 (September 2005), mandoc 1.9.5 (2009-09-21), neatroff (commit 1c6ab0f6e, 2016-09-13), and Plan 9 from User Space troff (commit 93f8143600, 2022-08-12), but not by Solaris or Documenter’s Workbench troffs. See Manipulating Filling and Adjustment.

GNU troff does not allow the use of the escape sequences \|, \^, \&, \{, \}, \SP, \', \`, \-, \_, \!, \%, and \c in identifiers; AT&T troff does. The \A escape sequence (see Identifiers) may be helpful in avoiding use of these escape sequences in names.

When adjusting to both margins, AT&T troff at first adjusts spaces starting from the right; GNU troff begins from the left. Both implementations adjust spaces from opposite ends on alternating output lines in this adjustment mode to prevent “rivers” in the text.

GNU troff does not always hyphenate words as AT&T troff does. The AT&T implementation uses a set of hard-coded rules specific to English, while GNU troff uses language-specific hyphenation pattern files derived from TeX. Furthermore, in old versions of troff there was a limited amount of space to store hyphenation exceptions (arguments to the hw request); GNU troff has no such restriction.

GNU troff predefines a string .T containing the argument given to the -T command-line option, namely the current output device (for example, ‘pdf’ or ‘utf8’). The existence of this string is a common feature of post-CSTR #54 troffs121 but valid values are specific to each implementation.

AT&T troff ignored attempts to remove read-only registers; GNU troff honors such requests. See Built-in Registers.

The (read-only) register .T interpolates 1 if GNU troff is called with the -T command-line option, and 0 otherwise. This behavior differs from AT&T troff, which interpolated 1 only if nroff was the formatter and was called with -T.

AT&T troff and other implementations handle the lf request differently. For them, its line argument changes the line number of the current line.

AT&T troff had only environments named ‘0’, ‘1’, and ‘2’. In GNU troff, any number of environments may exist, using any valid identifiers for their names (see Identifiers.)

Fractional type sizes cause one noteworthy incompatibility. In AT&T troff the ps request ignores scaling units and thus ‘.ps 10u’ sets the type size to 10 points, whereas in GNU troff it sets the type size to 10 scaled points. See Using Fractional Type Sizes.

The ab request differs from AT&T troff: GNU troff writes no message to the standard error stream if no arguments are given, and it exits with a failure status instead of a successful one.

The bp request differs from AT&T troff: GNU troff does not accept a scaling unit on the argument, a page number; the former (somewhat uselessly) does.

The pm request differs from AT&T troff: GNU troff reports the sizes of macros, strings, and diversions in bytes and ignores an argument to report only the sum of the sizes.

Unlike AT&T troff, GNU troff does not ignore the ss request if the output is a terminal device; instead, the values of minimal inter-word and additional inter-sentence space are each rounded down to the nearest multiple of 12.

In GNU troff there is a fundamental difference between (unformatted) characters and (formatted) glyphs. Everything that affects how a glyph is output is stored with the glyph node; once a glyph node has been constructed, it is unaffected by any subsequent requests that are executed, including bd, cs, tkf, tr, or fp requests. Normally, glyphs are constructed from characters immediately before the glyph is added to an output line. Macros, diversions, and strings are all, in fact, the same type of object; they contain a sequence of intermixed character and glyph nodes. Special characters transform from one to the other: before being added to the output, they behave as characters; afterward, they are glyphs. A glyph node does not behave like a character node when it is processed by a macro: it does not inherit any of the special properties that the character from which it was constructed might have had. For example, the input

.di x
\\\\
.br
.di
.x

produces ‘\\’ in GNU troff. Each pair of backslashes becomes one backslash glyph; the resulting backslashes are thus not interpreted as escape characters when they are reread as the diversion is output. AT&T troff would interpret them as escape characters when rereading them and end up printing one ‘\’.

One correct way to obtain a printable backslash in most documents is to use the \e escape sequence; this always prints a single instance of the current escape character,122 regardless of whether or not it is used in a diversion; it also works in both GNU troff and AT&T troff.

The other correct way, appropriate in contexts independent of the backslash’s common use as a troff escape character—perhaps in discussion of character sets or other programming languages—is the character escape \(rs or \[rs], for “reverse solidus”, from its name in the ECMA-6 (ISO/IEC 646) standard.123

To store an escape sequence in a diversion that is interpreted when the diversion is reread, either use the traditional \! transparent output facility, or, if this is unsuitable, the new \? escape sequence. See Diversions and gtroff Internals.

In the somewhat pathological case where a diversion exists containing a partially collected line and a partially collected line at the top-level diversion has never existed, AT&T troff will output the partially collected line at the end of input; GNU troff will not.