One of the most common uses for any computer is text processing, and in this respect machines running UNIX are no different than any others.
Many products exist for UNIX machines, including WordPerfect, Microsoft Word, IslandWrite, and FrameMaker. Although very powerful, these text processors might not be available on every machine. The best solution for almost every platform is the troff
text processor and its cousin, nroff. troff is short for "text run-off" and was originally developed by Joseph Ossanna in the early 1970s, for use with the Graphics Systems CAT typesetter. This was the typesetter in use at the Murray Hill
Computer Center of Bell Labs, where UNIX was first developed. In 1979, in response to the need to support more typesetters, Brian Kernighan rewrote troff. Although alternatives were investigated, UNIX had already invested a large amount of effort in troff,
including macro packages and preprocessors for the utility. You have already learned about manual pages, which are written in troff using a specialized macro package.
Closely associated with troff is nroff. They both use the same set of commands to format text, the biggest exception being that nroff does not support commands for changing point sizes and supports only a limited number of character set changes. nroff
also provides ASCII output, so you can see the results of your nroff command on your screen. Although third-party products can show the results of your troff command on screen if they have graphics capabilities, on a standard UNIX system, the only way to
see the troff output is to send it to a printer.
Many word processors such as Microsoft Word and WordPerfect are WYSIWYG processors (what you see is what you get). With those word processors, you choose menu items or press key combinations that cause the formatting to occur right on the screen, but
the formatting codes do not appear in your document. Text processors like nroff and troff are called descriptive markup languages, which means that you enter the formatting codes into your document like any other text, and you don't see the effects of
those instructions until you print the file.
Several building blocks are available for formatting files using nroff and troff, including the following:
Processing troff and nroff files for printing is discussed in Chapter 29, "Processing, Printing, and Troubleshooting Formatted Files."
Chapters 21 through 29 give you a good start on using the nroff/troff family of text processing tools, but there is much more that you can do with them. For additional information, you can consult the nroff and troff man pages online or your local
guidestore for guides dedicated to this subject.
UNIX offers a selection of commands and utilities for printing. Printing nroff and troff output files is covered in detail in Chapter 29. It describes the role of the preprocessors, nroff and troff, the role of the postprocessors, and introduces you to
PostScript. It also reviews raw printing (just dumping the contents of your file with no formatting at all) because sometimes you'll want to print a file without formatting it.
The cleanest look to any document is when the text looks symmetric, with one or two smooth margins, and spread across the pagelike this paragraph. The default settings for nroff and troff are to "fill" each line with text, and to
"adjust" the position of the text so that all lines begin at the left margin, and the right margin is justified. In the simplest case, the input file does not need any troff requests to format a basic document. Listing 21.1 illustrates a basic
input file, and Figure 21.1 illustrates the output produced by nroff.
Figure 21.1. roff output with no requests.
We, the people of the United States, in order to form a more perfect Union, establish justice, insure domestic tranquility, provide for the common defense, promote the general welfare, and secure the blessing of liberty to ourselves and our posterity do ordain and establish this Constitution for the United States of America.
The raw text file has a ragged right margin, with some lines very short, and one line longer than desired. By putting the text through nroff, the lines are set to an even length, and the margins are smooth. Two words were broken across lines. If you
look closely at the output, you'll see that nroff justifies the right margin by inserting extra spaces between words, at alternating ends of each line. The first line needed no extra spaces, but to even the margin on the second line, an extra space was
included between "perfect" and "Union," and the third line needed four extra spaces.
troff output of the same text, shown in Figure 21.2, shows that the lines are expanded to justify the margins by changing the spacing of letters across the entire line.
Figure 21.2. troff output of Figure 21.1.
The ability to fill the text can be set with two requests. The first, .fi, tells troff that you want the text to be filled with input. This is the default setting. The request .nf tells troff that you don't want text filled, that you want the right
margin to be ragged. This is useful for cases where a block of text is inappropriate, such as a return address or poetry. Listing 21.2 shows a sample input file for a letter, with no fill in places, and fill in places. Figure 21.3 shows the output.
Figure 21.3. troff output showing filled and nonfilled text.
.nf 101 Main Street Morristown, NJ 07960 15 March, 1994 Dear Sir, .fi I just wanted to drop you a note to thank you for spending the time to give me a tour of your facilities. I found the experience both educational and enjoyable. I hope that we can work together to produce a product we can sell.
Note that a blank line is used to separate blocks of text. On a longer document, these blank lines can be used to separate paragraphs. Another way to separate blocks is to use .br. This interrupts the filling of the current line and starts a new block
of text. The same can be done by starting a line of text with a space. Figure 21.4 shows the output of Listing 21.1, but includes a break after "the general welfare."
Figure 21.4. troff output showing the effect of a break in midsentence.
Although smooth margins are the default, this is also something under the control of the writer. The .ad command controls adjustment. It can take the following as arguments: l means to adjust the left margin only; r is to adjust the right margin only; c
is to center each line; and b or n means to adjust both margins. Figure 21.5 shows the effects of .ad l, .ad r, and .ad c on the first text sample. .ad b is the default starting value and is effectively demonstrated in the first example.
Figure 21.5. troff output showing the effects of different line adjustments.
Obviously, adjustment makes no sense if the text is not filled. Right margin adjustment can also be turned off with .na. The adjustment mode is not changed.
The last type of text adjustment is centering. This is a bit different than .ad c, which continues to fill lines before centering the text, but only if .fi is specified. The centering request is .ce and can be followed by a number. This centers the next
line or lines, without filling text. If the text is being filled, each input line is treated as if it is followed by a break. Non-filled lines would be treated the same as .ce. Chapter titles are an example of text centering. Listing 21.3 is the source for
a centering command, and the output is illustrated in Figure 21.6.
Figure 21.6. The effects of the centering request.
.ce 3 Scientific Methods of Computing A Simulation by John Smith
There are three types of vertical space controls in troff. Baseline spacing controls the basic spacing between consecutive lines of text. The next type is extra line spacing; this is the ability to double-space text, or more, both on a regular basis,
and on a per case basis. The last is a block of vertical space.
Space measurements have different scales. When a request needs a distance, you can use the default type or modify the number with an indicator. The measurement types are inches, centimeters, Picas, Ems, Ens, points, units, and vertical line spaces. A
Pica is 1/6 of an inch. An em is the width of the letter m and is dependent on the font used in troff. An en is half an em. The modifiers are listed in Table 21.1.
Measurement Option |
Description |
i |
inch |
c |
centimeter |
p |
Pica |
m |
Em |
n |
En |
p |
point |
u |
unit |
v |
vertical space |
The default vertical spacing between lines of text is dependent on the text processor used. For nroff, it is 1/6 of an inch. For troff, it is 12 points. This can be changed with .vs. For nroff, the command argument is rounded to Picas, so if extra space
is needed
regularly, .ls is clearer. With troff, the default space measurement is points, although any measurement type can be used. An example of different spacings is given in Figure 21.7, using the initial text sample.
Figure 21.7. Different vertical spacing using troff.
The .ls request, mentioned previously, is used to indicate the number of blank lines between each line of text. The default value is 1, for single spacing. Double-spacing text is accomplished with .ls 2. Figure 21.8 shows the first text sample, but with
.ls 2.
Figure 21.8. Different line spacing using troff.
Block spacing can be achieved with the .sp request. With no arguments, this gives a single blank line. It can take arguments of any size, with the default unit being the vertical spacing. Negative numbers space back up the page; positive numbers head
down the page. Spacing changes requested here will not leave the pageif the requested space is beyond the bottom of the page, the text will start at the top of the next page. Using the sample letter, you can leave an inch of space between the date
and the salutation. The source is changed in Listing 21.4, with the output in Figure 21.9.
Figure 21.9. troff output with a block of space.
.nf 101 Main Street Morristown, NJ 07960 15 March, 1994 .sp 1i Dear Sir, .fi I just wanted to drop you a note to thank you for spending the time to give me a tour of your facilities. I found the experience both educational and enjoyable. I hope that we can work together to produce a product we can sell.
Another method to grab a block of vertical space is the .sv request. It takes the same arguments as .sp but has some different behaviors. You cannot request space at the top of a page with .sp, for example. Also, if a space request exceeds the size of
the page, it is truncated at the bottom of the page with .sp. With .sv, the space is not generated unless there is room on the page for the space. In this case, the space requested is remembered and can be released on a new page with .os. Normally, .os
appears only in complicated macro definitions, which are discussed later.
For the sample letter, save a half inch of space at the top of the page. The source is Listing 21.5, and the output is Figure 21.10.
Figure 21.10. troff output with requested space using .sv.
.sv 0.5i .nf 101 Main Street Morristown, NJ 07960 15 March, 1994 .sp 1i Dear Sir, .fi I just wanted to drop you a note to thank you for spending the time to give me a tour of your facilities. I found the experience both educational and enjoyable. I hope that we can work together to produce a product we can sell.
Two other spacing controls are also available. The request .ns turns off spacing mode, effectively disabling the .sp command. To restore spacing, .rs is used. These commands are more likely to be found in macros.
So far, I have examined troff requests to fill and adjust lines of text and to move your location on a page. I will now examine how to alter the line itself.
By default, the length of a line of text is 6.5 inches in nroff, and 7.54 inches in troff. This can be changed with the .ll request. The default space measurement is in ems, but I find using inches a bit easier. Listing 21.6 shows the source, changing
the line length to 4 inches; its effect on the output is shown in Figure 21.11.
Figure 21.11. troff output with line indents and lengths.
Lines of text can also be indented, both for a single line and for all text. The .in request indents all lines of text a common distance. This is illustrated by indenting the return address in Listing 21.6. A temporary indent can be requested with .ti,
such as might lead a paragraph. This is also illustrated in Listing 21.6 and Figure 21.11.
.nf .ll 4.0i .in 2.0i 101 Main Street Morristown, NJ 07960 15 March, 1994 .sp 1i .in 0 Dear Sir, .fi .ti 0.25i I just wanted to drop you a note to thank you for spending the time to give me a tour of your facilities. I found the experience both educational and enjoyable. I hope that we can work together to produce a product we can sell.
Using text indents can help organize a document.
So far, this chapter has examined how to format text independent of the page, but for most documents, page controls are necessary. Both nroff and troff default to an 11-inch page. troff has a one-inch left margin, and nroff has no left margin. Pages
start at page one and are sequentially numbered. Each of these details can be changed by the document writer.
The .pl request sets the length of a page; the default space measurement is in vertical spaces. Again, inches can be better used here. For the sample letter, assume a page length of 8 inches. (Some other normal page lengths are 12 inches for A4 paper
and 14 inches for legal-sized paper. troff can support pages up to 75 inches in length, and nroff up to 136 inches.)
You can force new pages with the .bp request. An argument can affect the number of pages output. The .ns request, mentioned earlier, disables the .bp request, unless a specific number of pages is requested.
The .pn request assigns a page number to the next page printed. This does not affect the present page, only subsequent pages. These three requests are illustrated in Listing 21.7 and Figure 21.12, an extended form of the letter.
Figure 21.12. troff output with page controls.
.nf .ll 5.0i .pl 8.0i .in 2.5i 101 Main Street Morristown, NJ 07960 15 March, 1994 .in 0 .sp 1i Dear Sir, .fi .ti 0.5i I just wanted to drop you a note to thank you for spending the time to give me a tour of your facilities. I found the experience both educational and enjoyable. I hope that we can work together to produce a product we can sell. .pn 4 I am sending a copy of our proposal on the next page. I look forward to hearing from you. .sp 2 .in 2.5i Yours, .sp 0.5i Joe Smith, President Any Corp. .bp .in 0 We propose to build our widget tools with your widget makers.
Note that the page number is not printed. Page numbers are printed only if explicitly requested by the programmer. These techniques are discussed later in this chapter in Section 21.19 "Flotsam and Jetsam," where I discuss page titling.
The text can be offset on the page using the .po request. This is different from the .in request. .po sets the 0 value for indents and temporary indents. This is illustrated in Figure 21.13, which has a page offset of two inches to the preamble of the
Constitution.
Figure 21.13. troff output with a two-inch page offset.
Two very powerful page controls are the .mk and the .rt requests. The .mk request saves the current vertical location in an internal register (which can be specified in the argument). This sets a flag at the current location. The .rt request returns to
that previous location. One good use for these requests is to establish multiple column output. The programmer can set the mark at the top of the page, and at the bottom of the page return to the mark. This is illustrated in Listing 21.8 and Figure 21.14.
Note that the simple multiple column approach also requires the use of the .ll and .po requests.
Figure 21.14. troff output showing the work of .mk and .rt.
.ll 3i .mk a .ce Preamble .sp We, the people of the United States, in order to form a more perfect Union, establish justice, insure domestic tranquility, provide for the common defense, promote the general welfare, and secure the blessing of liberty to ourselves and our posterity do ordain and establish this Constitution for the United States of America. .sp .ce Article I .sp Section 1 Legislative powers; in whom vested: .sp All legislative powers herein granted shall be vested in a Congress of the United States, which shall consist of a Senate and a House of Representatives. .sp Section 2 House of Representatives, how and by whom chosen, Qualifications of a Representative. Representatives and direct taxes, how apportioned. Enumeration. Vacancies to be filled. Power of choosing officers and of impeachment. .sp 1. The House of Representatives shall be composed of members chosen every second year by the people of the several states, and the electors in each State shall have the qualifications requisite for electors of the most numerous branch of the State Legislature. .sp 2. No person shall be a Representative who shall not have attained to the age of twenty-five years, and been seven years a citizen of the United States, and who shall not, when elected, be an inhabitant of that State in which he shall be chosen. .sp .rt .po 4.5i 3. Representatives and direct taxes shall be apportioned among the several States which maybe included within this Union, according to their respective numbers, which shall be determined by adding to the whole number of free persons, including those bound for service for a term of years, and excluding Indians not taxed, three-fifths of all other persons. The actual enumeration shall be made within three years after the first meeting of the Congress of the United States, and within every subsequent term of ten years, in such manner as they shall by law direct. The number of Representatives shall not exceed one for every thirty thousand, but each State shall have at least one Representative; and until such enumeration shall be made, the State of New Hampshire shall be entitled to choose three, Massachusetts eight, Rhode Island and Providence Plantations one, Connecticut five, New York six, New Jersey four, Pennsylvania eight, Delaware one, Maryland six, Virginia ten, North Carolina five, South Carolina five, and Georgia three. .sp 4. When vacancies happen in the representation from any State, the Executive Authority thereof shall issue writs of election to fill such vacancies. .sp 5. The House of Representatives shall choose their Speaker and other officers; and shall have the sole power of impeachment.
The last page control is .ne. This is used to indicate that a certain amount of space is needed before the end of a page. Using this request, you can avoid starting paragraphs at the bottom of a page. Normally, .ne would be included in a macro. If the
space requested is available, nothing happens. If the space is not available, the end of page processing is triggered.
The previous sections have dealt with the positioning of text on the page and have ignored the actual modification of the text itself. This section handles different fonts and point sizes.
The standard font is a Times Roman font. Italic, Bold, and Special fonts are also available on all systems. Some sites may also include Helvetica, Bold-Helvetica, Italic-Helvetica, and Constant-Width fonts. Check your local system for which fonts are
available.
The request .ft sets the appropriate font. Mounting and unmounting fonts is performed automatically with this request. The requested font must be specified in the argument; if no argument is present, the previous font is restored. The arguments are
shown in Table 21.2.
Identifier |
Font |
B |
Bold |
I |
Italic |
R |
Roman |
P |
Previous |
H |
Helvetica |
CW |
Constant Width |
HB |
Helvetica Bold |
HI |
Helvetica Italic |
Fonts have limited meaning in nroff. The font used is a constant-width font. By specifying bold, characters are overstruck in printing. Italic is interpreted as an underline. Other fonts have no meaning.
By setting fonts, you can italicize the preamble to the Constitution and print each section header in bold. The source is in Listing 21.9, and the output is in Figure 21.15.
Figure 21.15. troff output using multiple fonts.
.ce .ft B Preamble .sp .ft I We, the people of the United States, in order to form a more perfect Union, establish justice, insure domestic tranquility, provide for the common defense, promote the general welfare, and secure the blessing of liberty to ourselves and our posterity do ordain and establish this Constitution for the United States of America. .sp .ce .ft B Article I .sp .ft R Section 1 Legislative powers; in whom vested: .sp All legislative powers herein granted shall be vested in a Congress of the United States, which shall consist of a Senate and a House of Representatives.
The .bd request sets an artificial bold capability by offsetting a second printing of the character by a number of points. This can be used to make the italic font appear to be bold, with .bd I 3. There is no effect in nroff.
Different sizes of text can be created using the .ps request. You can specify either a relative change or an absolute point size. Closely related is the .ss request, which sets the width of the space character. Similarly, when the point size is changed,
the vertical spacing may also need to be changed, or parts of consecutive lines may overlap. Using these requests, you can increase the size of the section headers in the Constitution and increase the size of the words "We the people." This is
illustrated in Listing 21.10 and Figure 21.16.
Figure 21.16. Multiple point sizes in troff output.
.ce .ft B .ps 24 .ss 28 .vs 28 Preamble .sp .ft I We, the people .ps 12 .ss 14 .vs 14 of the United States, in order to form a more perfect Union, establish justice, insure domestic tranquility, provide for the common defense, promote the general welfare, and secure the blessing of liberty to ourselves and our posterity do ordain and establish this Constitution for the United States of America. .sp .ce .ft B Article I .sp .ft R Section 1 Legislative powers; in whom vested: .sp All legislative powers herein granted shall be vested in a Congress of the United States, which shall consist of a Senate and a House of Representatives.
The last text request is .cs, which sets a constant character width for a given font in troff. This takes three arguments. The first is a font, the second is the width of the space, and the last is the character point size. If the third argument is
absent, the default is the current character width. If the second argument is also absent, that turns off the constant width.
Listing 21.11 shows this for the default Times Roman font in the preamble, and turns it off for the remainder of the Constitution. Figure 21.17 shows the output.
Figure 21.17. troff output using .cs.
.ce .ft B .ps 24 .ss 28 .vs 28 Preamble .sp .ft I We, the people .ps 12 .ss 14 .vs 14 .ft R .cs R 15 of the United States, in order to form a more perfect Union, establish justice, insure domestic tranquility, provide for the common defense, promote the general welfare, and secure the blessing of liberty to ourselves and our posterity do ordain and establish this Constitution for the United States of America. .sp .cs R .ce .ft B Article I .sp .ft R Section 1 Legislative powers; in whom vested: .sp All legislative powers herein granted shall be vested in a Congress of the United States, which shall consist of a Senate and a House of Representatives.
Fonts can also be specified by positionfont 1, font 2, font 3, and so on. In the olden days of troff, before device-independent troff (ditroff), only four positions were available. Quite naturally, 1 was the body type (Times Roman), 2 was the
italic version of 1, and 3 was the bold version of 1. You got one electiveposition 4but it was almost always used for the Special font (the one with Greek letters and mathematical symbols). As a consequence, specifying fonts by position is not
done frequently.
The following examples all change the word "very" to italics (in nroff, the words are underlined):
This is \f2very\fP easy. This is .fp 2 very .fp 1 easy.
Notice that in the first line, \fP is used to turn off italics. The P stands for Previous and resets the font to what it was before the italic font was requested (in this case, Times Roman). The second example resets the font to Times Roman by
specifying its font
position.
You can count on finding your default body type in position 1, italics in 2, and bold in 3. Beyond that, you have no idea. It depends on your system installation, and they're all different.
The basics of document building are now passed. All the requests I have examined have been of the form .xx and stand alone on each line. Although any document can be produced using these requests, an in-line request may be easier to use in many cases.
These can generate special characters, change fonts, change point sizes, and produce local motions.
Escape sequences (backslash-character or backslash-open-parenthesis-character-character) can be used to change fonts and point size and for many other tasks. Table 21.3 lists troff escape sequences.
Sequence |
Description |
\ |
Prevents the next character from being processed by troff |
\e |
Prints the escape character; default is the backslash (\) |
\' |
Prints acute accent |
\' |
Prints grave accent |
\- |
Prints a minus sign in the current font |
\[space] |
Creates an unpaddable 1-en space |
\0 |
Prints a space the width of a digit |
\| |
Prints a 1/6-em width space |
\^ |
Prints a 1/12-em width space |
\& |
Nonprinting zero-width character |
\! |
Transparent line indicator |
\" |
Begins a comment |
\\$n |
Interpolates argument |
\% |
Before word, prevents hyphenation; in middle of word, indicates where word can be hyphenated |
\(xx |
Specifies character named xx |
\\*x , \*(xx |
Specifies string named x or xx |
\a |
Specifies leader character used in macros |
\b'abc...' |
Bracket-building function |
\c |
Interrupts text processing |
\d |
Moves down half a line space |
\D |
Draws line, circle, ellipse, arc, or spline |
\fx, \f(xx, \fn |
Requests a font change; font with 1-character name is specified as \fH; font with 2-character name is specified as \f(HB. |
\h'n' |
Moves horizontally to the right; to move left, specify negative number |
\H'n' |
Sets character height to n points |
\jx |
Marks horizontal place on output line in register x |
\kx |
Marks horizontal place on input line in register x |
\l |
Draws horizontal line |
\L |
Draws vertical line |
\nx, \n(xx |
Interpolates number register x or xx |
\o |
Overstrikes specified characters |
\p |
Breaks output line |
\r |
Reverse 1-em vertical motion |
\s |
Requests a change in point size; can be specified as an absolute value or with ± |
\S'n' |
Slants output n degrees to the right |
\t |
Horizontal tab |
\u |
Moves up half a line space |
\v'n' |
Moves vertically down; to move up the page, specify negative number |
\w |
Interpolates width of specified string |
\x |
Extra line-space function |
\zc |
Prints c with zero width (without spacing) |
\{ |
Begins conditional input |
\} |
Ends conditional input |
\[newline] |
Concealed (ignored) newline |
\X |
X, any character not listed above |
Listing 21.12 shows troff input with in-line font and size changes, and Figure 21.18 shows the output.
Figure 21.18. troff output with in-line font changes.
\fB\s+4We, the people\s-4\fP of the United States, in order to form a more perfect Union, establish justice, insure domestic tranquility, provide for the common defense, promote the general welfare, and secure the blessing of liberty to ourselves and our posterity do ordain and establish this Constitution for the United States of America.
Two other in-line escapes are \& and \p. The \& escape is a zero-length control character and can be used to enable the printing of a control character (.) at the start of a line. The \p escape generates a break, but also requests that the line
be spread to the current input line length.
Similarly, if a word requires extra vertical space, the in-line escape \x is used to request the additional vertical space. The amount of space needed must be enclosed in single quotes.
The next in-line escape deals with unfilled text only. If a line of unfilled text is terminated with a \c, the next text present will be treated as a continuation of that line. This allows the document writer to include a sequence of requests in the
middle of a line, even if those requests do not have associated in-line escapes. The .cs request is an example of a case where \c may be used.
Fonts may be changed in-line by using the \f escape. Single character font identifiers can be designated with \fB, but two-character identifiers need a ( to group the letters. An example would be \f(HI for a change to Helvetica-Italic. Point sizes can
similarly be changed with \s. Here, two-digit fonts are acceptable. Relative changes can be made, too. Figure 21.18 shows a case where the words "We the people" are bold and four points larger than surrounding text.
Although special characters are system-dependent, there are several special characters that you can expect to have in your system. Table 21.4 lists these.
ASCII is limited to a small number of printable characters; fortunately, troff provides access to many more characters and symbols needed for mathematics and other applications. A few are escape sequences, but most are two-character escapes. Several
two-character printing symbols are available, some on the default font, and some on a special font. These include Greek characters, mathematical characters, and editing symbols. An example of this is the mathematical expressions in Listing 21.13 and Figure
21.19.
Figure 21.19. troff output of special characters.
2\(*pr \(issin\(*td\(*t\(eqcos\(*t \(*S(\(*a\(mu\(*b)\(->\(if
Other characters that can come in handy are bullets, \(bu, the symbol, \(co, and daggers, \(dg. Four characters have their own commands. To print a backslash, use \\. A minus sign is \-, an open quote is \', and a close quote is \'.
Table 21.4 list the special characters typically available for the standard fonts.
In-line Request |
Character Produced |
\\ |
backslash |
\' |
close quote |
\' |
open quote |
- |
hyphen |
\- |
current font minus sign |
\(bu |
bullet |
\(co | |
\(ct |
cent sign |
\(de |
degree |
\(dg |
dagger |
\(em |
3/4 em dash |
\(ff |
ff ligature |
\(fi |
fi ligature |
\(Fi |
ffi ligature |
\(fl |
fl ligature |
\(Fl |
ffl ligature |
\(fm |
foot mark |
\(hy |
hyphen |
\(rg |
registered trademark |
\(ru |
rule |
\(sq |
square |
\(14 |
1/4 |
\(12 |
1/2 |
\(34 |
3/4 |
troff and nroff provide the ability to specify strings that can be used repeatedly. The strings can be given one- or two-character identifiers, and those identifiers can be referenced later. Strings can be defined with the .ds request. The next argument
must be the identifier, and the string that follows is assigned to the identifier. The .as request appends additional text to the string. Accessing the string is accomplished with the in-line escape \*. Our Constitution provides an example in Listing 21.14
and Figure 21.20.
Figure 21.20. troff output with a defined string.
.ce .ds us United States Preamble .sp We, the people of the \*(us, in order to form a more perfect Union, establish justice, insure domestic tranquility, provide for the common defense, promote the general welfare, and secure the blessing of liberty to ourselves and our posterity do ordain and establish this Constitution for the \*(us of America. .sp .ce Article I .sp Section 1 Legislative powers; in whom vested: .sp All legislative powers herein granted shall be vested in a Congress of the \*(us, which shall consist of a Senate and a House of Representatives.
Macros provide a technique for the document writer to group repeated requests into a single troff request. If the document writer notices that groups of requests are being repeated, those are ideal candidates for making a macro. Examples include
quotations, paragraphs, and section headers. Chapter 26 goes into greater detail on macro writing; however, I will show you the basics here.
Macros are defined with the .de request. A one- or two-character label should follow the request. By convention, macro names are often uppercase, although this is not a requirement. The troff requests then follow the .de until the .. request is present.
These requests are then executed whenever the macro is called. You call the macro by starting the line with a . followed by the macro name, without a space.
Macros can be designed to take arguments. Up to nine arguments can be passed to a macro and are accessed as \$N, where N is the argument position from 1 to 9. These can be treated as ordinary variables and can be used anywhere in the macro. When a macro
is defined, the contents of the commands are interpreted. This means that the presence of strings, variables, and comments are translated when the macro is read. To insure that the argument is not interpreted until the macro is used, the argument should be
listed in the definition as \\$N. The \\ will be interpreted as \. This \\ can be used whenever the writer wants the escape to be interpreted when the macro is invoked.
Two examples are illustrated in Listing 21.15 and Figure 21.21. The first macro defined, PP, is used to signal a new paragraph. You first request a space, then you temporarily indent the first line by a quarter-inch. You also insure that the font is
Times Roman. The second macro defined is for a header, HD. Give it two arguments: the first is the point size desired for the header and the second is the text of the header. First request a space, then change the point size to the requested size. Next,
request that the text be centered and made bold. Then issue the text, reset the point size and font, and request an additional space.
Figure 21.21. troff output with a defined macro.
.de PP .sp .ti +0.25i .ft R .. .de HD .sp .ps \\$1 .ce .ft B \\$2 .ps .ft P .sp .. .HD 14 "A sample header" .PP We begin the text of the first paragraph here. This is indented and formatted. We continue with the text of the first paragraph until we want the second paragraph. .PP We re-issue the macro, and get the space and indent.
Macros can be changed after creation using the .am request. This appends troff requests to the already existing macro, given in the first argument. In the preceding example, assume you wanted the second and subsequent paragraphs to have a point size of
ten for the text. You could do this by including the following commands after the first call to PP:
.am PP .ss 10 ..
You could have redefined the macro with .de, but the .am request is quicker. You can also rename macros with .rn. This can be used even with standard troff requests and strings. The original name is the first argument, and the new name is the second
argument. The old name is not retained.
Lastly, macros, strings, and other requests can be removed with .rm. Any subsequent commands to the macro will be ignored.
troff provides number registers for the tracking of parameters for troff. These can be accessed with the escape sequence \n. For single character names, like x, use \nx. For multiple character names, like xx, use \n(xx. Number registers are used for
items such as page numbers and line length. The predefined registers include % for page number, dw for the day of the week, dy for the day, mo for the month, and yr for the year. nl also shows the position of the last printed line. Listing 21.16 shows how
some of these registers can be used. Figure 21.22 is the output.
Figure 21.22. troff number registers in output.
.nf .ll 5.0i .in 2.5i 101 Main Street Morristown, NJ 07960 \n(mo/\n(dy/\n(yr .in 0 .sp Dear Sir,
Many read-only registers contain configuration parameters. Some of these are listed in Table 21.5.
Register |
Description |
.$ |
Number of arguments to a macro |
.A |
Set to 1 if -a is used on troff command line; always 1 for nroff |
.T |
Set to 1 if -T is used on nroff command line; always 1 for troff |
.a |
Value of extra space most recently used |
.c |
Number of lines read from current input file |
.f |
Current font |
.h |
Text high water mark for current page |
.i |
Current indent |
.l |
Current line length |
.n |
Length of text on previous output line |
.o |
Current page offset |
.p |
Current page length |
.s |
Current point size |
.u |
Fill more flag (1 for on, 0 for off) |
.v |
Current vertical line spacing |
A short script to list default values is shown in Listing 21.17, with Figure 21.23 showing the output.
Figure 21.23. troff output with register values.
.nf The current font is \n(.f The current point size is \n(.s The line length is \n(.l The page length is \n(.p The page offset is \n(.o
Of course, these registers are useful; however, the real benefit of registers comes from the user's ability to define their own registers. These can be used to track headers, paragraph numbers, and section numbers. The .nr request initializes and
modifies user-specified registers. It takes two or three arguments: the first is the register name, and the second is the register modification. When first created, a register is assigned the value of zero. A positive number is added to the value; a
negative number is subtracted. An optional third argument sets a default increment and decrement value. The automatic increment can be used in escape sequences: \n+(xx adds the increment to register xx, and \n-(xx subtracts the decrement.
The appearance of the number is set with the .af request. The first argument is the register, the second is one of six formats. 1 is for an Arabic number sequence, 001 is for a zero-filled Arabic number sequence. i and I are for Times Roman numbers,
upper- and lowercase, and a and A are for alphabetic sequences.
Lastly, the .rr request removes a number register. There are a limited number of registers available, identified by the read-only register .R. The document writer may need to remove registers if space becomes a problem.
Listing 21.18 illustrates the source of a macro that numbers sections of the Constitution. The output is in Figure 21.24. The section header macros are for Articles, sections, and paragraphs of the constitution. First define the aR number register to
count the articles, and set its display format to Times Roman numerals. You first define the AR macro. It centers a 16-point bold text, with the word "Article" and the number register. Note that you increment the number register every time you
print the value. You also set the sE number register to zero, as an Arabic number. You then reset the point size and font. The SE macro is similar, printing the section and number, and setting pP to zero. The PP macro increments pP.
Figure 21.24. troff output with number registers.
.ce Preamble .sp We, the people of the United States, in order to form a more perfect Union, establish justice, insure domestic tranquility, provide for the common defense, promote the general welfare, and secure the blessing of liberty to ourselves and our posterity do ordain and establish this Constitution for the United States of America. .sp .nr aR 0 1 .af aR I .de AR .ce .ps 16 .ft B Article \\n+(aR .nr sE 0 1 .af sE 1 .ps 12 .ft P .. .de SE .sp .ft B \\s-2SECTION \\n+(sE:\\s+2 .ft P .nr pP 0 1 .af pP 1 .. .de PP .sp .ft I \\s-3Paragraph \\n+(pP:\\s+3 .ft P .. .AR .SE Legislative powers; in whom vested: .PP All legislative powers herein granted shall be vested in a Congress of the United States, which shall consist of a Senate and a House of Representatives. .SE House of Representatives, how and by whom chosen, Qualifications of a Representative. Representatives and direct taxes, how apportioned. Enumeration. Vacancies to be filled. Power of choosing officers and of impeachment. .PP The House of Representatives shall be composed of members chosen every second year by the people of the several states, and the electors in each State shall have the qualifications requisite for electors of the most numerous branch of the State Legislature. .PP No person shall be a Representative who shall not have attained to the age of twenty-five years, and been seven years a citizen of the United States, and who shall not, when elected, be an inhabitant of that State in which he shall be chosen. .PP Representatives and direct taxes shall be apportioned among the several States which maybe included within this Union, according to their respective numbers, which shall be determined by adding to the whole number of free persons, including those bound for service for a term of years, and excluding Indians not taxed, three-fifths of all other persons. The actual enumeration shall be made within three years after the first meeting of the Congress of the United States, and within every subsequent term of ten years, in such manner as they shall by law direct. The number of Representatives shall not exceed one for every thirty thousand, but each State shall have at least one Representative; and until such enumeration shall be made, the State of New Hampshire shall be entitled to choose three, Massachusetts eight, Rhode Island and Providence Plantations one, Connecticut five, New York six, New Jersey four, Pennsylvania eight, Delaware one, Maryland six, Virginia ten, North Carolina five, South Carolina five, and Georgia three. .PP When vacancies happen in the representation from any State, the Executive Authority thereof shall issue writs of election to fill such vacancies. .PP The House of Representatives shall choose their Speaker and other officers; and shall have the sole power of impeachment.
So far, I have examined the results of invoking troff requests where you place them in your document. These are not the only examples of executing troff requests. You can specify macros to be executed at any given physical position on a document. These
are called traps, and they can be triggered by page position, diversions, and input line count. A common use for page traps is to place headers or footers on pages. Diversion traps can be used to create footnotes in text, or to create a reference list for
the end of a chapter. Input line traps count the number of lines since the request. These are useful for when macros are meant to be a single line.
Diversions are used to direct output to a macro, instead of to the page. The diversion requests are usually in macros, and traps must be set to produce the diversion output. Diversions are created with the .di request, the call followed by the name of
the diversion macro. If no argument is present, the diversion ends, and output resumes on the page. Text can be added to the diversion with the .da request. Diversions can also be requested by page position with .dt, followed by the position and diversion
macro name.
Traps are set with the .wh request. This is followed by a position and a macro name. If a macro had previously been set at that position, then that trap is removed. If no macro is passed as an argument, then any traps at that position are removed. The
position of a macro trap can be changed with the .ch request, followed by the macro name and position. If a position is missing, the macro is removed. Input traps are set with the .it request, followed by a text position and macro name. Finally, a trailing
macro can be set with .em. This sets a macro to be run at the end of input.
The use of diversions and traps is illustrated in Chapter 26, "Writing Your Own Macros."
Tabs and tab spacing can be set by the document writer in troff. This gives the writer the ability to create simple tables by lining up columns and using tabs. The .ta request sets the tab stops, and if a stop value is preceded by a +, then the stop is
relative to the previous tab stop. The tab repetition character (the character that fills the space between text and tab stops) can be specified with the .tc request. The nature of the tab stop can also be specified right after the tab stop distance. The
text left-adjusts within the tab space by default. To center the text, use a C after the distance (no space), and use an R to right-adjust.
A simple table is illustrated in Listing 21.19, with the output in Figure 21.25.
Figure 21.25. A formatted table with tabs.
.nf .ta 3i 4.5i Name Birthday Telephone John Smith 1/1/70 (410) 555-1111 Dave Jones 2/2/63 (311) 800-0000 .tc - Bob Williams 3/3/56 (999) 555-2222
Some characters are considered control characters. These are the . used to signal a troff request, \ to indicate an in-line escape, and ' to indicate a breakless command. The escape character can be reset with the .ec request and can be turned off with
the .eo request. .ec takes an argument, which is the new escape character. If no argument is present, it returns to the default. The .cc request changes the basic control character, ., to whatever is specified. This is particularly useful if a writer
wishes to show a sample of troff input in a document, as shown in Listing 21.20 and Figure 21.26. Finally, .c2 changes the no-break control character from ' to the specified argument.
Figure 21.26. troff output with character translations.
Underlining in nroff and italics in troff can also be invoked with the .ul and .cu requests. This turns on underline mode. In troff, the two requests have an identical effect; in nroff, .cu is for continuous underlining, and .ul underlines characters.
The underlining font can be changed with the .uf request.
Character translations are also possible with troff. The .tr request is analogous to the tr UNIX command. Instead of two groups of characters, though, the from-to pairs of characters are side by side in a single character string argument. This is also
illustrated in Listing 21.20 and Figure 21.26.
.nf A sample of troff input: .sp .cc , .de PP .br .sp .it +0.5i .. ,sp ,cc And another sample: .tr ,. .sp ,de PP ,br ,sp ,it +0.5i ,,
Input can be made transparent to troff by prepending the input line with \!. This can be used to pass information to a post processor. Comments can also be embedded in the troff source document with \. This must come after the requests. It can appear at
the start of a line if prepended with the control character.
Besides the .sp and related requests, there are in-line techniques to move the current output location in troff. These are called local motions and can be vertical or horizontal.
There are four types of vertical motions. All are in-line escapes. The first, \r, moves up single line. \d is used to move down half a line, for subscripts, and \u is used to move up half a line, for superscripts. Finally, \v'N' is used to make a local
motion of vertical distance N. A negative number moves up the page, and a positive number moves down the page. You cannot leave the page with a local motion. An example is in Listing 21.21, with output in Figure 21.27.
Figure 21.27. troff output with local motions.
There are five types of horizontal motions. Two simple space functions are \ , which is an unpadded space-sized space (as defined by .ss). The \0 request is a digit-sized space. \| produces one-sixth of a character width, and \^ produces one-twelfth.
Finally, generic local motion is produced by \h'N'. The rules for vertical motions also apply to horizontal motions.
Jan 26\u\s-2th\s+2\d is a sample. .sp 2 We can move up \r easily. .sp 2 Here is some space \0\0\0for us.
The width of a string can be determined with the \w escape. The string follows in single quotes. This width can be used in local motions and for other times when space measures are needed. Listing 21.22 illustrates how you can use this to place
paragraph numbers outside the left margin of some text.
You can also mark the horizontal space with the \k request. Listing 21.22 also shows a primitive use of this to embolden a word, and Figure 21.28 shows its output.
Figure 21.28. troff output with local motions and width calculations.
.sp 0.5i .in 1i .ti -\w'1.\0'u 1.\0This is a paragraph with a number indented out the \kxleft\h'|\nxu+2u'left margin. We continue with the text to prove the indent.
Characters can be overstruck with the \o escape. Up to nine characters can be overstruck, each appearing in the string following the escape.
Both vertical and horizontal lines can be drawn in troff. These are done by escape sequences \l, \L, and \D. The first draws a line of length specified in quotes after the escape. An optional character after the length can be used, and that will be used
instead of the line. The second escape draws a horizontal line. The \D escape is the drawing escape, and it draws lines, circles, ellipses, and arcs. The specific format is the first character, followed by one to four arguments. These escapes are generated
by calls to preprocessors like pic, described in Chapter 25, "Drawing Pictures with pic."
A line is drawn with two arguments, and the line is drawn from the present location to the specified location. The first character argument is l.
A circle of a fixed diameter is drawn with c. The single argument is the diameter.
An ellipse is drawn with e, and the two arguments are the two diameters of the ellipse.
An arc is drawn with a. There are four arguments, in two pairs. The arc is drawn from the present position to the first argument, assuming that the second argument is the center of the circle.
A spline can be drawn with the character ~. This can take an unlimited group of pairings, drawing the spline from the current position through the pairs of points.
Like a programming language, troff and nroff provide for a conditional execution of requests. There are two forms of the if request: .if followed by a condition and then requests, and an if-else construct, .ie and .el. There are six conditional formats,
and there is a format for grouping requests after an if: \{-requests-\}.
The six conditional forms are shown in the following.
.if c |
.if !N |
.if !c |
.if 'string1'string2' |
.if N |
.if !'string1'string2' |
In each of the six conditional forms, the ! represents the negation of the basic form. In the first two cases, c represents one of four special condition flags: o for an odd-numbered page, e for an even-numbered page, t for troff, and n for nroff. The
middle two cases are for a numerical value N. The third case is for N>0, and the fourth case is for N<=0. In the last two cases, the strings are compared: if they are identical, the fifth is true; if not, the sixth is true.
if requests are rarely included in a normal document but are essential tools of macro writers. Macro writing is explored in greater depth in Chapter 26. Despite this, there are occasional circumstances where you might use the conditional. Listing 21.23
and Figure 21.30 show a simple case.
Figure 21.29. troff conditional output.
This text is formatted with the .if n nroff .if t troff text processor.
These text processors also provide the ability to change input files, and to modify output files. There are three ways to modify input.
Input can be requested with the .rd request. A prompt can be provided as an argument, and the input is read from the terminal until two consecutive newlines are input. This is often used for insertion into form letter type documents.
An entire file can be interpreted with the .so command. If a document writer has created his own macro set, he may wish to keep this in a separate file and include that file in subsequent documentation using this request. Once the file has been read and
interpreted, the text processor continues to read from the current file.
The .nx request is similar to the .so request, except that when the file is completed, the text processor is considered to have finished its input.
An example of these three requests is shown in Listing 21.24. Listing 21.25 shows the contents of the header file, which defines a few macros. Listing 21.26 shows the terminal session.
.so headers .in 3i .nf 1 Main Street Myhometown, ST 98765 \n(mo/\n(dy/\n(yr .sp 2 .in 0 .rd Please_enter_the_company_address .sp Dear Sir, .PP I read your add in the \fISan Jose Mercury News\fP advertising positions with .rd Please_enter_the_company_name for software engineers. I'd like to express my interest in a position. My resume is enclosed. .sp .in 3i Yours sincerely, .sp 3 Joe Smith .in 0 .bp .nx resume
.de PP .sp .ti +0.5i .fi .ad b ..
$ troff -t fig21.58src Please_enter_the_company_address:The Fixture Company 1001 Main Street Anytown, USA 77777 Please_enter_the_company_name:The Fixture Company $
Note that the .rd request needed the underbars between words. The space would normally end the argument, even with surrounding double quotes. Also, note that the text read in is processed based on the fill and adjustment settings.
A fourth type of file input is .cf. This copies a file directly onto the output, without interpolation.
Output from nroff and troff can be piped automatically through a program. The .pi request must be placed before any output is generated, and it can receive no arguments.
The current settings for troff are considered the troff environment. These settings include indentation, page length, line length, fonts, and other values that describe the page. There are occasions when this environment may need to be saved. Three
environments are allowed, and the specific environment can be set with the .ev request. The environments are numbered 0, 1, and 2. Environments are usually included in macro calls that include diversions, such as for footnotes.
Two other controls are for aborts and exits. The .ex request terminates input processing as if the file were complete. This is often used for debugging macros. The .ab request aborts all processing. Any arguments are printed on the diagnostic output,
usually the terminal, and the program exits without terminal processing.
A last control is for system calls. The .sy request executes a UNIX command. The output is not captured anywhere, and there is no input.
There are a few requests I have not covered, which do not conveniently fit into any of the previous categories. These include hyphenation requests, three-part titles, and line numbering.
Four requests affect word hyphenation. The .nh request turns off all hyphenation, except for input with hyphens, such as "sister-in-law." The .hy request provides a greater control over hyphenation. It accepts a numeric argument. If 0,
hyphenation is turned off. If 2, lines that will trigger a trap are not hyphenated. If 4, the first two characters of a word are not split off, and if 8, the last two are not split off. The values can be added to create a single hyphenation request. The
.hw request enables the writer to specify hyphenation points within words, by using an embedded minus sign. An example might be .hw fish-head. The buffer for these words is only 128 characters in length.
Lastly, word hyphenation can be specified with an embedded character with a word. By default, this is \%, although the character can be changed with the .hc request.
A three-part title can be specified with the .tl request. This takes three strings as arguments, separated by a single quote and surrounded by single quotes: .tl 'left'center'right'. Any string can be empty. The title length is set with .lt and is
separate from the .ll request. The page character, initially %, can be changed with .pc.
Output lines can be numbered with the .nm request. It takes up to four arguments: a start number, a multiplier, a spacing value, and an indent value. If a multiplier is present, only those lines that are even multiples will have numbers attached. The
.nn request is used to ignore a number of lines for line numbering.
A margin character can be specified for the right margin using the .mc request. It takes two arguments: the margin character and a distance to the right for the character. This is often used to highlight changed sections of text between document
revisions.
The .tm request is used to print a line to the invoking terminal.
The .ig request ignores all subsequent lines until the terminating request is issued, usually ...
The .pm request prints all the macros defined, and their associated sizes. The sizes are in 128-character blocks.
The .fl request flushes the output buffer.
The .lf request sets the current line number and file name.
Character heights can be changed in troff using the \H'n' in-line request. This can result in a disproportionate font. The value n is the point size height of the text.
Also illustrated is the ability to put the text at a slant, using the \S'n' request. The value n is the degree of slant.
Table 21.6 presents all the nroff/troff requests along with their syntax. Arguments not in brackets are arguments that you must specify for the request. Arguments in brackets are optional arguments that you can specify for the request. Italicized
arguments indicate that you need to substitute something specific; for example, .so file means that you need to provide a real filename as an argument to the .so request.
Request |
Description |
.ab [text] |
Abort and print message |
.ad [c] |
Adjust text margins |
.af r c |
Assign format c to register r |
.am xx yy |
Append following commands to macro xx, terminated with yy |
.as xx string |
Append string to defined string xx |
.bd f n |
Embolden font fwith ^ overstrikes |
.bd f s n |
Embolden special font when current font is s, with ^ overstrikes |
.bp [n] |
Begin a page and set page number to n |
.br |
Breakstop filling text |
.c2 c |
Set no break control character |
.cc c |
Set control character |
.cf filename |
Copy file |
.ce [n] |
Center text |
.ch xx [n] |
Change trap position for macro xx to n |
.cs f n m |
Use constant character spacing for font f |
.cu [n] |
Constant underlining |
.da [xx] |
Direct and append text to macro xx |
.de xx [yy] |
Define macro |
.di [xx] |
Direct text to macro xx |
.ds xx string |
Define string |
.dt n xx |
Install division trap |
.ec [c] |
Set escape character |
.el action |
Else portion of if-else |
.em xx |
Set macro to run at the end of the document |
.eo |
Turn off in-line escapes |
.ev [n] |
Change environment to n or restore environment |
.ex |
Exit formatter |
.fc a b |
Set field character and padding character |
.fi |
Fill text |
.fl |
Flush output buffer |
.fp n f |
Change font positions |
.ft f |
Change font in output |
.hc [c] |
Set hyphenation character |
.hw words |
Set hyphenation exception list |
.hy n |
Set hyphenation mode |
.ie c action |
If else |
.if c action |
If c is true, perform action |
.if !c action |
If condition is false, perform action |
.if n action |
If n>0, perform action |
.if !n action |
If n>=0, perform action |
.if !'string1'string2' action |
If strings are equal, perform action |
.if !'string1'string2' action |
If strings are different, perform action |
.ig yy |
Ignore subsequent text to yy |
.in ±[n] |
Set indent |
.it n xx |
Set input trap |
.lc c |
Set leader repetition character |
.lg n |
Set ligature mode |
.ll ±[n] |
Set line length |
.ls n |
Set line spacing |
.lt n |
Set title length |
.mc [c] [m] |
Set margin character |
.mk [r] |
Mark vertical place in register |
.na |
Do not adjust text |
.ne n |
If n lines do not remain on the page, get a new |
page | |
.nf |
Turn off filling |
.nh |
Turn off hyphenation |
.nm [n m s i] |
Number output lines |
.nn n |
Disable numbering output but track line numbers |
.nr r n [m] |
Assign number register |
.ns |
Turn on no-space mode |
.nx file |
Go to the next file |
.os |
Output saved space |
.pc c |
Set page number character |
.pi command |
Pipe output of troff to command |
.pl ±[n] |
Set page length |
.pm |
Print names and sizes of macros |
.pn ±[n] |
Set next page number |
.po ±[n] |
Set page offset |
.ps n |
Set font point size |
.rd [prompt] |
Read input from #y |
.rm xx |
Remove macro or string |
.rn xx yy |
Rename macro, request, or string |
.rr r |
Remove register |
.rs xx yy |
Restore spacing |
.rt ±[n] |
Return back to marked place |
.so file |
Include file |
.sp n |
Leave n blank lines |
.ss n |
Set character size |
.sv n |
Save n lines of space |
.sy command [arguments] |
Execute command |
.ta n[t] m[t] |
Set tab stops |
.tc c |
Set tab character |
.ti ±[n] |
Set temporary indent |
.tl 'l'c'r' |
Three part title |
.tm message |
Display message on terminal |
.tr ab |
Translate characters |
.uf f |
Set underline font |
.ul [n] |
Underline lines |
.vs [n] |
Set vertical space |
.wh n xx |
Set trap locations |
The essentials of troff allow a user to format a document. The real value of troff, though, comes when incorporated with a standard macro package, such as ms or me, which are described in the next chapter.