A TROFF Tutorial USD:25-1
A TROFF Tutorial
Brian W. Kernighan
(updated for 4.3BSD by Mark Seiden)
AT&T Bell Laboratories
Murray Hill, New Jersey 07974
ABSTRACT
troff is a text-formatting program for typesetting
on the UNIX- operating system. This device is capable
of producing high quality text; this paper is an exam-
ple of troff output.
The phototypesetter itself normally runs with four
fonts, containing roman, italic and bold letters (as on
this page), a full greek alphabet, and a substantial
number of special characters and mathematical symbols.
Characters can be printed in a range of sizes, and
placed anywhere on the page.
troff allows the user full control over fonts,
sizes, and character positions, as well as the usual
features of a formatter - right-margin justification,
automatic hyphenation, page titling and numbering, and
so on. It also provides macros, arithmetic variables
and operations, and conditional testing, for compli-
cated formatting tasks.
This document is an introduction to the most basic
use of troff. It presents just enough information to
enable the user to do simple formatting tasks like mak-
ing viewgraphs, and to make incremental changes to
existing packages of troff commands. In most respects,
the UNIX formatter nroff and a more recent version
(device-independent troff) are identical to the version
described here, so this document also serves as a
tutorial for them as well.
-------------------------
- UNIX is a registered trademark of AT&T Bell Labora-
tories in the USA and other countries.
April 27, 2013
USD:25-2 A TROFF Tutorial
1. Introduction
troff [1] is a text-formatting program, written originally
by J. F. Ossanna, for producing high-quality printed output from
the phototypesetter on the UNIX operating system. This document
is an example of troff output.
The single most important rule of using troff is not to use
it directly, but through some intermediary. In many ways, troff
resembles an assembly language - a remarkably powerful and flexi-
ble one - but nonetheless such that many operations must be
specified at a level of detail and in a form that is too hard for
most people to use effectively.
For two special applications, there are programs that pro-
vide an interface to troff for the majority of users. eqn [2]
provides an easy to learn language for typesetting mathematics;
the eqn user need know no troff whatsoever to typeset mathemat-
ics. tbl [3] provides the same convenience for producing tables
of arbitrary complexity.
For producing straight text (which may well contain
mathematics or tables), there are a number of `macro packages'
that define formatting rules and operations for specific styles
of documents, and reduce the amount of direct contact with troff.
In particular, the `-ms' [4], PWB/MM [5], and `-me' [6] packages
for internal memoranda and external papers provide most of the
facilities needed for a wide range of document preparation.-
(This memo was prepared with `-ms'.) There are also packages for
viewgraphs, for simulating the older roff formatters, and for
other special applications. Typically you will find these pack-
ages easier to use than troff once you get beyond the most
trivial operations; you should always consider them first.
In the few cases where existing packages don't do the whole
job, the solution is not to write an entirely new set of troff
instructions from scratch, but to make small changes to adapt
packages that already exist.
In accordance with this philosophy of letting someone else
do the work, the part of troff described here is only a small
part of the whole, although it tries to concentrate on the more
useful parts. In any case, there is no attempt to be complete.
Rather, the emphasis is on showing how to do simple things, and
how to make incremental changes to what already exists. The con-
tents of the remaining sections are:
2.Point sizes and line spacing
3.Fonts and special characters
4.Indents and line length
-------------------------
- Most Berkeley Unix sites only have -ms and -me.
April 27, 2013
A TROFF Tutorial USD:25-3
5.Tabs
6.Local motions: Drawing lines and characters
7.Strings
8.Introduction to macros
9.Titles, pages and numbering
10.Number registers and arithmetic
11.Macros with arguments
12.Conditionals
13.Environments
14.Diversions
Appendix: Typesetter character set
The troff described here is the C-language version supplied with
UNIX Version 7 and 32V as documented in [1].
To use troff you have to prepare not only the actual text
you want printed, but some information that tells how you want it
printed. (Readers who use roff will find the approach familiar.)
For troff the text and the formatting information are often
intertwined quite intimately. Most commands to troff are placed
on a line separate from the text itself, beginning with a period
(one command per line). For example,
Some text.
.ps 14
Some more text.
will change the `point size', that is, the size of the letters
being printed, to `14 point' (one point is 1/72 inch) like this:
Some text. Some more text.
Occasionally, though, something special occurs in the middle
of a line - to produce
Area = i̅i̅r2
you have to type
Area = \(*p\fIr\fR\|\s8\u2\d\s0
(which we will explain shortly). The backslash character \ is
used to introduce troff commands and special characters within a
line of text.
2. Point Sizes; Line Spacing
As mentioned above, the command .ps sets the point size. One
point is 1/72 inch, so 6-point characters are at most 1/12 inch
high, and 36-point characters are 1/2 inch. There are 15 point
sizes, listed below.
April 27, 2013
USD:25-4 A TROFF Tutorial
6 point: Pack my box with five dozen liquor jugs.
7 point: Pack my box with five dozen liquor jugs.
8 point: Pack my box with five dozen liquor jugs.
9 point: Pack my box with five dozen liquor jugs.
10 point: Pack my box with five dozen liquor
11 point: Pack my box with five dozen
12 point: Pack my box with five dozen
14 point: Pack my box with five
16 point 18 point 20 point
22 24 28 36
If the number after .ps is not one of these legal sizes, it
is rounded up to the next valid value, with a maximum of 36. If
no number follows .ps, troff reverts to the previous size, what-
ever it was. troff begins with point size 10, which is usually
fine. The original of this document (on 8.5 by 11 inch paper) is
in 9 point.
The point size can also be changed in the middle of a line
or even a word with the in-line command \s. To produce
UNIX runs on a PDP-11/45
type
\s8UNIX\s10 runs on a \s8PDP-\s1011/45
As above, \s should be followed by a legal point size, except
that \s0 causes the size to revert to its previous value. Notice
that \s1011 can be understood correctly as `size 10, followed by
an 11', if the size is legal, but not otherwise. Be cautious with
similar constructions.
Relative size changes are also legal and useful:
\s-2UNIX\s+2
temporarily decreases the size, whatever it is, by two points,
then restores it. Relative size changes have the advantage that
the size difference is independent of the starting size of the
document. The amount of the relative change is restricted to a
single digit.
The other parameter that determines what the type looks like
is the spacing between lines, which is set independently of the
point size. Vertical spacing is measured from the bottom of one
line to the bottom of the next. The command to control vertical
spacing is .vs. For running text, it is usually best to set the
April 27, 2013
A TROFF Tutorial USD:25-5
vertical spacing about 20% bigger than the character size. For
example, so far in this document, we have used ``9 on 11'', that
is,
.ps 9
.vs 11p
If we changed to
.ps 9
.vs 9p
the running text would look like this. After a few lines, you
will agree it looks a little cramped. The right vertical spacing
is partly a matter of taste, depending on how much text you want
to squeeze into a given space, and partly a matter of traditional
printing style. By default, troff uses 10 on 12.
Point size and vertical spacing make a substantial differ-
ence in the amount of text per square inch. This is 12 on 14.
Point size and vertical spacing make a substantial differ-
ence in the amount of text per square inch. For example, 10 on 12
uses about twice as much space as 7 on 8. This is 6 on 7, which
is even smaller. It packs a lot more words per line, but you can
go blind trying to read it.
When used without arguments, .ps and .vs revert to the pre-
vious size and vertical spacing respectively.
The command .sp is used to get extra vertical space. Una-
dorned, it gives you one extra blank line (one .vs, whatever that
has been set to). Typically, that's more or less than you want,
so .sp can be followed by information about how much space you
want -
.sp 2i
means `two inches of vertical space'.
.sp 2p
means `two points of vertical space'; and
.sp 2
means `two vertical spaces' - two of whatever .vs is set to (this
can also be made explicit with .sp 2v); troff also understands
decimal fractions in most places, so
.sp 1.5i
is a space of 1.5 inches. These same scale factors can be used
April 27, 2013
USD:25-6 A TROFF Tutorial
after .vs to define line spacing, and in fact after most commands
that deal with physical dimensions.
It should be noted that all size numbers are converted
internally to `machine units', which are 1/432 inch (1/6 point).
For most purposes, this is enough resolution that you don't have
to worry about the accuracy of the representation. The situation
is not quite so good vertically, where resolution is 1/144 inch
(1/2 point).
3. Fonts and Special Characters
troff and the typesetter allow four different fonts at any
one time. Normally three fonts (Times roman, italic and bold) and
one collection of special characters are permanently mounted.
abcdefghijklmnopqrstuvwxyz 0123456789
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
ABCDEFGHIJKLMNOPQRSTUVWXYZ
The greek, mathematical symbols and miscellany of the special
font are listed in Appendix A.
troff prints in roman unless told otherwise. To switch into
bold, use the .ft command
.ft B
and for italics,
.ft I
To return to roman, use .ft R; to return to the previous font,
whatever it was, use either .ft P or just .ft. The `underline'
command
.ul
causes the next input line to print in italics. .ul can be fol-
lowed by a count to indicate that more than one line is to be
italicized.
Fonts can also be changed within a line or word with the
in-line command \f:
boldface text
is produced by
\fBbold\fIface\fR text
April 27, 2013
A TROFF Tutorial USD:25-7
If you want to do this so the previous font, whatever it was, is
left undisturbed, insert extra \fP commands, like this:
\fBbold\fP\fIface\fP\fR text\fP
Because only the immediately previous font is remembered, you
have to restore the previous font after each change or you can
lose it. The same is true of .ps and .vs when used without an
argument.
There are other fonts available besides the standard set,
although you can still use only four at any given time. The com-
mand .fp tells troff what fonts are physically mounted on the
typesetter:
.fp 3 H
says that the Helvetica font is mounted on position 3. (The com-
plete list of font sizes and styles depends on your typesetter or
laser printer.) Appropriate .fp commands should appear at the
beginning of your document if you do not use the standard fonts.
It is possible to make a document relatively independent of
the actual fonts used to print it by using font numbers instead
of names; for example, \f3 and .ft 3 mean `whatever font is
mounted at position 3', and thus work for any setting. Normal
settings are roman font on 1, italic on 2, bold on 3, and special
on 4.
There is also a way to get `synthetic' bold fonts by over-
striking letters with a slight offset. Look at the .bd command in
[1].
Special characters have four-character names beginning with
\(, and they may be inserted anywhere. For example,
1/4 + 1/2 = 3/4
is produced by
\(14 + \(12 = \(34
In particular, greek letters are all of the form \(*-, where - is
an upper or lower case roman letter reminiscent of the greek.
Thus to get
≥̅((x|) -> oo
in bare troff we have to type
\(*S(\(*a\(mu\(*b) \(-> \(if
That line is unscrambled as follows:
April 27, 2013
USD:25-8 A TROFF Tutorial
\(*S ≥̅
( (
\(*a (
\(mu x
\(*b |
) )
\(-> ->
\(if oo
A complete list of these special names occurs in Appendix A.
In eqn [2] the same effect can be achieved with the input
SIGMA ( alpha times beta ) -> inf
which is less concise, but clearer to the uninitiated.
Notice that each four-character name is a single character
as far as troff is concerned - the `translate' command
.tr \(mi\(em
is perfectly clear, meaning
.tr --
that is, to translate - into -.
Some characters are automatically translated into others:
grave ` and acute ' accents (apostrophes) become open and
close single quotes `'; the combination of ``...'' is generally
preferable to the double quotes "...". Similarly a typed minus
sign becomes a hyphen -. To print an explicit - sign, use \-. To
get a backslash printed, use \e.
4. Indents and Line Lengths
troff starts with a line length of 6.5 inches, which some
people think is too wide for 81/2x11 paper. To reset the line
length, use the .ll command, as in
.ll 6i
As with .sp, the actual length can be specified in several ways;
inches are probably the most intuitive.
The maximum line length provided by the typesetter is 7.5
inches, by the way. To use the full width, you will have to reset
the default physical left margin (``page offset''), which is nor-
mally slightly less than one inch from the left edge of the
paper. This is done by the .po command.
.po 0
April 27, 2013
A TROFF Tutorial USD:25-9
sets the offset as far to the left as it will go.
The indent command .in causes the left margin to be indented
by some specified amount from the page offset. If we use .in to
move the left margin in, and .ll to move the right margin to the
left, we can make offset blocks of text:
.in 0.3i
.ll -0.3i
text to be set into a block
.ll +0.3i
.in -0.3i
will create a block that looks like this:
Pater noster qui est in caelis sanctificetur nomen tuum;
adveniat regnum tuum; fiat voluntas tua, sicut in caelo,
et in terra. ... Amen.
Notice the use of `+' and `-' to specify the amount of change.
These change the previous setting by the specified amount, rather
than just overriding it. The distinction is quite important:
.ll +1i makes lines one inch longer; .ll 1i makes them one inch
long.
With .in, .ll and .po, the previous value is used if no
argument is specified.
To indent a single line, use the `temporary indent' command
.ti. For example, all paragraphs in this memo effectively begin
with the command
.ti 3
Three of what? The default unit for .ti, as for most horizontally
oriented commands (.ll, .in, .po), is ems; an em is roughly the
width of the letter `m' in the current point size. (Precisely, a
em in size p is p points.) Although inches are usually clearer
than ems to people who don't set type for a living, ems have a
place: they are a measure of size that is proportional to the
current point size. If you want to make text that keeps its pro-
portions regardless of point size, you should use ems for all
dimensions. Ems can be specified as scale factors directly, as in
.ti 2.5m.
Lines can also be indented negatively if the indent is
already positive:
.ti -0.3i
causes the next line to be moved back three tenths of an inch.
Thus to make a decorative initial capital, we indent the whole
paragraph, then move the letter `P' back with a .ti command:
April 27, 2013
USD:25-10 A TROFF Tutorial
ater noster qui est in caelis sanctificetur nomen tuum;
adveniat regnum tuum; fiat voluntas tua, sicut in cae-
lo, et in terra. ... Amen.
Of course, there is also some trickery to make the `P' bigger
(just a `\s36P\s0'), and to move it down from its normal position
(see the section on local motions).
5. Tabs
Tabs (the ASCII `horizontal tab' character) can be used to
produce output in columns, or to set the horizontal position of
output. Typically tabs are used only in unfilled text. Tab stops
are set by default every half inch from the current indent, but
can be changed by the .ta command. To set stops every inch, for
example,
.ta 1i 2i 3i 4i 5i 6i
Unfortunately the stops are left-justified only (as on a
typewriter), so lining up columns of right-justified numbers can
be painful. If you have many numbers, or if you need more compli-
cated table layout, don't use troff directly; use the tbl program
described in [3].
For a handful of numeric columns, you can do it this way:
Precede every number by enough blanks to make it line up when
typed.
.nf
.ta 1i 2i 3i
1 tab 2 tab 3
40 tab 50 tab 60
700 tab 800 tab 900
.fi
Then change each leading blank into the string \0. This is a
character that does not print, but that has the same width as a
digit. When printed, this will produce
1 2 3
40 50 60
700 800 900
It is also possible to fill up tabbed-over space with some
character other than blanks by setting the `tab replacement char-
acter' with the .tc command:
.ta 1.5i 2.5i
.tc \(ru (\(ru is "_")
Name tab Age tab
April 27, 2013
A TROFF Tutorial USD:25-11
produces
Name___________ Age _____
To reset the tab replacement character to a blank, use .tc with
no argument. (Lines can also be drawn with the \l command,
described in Section 6.)
troff also provides a very general mechanism called `fields'
for setting up complicated columns. (This is used by tbl). We
will not go into it in this paper.
6. Local Motions: Drawing lines and characters
Remember `Area = i̅i̅r2' and the big `P' in the Paternoster.
How are they done? troff provides a host of commands for placing
characters of any size at any place. You can use them to draw
special characters or to tune your output for a particular
appearance. Most of these commands are straightforward, but messy
to read and tough to type correctly.
If you won't use eqn, subscripts and superscripts are most
easily done with the half-line local motions \u and \d. To go
back up the page half a point-size, insert a \u at the desired
place; to go down, insert a \d. (\u and \d should always be used
in pairs, as explained below.) Thus
Area = \(*pr\u2\d
produces
Area = i̅i̅r2
To make the `2' smaller, bracket it with \s-2...\s0. Since \u and
\d refer to the current point size, be sure to put them either
both inside or both outside the size changes, or you will get an
unbalanced vertical motion.
Sometimes the space given by \u and \d isn't the right
amount. The \v command can be used to request an arbitrary amount
of vertical motion. The in-line command
\v'(amount)'
causes motion up or down the page by the amount specified in
`(amount)'. For example, to move the `P' down, we used
.in +0.6i (move paragraph in)
.ll -0.3i (shorten lines)
.ti -0.3i (move P back)
\v'2'\s36P\s0\v'-2'ater noster qui est
in caelis ...
A minus sign causes upward motion, while no sign or a plus sign
April 27, 2013
USD:25-12 A TROFF Tutorial
means down the page. Thus \v'-2' causes an upward vertical motion
of two line spaces.
There are many other ways to specify the amount of motion -
\v'0.1i'
\v'3p'
\v'-0.5m'
and so on are all legal. Notice that the scale specifier i or p
or m goes inside the quotes. Any character can be used in place
of the quotes; this is also true of all other troff commands
described in this section.
Since troff does not take within-the-line vertical motions
into account when figuring out where it is on the page, output
lines can have unexpected positions if the left and right ends
aren't at the same vertical position. Thus \v, like \u and \d,
should always balance upward vertical motion in a line with the
same amount in the downward direction.
Arbitrary horizontal motions are also available - \h is
quite analogous to \v, except that the default scale factor is
ems instead of line spaces. As an example,
\h'-0.1i'
causes a backwards motion of a tenth of an inch. As a practical
matter, consider printing the mathematical symbol `>>'. The
default spacing is too wide, so eqn replaces this by
>\h'-0.3m'>
to produce >>.
Frequently \h is used with the `width function' \w to gen-
erate motions equal to the width of some character string. The
construction
\w'thing'
is a number equal to the width of `thing' in machine units (1/432
inch). All troff computations are ultimately done in these units.
To move horizontally the width of an `x', we can say
\h'\w'x'u'
As we mentioned above, the default scale factor for all horizon-
tal dimensions is m, ems, so here we must have the u for machine
units, or the motion produced will be far too large. troff is
quite happy with the nested quotes, by the way, so long as you
don't leave any out.
As a live example of this kind of construction, all of the
April 27, 2013
A TROFF Tutorial USD:25-13
command names in the text, like .sp, were done by overstriking
with a slight offset. The commands for .sp are
.sp\h'-\w'.sp'u'\h'1u'.sp
That is, put out `.sp', move left by the width of `.sp', move
right 1 unit, and print `.sp' again. (Of course there is a way to
avoid typing that much input for each command name, which we will
discuss in Section 11.)
There are also several special-purpose troff commands for
local motion. We have already seen \0, which is an unpaddable
white space of the same width as a digit. `Unpaddable' means that
it will never be widened or split across a line by line justifi-
cation and filling. There is also \(blank), which is an unpadd-
able character the width of a space, \|, which is half that
width, \^, which is one quarter of the width of a space, and \&,
which has zero width. (This last one is useful, for example, in
entering a text line which would otherwise begin with a `.'.)
The command \o, used like
\o'set of characters'
causes (up to 9) characters to be overstruck, centered on the
widest. This is nice for accents, as in
syst\o"e\(ga"me t\o"e\(aa"l\o"e\(aa"phonique
which makes
syst`me t'l'phonique
The accents are \(ga and \(aa, or \` and \'; remember that each
is just one character to troff.
You can make your own overstrikes with another special con-
vention, \z, the zero-motion command. \zx suppresses the normal
horizontal motion after printing the single character x, so
another character can be laid on top of it. Although sizes can be
changed within \o, it centers the characters on the widest, and
there can be no horizontal or vertical motions, so \z may be the
only way to get what you want:
[[]]
is produced by
.sp 2
\s8\z\(sq\s14\z\(sq\s22\z\(sq\s36\(sq
April 27, 2013
USD:25-14 A TROFF Tutorial
The .sp is needed to leave room for the result.
As another example, an extra-heavy semicolon that looks like
. instead of ; or ;
can be constructed with a big comma and a big period above it:
\s+6\z,\v'-0.25m'.\v'0.25m'\s0
`0.25m' is an experimentally-derived constant.
A more ornate overstrike is given by the bracketing function
\b, which piles up characters vertically, centered on the current
baseline. Thus we can get big brackets, constructing them with
piled-up smaller pieces:
|
| |
| | x | |
| |
|
by typing in only this:
.sp
\b'\(lt\(lk\(lb' \b'\(lc\(lf' x \b'\(rc\(rf' \b'\(rt\(rk\(rb'
troff also provides a convenient facility for drawing hor-
izontal and vertical lines of arbitrary length with arbitrary
characters. \l'1i' draws a line one inch long, like this:
__________. The length can be followed by the character to use if
the _ isn't appropriate; \l'0.5i.' draws a half-inch line of
dots: ...... The construction \L is entirely analogous, except
that it draws a vertical line instead of horizontal.
7. Strings
Obviously if a paper contains a large number of occurrences
of an acute accent over a letter `e', typing \o"e\'" for each '
would be a great nuisance.
Fortunately, troff provides a way in which you can store an
arbitrary collection of text in a `string', and thereafter use
the string name as a shorthand for its contents. Strings are one
of several troff mechanisms whose judicious use lets you type a
document with less effort and organize it so that extensive for-
mat changes can be made with few editing changes.
A reference to a string is replaced by whatever text the
string was defined as. Strings are defined with the command .ds.
The line
.ds e \o"e\'"
April 27, 2013
A TROFF Tutorial USD:25-15
defines the string e to have the value \o"e\'"
String names may be either one or two characters long, and
are referred to by \*x for one character names or \*(xy for two
character names. Thus to get t'l'phone, given the definition of
the string e as above, we can say t\*el\*ephone.
If a string must begin with blanks, define it as
.ds xx " text
The double quote signals the beginning of the definition. There
is no trailing quote; the end of the line terminates the string.
A string may actually be several lines long; if troff
encounters a \ at the end of any line, it is thrown away and the
next line added to the current one. So you can make a long string
simply by ending each line but the last with a backslash:
.ds xx this \
is a very \
long string
Strings may be defined in terms of other strings, or even in
terms of themselves; we will discuss some of these possibilities
later.
8. Introduction to Macros
Before we can go much further in troff, we need to learn a
bit about the macro facility. In its simplest form, a macro is
just a shorthand notation quite similar to a string. Suppose we
want every paragraph to start in exactly the same way - with a
space and a temporary indent of two ems:
.sp
.ti +2m
Then to save typing, we would like to collapse these into one
shorthand line, a troff `command' like
.PP
that would be treated by troff exactly as
.sp
.ti +2m
.PP is called a macro. The way we tell troff what .PP means is to
define it with the .de command:
April 27, 2013
USD:25-16 A TROFF Tutorial
.de PP
.sp
.ti +2m
..
The first line names the macro (we used `.PP' for `paragraph',
and upper case so it wouldn't conflict with any name that troff
might already know about). The last line .. marks the end of the
definition. In between is the text, which is simply inserted
whenever troff sees the `command' or macro call
.PP
A macro can contain any mixture of text and formatting commands.
The definition of .PP has to precede its first use; unde-
fined macros are simply ignored. Names are restricted to one or
two characters.
Using macros for commonly occurring sequences of commands is
critically important. Not only does it save typing, but it makes
later changes much easier. Suppose we decide that the paragraph
indent is too small, the vertical space is much too big, and
roman font should be forced. Instead of changing the whole docu-
ment, we need only change the definition of .PP to something like
.de PP \" paragraph macro
.sp 2p
.ti +3m
.ft R
..
and the change takes effect everywhere we used .PP.
\" is a troff command that causes the rest of the line to be
ignored. We use it here to add comments to the macro definition
(a wise idea once definitions get complicated).
As another example of macros, consider these two which start
and end a block of offset, unfilled text, like most of the exam-
ples in this paper:
.de BS \" start indented block
.sp
.nf
.in +0.3i
..
.de BE \" end indented block
.sp
.fi
.in -0.3i
..
April 27, 2013
A TROFF Tutorial USD:25-17
Now we can surround text like
Copy to
John Doe
Richard Roberts
Stanley Smith
by the commands .BS and .BE, and it will come out as it did
above. Notice that we indented by .in +0.3i instead of .in 0.3i.
This way we can nest our uses of .BS and BE to get blocks within
blocks.
If later on we decide that the indent should be 0.5i, then
it is only necessary to change the definitions of .BS and .BE,
not the whole paper.
9. Titles, Pages and Numbering
This is an area where things get tougher, because nothing is
done for you automatically. Of necessity, some of this section is
a cookbook, to be copied literally until you get some experience.
Suppose you want a title at the top of each page, saying
just
left top center topright top
In roff, one can say
.he 'left top'center top'right top'
.fo 'left bottom'center bottom'right bottom'
to get headers and footers automatically on every page. Alas,
this doesn't work so easily in troff, a serious hardship for the
novice. Instead you have to do a lot of specification (or use a
macro package, which makes it effortless).
You have to say what the actual title is (easy); when to
print it (easy enough); and what to do at and around the title
line (harder). Taking these in reverse order, first we define a
macro .NP (for `new page') to process titles and the like at the
end of one page and the beginning of the next:
.de NP
'bp
'sp 0.5i
.tl 'left top'center top'right top'
'sp 0.3i
..
To make sure we're at the top of a page, we issue a `begin page'
command 'bp, which causes a skip to top-of-page (we'll explain
the ' shortly). Then we space down half an inch, print the title
(the use of .tl should be self explanatory; later we will discuss
parameterizing the titles), space another 0.3 inches, and we're
done.
April 27, 2013
USD:25-18 A TROFF Tutorial
To ask for .NP at the bottom of each page, we have to say
something like `when the text is within an inch of the bottom of
the page, start the processing for a new page.' This is done with
a `when' command .wh:
.wh -1i NP
(No `.' is used before NP; this is simply the name of a macro,
not a macro call.) The minus sign means `measure up from the bot-
tom of the page', so `-1i' means `one inch from the bottom'.
The .wh command appears in the input outside the definition
of .NP; typically the input would be
.de NP
...
..
.wh -1i NP
Now what happens? As text is actually being output, troff
keeps track of its vertical position on the page, and after a
line is printed within one inch from the bottom, the .NP macro is
activated. (In the jargon, the .wh command sets a trap at the
specified place, which is `sprung' when that point is passed.)
.NP causes a skip to the top of the next page (that's what the
'bp was for), then prints the title with the appropriate margins.
Why 'bp and 'sp instead of .bp and .sp? The answer is that
.sp and .bp, like several other commands, cause a break to take
place. That is, all the input text collected but not yet printed
is flushed out as soon as possible, and the next input line is
guaranteed to start a new line of output. If we had used .sp or
.bp in the .NP macro, this would cause a break in the middle of
the current output line when a new page is started. The effect
would be to print the left-over part of that line at the top of
the page, followed by the next input line on a new output line.
This is not what we want. Using ' instead of . for a command
tells troff that no break is to take place - the output line
currently being filled should not be forced out before the space
or new page.
The list of commands that cause a break is short and
natural:
.bp .br .ce .fi .nf .sp .in .ti
All others cause no break, regardless of whether you use a . or a
'. If you really need a break, add a .br command at the appropri-
ate place.
One other thing to beware of - if you're changing fonts or
point sizes a lot, you may find that if you cross a page boundary
in an unexpected font or size, your titles come out in that size
April 27, 2013
A TROFF Tutorial USD:25-19
and font instead of what you intended. Furthermore, the length of
a title is independent of the current line length, so titles will
come out at the default length of 6.5 inches unless you change
it, which is done with the .lt command.
There are several ways to fix the problems of point sizes
and fonts in titles. For the simplest applications, we can change
.NP to set the proper size and font for the title, then restore
the previous values, like this:
.de NP
'bp
'sp 0.5i
.ft R \" set title font to roman
.ps 10 \" and size to 10 point
.lt 6i \" and length to 6 inches
.tl 'left'center'right'
.ps \" revert to previous size
.ft P \" and to previous font
'sp 0.3i
..
This version of .NP does not work if the fields in the .tl
command contain size or font changes. To cope with that requires
troff's `environment' mechanism, which we will discuss in Section
13.
To get a footer at the bottom of a page, you can modify .NP
so it does some processing before the 'bp command, or split the
job into a footer macro invoked at the bottom margin and a header
macro invoked at the top of the page. These variations are left
as exercises.
Output page numbers are computed automatically as each page
is produced (starting at 1), but no numbers are printed unless
you ask for them explicitly. To get page numbers printed, include
the character % in the .tl line at the position where you want
the number to appear. For example
.tl ''- % -''
centers the page number inside hyphens, as on this page. You can
set the page number at any time with either .bp n, which immedi-
ately starts a new page numbered n, or with .pn n, which sets the
page number for the next page but doesn't cause a skip to the new
page. Again, .bp +n sets the page number to n more than its
current value; .bp means .bp +1.
10. Number Registers and Arithmetic
troff has a facility for doing arithmetic, and for defining
and using variables with numeric values, called number registers.
April 27, 2013
USD:25-20 A TROFF Tutorial
Number registers, like strings and macros, can be useful in set-
ting up a document so it is easy to change later. And of course
they serve for any sort of arithmetic computation.
Like strings, number registers have one or two character
names. They are set by the .nr command, and are referenced any-
where by \nx (one character name) or \n(xy (two character name).
There are quite a few pre-defined number registers main-
tained by troff, among them % for the current page number; nl for
the current vertical position on the page; dy, mo and yr for the
current day, month and year; and .s and .f for the current size
and font. (The font is a number from 1 to 4.) Any of these can be
used in computations like any other register, but some, like .s
and .f, cannot be changed with .nr.
As an example of the use of number registers, in the -ms
macro package [4], most significant parameters are defined in
terms of the values of a handful of number registers. These
include the point size for text, the vertical spacing, and the
line and title lengths. To set the point size and vertical spac-
ing for the following paragraphs, for example, a user may say
.nr PS 9
.nr VS 11
The paragraph macro .PP is defined (roughly) as follows:
.de PP
.ps \\n(PS\" reset size
.vs \\n(VSp\" spacing
.ft R \" font
.sp 0.5v \" half a line
.ti +3m
..
This sets the font to Roman and the point size and line spacing
to whatever values are stored in the number registers PS and VS.
Why are there two backslashes? This is the eternal problem
of how to quote a quote. When troff originally reads the macro
definition, it peels off one backslash to see what's coming next.
To ensure that another is left in the definition when the macro
is used, we have to put in two backslashes in the definition. If
only one backslash is used, point size and vertical spacing will
be frozen at the time the macro is defined, not when it is used.
Protecting by an extra layer of backslashes is only needed
for \n, \*, \$ (which we haven't come to yet), and \ itself.
Things like \s, \f, \h, \v, and so on do not need an extra
backslash, since they are converted by troff to an internal code
immediately upon being seen.
April 27, 2013
A TROFF Tutorial USD:25-21
Arithmetic expressions can appear anywhere that a number is
expected. As a trivial example,
.nr PS \\n(PS-2
decrements PS by 2. Expressions can use the arithmetic operators
+, -, *, /, % (mod), the relational operators >, >=, <, <=, =,
and != (not equal), and parentheses.
Although the arithmetic we have done so far has been
straightforward, more complicated things are somewhat tricky.
First, number registers hold only integers. troff arithmetic uses
truncating integer division, just like Fortran. Second, in the
absence of parentheses, evaluation is done left-to-right without
any operator precedence (including relational operators). Thus
7*-4+3/13
becomes `-1'. Number registers can occur anywhere in an expres-
sion, and so can scale indicators like p, i, m, and so on (but no
spaces). Although integer division causes truncation, each number
and its scale indicator is converted to machine units (1/432
inch) before any arithmetic is done, so 1i/2u evaluates to 0.5i
correctly.
The scale indicator u often has to appear when you wouldn't
expect it - in particular, when arithmetic is being done in a
context that implies horizontal or vertical dimensions. For exam-
ple,
.ll 7/2i
would seem obvious enough - 31/2 inches. Sorry. Remember that the
default units for horizontal parameters like .ll are ems. That's
really `7 ems / 2 inches', and when translated into machine
units, it becomes zero. How about
.ll 7i/2
Sorry, still no good - the `2' is `2 ems', so `7i/2' is small,
although not zero. You must use
.ll 7i/2u
So again, a safe rule is to attach a scale indicator to every
number, even constants.
For arithmetic done within a .nr command, there is no impli-
cation of horizontal or vertical dimension, so the default units
are `units', and 7i/2 and 7i/2u mean the same thing. Thus
.nr ll 7i/2
.ll \\n(llu
April 27, 2013
USD:25-22 A TROFF Tutorial
does just what you want, so long as you don't forget the u on the
.ll command.
11. Macros with arguments
The next step is to define macros that can change from one
use to the next according to parameters supplied as arguments. To
make this work, we need two things: first, when we define the
macro, we have to indicate that some parts of it will be provided
as arguments when the macro is called. Then when the macro is
called we have to provide actual arguments to be plugged into the
definition.
Let us illustrate by defining a macro .SM that will print
its argument two points smaller than the surrounding text. That
is, the macro call
.SM TROFF
will produce TROFF.
The definition of .SM is
.de SM
\s-2\\$1\s+2
..
Within a macro definition, the symbol \\$n refers to the nth
argument that the macro was called with. Thus \\$1 is the string
to be placed in a smaller point size when .SM is called.
As a slightly more complicated version, the following defin-
ition of .SM permits optional second and third arguments that
will be printed in the normal size:
.de SM
\\$3\s-2\\$1\s+2\\$2
..
Arguments not provided when the macro is called are treated as
empty, so
.SM TROFF ),
produces TROFF), while
.SM TROFF ). (
produces (TROFF). It is convenient to reverse the order of argu-
ments because trailing punctuation is much more common than lead-
ing.
By the way, the number of arguments that a macro was called
with is available in number register .$.
April 27, 2013
A TROFF Tutorial USD:25-23
The following macro .BD is the one used to make the `bold
roman' we have been using for troff command names in text. It
combines horizontal motions, width computations, and argument
rearrangement.
.de BD
\&\\$3\f1\\$1\h'-\w'\\$1'u+1u'\\$1\fP\\$2
..
The \h and \w commands need no extra backslash, as we discussed
above. The \& is there in case the argument begins with a period.
Two backslashes are needed with the \\$n commands, though,
to protect one of them when the macro is being defined. Perhaps a
second example will make this clearer. Consider a macro called
.SH which produces section headings rather like those in this
paper, with the sections numbered automatically, and the title in
bold in a smaller size. The use is
.SH "Section title ..."
(If the argument to a macro is to contain blanks, then it must be
surrounded by double quotes, unlike a string, where only one
leading quote is permitted.)
Here is the definition of the .SH macro:
.nr SH 0 \" initialize section number
.de SH
.sp 0.3i
.ft B
.nr SH \\n(SH+1\" increment number
.ps \\n(PS-1\" decrease PS
\\n(SH. \\$1\" number. title
.ps \\n(PS \" restore PS
.sp 0.3i
.ft R
..
The section number is kept in number register SH, which is incre-
mented each time just before it is used. (A number register may
have the same name as a macro without conflict but a string may
not.)
We used \\n(SH instead of \n(SH and \\n(PS instead of \n(PS.
If we had used \n(SH, we would get the value of the register at
the time the macro was defined, not at the time it was used. If
that's what you want, fine, but not here. Similarly, by using
\\n(PS, we get the point size at the time the macro is called.
As an example that does not involve numbers, recall our .NP
macro which had a
April 27, 2013
USD:25-24 A TROFF Tutorial
.tl 'left'center'right'
We could make these into parameters by using instead
.tl '\\*(LT'\\*(CT'\\*(RT'
so the title comes from three strings called LT, CT and RT. If
these are empty, then the title will be a blank line. Normally CT
would be set with something like
.ds CT - % -
to give just the page number between hyphens (as on the top of
this page), but a user could supply private definitions for any
of the strings.
12. Conditionals
Suppose we want the .SH macro to leave two extra inches of
space just before section 1, but nowhere else. The cleanest way
to do that is to test inside the .SH macro whether the section
number is 1, and add some space if it is. The .if command pro-
vides the conditional test that we can add just before the head-
ing line is output:
.if \\n(SH=1 .sp 2i \" first section only
The condition after the .if can be any arithmetic or logical
expression. If the condition is logically true, or arithmetically
greater than zero, the rest of the line is treated as if it were
text - here a command. If the condition is false, or zero or
negative, the rest of the line is skipped.
It is possible to do more than one command if a condition is
true. Suppose several operations are to be done before section 1.
One possibility is to define a macro .S1 and invoke it if we are
about to do section 1 (as determined by an .if).
.de S1
--- processing for section 1 ---
..
.de SH
...
.if \\n(SH=1 .S1
...
..
An alternate way is to use the extended form of the .if,
like this:
April 27, 2013
A TROFF Tutorial USD:25-25
.if \\n(SH=1 \{--- processing
for section 1 ----\}
The braces \{ and \} must occur in the positions shown or you
will get unexpected extra lines in your output. troff also pro-
vides an `if-else' construction, which we will not go into here.
A condition can be negated by preceding it with !; we get
the same effect as above (but less clearly) by using
.if !\\n(SH>1 .S1
There are a handful of other conditions that can be tested
with .if. For example, is the current page even or odd?
.if o .tl 'odd page title''- % -'
.if e .tl '- % -''even page title'
gives facing pages different titles and page numbers on the out-
side edge when used inside an appropriate new page macro.
Two other conditions are t and n, which tell you whether the
formatter is troff or nroff.
.if t troff stuff ...
.if n nroff stuff ...
Finally, string comparisons may be made in an .if:
.if 'string1'string2' stuff
does `stuff' if string1 is the same as string2. The character
separating the strings can be anything reasonable that is not
contained in either string. The strings themselves can reference
strings with \*, arguments with \$, and so on.
13. Environments
As we mentioned, there is a potential problem when going
across a page boundary: parameters like size and font for a page
title may well be different from those in effect in the text when
the page boundary occurs. troff provides a very general way to
deal with this and similar situations. There are three `environ-
ments', each of which has independently settable versions of many
of the parameters associated with processing, including size,
font, line and title lengths, fill/nofill mode, tab stops, and
even partially collected lines. Thus the titling problem may be
readily solved by processing the main text in one environment and
titles in a separate one with its own suitable parameters.
The command .ev n shifts to environment n; n must be 0, 1 or
April 27, 2013
USD:25-26 A TROFF Tutorial
2. The command .ev with no argument returns to the previous
environment. Environment names are maintained in a stack, so
calls for different environments may be nested and unwound con-
sistently.
Suppose we say that the main text is processed in environ-
ment 0, which is where troff begins by default. Then we can
modify the new page macro .NP to process titles in environment 1
like this:
.de NP
.ev 1 \" shift to new environment
.lt 6i \" set parameters here
.ft R
.ps 10
... any other processing ...
.ev \" return to previous environment
..
It is also possible to initialize the parameters for an environ-
ment outside the .NP macro, but the version shown keeps all the
processing in one place and is thus easier to understand and
change.
14. Diversions
There are numerous occasions in page layout when it is
necessary to store some text for a period of time without actu-
ally printing it. Footnotes are the most obvious example: the
text of the footnote usually appears in the input well before the
place on the page where it is to be printed is reached. In fact,
the place where it is output normally depends on how big it is,
which implies that there must be a way to process the footnote at
least enough to decide its size without printing it.
troff provides a mechanism called a diversion for doing this
processing. Any part of the output may be diverted into a macro
instead of being printed, and then at some convenient time the
macro may be put back into the input.
The command .di xy begins a diversion - all subsequent out-
put is collected into the macro xy until the command .di with no
arguments is encountered. This terminates the diversion. The pro-
cessed text is available at any time thereafter, simply by giving
the command
.xy
The vertical size of the last finished diversion is contained in
the built-in number register dn.
As a simple example, suppose we want to implement a `keep-
release' operation, so that text between the commands .KS and .KE
will not be split across a page boundary (as for a figure or
April 27, 2013
A TROFF Tutorial USD:25-27
table). Clearly, when a .KS is encountered, we have to begin
diverting the output so we can find out how big it is. Then when
a .KE is seen, we decide whether the diverted text will fit on
the current page, and print it either there if it fits, or at the
top of the next page if it doesn't. So:
.de KS\" start keep
.br \" start fresh line
.ev 1 \" collect in new environment
.fi \" make it filled text
.di XX\" collect in XX
..
.de KE\" end keep
.br \" get last partial line
.di \" end diversion
.if \\n(dn>=\\n(.t .bp \" bp if doesn't fit
.nf \" bring it back in no-fill
.XX \" text
.ev \" return to normal environment
..
Recall that number register nl is the current position on the
output page. Since output was being diverted, this remains at its
value when the diversion started. dn is the amount of text in the
diversion; .t (another built-in register) is the distance to the
next trap, which we assume is at the bottom margin of the page.
If the diversion is large enough to go past the trap, the .if is
satisfied, and a .bp is issued. In either case, the diverted out-
put is then brought back with .XX. It is essential to bring it
back in no-fill mode so troff will do no further processing on
it.
This is not the most general keep-release, nor is it robust
in the face of all conceivable inputs, but it would require more
space than we have here to write it in full generality. This sec-
tion is not intended to teach everything about diversions, but to
sketch out enough that you can read existing macro packages with
some comprehension.
Acknowledgements
I am deeply indebted to J. F. Ossanna, the author of troff,
for his repeated patient explanations of fine points, and for his
continuing willingness to adapt troff to make other uses easier.
I am also grateful to Jim Blinn, Ted Dolotta, Doug McIlroy, Mike
Lesk and Joel Sturman for helpful comments on this paper.
References
[1] J. F. Ossanna, NROFF/TROFF User's Manual, Bell Laboratories
Computing Science Technical Report 54, 1976.
April 27, 2013
USD:25-28 A TROFF Tutorial
[2] B. W. Kernighan, A System for Typesetting Mathematics -
User's Guide (Second Edition), Bell Laboratories Computing
Science Technical Report 17, 1977.
[3] M. E. Lesk, TBL - A Program to Format Tables, Bell Labora-
tories Computing Science Technical Report 49, 1976.
[4] M. E. Lesk, Typing Documents on UNIX, Bell Laboratories,
1978.
[5] J. R. Mashey and D. W. Smith, PWB/MM - Programmer's Work-
bench Memorandum Macros, Bell Laboratories internal memoran-
dum.
[6] Eric P. Allman, Writing Papers with NROFF using -me, Univer-
sity of California, Berkeley.
April 27, 2013
A TROFF Tutorial USD:25-29
Appendix A: Phototypesetter Character Set (APS-5)
These characters exist in roman, italic, and bold. To get the one
on the left, type the four-character name on the right.
ff \(ff fi \(fi fl \(fl ffi \(Fiffl\(Fl
_ \(ru - \(em 1/4 \(14 1/2 \(12 3/4 \(34
(C) \(co \(de - \(dg ' \(fm / \(ct
(R) \(rg + \(bu [] \(sq - \(hy
(In bold, \(sq is [].)
The following are special-font characters:
+ \(pl - \(mi x \(mu - \(di
= \(eq _ \(== ≥ \(>= ≤ \(<=
/ \(!= ± \(+- \(no / \(sl
~ \(ap ̅ \(~= oc \(pt \̅/̅ \(gr
-> \(-> <- \(<- ^ \(ua v \(da
\(is ` \(pd oo \(if / \(sr
(= \(sb =) \(sp (̅)̅ \(cu _)_ \(ca
(_ \(ib _) \(ip - \(mo / \(es
' \(aa ` \(ga O \(ci \(bs
S \(sc = \(dd <= \(lh => \(rh
| \(lt | \(rt | \(lc | \(rc
| \(lb | \(rb | \(lf | \(rf
| \(lk | \(rk | \(bv \(ts
| \(br | \(or _ \(ul ~ \(rn
* \(**
These four characters also have two-character names. The ' is the
apostrophe on terminals; the ` is the other quote mark.
' \' ` \` - \- _ \_
These characters exist only on the special font, but they do not
have four-character names:
" { } < > ~ ^ \ # @
For greek, precede the roman letter by \(* to get the correspond-
ing greek; for example, \(*a is (.
abgdezyhiklmncoprstufxqw
(|/`-n-ik\uvoi̅i̅po̅i̅u|x|w
ABGDEZYHIKLMNCOPRSTUFXQW
ABI̅_\_EZH-IK/\MN_OTTP≥̅TY|X|_O
April 27, 2013
USD:25-30 A TROFF Tutorial
Index changing fonts (^ft, #f) 5
changing macros 15
! (negating conditionals) 17 character set 4,5,19
#$ (macro argument) 16 character translation (^tr) 2,6
#*x, #(xy (invoke string macro) 14 columnated output 10
#b (bracketing function) 13 commands 1
#d (subscript) 11 commands that cause break 9
#f (font change) 5 conditionals (^if) 16
#h (horizontal motion) 12 constant proportion 7
#nx, #n(xy (number register) 15 default break list 9
#o (overstrike) 13 define macro (^de) 7
#s (size change) 3 define string macro (^ds) 14
#u (superscript) 11 drawing lines 11
#v (vertical motion) 11 em 7,11
#w (width function) 12 end of macro (^^) 7
#z (zero motion) 13 even page test (e) 17
'command instead of ^command 9 fill (^fi) 2
% (page number register) 10,15 fonts (^ft) 4,19
^^ (end of macro definition) 7 Greek (#(*-) 5,19
^bp 9,10 hanging indent (^ti) 12
^br (break) 9 hints 20
^ce (center) 2 horizontal motion (#h) 12
^ds (define string macro) 7,14 hp (horizontal position register) 15
^fi (fill) 2 hyphen 6
^ft (change font) 5 i scale indicator 4
^if (conditional test) 16 indent (^in) 6
^in (indent) 6 index 21
^lg (set ligatures 5 italic font (.ft I) 4
^ll (line length) 6 italicize (^ul) 6
^nf (nofill) 2 legal point sizes 3
^nr (set number register) 14 ligatures (ff,fi,fl; ^lg) 5
^pn (page number) 10 line length (^ll) 6
^ps (change point size) 1,3 line spacing (^vs) 3
^sp (space) 4 local motions (#u,#d,#v,#h,#w,#o,#z,#b) 11 ff
^ss (set space size) 10 m scale indicator 7
^ta (set tab stops) 11 machine units 4,12
^tc (set tab character) 10 macro arguments 15
^tl (title) 9 macros 7
^tr (translate characters) 2,6 macros that change 15
^ul (italicize) 6 multiple backslashes 14
^vs (vertical spacing) 3 negating conditionals (!) 17
^wh (when conditional) 9,17 new page macro (NP) 8
accents 6,13 nl (current vertical position register) 15
apostrophes 6 nofill (^nf) 2
arithmetic 15 NROFF test (n) 17
backslash 1,3,5,14,16 nested quotes 12
begin page (^bp) 9 number registers (^nr,#n) 14
block macros (B1,B2) 8 numbered paragraphs 12
bold font (.ft B) 5 odd page test (o) 17
boustrophedon 12 order of evaluation 14
bracketing function (##b) 13 overstrike (#o) 13
break (^br) 9 p scale indicator 3
break-causing commmands 9 page number register (%) 10
centering (^ce) 2 page numbers (^pn, ^bp) 10
April 27, 2013
A TROFF Tutorial USD:25-31
paragraph macro (PG) 7
Paternoster 6
point size (^ps) 1,3
previous font (#fP, ^ft P) 5
previous point size (#s0,^ps) 3
quotes 6
relative change (±) 6
ROFF 1
ROFF header and footer 8
Roman font (.ft R) 4
scale indicator i 4
scale indicator m 7
scale indicator p 3
scale indicator u 12
scale indicators in arithmetic 15
section heading macro (SC) 15
set space size (^ss) 10
size _ see point size
space (^sp) 4
space between lines (^vs) 3
special characters (#(xx) 5,19
string macros (^ds,#*) 14
subscripts (#d) 11
superscripts (#u) 11
tab character (^tc) 11
tabs (^ta) 10
temporary indent (^ti) 7
titles (^tl) 8
translate (^tr) 2,6,12
TROFF examples 19
TROFF test (t) 17
truncating division 15
type faces _ see fonts
u scale indicator 12
underline (^ul) 6
valid point sizes 3
vertical motion (#v) 11
vertical position on page 9
vertical spacing (^vs) 3
when (^wh) 9,17
width function (#w) 12
width of digits 10
zero motion (#z) 13
April 27, 2013
Generated on 2013-04-27 00:20:00 by $MirOS: src/scripts/roff2htm,v 1.77 2013/01/01 20:49:09 tg Exp $
These manual pages and other documentation are copyrighted by their respective writers;
their source is available at our CVSweb,
AnonCVS, and other mirrors. The rest is Copyright © 2002‒2013 The MirOS Project, Germany.
This product includes material
provided by Thorsten Glaser.
This manual page’s HTML representation is supposed to be valid XHTML/1.1; if not, please send a bug report – diffs preferred.