Полезная информация



TOC
BACK
FORWARD
HOME

UNIX Unleashed, Internet Edition

- 11 -

Tools for Writers

By David B. Horvath, CCP and Susan Peppard

The preceding chapters in this section described the heart of text formatting and printing (processing)--nroff, troff, and related macros. In this chapter, I show you many of the commands that UNIX provides to support writers.

These commands are as follow:

  • tbl: Formatting tables
  • eqn/neqn: Formatting equations for troff/nroff
  • pic: Drawing pictures
  • grap: Creating graphs
  • cw: Formatting programs in a fixed font
  • refer: Building literature references
  • ptx and mptx: Building permutated indexes
  • spell and ispell: Checking for spelling mistakes
  • diction, explain, and style: Checking grammar
  • grep: Searching for text
  • sed: Global editing of text
  • diffmk: Marking changed text'
  • man: Getting more information
  • SCCS: Controlling document source
  • deroff: Removing troff requests from text

Not all these commands are available with all versions of UNIX. When you're in doubt, check the man page or contact your system administrator.

Preprocessors for nroff and troff

A number of the tools for writers are actually preprocessors. You describe the object you are building using the language specific to that tool. The tool takes your input and creates output that nroff or troff can process. These tools evolved because the syntax of nroff and troff can be so complicated.

These preprocessors are as follow:

  • tbl: Formatting tables
  • eqn/neqn: Formatting equations for troff/nroff
  • pic: Drawing pictures
  • grap: Creating graphs
  • cw: Formatting programs in a fixed font
  • refer: Building literature references
  • ptx and mptx: Building permutated indexes

Formatting Tables with tbl

tbl is a troff preprocessor used to create tables (columns of data with headings). The code you write is processed by tbl before the file is processed by troff. Often, you pipe the tbl output of a file into troff as follows:

tbl filename | troff -options

tbl takes as input the commands between each .TS/.TE macro pair and converts the input into a printable table. All other input is passed through without modification.

