GROFF_DIFF(7) | Miscellaneous Information Manual | GROFF_DIFF(7) |
groff_diff - differences between GNU troff and classical troff
This manual page describes the language differences between groff, the GNU roff text processing system, and the classical roff formatter of the freely available Unix 7 of the 1970s, documented in the Troff User's Manual by Ossanna and Kernighan. This includes the roff language as well as the intermediate output format (troff output).
Section “See Also” below gives pointers to both the classical roff and the modern groff documentation.
In this section, all additional features of groff compared to the classical Unix 7 troff are described in detail.
The names of number registers, fonts, strings/macros/diversions, special characters (glyphs), and colors can be of any length. In escape sequences, additionally to the classical ‘(xx’ construction for a two-character glyph name, you can use ‘[xxx]’ for a name of arbitrary length.
A scaled point is equal to 1/sizescale points, where sizescale is specified in the DESC file (1 by default). There is a new scale indicator z that has the effect of multiplying by sizescale. Requests and escape sequences in troff interpret arguments that represent a point size as being in units of scaled points, but they evaluate each such argument using a default scale indicator of z. Arguments treated in this way are the argument to the ps request, the third argument to the cs request, the second and fourth arguments to the tkf request, the argument to the \H escape sequence, and those variants of the \s escape sequence that take a numeric expression as their argument.
For example, suppose sizescale is 1000; then a scaled point is equivalent to a millipoint; the call .ps 10.25 is equivalent to .ps 10.25z and so sets the point size to 10250 scaled points, which is equal to 10.25 points.
The number register \n[.s] returns the point size in points as decimal fraction. There is also a new number register \n[.ps] that returns the point size in scaled points.
It would make no sense to use the z scale indicator in a numeric expression whose default scale indicator was neither u nor z, and so troff disallows this. Similarly it would make no sense to use a scaling indicator other than z or u in a numeric expression whose default scale indicator was z, and so troff disallows this as well.
There is also new scale indicator s which multiplies by the number of units in a scaled point. So, for example, \n[.ps]s is equal to 1m. Be sure not to confuse the s and z scale indicators.
Spaces are permitted in a number expression within parentheses.
M indicates a scale of 100ths of an em. f indicates a scale of 65536 units, providing fractions for color definitions with the defcolor request. For example, 0.5f = 32768u.
.ds { \v'-.3m'\s'\En[.s]*6u/10u' .ds } \s0\v'.3m'
.char \[phone] \f(ZD\N'37'
.nr x 1 .nf .di d \?\\?\\\\?\\\\\\\ \nx\\\\?\\?\? .di .nr x 2 .di e .d .di .nr x 3 .di f .e .di .nr x 4 .f
.tr @. .di x @nr n 1 .br .di .tr @@ .asciify x .x
.defcolor darkgreen rgb 0.1f 0.5f 0.2f
.defcolor darkgreen rgb 0.1 0.5 0.2
.ds xx aa .ds yy bb .dei xx yy
.de aa bb
.do fam T
would have the same effect as
.fam T
except that it would work even if compatibility mode had been enabled. Note that the previous compatibility mode is restored before any files sourced by xxx are interpreted.
.ds x a\t\c .ds y b\t\c .ds z c .ta 1i 3i \*x \*y \*z
a b c
a b c
.di x .trf f .di
.trin ax .di xxx a .br .di .xxx .trin aa .asciify xxx .xxx
.tr ab .di x \!.tm a .di .x
.ta T .5i
sets tabs every half an inch.
The following read-only registers are available:
.als bp*orig bp .de bp .tm before bp .ie \\n[.br] .bp*orig .el 'bp*orig .tm after bp ..
The following read/write registers are set by the \w escape sequence:
Other available read/write number registers are:
troff predefines a single (read/write) string-based register, \*[.T], which contains the argument given to the -T command-line option, namely the current output device (for example, latin1 or ascii). Note that this is not the same as the (read-only) number register \n[.T] which is defined to be 1 if troff is called with the -T command-line option, and zero otherwise. This behaviour is different from Unix troff.
Fonts not listed in the DESC file are automatically mounted on the next available font position when they are referenced. If a font is to be mounted explicitly with the fp request on an unused font position, it should be mounted on the first unused font position, which can be found in the \n[.fp] register; although troff does not enforce this strictly, it does not allow a font to be mounted at a position whose number is much greater than that of any currently used position.
Interpolating a string does not hide existing macro arguments. Thus in a macro, a more efficient way of doing
is
If the font description file contains pairwise kerning information, glyphs from that font are kerned. Kerning between two glyphs can be inhibited by placing a \& between them.
In a string comparison in a condition, characters that appear at different input levels to the first delimiter character are not recognized as the second or third delimiters. This applies also to the tl request. In a \w escape sequence, a character that appears at a different input level to the starting delimiter character is not recognized as the closing delimiter character. The same is true for \A, \b, \B, \C, \l, \L, \o, \X, and \Z. When decoding a macro or string argument that is delimited by double quotes, a character that appears at a different input level to the starting delimiter character is not recognized as the closing delimiter character. The implementation of \$@ ensures that the double quotes surrounding an argument appear at the same input level, which is different to the input level of the argument itself. In a long escape name ] is not recognized as a closing delimiter except when it occurs at the same input level as the opening [. In compatibility mode, no attention is paid to the input-level.
There are some new types of condition:
The tr request can now map characters onto \~.
The space width emitted by the \| and \^ escape sequences can be controlled on a per-font basis. If there is a glyph named \| or \^, respectively (note the leading backslash), defined in the current font file, use this glyph's width instead of the default value.
It is now possible to have whitespace between the first and second dot (or the name of the ending macro) to end a macro definition. Example:
.if t \{\ . de bar . nop Hello, I'm ‘bar’. . . .\}
This section describes the format output by GNU troff. The output format used by GNU troff is very similar to that used by Unix device-independent troff. Only the differences are documented here.
The argument to the s command is in scaled points (units of points/n, where n is the argument to the sizescale command in the DESC file). The argument to the x Height command is also in scaled points.
If the tcommand line is present in the DESC file, troff uses the following two commands.
Note that single characters can have the eighth bit set, as can the names of fonts and special characters.
The names of glyphs and fonts can be of arbitrary length; drivers should not assume that they are only two characters long.
When a glyph is to be printed, that glyph is always in the current font. Unlike device-independent troff, it is not necessary for drivers to search special fonts to find a glyph.
For color support, some new commands have been added:
The x device control command has been extended.
The D drawing command has been extended. These extensions are not used by GNU pic if the -n option is given.
A difficulty arises in how the current position should be changed after the execution of these commands. This is not of great importance since the code generated by GNU pic does not depend on this. Given a drawing command of the form
where c is not one of c, e, l, a, or ~, Unix troff treats each of the as a horizontal quantity, and each of the as a vertical quantity and assumes that the width of the drawn object is , and that the height is . (The assumption about the height can be seen by examining the st and sb registers after using such a D command in a \w escape sequence). This rule also holds for all the original drawing commands with the exception of De. For the sake of compatibility GNU troff also follows this rule, even though it produces an ugly result in the case of the Dt and Df, and, to a lesser extent, DE commands. Thus after executing a D command of the form
the current position should be increased by .
Another set of extensions is
The current position isn't changed by those colour commands (contrary to Df).
There is a continuation convention which permits the argument to the x X command to contain newlines: when outputting the argument to the x X command, GNU troff follows each newline in the argument with a + character (as usual, it terminates the entire argument with a newline); thus if the line after the line containing the x X command starts with +, then the newline ending the line containing the x X command should be treated as part of the argument to the x X command, the + should be ignored, and the part of the line following the + should be treated like the part of the line following the x X command.
The first three output commands are guaranteed to be:
In spite of the many extensions, groff has retained compatibility to classical troff to a large degree. For the cases where the extensions lead to collisions, a special compatibility mode with the restricted, old functionality was created for groff.
groff provides a compatibility mode that allows the processing of roff code written for classical troff or for other implementations of roff in a consistent way.
Compatibility mode can be turned on with the -C command-line option, and turned on or off with the .cp request. The number register \n(.C is 1 if compatibility mode is on, 0 otherwise.
This became necessary because the GNU concept for long names causes some incompatibilities. Classical troff interprets
as defining a string ab with contents cd. In groff mode, this is considered as a call of a macro named dsabcd.
Also classical troff interprets \*[ or \n[ as references to a string or number register called [ while groff takes this as the start of a long name.
In compatibility mode, groff interprets these things in the traditional way; so long names are not recognized.
On the other hand, groff in GNU native mode does not allow to use the single-character escapes \\ (backslash), \| (vertical bar), \^ (caret), \& (ampersand), \{ (opening brace), \} (closing brace), ‘\ ’ (space), \' (single quote), \` (backquote), \- (minus), \_ (underline), \! (bang), \% (percent), and \c (character c) in names of strings, macros, diversions, number registers, fonts or environments, whereas classical troff does.
The \A escape sequence can be helpful in avoiding these escape sequences in names.
Fractional point sizes cause one noteworthy incompatibility. In classical troff, the ps request ignores scale indicators and so
.ps 10u
sets the point size to 10 points, whereas in groff native mode the point size is set to 10 scaled points.
In groff, there is a fundamental difference between unformatted input characters, and formatted output characters (glyphs). Everything that affects how a glyph is output is stored with the glyph; once a glyph has been constructed it is unaffected by any subsequent requests that are executed, including the bd, cs, tkf, tr, or fp requests.
Normally glyphs are constructed from input characters at the moment immediately before the glyph is added to the current output line. Macros, diversions and strings are all, in fact, the same type of object; they contain lists of input characters and glyphs in any combination.
Special characters can be both; before being added to the output, they act as input entities, afterwards they denote glyphs.
A glyph does not behave like an input character for the purposes of macro processing; it does not inherit any of the special properties that the input character from which it was constructed might have had. The following example makes things clearer.
.di x \\\\ .br .di .x
With GNU troff this is printed as \\. So each pair of input backslashes ‘\\’ is turned into a single output backslash glyph ‘\’ and the resulting output backslashes are not interpreted as escape characters when they are reread.
Classical troff would interpret them as escape characters when they were reread and would end up printing a single backslash ‘\’.
In GNU, the correct way to get a printable version of the backslash character ’\’ is the \(rs escape sequence, but classical troff does not provide a clean feature for getting a non-syntactical backslash. A close method is the printable version of the current escape character using the \e escape sequence; this works if the current escape character is not redefined. It works in both GNU mode and compatibility mode, while dirty tricks like specifying a sequence of multiple backslashes do not work reliably; for the different handling in diversions, macro definitions, or text mode quickly leads to a confusion about the necessary number of backslashes.
To store an escape sequence in a diversion that is interpreted when the diversion is reread, either the traditional \! transparent output facility or the new \? escape sequence can be used.
The groff intermediate output format is in a state of evolution. So far it has some incompatibilities, but it is intended to establish a full compatibility to the classical troff output format. Actually the following incompatibilities exist:
This document was written by James Clark and modified by Werner Lemberg and Bernd Warken.
Groff: The GNU Implementation of troff, by Trent A. Fisher and Werner Lemberg, is the primary groff manual. You can browse it interactively with “info groff”.
man 7 groff
19 March 2021 | groff 1.22.4 |