The general format of a table is as follows (don't try to process this through tbl):

.TS H
global option;
formatting options 1
formatting options 2.
Column 1 title [tab] column 2 title [tab] column 3 title
.TH
Col 1 Item 1 [tab] Col 2 Item 1 [tab] Col 3 Item 1
Col 1 Item 2 [tab] Col 2 Item 2 [tab] Col 3 Item 2
.TE

You use the H option on .TS when the table might cross page boundaries, and you want the column titles to print on each page. You place the .TH macro after the column titles to separate them from the actual data values. If the table will definitely fit on one page, you can omit the H option on .TS and the .TH.

The global option; can be any one of the values shown in Table 11.1. Note that the ; line terminator is required. The default, with no global option; specified, is to create the table flush with the left margin.

Table 11.1. tbl global options.

Option Description
allbox Puts each table item in a box (grid)
box Draws a box around the table
center Centers the table on the current page
delim(xy) Changes eqn/neqn delimiters to x and y
doublebox Draws a double box (created with two lines)
expand Expands the table to the full page width
linesize(n) Changes the line point size to n
tab(x) Changes the column separator to x

You must have at least one line of formatting options (which apply to the entire table). If you specify multiple lines of formatting options, the first applies to the column headers, and the last lines apply to the table items themselves. You can have multiple lines of column headings and multiple lines of column formatting options. The period . at the end of the last line of formatting options is required. Table 11.2 shows the available formatting options; note that they are not case sensitive. You should have one option per column.

Table 11.2. tbl formatting options.

Option Description
^ Spans column vertically
| Separates columns with single vertical line
|| Separates columns with double vertical line
a Indicates an alphabetic column (indent one em)
b Changes to bold font
c Centers the column
e Equalizes width of columns
fF Changes font to F
i Changes to italic font
l Left-justifies column
n Indicates a numeric column (aligns on decimal point)
N Spaces between columns in ens (default is 3)
pN Change font point size to N
r Right-justifies column
s Spans column horizontally
vN Changes vertical spacing to N
w(N) Specifies column width to N


TIP: The a option does not work properly in older versions of tbl. Use \0\0 instead.


NOTE: Be sure to specify a unit with the w (width) option. The default unit is ens. The width you specify does not include the gap between columns.


NOTE: 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.

You also can use another tbl macro for formatting columns: .T&. You use it when you want to change the column format at a later time.

The columns are separated through the use of the [tab] character. You can change this character by using the tab(x) global option.

To print a horizontal line at any time, use the underscore character _ on a line by itself. Underscores separated by the current tab character cause a single line to be drawn under that column. You can use the equal sign (=) in place of the underscore (_) to draw a double line across the line or column. You can use them in the column heading or data areas.

Listing 11.1 shows the tbl source of a simple table. Figure 11.1 shows the resulting table.

Figure 11.1.
tbl output: Simple table.

Listing 11.1. tbl source: Simple table.

.sp 3i
.TS H
box tab(@);
c s s
c c c
l l n.
State Statistics
State@Capital@Population
_
.TH
Missouri@Jefferson City@5,192,632
Montana@Helena@823,697
_
Nebraska@Lincoln@1,605,603
=@@=
.TE

In Listing 11.1, note that the tab character has been changed to @. The entire table is enclosed in a box. The first line of the heading spans multiple columns. The first underscore character draws the line under the column headings, and the second draws the line under Montana. The equal signs separated by two tab characters create double underlines for the state and population columns under Nebraska.

Troubleshooting

When you use tbl, keep the following points in mind:

  • Do not use macros in tables. They are not digested properly. Although putting in a .P is tempting, and you may do so without thinking, often a single .P can wreck your table.

  • Do not try to embed lists in tables. At the very least, do not try embedding lists when the deadline is tight. Macros and tables usually do not mix.

  • Do not mix your font changes. If you use B in a format option line to get bold text, do not use \f2 for italics. However, escape sequences in your table data are fine.

  • If you cannot get the a format option to work, indent with \0. \0 inserts a space the width of a numeral.


TIP: Use the ex command :se list (in the vi editor). list turns each tab into a Ctrl+I, which shows up as ^I in your file but is actually a single character. You can count these characters to see whether you put in too many. list also puts the line end symbol ($) at the end of each line in the file. To turn off list, use :se nolist.
  • If you specify a column width, and the contents of that column are longer than the specified width, your width setting is ignored. Think of the width as a minimum, not a maximum.

  • Try to avoid using a text block as a table entry. The T{ text }T tbl construct allows you do so but at your own risk. You must include a space after the T{ with the text beginning on the next line; }T should be on its own line.


NOTE: Occasionally, you get a table too wide error message when using tbl. Processing does not stop, though; the table is still printed. Chances are, though, that it will be too wide because tbl does not respect margins. You can often use this feature to your advantage, however.

Formatting Equations with eqn/neqn

eqn is a troff preprocessor used to format equations (written in a form that would make your calculus teacher happy, not like you use in a C program). The code you write is processed by eqn before the file is processed by troff. Often, you pipe the eqn output of a file into troff as follows:

eqn filename | troff -options

eqn takes as input the commands between each .EQ/.EN macro pair and converts that input into a printable equation. All other input is passed through without modification.

neqn is used with nroff to simulate the equations when the output is a fixed format.

The two general formats of equations are shown in Listing 11.2.

Listing 11.2. eqn source: Simple equations.

.EQ
a + b over d = c
.EN
.EQ
delim ##
.EN
This is text with the same equation # a + b over d = c # in it.

The first form requires the equation to be embedded within a .EQ/.EN macro pair, and the second form defines a pair of delimiters within which eqn or neqn recognizes equations. The results are shown in Figure 11.2.

Figure 11.2.
eqn output: Simple equations.


TIP: Putting delimiter identification lines near the top of your file is usually a good idea.

You use the eqn delimiters for inline equations. Even if you're sure that you will not use inline equations, providing the delimiters is still a good idea.

If the defined delimiters are used in your text for other things besides equations, you can always turn them off by using the following command:

.EQ
delim off
.EN

eqn Keywords

eqn was designed to be easy for mathematicians to learn and use. It uses familiar words and abbreviations. For example, if you read a1=b2 aloud, you would say, "a sub one equals b sub two." You write eqn code the same way. The spaces here are important:

#a sub 1 = b sub 2#

The opposite of sub is sup, for superscript. Here's an example:

#a sup 2 > b sup 2

The following are the eqn keywords:
above back bar bold
ccol copy cpile define
delim dot dotdot down
dyad fat font from
fwd gfont gsize hat
highbar ifdef include int
integral inter italic lcol
left lineup lowbar lpile
mark matrix over pile
prod rcol right roman
rpile size space sqrt
sub sum sup tilde
to under union up
utilde vec

The following are the eqn keywords for the uppercase Greek characters (mathematical symbols):
GAMMA DELTA THETA LAMDA
XI PI SIGMA PHI
PSI OMEGA

The following are the eqn keywords for the lowercase Greek characters (mathematical symbols):
alpha beta gamma delta
epsilon zeta eta theta
iota kappa lamda mu
nu xi omicron pi
rho sigma tau upsilon
phi chi psi omega

There is no provision for the uppercase letters that are identical to their roman cousins (A, B, E, H, I, K, M, N, O, P, T, X, and Z). If you want an uppercase alpha, just type A.


NOTE: If you want an uppercase alpha that is not italicized, you have to specify roman A.

eqn also includes the following terms, which are printed in roman, not italic, type:

and arc cos cosh
det exp for if
Im lim ln log
max min Re sin
sinh tan tanh

eqn Operators

You have already seen some of the eqn operators--+, -, =, and >. Table 11.3 lists the others.

Table 11.3. eqn operators.

Keyword Operator Keyword Operator
>= <=
== !=
+- ->
<- << <<
>> >> approx
inf sum
prod int
union inter
nothing partial
half 1/2 prime
cdot times
del grad
... ,..., ,,
dollar $
In addition, eqn offers nine diacritical marks, which are listed in Table 11.4.

Table 11.4. Diacritical marks.

Keyword Diacritical Mark Keyword Diacritical Mark
dot . dotdot [dieresis]
hat ^ tilde ~
vec dyad
bar - under _
utilde ~
If you need to use a bar with one of the other diacritical marks, use highbar to place the bar correctly. lowbar is also available.

eqn pays no attention to spaces or new-line characters except as delimiters. After eqn determines what you mean (or what it thinks you mean), it throws away spaces and newlines.

To obtain spaces in your output, use a tilde (~) for a one-character space or a caret, also known as circumflex, (^) for a half-character space.

If you say "3 plus 2 times 5," your listeners do not know whether you mean the result 25 or 13. eqn has the same problem. Like your listeners, eqn makes an assumption about # a + b * c #. If you provide no more information, eqn groups according to the order in which you enter information. In other words, it assumes parentheses. Although computers do this, mathematicians do not. They believe in precedence, which holds that multiplication always precedes addition. Therefore, 3 + 2 x 5 is 13. Period. Even mathematicians, though, sometimes need parentheses.

Because parentheses are used so often in mathematical expressions, with eqn you must use curly braces--{ and }--to indicate grouping in your expressions. Therefore, if you really mean the result 13, you write the following:

# 3 + {2 * 5} #

The form for the equation is

# a + {b * c} #

The spaces here are important to help eqn determine the meaning of the symbols.

You can also change fonts and point sizes in an equation. Table 11.5 describes the keywords used.

Table 11.5. Keywords used to change fonts and point sizes.

Keyword Description
bold Prints the next character or term in bold type
fat Prints the next character or term in pseudo-bold, by overstriking
font f Changes to font f any font that troff recognizes (such as R, B, I, CW, and HB)
italic Prints the next character or term in italic type
roman Prints the next character or term in roman type
size n Changes to point size n, which can be specified as a number or as a relative quantity (such as size -2 or size +3)

You can use the gsize option to set a global point size. Similarly, you can use gfont. You should put these options near the top of your file; otherwise, eqn uses the default point size (usually 10).

Defines

If you use a complex term repeatedly, you can define it as something short. A good choice, for example, is &. Then, instead of typing

x= sqrt {SIGMA {x sup 2}} over N

you can type

x= &

define works like this:

.EQ
define &  'sqrt {SIGMA {x sup 2}} over N'
x = &
.EN

You can select any characters you want--fg, xy, and so on--but you should be sensible. Do not choose the special characters that eqn uses, the delimiters, and don't use eqn keywords, even though doing so is permitted.

Precedence

Without braces to force it to look at terms as groups, eqn recognizes the following orders of precedence:

dyad vec under bar tilde hat dot dotdot

left right

fwd back down up

fat roman italic bold size

sub sup

sqrt over

from to

All operations group to the right, except for sqrt, left, and right, which group to the left.

Troubleshooting

Sometimes, despite your best efforts, your equations just do not come out right. In this section, I provide some suggestions for detecting and correcting faulty code and for dealing with some of eqn's more arcane characteristics.

At its best, eqn is quirky. So, before you print a 50-page chapter containing 70 equations, check your equations. This way, you can pinpoint syntax errors such as unmatched delimiters. The checkeq program is a good place to start. You use checkeq like this:

checkeq myeqnfile

If checkeq finds no errors, it displays the following:

myeqnfile

or

myeqnfile:
     New delims: ##, line 2

If you have an odd number of delimiters, you see something like the following:

myeqnfile:
myeqnfile:
     New delims: ##, line 2
     3 line ##, lines 7-9
     3 line ##, lines 9-11
     3 line ##, lines 11-13
     3 line ##, lines 13-15
     3 line ##, lines 15-17
     Unfinished ##

If, for some reason, you specified bad delimiters (#$, for example, or #), checkeq announces

myeqnfile
     Strange delims at Line 2

or

myeqnfile
     Unfinished

checkeq is good for not much more than this use.

Because checkeq lets many mistakes slip by, you can also process your equation and send output to /dev/null (so that you do not clutter your directory with a lot of troff output). To do so, use the following:

eqn myeqnfile > /dev/null

When errors are found, you see a message like the following:

eqn: syntax error near line 19, file nyeqnfile
    context is
    !a = (x >>> {sup <<<< 2}) + 1!

The line number is not guaranteed, but it should be close.

Again, this approach is not foolproof because, if eqn can process your code, it does. You get no error message, even if your output is garbled or non-existent.

If you get no output at all: If your file contains only an equation, try inserting a line of text before the equation. If you do not want text, use translated tildes as follows:

.tr ~
~ ~ ~
.EQ
x sup 2 + y sup 2 = z sup 2
.EN

Oddly enough, this approach does not seem to affect eqn code--even code with tildes in it.

If the vertical spacing is wrong: Try printing your file with a different macro package--or with no macro package. If you're using your own package, you might have to pipe your file through eqn before you send it through troff. Try processing the eqn code and replacing the code with the processed code in your file. Try using space 0 as the first line of your eqn code:

.EQ
space 0
code
.
.
.
.EN

If you're using the .EQ/.EN macros to delimit your equation, try using delimiters (## or !!).

If your equation is garbled: Check for omitted spaces and braces. Use them, even if it looks like you really don't need them. Count braces and parentheses to make sure that you have an even number of each. Sometimes checkeq and eqn do not always find this problem. If your equation contains a sup, make sure that you use spaces around its argument, even if you have a brace. Make sure that you have keywords in the right order. For example, #x highbar tilde# produces no error message, but it prints the bar right on the tilde. The correct order is #x tilde highbar#. If your equation is long or complicated, use lots of spaces and newlines to make it easy to read.

Drawing Pictures with pic

pic is rarely your first choice as a drawing tool. With pic, you can draw lines and a limited variety of shapes--no color, no shading--but you can create a complex and detailed picture, if you're willing to work at it. pic was developed before everyone had personal computers with sophisticated, mouse-based drawing packages. Today, troff users with graphics terminals can use mouse-based programs such as xcip. These programs provide many of the capabilities--except for color--of the sophisticated packages, and they do not require a knowledge of pic. xcip produces pic code, which you can edit if you know pic.

pic is no substitute for a sophisticated drawing tool. If you can use one of those tools, do so!

pic is a troff preprocessor used to create pictures (line drawings, actually). The code you write is processed by pic before the file is processed by troff. Often, you pipe the pic output of a file into troff as follows:

pic filename | troff -options

pic takes as input the commands between each .PS/.PE macro pair and converts that input into a line drawing. All other input is passed through without modification.

The general format of a picture is as follows:

.PS
.box ht 1 wid 1.25
.PE

ms includes a .PF macro for picture flyback. This macro restores you to your last position on the page (vertically and horizontally) before the picture--where you were located before you invoked pic. This feature is rarely used. Some pic users surround their pic code with display macros and specify no-fill mode. Here's an example:

.DS
.nf
.PS
.box ht 1 wid 1.25
.
.
.PE
.DE

This example might look like overkill, but mm likes it.

You also can use the .PS macro to do the following:

.PS < filename Sources in a pic file; imports an external file called filename and allows it to be processed as if filename were part of your text file.
.PS wid ht Enables you to specify the width or height, or both, of the final picture


CAUTION: If you have a space after the .PS and no measurements, your figure is enlarged proportionally so that its width is the current width (line length) of your pages.

Whatever you do, do not include any spacing requests--.sp, .ls, .vs, .SP, and .P--inside your pic code. pic does its own spacing, and it gets really annoyed if you interfere. Use the move command instead.

pic keywords

pic is built on a series of keywords to build line drawings; these keywords are shown in Table 11.6.

Table 11.6. pic keywords.

Primitive Description
arc n Draws fraction of a circle specified by n; [1/4] is the default
arrow Draws an arrow (line with ->)
box Draws a box
circle Draws a full circle
ellipse Draws an ellipse
line Draws a line
move Moves your position in a drawing
spline Draws a sloped line (using then option)
"text" Includes and centers at the current point
#comment Includes comments in pic text

All these primitives accept options and text (except for the text itself and comments, of course). The options are shown in Table 11.7.

Table 11.7. pic keywords options.

Option Description
cw Clockwise; valid only with arc
at P Centers drawing item at point P
from P1 to P2 Draws an item from P1 to P2
-> Draws an arrow on the front end
<- Draws an arrow on the back end
<-> Draws an arrow on both ends
dashed Draws an item with a dashed line
dotted Draws an item with a dotted line
invis Draws an item invisibly (nothing shown)
solid Draws an item with a solid line (default)
up N Draws an item in this direction; N is length
down N Draw as item in this direction; N is length
left N Draws an item in this direction; N is length
right N Draws an item in this direction; N is length
diam N Draws an item using a diameter of N
rad N Draws an item using a radius of N
ht N Draws an item using a height of N
wid N Draws an item using a width of N
same Draws an item using the same dimensions as the previous item
above Text only; appears above the center of an item
below Text only; appears below the center of an item
ljust Text only; flush left, vertical center
rjust Text only; flush right, vertical center
then Continues item in a new direction

pic also recognizes trigonometric and other mathematical functions, as follow:
atan2 (e1, e2) Arctangent of e1, e2
cos Cosine of e (e must be in radians)
exp 10e
int integer part (by truncation)
log logarithm base 10 of e
max (e1, e2) maximum of e1 and e2
min (e1, e2) minimum of e1 and e2
rand (n) random number between 1 and n
sin sine of e (e must be in radians)
sqrt square root of e

These functions must be followed by an expression in parentheses. In the case of atan2, max, and min, two expressions must follow. rand is followed by empty parentheses and produces a random number between 0 and 1.

Other options and keywords are available for the creation of more complicated items such as object blocks (used for complex objects such as hexagons) and macros (for repeated commands). Look at the man page if you need this information.

More About Placement

To avoid having to think like pic--an exercise that can be dangerous to your mental health--you can refer to parts of objects that you have already drawn. pic recognizes all of the following:

.l left .ne northeast
.r right .nw northwest
upper bottom
lower start
.t top end
.n north 1st
.e east 2nd
.w west 3rd (and so on)
.s south last
.nw northwest 2nd last
.sw southwest 3rd last (and so on)

pic also understands compass points.

The position notation words and the compass points enable you to specify positions like the following:

line from upper right of 2nd last box to upper left of last box
arrow from 1st circle.e to 2nd circle.w
box at end of last line
move left 1i from start of last box
line from Box.c to Box.s
move down 1i from bottom of 2nd last ellipse


NOTE: You can use terms such as upper left and lower right, but not top left and lower bottom.

Now you have several ways of specifying positions to draw objects. You can write

.PS
box "Box 1"
move to last box.s down .5
box "Box 2"
.PE

Or you can write

.PS
box "Box 1"
move to bottom of last box down .5
box "Box 2"
.PE

If you want to avoid the wordiness of bottom of last box, you can label your construct as follows:

B1: box "Box 1"

Labels must begin with a capital letter.

Using labels enables you to specify the two boxes as follows:

.PS
B1:box "Box 1"
B2:box  with .c down 1i from B1.c "Box 2"
.PE

No matter which notation you use, you get the two boxes shown in Figure 11.4.

Figure 11.3.
pic
drawn boxes.


TIP: If you reference objects by their centers, you do not have to worry about where pic starts a new object or in which direction the new object is drawn.

The notations left, right, .ne, .sw, and others assume that you can tell left from right and east from west. If you are directionally challenged, you should allow extra debugging time when using pic.

pic comes to your rescue with a solution. It also understands Cartesian coordinates, as shown in Figure 11.3.

Figure 11.4.
x,y coordinates.

Again, the unit is inches. The important point to remember is that your first object starts at 0,0. In other words, the coordinates are relative. No specific location on a page or in a drawing is always 0,0. This location depends on where you start.

Cartesian coordinates enable you to specify the two boxes shown in Figure 11.4 as follows:

.PS
box at 0,0 "Box 1"
box at 0,-1 "Box 2"
.PE

You might find working with this approach easier.

Controlling Size

pic variables include several that specify the default size of pic objects. Table 11.8 lists these variables and their default values.

Table 11.8. Default values of pic variables.

Variable Default Value Variable Default Value
arcrad .25i ellipsewid .75i
arrowhead 2i lineht .5i
arrowht .1i linewid .75i
arrowwid .05i moveht .5i
boxht .5i movewid .75i
boxwid .75i scale 1i
circlerad .25i textht 0i
dashwid .5i textwid 0i
ellipseht .5i

arrowwid and arrowht refer to the arrowhead. The arrowhead variable specifies the fill style of the arrowhead.

You can easily change the value of a variable as follows:

boxht = .75; boxwid = .5

Remember: The default unit for pic is inches.

You also can control the size of a picture in other ways. You can specify a height or a width--or both--on the .PS line. Specifying only the width is usually better. If you specify both dimensions, your picture may be distorted.


NOTE: For some reason, you must specify the width first. For example, .PS 2 4 produces a picture 2 inches wide and 4 inches long. This order is the opposite of the order in which you specify the dimensions of a box or ellipse. The width and height you specify refer to the whole picture.

You can also set the variable scale. By default, scale is set at 100 or 1, depending on your version of pic. You can test it by scaling a drawing to 1.5. If you get an error message or a garbled result, use 150. All the dimensions in a pic drawing are divided by the scaling factor. Therefore, if the scale is normally 1 and you set it to 4, your 1-inch lines end up a quarter-inch long. Here's an example:

.PS
scale = 2
box ht 2i wid 2i
.PE

This code produces a box scaled down to half the size of its specifications, that is, a 1-inch square.


CAUTION: Text is not scaled. If you need to resize text, you must do so by using \s. This approach involves trial and error to find out what fits in your scaled figure.

Debugging

When using pic, you are not troubleshooting; you are debugging. Debugging as you code is much easier. Draw the first element of your picture. Before you print it, send the file through pic to see whether any error messages are generated. If your file contains only pic, you can use the following:

pic filename

If your file contains text, just use your normal troff command line. However, instead of sending the file to a printer, redirect your output to /dev/null.

pic tries to help you pinpoint your errors with messages similar to the following:

pic: syntax error near line 26
context is
        >>> linr <<< left 1i

Occasionally, pic tells you that it has reduced the size of your picture. This result occurs almost always because you made a mistake. Most often, you left out a decimal point, and pic is trying to fit a line 1,625 inches long--you meant 1.625 inches--on an 8.5-inch page. When you get this result, your picture naturally is mangled out of all recognition.

Usually, your debugging involves the placement of objects and the placement or size of text.

pic Tips and Tricks

There are a few things that will make your life easier:

  • If you cannot get an object placed correctly by moving down and left (or up and right) from an object, try referring to both objects by their centers, as in box.c.

  • If your drawing involves a number of objects and placement is crucial, use x,y coordinates.

  • If you have trouble placing text, remember to use over and under.

  • Using box invis or line invis to place your text usually works well.

  • Make yourself a library of pic drawings so that you do not have to keep reinventing the spiral.

Creating Graphs with grap

grap is a troff preprocessor used to create graphs. The code you write is processed by grap and pic before the file is processed by troff. Often, you pipe the grap output of a file into pic and then into troff as follows:

grap filename | pic | troff -options

grap takes as input the commands between each .G1/.G2 macro pair and converts that input into a printable graph. All other input is passed through without modification.

The general format of a graph is as follows:

.G1
grap command
value
value
.G2

Because grap has a copy facility similar to that of pic, you can simplify your code even more by putting the data in a separate file.

.G1
copy "test.scores"
.G2

If you want the graph to have a solid line instead of scatter points, simply add a line of code that says draw solid immediately after the .G1 macro.

Adding Bells, Whistles, and Ticks

You can make your graph much more attractive by drawing a frame, adding labels, and specifying ticks. The code in Listing 11.3 produces a more sophisticated graph, which is shown in Figure 11.6.

Listing 11.3. grap source: Simple graph.

.G1
frame invis ht 2 wid 3 left solid bot solid
label left "1990" "Dollars" left .5
label bot "Grand Total:  $210,000"
ticks left out at 6000 "6,000", 9000 "9,000", 12000 "12,000", 15000 "15,000",\
18000 "18,000", 21000 "21,000"
ticks bot at 1990 "1990", 1995 "1995", 2000 "2000", 2005 "2005", \
2010 "2010"
draw solid
copy "cost.child"
.G2

Figure 11.5.
grap graph.

The data file "cost.child" is shown in Listing 11.4.

Listing 11.4. grap: Contents of the cost.child file.

1990     4330
1991     4590
1992     4870
1993     5510
1994     5850
1995     6200
1996     6550
1997     6859
1998     7360
1999     7570
2000     8020
2001     8500
2002     10360
2003     10980
2004     11640
2005     13160
2006     13950
2007     14780

Here, the frame is shown only on the bottom and left side. The x and y coordinates have labels. Also, the ticks have been specified explicitly; they are not determined by grap.


TIP: You can save yourself hours of debugging if you remember that grap does not understand commas in large numbers. The ticks left line in Listing 11.3 specifies 9000 "9,000". The commas are safely isolated in labels specified in quotation marks. The grap specifications themselves contain no commas.
The data file--in this case, cost.child--also must contain no commas.


NOTE: Earlier versions of grap may not recognize the abbreviation bot for bottom.

You can specify ticks as out. This means that the ticks themselves, but not their labels, appear outside the grap fra