pic(1M) pic(1M)
NAME
pic - troff preprocessor for drawing pictures
SYNOPSIS
pic [-T device] [--] [-] [file] ...
DESCRIPTION
Requirements
Like the tbl(1M) program for tables or the eqn(1M) program for
mathematical formulae, the pic program for generating graphics is a
preprocessor which translates the special source code embedded in
troff source texts to troff source text. Only then is this expanded,
"translated" input text as well as the remaining "normal" input text
actually formatted.
The entire context is again illustrated in the following figure.
+----------+
| input | edited and modified
| file | by the user
+----------+
|
|
|
v
+-------+ +-------+ +-------+
|¢ pic ¢| |¢ tbl ¢| |¢ eqn ¢|
+-------+ +-------+ +-------+
|
|
|
v
+------------+
| expanded | +---------+ +----------+
| input |-------->|¢ troff ¢|-------->| output |
| file | | | | file |
+------------+ +---------+ +----------+
¢ = program
In contrast to tbl and eqn/neqn, pic can only be used in combination
with troff:
pic option file ... | troff ...
If you use pic, eqn and tbl, the pipe order is as follows:
pic option file ... | tbl | eqn | troff ...
Page 1 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
OPTIONS
The following option is permitted:
-T device
The output is prepared for the output device. The complete
/usr/lib/font/devdevice directory must be available for device.
The following parameters are permitted:
-- End of list of options. This entry is required if file begins
with -.
- If no file is specified, or if - is specified as an argument,
standard input is read.
file Name of troff input file.
INTRODUCING PICTURES IN TROFF TEXTS
Picture descriptions are delimited in troff input text by .PS and .PE
(on separate lines). As an option after .PS, you can specify the width
and height of the picture in inches; the picture is then stretched and
dragged to fit this size. Otherwise, standard dimensions or those
specified in the picture description are used. If only the width is
specified, the height is adjusted proportionally. If the .PS line
appears as
.PS <file
it is replaced by the contents of file. file may contain delimiters,
but this is optional.
If you use .PF instead of .PE, the text position before the start of
the picture is restored once the picture has been created. This allows
you to output text as well as the picture for example.
pic passes through the .PS/.PE delimiters, and appends the calculated
height and width of the picture to .PS (before any values that may be
present). The delimiters and height and width values of the picture
can then be processed again using a macro package. For example, you
can center all pictures as follows:
.de PS
.ne \\$1u
.in (\\n(.lu-\\$2u)/2u
..
.de PE
.in
..
Page 2 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
SYNTAX OF PIC INPUT LANGUAGE
The description of a picture basically comprises a number of figures
each with specific attributes; these will now be explained. Each com-
bination of figure and attribute (= object or element) appears in a
separate line. You can also specify several elements on one line, sep-
arating them with a ; character. If the description of an element is
very long, you can split it over several lines, though the last char-
acter of each line before a follow-on line must be a backslash, i.e.
\.
You can also add comments to the description of the picture. These
comments are introduced by a # character and terminate at the line
end.
You will see later how you may also use variables and set markers, but
first let us look at the notation: Variable names begin with a lower-
case letter, while marker names begin with an uppercase letter. Both
variables and markers retain their values in subsequent pictures in
the same document.
Each line beginning with a period is interpreted as a troff command
and is passed through unchanged. You must not use control characters
for vertical spaces or for changing the line spacing. You can, how-
ever, change the font and point size.
BASIC FIGURES AND THEIR ATTRIBUTES
The basic figures in pic are boxes, lines and arrows, circles,
ellipses, arcs, splines, text in quotation marks as well as moves. You
can see all of these in the diagram below:
==> See hardcopy in System Administrator's Reference Manual <==
An arrow is another word for a line ->.
Each of these basic figures can be assigned attributes which basically
influence the size, positioning and labeling of the figures. You can
also make each figure invisible by appending the word invis(ible).
This makes it easier, for example, to position picture labels. Each
attribute comprises a keyword possibly followed by a value. For exam-
ple:
height 3.5 or ht 3.5
means that the previous basic figure will have a height of 3.5 inches.
Default values can be used to replace any missing attributes and
values. Not every attribute can be applied to every basic object, and
unsuitable attributes are simply ignored. The possible attributes for
each figure are listed below:
Page 3 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
Figure Permitted Attributes
box h(eigh)t, wid(th), at, same, dotted, dashed, invis,
"Text"
circle, ellipse chop, rad(ius), diam(eter), h(eigh)t, wid(th), at,
same, invis, "Text"
line, arrow up, down, left, right, h(eigh)t, wid(th), from, to,
by, then, at, same, dotted, dashed, invis, <-, ->,
<->, "Text"
arc up, down, left, right, h(eigh)t, wid(th), from, to,
at, rad(ius), invis, cw (= clockwise), <-, ->, <->,
"Text"
spline up, down, left, right, h(eigh)t, wid(th), from, to,
by, then, at, same, invis, <-, ->, <->, "Text"
move up, down, left, right, to, by, same, "Text"
"Text" at, by
Box
The keyword box creates a standard sized box (0.75 inches wide, 0.5
inches high) at the current position:
==> See hardcopy in System Administrator's Reference Manual <==
A number of figures are directly concatenated without any spaces in
between, i.e.
box; box; box
produces
==> See hardcopy in System Administrator's Reference Manual <==
You could also have entered:
box
box
box
To label the boxes, you append text attributes to the names of the
figures in double quotes:
box "box"
box "middle" "box"
box "this" "is the" "last"
==> See hardcopy in System Administrator's Reference Manual <==
Page 4 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
Quotation marks must be inserted even if the text does not contain
spaces. Each text attribute is output in its current point size and
type and centered horizontally and vertically; if there are several
text attributes for the same figure they are output one above the
other assuming the current line spacing.
Dashed or dotted boxes are an interesting variation. In this case, you
enter dashed or dotted after box.
You can also make the box any size you wish. Thus, for example, the
following box is produced with
box dotted wid 2i height 0.2
==> See hardcopy in System Administrator's Reference Manual <==
Dimensions are always interpreted as inches. The letter "i" can be
specified, but this is optional. The dimensions are only valid for the
basic figure specified immediately beforehand. Even if a basic figure
of the same type follows, the default size applies again initially.
You can retain the dimensions, however, by specifying the keyword
same:
box dotted wid 2i height 0.2; box same
==> See hardcopy in System Administrator's Reference Manual <==
You can also specify dimensions after dotted and dashed. These dimen-
sions are explained in the section "Lines and arrows".
Move
Basic figures are generally output in direct succession from left to
right. If you want space in between, you should use move:
box; move; box; move; box
==> See hardcopy in System Administrator's Reference Manual <==
Since move is not a figure, you use up, down, left or right and possi-
bly a value to specify the size of the move and not "width" or
"height". But be careful: Each of these attributes also changes the
general direction of the basic figures. Thus, for example, the follow-
ing picture is produced with:
box; move; box; move; box; move down; box
move; box;
==> See hardcopy in System Administrator's Reference Manual <==
(The moves are indicated by dotted lines.)
Page 5 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
Lines and arrows
Lines and arrows are produced with line and arrow. arrow is not a
basic figure, rather a shortcut for writing line -> and produces a
line with an arrow at the end. You could also use arrowheads at the
beginning or at both ends using line <- or line <->.
Take a look at the text output at the lines and arrows in the follow-
ing examples:
line "line"; move; arrow "this is" "an arrow"
move; line <- "this is " "a left " "arrow"
==> See hardcopy in System Administrator's Reference Manual <==
If lines and arrows are to have different lengths and directions, you
specify the direction of movement and spacing from the current posi-
tion as with move, i. e. up, down, left and right and possibly a dis-
tance. For example:
line up .5 right 1
line down .5
arrow up .5 right 1
==> See hardcopy in System Administrator's Reference Manual <==
If you do not specify a distance after up, down etc., pic will use
default values. However, you cannot specify a distance without a
direction. Once more beware: In this case also, a direction attribute
changes the general direction of the picture.
If you specify a "width" or "height" for line or arrow, this only
refers to the dimension of the arrowhead. These attributes are mean-
ingless for lines without ->, <- or <->. As with boxes, lines can be
dotted or dashed:
line dotted; move; line dashed
==> See hardcopy in System Administrator's Reference Manual <==
Both attributes can be assigned dimensions. A number after dotted
defines the distance between the dots. The dimension for dashed
defines both the width of the dashes as well as the space in between.
For example:
==> See hardcopy in System Administrator's Reference Manual <==
is produced from the following input (separate pictures):
line right 3i dotted 0.2
line right 3i dashed 0.2
line right 3i dashed 0.5
Page 6 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
Circle
Circles are produced using the word circle. The size of the circle can
be specified as a radius ("rad") or a diameter ("diam" or "wid") if
the default is not to be used:
circle rad 0.5 "circle"; circle diam 0.5
==> See hardcopy in System Administrator's Reference Manual <==
Circles and arcs are never stretched or dragged if a dimension is
specified after .PS, rather they are increased or reduced proportion-
ally. Circles and arcs cannot be dotted or dashed.
Ellipse
Ellipses are produced using the word ellipse. The size of an ellipse
is specified with height ("ht") or width ("wid" or "diam") if the
default is not to be used.
ellipse ht 0.8 wid 1.2 "ellipse"
ellipse wid 0.8 ht 1.2
==> See hardcopy in System Administrator's Reference Manual <==
The radius, if specified ("rad"), only affects the width of an
ellipse.
Arc
Arcs are produced with arc. Default values rotate the arc 90° in an
anticlockwise direction. Thus, for example,
arc; arc; arc; arc
==> See hardcopy in System Administrator's Reference Manual <==
naturally produces a circle. The direction can also be reversed with
the attribute cw (= clockwise):
arc cw; arc cw; arc
==> See hardcopy in System Administrator's Reference Manual <==
The default radius is the same as for circles but can be changed with
the rad attribute.
Each arc changes the general direction of the picture in the direction
of its last segment. Take a look at the example below:
arc; arc; arc; move
arc; arc; arc; move
arc; arc; arc; move
arc; arc; arc; move
Page 7 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
==> See hardcopy in System Administrator's Reference Manual <==
If you have established the sequence in which the arcs in this picture
are drawn, then you have understood the general principle.
If an arc is to start in a different direction than the current one,
specify up, down, left or right as an attribute (without a distance).
If arcs are to have completely different lengths and directions, you
should use the attributes from and to, specifying a position in each
case (see section "Coordinates").
You use the attributes <-, -> or <-> for arrowheads in arcs; height
and width only affect the arrowhead in arcs. Arcs cannot be dotted or
dashed.
Spline
A spline is a rounded curve drawn along a series of straight lines.
The syntax for a spline is the same as the syntax for a series of
linked straight lines (polygons), though using the keyword spline. A
polygon and spline are shown side by side in the picture below:
line left .3 down 1 then right 1 then \
left .3 up 1
move right
spline left .3 down 1 then right 1 then \
left .3 up 1
==> See hardcopy in System Administrator's Reference Manual <==
The elements in a polygon or spline are specified as a series of ver-
tices separated by "then". The vertices are generally specified as
coordinates (see section "Coordinates").
Arrowheads can be output at the tips of the polygon or spline, where
height and width only affect the arrowheads. Splines cannot be dotted
or dashed.
Text
Text attributes are enclosed in double quotes. A text attribute is
generally output at the center of the basic figure (text position).
However, there are also additional attributes for text attributes,
which allow the text to be output left or right justified from the
current position or half a line higher or lower. These additional
attributes are ljust, rjust, above and below. They must not be com-
bined however.
box "Text"; move
box "Text" ljust; move
box "Text" rjust; move
box "Text" above; move
line "Text"; move
line "Text" above
Page 8 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
==> See hardcopy in System Administrator's Reference Manual <==
If several text attributes are specified for a basic figure, they are
output one above the other to the center of the figure, unless speci-
fied otherwise. An additional attribute only affects the directly
preceding text attribute.
Text is generally an attribute of another object, but can also be
created independently:
box; move right 3; "Text"
==> See hardcopy in System Administrator's Reference Manual <==
Stand-alone text can also be assigned additional attributes.
DIMENSIONS OF BASIC FIGURES
Each basic figure (box, circle etc.) has default measurements such as
height, width, radius etc.:
_______________________________________________________
| Basic figure Dimension |
|______________________________________________________|
| box 0.75 inches wide x 0.5 inches high |
| move 0.5 inches vertically and horizontally|
| line/arrow 0.5 inches vertically and horizontally|
| circle 0.5-inch diameter = 0.25-inch radius |
| ellipse 0.75 inches wide x 0.5 inches high |
| arc 0.25-inch radius |
| spline 0.5 inches |
| "Text" 0 inches wide and high |
|______________________________________________________|
The description of the basic figures explains how to changes these
dimensions for individual basic figures using attributes. If you
specify an attribute like width, then only one object is changed. If a
figure is to be the same size as a previous object of the same type,
append the name same. For example:
down; box ht 0.2i wid 1.5i; move down 0.15i
box same; move same; box same; move; box
==> See hardcopy in System Administrator's Reference Manual <==
By assigning new values to particular variables, you can permanently
change the default dimensions for the basic figures. These names are
as follows (see section "Variables and arithmetic" below):
boxwid, boxht
movewid, moveht
arrowwid, arrowht
linewid, lineht
dashwid
Page 9 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
circlerad
arcrad
ellipsewid, ellipseht
textwid, textht
For example, if all circles are to be large and be placed closely
together, you can assume the following general setting:
circlerad = .5; movewid = 0.2i
circle; move; circle; move; circle
==> See hardcopy in System Administrator's Reference Manual <==
Although text is always output as normal, the space taken up by the
text is 0 by default (textwid = textht = 0). Take a look at the fol-
lowing example:
box; "Text"; box;
move; textwid = .5
box; "Text"; box;
==> See hardcopy in System Administrator's Reference Manual <==
pic generally works with inches as a unit of measurement, but offers
the option with the default variable scale of using a different unit
within the description of the picture - e. g. centimeters. If you set
scale to a value other than 1 all measurements will be divided on the
basis of this value. scale=2.54 therefore causes all measurements to
be interpreted as centimeters.
The number specified as the width in the .PS line overrides the meas-
urements defined in the picture. This is how you set a picture to a
particular size. For example:
boxwid = 1; boxht = .1; box
If you enter this information with .PS without parameters or with
.PS 3, the following is output:
==> See hardcopy in System Administrator's Reference Manual <==
POSITIONING
Coordinates
pic figures are generally output in direct succession from left to
right below the last formatted text. However, objects can be placed at
any position. pic uses a typical two-dimensional coordinate system in
which every point has an x and a y coordinate. The position 0,0 is
always the starting point for the first object in a picture. The x,y
position of a box, a circle or an ellipse is its geometrical center-
point. The position of a straight line or move is the starting point.
The position of an arc is the centerpoint of the circle.
Page 10 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
You can change the absolute positioning of a figure with the attribute
"at" and a pair of coordinates or the relative positioning with the
attribute "by" and a pair of coordinates. In the case of moves, lines,
arrows and arcs, use "from" and "to" (or simply to) with coordinates
to specify the positioning.
If you omit the attribute from, the move, line or arc begins at the
position at which you are now located and runs to the point specified
by to.
The x and y coordinates can also be changed individually using the
familiar attributes left/right and up/down and a relative value.
A position is therefore a pair of x,y coordinates, but can also be
specified in another way. The expression,expression pair of coordi-
nates can be enclosed in parentheses.
The size and position attributes such as ht, wid and at can be written
in any sequence. As a result,
circle rad .3 at 1.5,.8
circle at 1.5,.8 rad .3
have the same effect.
Positions can be added, subtracted and projected in order to create
new positions:
(x1,y1)+(x2,y2) = (x1+x2,y1+y2)
==> See hardcopy in System Administrator's Reference Manual <==
If p1 and p2 are positions with the coordinates (x1,y1) and (x2,y2).
Then
(p1,p2)
references the projection of the two positions
(p1.x,p2.y) (= (x1,y2))
==> See hardcopy in System Administrator's Reference Manual <==
Start and end points for figures
Objects are linked in the sequence defined by the last up, down, left
or right. The starting point for the second object is therefore the
end point for the first object. The start and end points for boxes,
circles and ellipses are always at the center of the opposite side of
the figure in the current direction, and represent the beginning and
end of lines, splines, moves and arcs. For example:
box "1"; move; box "2"; move down; box "3"
Page 11 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
==> See hardcopy in System Administrator's Reference Manual <==
The start and end points for boxes are indicated with Ai and Ei. The
end point of a figure is also the starting point of the next figure,
i.e. E2 is the starting point of the next move (move down) and A3 is
its end point.
Direction
The initial direction set for every picture is right, i. e. objects
are linked from left to right. If you specify a direction as its own
object or as an attribute, all subsequent objects are linked in this
direction. For example:
circlerad = .1; movewid = 0.2i; moveht = .2
circle; move; circle; move; circle; move down
circle; move; circle; move; left
circle; move; circle; move; circle; move up
circle; move; circle; move
==> See hardcopy in System Administrator's Reference Manual <==
Every other picture (.PS-.PE) again runs from left to right.
Markers
Objects can be marked and named to allow their position to be
addressed again later. For example:
Cir1:
circle; move; circle; move; circle; move
circle; move to Cir1; "circle 1"
The marker in this example is Cir1. Marker names must begin with an
uppercase letter. The name indicates the position of the next figure.
In most cases, this position is the geometrical centerpoint. You can
use markers as follows:
line from Cir1 to Cir2
move to Cir1 down .5 right 0.3
line to Cir1 + 0.5,0.3
circle at Cir1 + 0.5,0.3
In the last two examples, marker + x,y creates a new position. The
reserved name Here identifies the current position:
Position1: Here
Markers are variable and can also be changed within a picture, and
even redefined as follows:
Position1: Position1 + 1,1
Page 12 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
Instead of a suitable marker, you can also refer to previously
described objects of any type using the word last. In this picture
description,
box "1"; circle "2"; box "3"
last box refers to box 3, last circle to circle 2 and 2nd last box to
box 1. Objects of the same type are numbered consecutively in each
picture. Boxes 1 and 3 are thus 1st box and 2nd box (1th is also per-
mitted as is 1st or 3rd).
Corners
So that not only the position of an object can be addressed, but also
a number of its boundary points, most objects have "corners" named in
accordance with compass points:
.n
.nw +-----------------------+ .ne
| |
| |
| |
.w + .c + .e
| |
| |
| |
| |
.sw +-----------------------+ .se
.s
The descriptors .r, .b, .l and .t (for "right", "bottom", "left" and
"top") can also be specified for the corners .e, .s, .w and .n. Like
corners, lines and arrows have a .start and .end. Arcs only have .c,
.start and .end. Apart from this type, almost every combination of
left, right, top, bottom, upper, lower and center is possible for
describing particular points in a basic figure. Thus last box.ne cor-
responds to upper right of last box.
Objects can be positioned by allowing a corner of one object simul-
taneously form the corner of another object. The with attribute allows
this type of positioning. For example:
box ht 0.75i wid 0.75i
circle with .nw at last box.se
produces:
==> See hardcopy in System Administrator's Reference Manual <==
Finally, you can position along a line defined by two points:
fraction [of the way] between position1 and position2
Page 13 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
This notation can be shortened as follows:
fraction <position1, position2>
The value specified by fraction can be greater than 1 or less than 0.
For example:
box
arrow right from -1/2 <last box.sw, last box.ne>
arrow right from 1/2 of the way between \
last box.nw and last box.se
arrow right from 3/2 <last box.nw, last box.se>
produces:
==> See hardcopy in System Administrator's Reference Manual <==
Concealed lines
There are many cases where a line is to intersect a circle at a point,
which is not one of the eight compass points allowed for in pic. A
line is drawn to the centerpoint and a section of the line is trun-
cated using the chop attribute:
circle "1"
circle "2" at 1st circle + 1,-.2
line from 1st circle to 2nd circle chop
produces:
==> See hardcopy in System Administrator's Reference Manual <==
chop generally cuts a line at each end by the circlerad, whose size
can be changed as follows:
line ... chop length
reduces both ends by length,
line ... chop length1 chop length2
reduces the start by length1 and the end by length2.
Blocks
A block is formed by a sequence of pic statements enclosed in parenthe-
ses. A block counts as a single object and can be manipulated like an
ordinary box which contains all of the figures in the block. For example:
[down; box; arrow; box]
move; move; move
[down; box; arrow; box]
"control" "flow" at 1st [].e
"data" "flow" at last [].e
Page 14 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
==> See hardcopy in System Administrator's Reference Manual <==
A block is treated like a unit, but has its own direction of movement
and its internal objects cannot be addressed: last box is not known
outside of the blocks, but you can use last [] to address the block as
a whole.
Blocks have compass points like boxes because every block is delimited
by an invisible box. A block can also be positioned by either moving
it in its entirety or using an internal marker:
[ ...; Cir1: ...; ... ] with .Cir1 at ...
Blocks are linked with the following figure in the same way as boxes
(i. e. at the endpoint of the adjacent box).
Names of variables and markers within a block are only valid within
the block; they do not come into conflict with external variables and
markers of the same name. However, internal markers can also be used
outside the block in the following ways:
last [].Cir1 or Block1.Cir1
if Block1 is a marker, which is assigned to the block:
Block1: [ ... ; Cir1: ...; ]
Even though blocks may be nested, the nesting of markers such as
Block1.Cir1 can only be one level deep. Cir1 can be described more
explicitly however. For example Block1.Cir1.e or start of Block1.Cir1.
Command sequences appear in curly brackets {...} alongside the actual
blocks. These commands cause the current position and direction of
movement to be exactly the same following the closing bracket as for
the open bracket. This is their only effect.
VARIABLES AND ARITHMETIC
Wherever you are to use values - thus, for example, after down or wid
-, you can also define variables or any other expressions. As with
programming, absolute coordinates are time consuming and prone to
error if changes need to be made subsequently. Variables allow you to
specify parameters for your picture. For example:
g = .75; h = 1.2
box wid g/3 ht h*1.5
move to last box - (a, b*2)
Expressions can use the operators +, -, *, / and %, with round brack-
ets used for summaries. Please note that variable names should begin
with a lowercase letter.
Page 15 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
There are already a number of predefined variables which establish the
default dimension of the basic figures. You can changes their values
in a picture at any time, and they are preserved until they are
defined again in the same document. The predefined variables and their
initializations are as follows:
________________________________________________________________________
| Variable | Default Value | Meaning |
|___________|________________|__________________________________________|
| arcrad | 0.25i = 0.635c| Radius of arc |
| arrowwid | 0.05i = 0.127c| Width of arrowhead |
| arrowht | 0.1i = 0.254c| Length of arrowhead |
| boxwid | 0.75i = 1.905c| Width of box |
| boxht | 0.5i = 1.27c | Height of box |
| circlerad | 0.25i = 0.635c| Radius of circle |
| dashwid | 0.05i = 0.127c| Width of dash and space in a dashed line|
| ellipsewid| 0.75i = 1.905c| Width of ellipse |
| ellipseht | 0.5i = 1.27c | Height of ellipse |
| linewid | 0.5i = 1.27c | Length of horizontal line |
| lineht | 0.5i = 1.27c | Length of vertical line |
| movewid | 0.5i = 1.27c | Distance of horizontal motion |
| moveht | 0.5i = 1.27c | Distance of vertical motion |
| scale | 1i = 2.54c | Scale dimensions |
| textwid | 0i | Width of space required by a text as an |
| | | object |
| textht | 0i | Height of space required by a text as an|
| | | object |
|___________|________________|__________________________________________|
For example, you can enlarge an arrowhead by changing the following
predefined variables as shown below:
==> See hardcopy in System Administrator's Reference Manual <==
You can use the default variables as required in expressions. Other
possible values are other variables, height, width, radius and x and y
coordinates of an object or a corner. For example:
spacing # Variable
Cir1.x # x-coordinate of Cir1
Cir1.ne.y # y-coordinate of northeast corner of Cir1
Cir1.diam # Diameter of Cir1
2nd last circle.rad # Radius of second last circle
Expressions are calculated as broken values. All digits describing
measurements are interpreted as inches, which are scaled when output.
Page 16 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
PROGRAMMING OPTIONS FOR PIC
Apart from the use of variables and the creation of expressions as we
are now familiar with, the options for programming in pic are not very
extensive, but are ideal for creating pictures. In addition to the
most important elements like definitions and macros, the loop con-
struction as well as their conditional execution, there are other ele-
ments such as formatting of values, importing other files as well as a
number of integrated mathematical functions.
Definitions and macros
pic provides a macro facility, which in its simplest form is identical
to that in eqn:
define name 'replacementtext'
Every time name appears in the following pictures, it is replaced by
replacementtext. The separator (' in this case) can be any character
that does not appear in the replacementtext. The replacementtext can
include line feeds.
Macros can also be defined with arguments. The characters $1 to $9 can
appear in the replacement string of a macro definition and are
replaced by the corresponding actual arguments when the macro is
invoked. To invoke a macro with arguments:
name(arg1, arg2, ...)
Non-existent arguments are replaced by null strings. Pairs of coordi-
nates may be enclosed in parentheses (as in (x,y)), so that they can
be included in a macro argument. For example:
define square Xbox ht $1 wid $1 $2X
The input
square(.9, "big" "box"); square(.3)
produces a large labeled and a small unlabeled box:
==> See hardcopy in System Administrator's Reference Manual <==
Loops
Loops for repeated execution of processes of a similar type are writ-
ten as follows:
for variable = startvalue to endvalue [ by increment ] do
X
... # loop
... # body
X
Page 17 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
X is any character that does not appear in the loop body. 1 is used if
no increment is specified. For example:
for i = 1 to 5 do
X
circle at (i*0.2,0+0.33*(i%2))
X
produces:
==> See hardcopy in System Administrator's Reference Manual <==
Conditional execution
The syntax for conditional execution of pic statements is as follows:
if expression then X
...
X [ else X
...
X ]
X is any character that does not appear in the enclosed pic state-
ments. Depending on whether expression is true (not equal to 0) or
false (= 0), the segment after then or else is executed. If the else
branch is missing and expression is false, nothing will be executed.
The true-false semantic thus relates to the C language, and not
nroff/troff.
In addition to the arithmetic operators, conditional and logical
operators for C are also permitted:
Operator Meaning
______________________________________________________________
conditional operators == equal to
!= not equal to
< less than
<= less than or equal to
> greater than
>= greater than or equal to
______________________________________________________________
logical operators ! (logical) Not
&& (logical) And
|| (logical) Or
______________________________________________________________
You can even compare strings with the conditional operators == and !=
(more extensively than in C). For example:
for i = 0 to 0.8 by 0.2 do
X
if i == 0.2 || i == 0.6 then #
circle at (i, 0)
Page 18 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
# else #
circle at (i, 0.33)
#
X
produces:
==> See hardcopy in System Administrator's Reference Manual <==
Formatted values
You use the plot function to output values calculated in expressions.
The formatting that can be used here is similar to printf() in C:
plot expression [format] attributes
Example:
box "43 / 17"; arrow; box "arith." "unit"
arrow; box; plot 43 / 17 "%4.2f" at last box
produces:
==> See hardcopy in System Administrator's Reference Manual <==
Integrated functions
The following mathematical functions can be used to create values in
expressions:
sin(expression) sine of expression
cos(expression) cosine of expression
atan2(expression1, expression2) arctangent of (expression1/expression2)
log(expression) base 10 logarithm of expression
exp(expression) 10 "to the power of" expression
sqrt(expression) square root of expression
int(expression) integer expression
max(expression1, expression2) maximum value of expression1, expression2
min(expression1, expression2) minimum value of expression1, expression2
rand(expression) integer random number in the range [1,
expression]
Examples:
box "log(10)"; arrow; box "arith." "unit"
arrow; box; plot log(10) "%4.2f" at last box
produces:
==> See hardcopy in System Administrator's Reference Manual <==
Page 19 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
for i = 0 to 6.3 by 0.1 do
X
"." at (i, sin(i))
X
produces:
==> See hardcopy in System Administrator's Reference Manual <==
Shell commands and linking in files
You can also invoke shell commands from pic with:
sh X shellcommand X
X is again a character that does not appear in the enclosed segment.
Please note that like pic output, any output of the shell command is
sent to standard output.
Apart from the rarely used option of linking in files using .PS <file,
the much more flexible copy command can also be used, and can be
specified at any position within a picture. The simplest form is:
copy "file"
This statement is simply replaced by the contents of file. If file
contains .PS/.PE, they are ignored. This means that existing pictures
can easily be used in other pictures. The copy function also offers
the possibility of specifying parameters for macros externally:
copy "file" thru macroname or
copy "file" thru X replacementstring X
Every line in the copied file invokes the macros specified in either
of these ways. This means that the fields of the file content form the
macro parameters. For example, both the input
define CI X circle rad $1 at 0,0 X
copy "radian" thru CI
and
copy "radian" thru X circle rad $1 at 0,0 X
create this picture with the file radian:
==> See hardcopy in System Administrator's Reference Manual <==
Page 20 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
ERROR HANDLING AND AVOIDING ERRORS
The most harmless pic message is
pic: xx X yy picture shrunk to aa X bb
It means that a picture has exceeded the page margins and has been
reduced automatically by pic.
If you make a grammatical error when describing a picture, pic tries
to specify the position at which the error has occurred. For example,
the invalid input
circle move circle
produces the message:
pic: syntax error near line n, file abc
context is
circle >>> move <<< circle
The >>> <<< characters mark the position at which the error was esta-
blished. In some cases, the cause of the error may be before this
position. pic ends processing following such a message.
pic provides the print statement for testing and debugging. print can
output the values in expressions (and also the variables therefore),
positions and complete strings to standard error output. For example:
box
print "The current position is"
print Here
print "The box width is"
print boxwid
outputs the following messages to standard error output:
The current position is
0.75, 0
The box width is
0.75
To check whether pic runs without an error message, enter the follow-
ing command:
pic file >/dev/null
pic therefore does not produce troff output, but the error messages
and print output are shown.
A good way to suppress errors caused by the effects of one picture on
another picture in the same document is to place each picture in its
own block:
Page 21 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
.PS
[ ...
...
... ]
.PE
This means, for example, that changes to standard variables only
affect the current picture.
EXAMPLES
Example 1
Information flow diagram:
==> See hardcopy in System Administrator's Reference Manual <==
The information flow diagram was produced from the following input:
.PS
scale=2.54
# boxes right
boxht = 1; boxwid = 2
BoxTM: box "TM" "\s-1management\s0"
BoxTCB: box with .n at BoxTM.s -(0,1.5) "TCB"
BoxPCB: box with .n at BoxTCB.s -(0,6) "PCB"
# boxes left
BoxWG: box with .e at BoxTCB.w -(5.8,0) "working" "groups"
BoxPG: box with .n at BoxWG.s -(0,6) "project" "groups"
# central circles
Circledemand: circle diam 1.8 with .e at BoxTCB.w -(2,0) \
"making" "demands"
Circleproduct: circle rad same with .n at Circledemand.s -(0,1) \
"product" "planning"
Circleproject: circle rad same with .n at Circleproduct.s -(0,1) \
"project" "planning"
Circledevelop: circle rad same with .n at Circleproject.s -(0,1) \
"product" "developing"
# right circle
Circledecision: circle rad same with .w at Circleproduct.e +(2.1,0) \
"product" "devel." "decision"
# connecting arrows
arrow from BoxTCB.s to Circledecision.n
arrow from BoxWG.e to Circledemand.w
arrow from BoxPG.e to Circleproject.w
arrow from BoxPG.e to Circledevelop.n
arrow from BoxPCB.n to Circleproduct.e
Page 22 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
arrow dotted from BoxTCB.n to BoxTM.s
arrow dotted from Circledecision.s to BoxPCB.n
arrow dotted from Circledemand.e to BoxTCB.w
arrow dotted from Circledevelop.e to BoxPCB.s
arrow dotted from Circleproject.e to BoxPCB.w
arrow dotted from Circleproduct.e to BoxTCB.s
arrow dotted from Circleproduct.w to BoxWG.s
arrow dotted from Circleproduct.w to BoxPG.n
arrow dashed from BoxPCB.w +(0,.2) to Circleproject.e +(0,.2)
arrow dashed from BoxPCB.s +(-.4,0) to Circledevelop.e +(0,.2)
arrow dashed from BoxTCB.s +(-.2,0) to Circleproduct.e +(0,.2)
arrow dashed from BoxTCB.w +(0,.2) to Circledemand.e +(0,.2)
# spline
spline -> left 5.5 from Circledevelop.w then up 8.5 \
then right 1.5
.PE
Example 2
We will now draw a Christmas greeting:
==> See hardcopy in System Administrator's Reference Manual <==
The Christmas greeting was produced from the following input:
.PS 3.9
define fir Y FIR: [
xshift=1.0i
yshift=-2.0i
rd=1.5i
pi=atan2(0,-1)
p2=pi/2
an=pi/5
ic=pi/60
for i = p2 + ic to p2 + an by ic do X
arc -> from xshift + 0,yshift + rd \
to xshift + rd * cos(i),yshift + rd * sin(i) rad rd X
# 2nd (lower) branch
an2=an/2
betan=pi/6
r2=rd/2
ic2=pi/30
ctx1=rd*cos(p2+an2)
ctx=xshift + ctx1
cty1=rd*sin(p2+an2)
cty=yshift+cty1-r2
Page 23 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
for i = p2 - betan + ic2 to p2 by ic2 do X
arc -> from ctx + r2 * cos(p2 - betan),cty + r2 * sin(p2 -betan) to \
ctx + r2 * cos(i),cty + r2 * sin(i) rad r2 X
# glitter ball
kh = 0.3i
ll=kh/2
rk= ll/2
cx= ctx
cy= cty+r2-ll-rk
h=rk/5
L: line down ll
C: circle rad rk at cx,cy
for ynew=0.0 to rk by h do X
yh=cy+ynew
yl=cy-ynew
xnew=sqrt(rk*rk-ynew*ynew)
xr=cx+xnew
xl=cx-xnew
line dotted .02 from xl,yh to xr-.01,yh
line dotted .02 from xl,yl to xr-.01,yl
X
# 3rd (higher) branch
an2 = 3 * an/4
betan = pi/6
shan = pi - pi/6
r2 = rd/2
ic2 = pi/30
ctx1 = rd * cos(p2 + an2)
ctx = xshift + ctx1 - r2 * cos(shan)
cty1 = rd * sin(p2 + an2)
cty = yshift + cty1 - r2 * sin(shan)
for i = shan - betan + ic2 to shan by ic2 do X
arc -> from ctx + r2 * cos(shan - betan),cty + r2 * sin(shan-betan) \
to ctx + r2 * cos(i),cty + r2 * sin(i) rad r2 X
# candle and wick
kh = 0.3i
kw = kh/4
krzx = xshift + rd * cos(p2 + an/3)
krzy = yshift + rd * sin(p2 + an/3)
move to krzx,krzy + kh
KRZ: box ht kh wid kw
Page 24 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
line up kh/10 from KRZ.n
# flame
fh = kh/3
fw = fh/3
ellipse ht fh wid fw
# rays
flcx = krzx + kw/2 -.035
flcy = krzy + kh + kh/10 + fh/2
gamfac = 6
gams = 2 * pi/gamfac
shni = fh
shno = fh * 1.8
for i = -pi/2 + gams to 3 * pi/2 - gams by gams do X
line from flcx + shni * cos(i),flcy + shni * sin(i) \
to flcx + shno * cos(i),flcy + shno * sin(i) X
]
# frame
air = 0.2i
box ht last [].ht + 1.3 * air wid last [].wid + air at last []
Y
fir
.PE
Example 3
Pie chart:
==> See hardcopy in System Administrator's Reference Manual <==
The pie chart was produced from the following input:
.PS
scale=2.54
copy "pietxtmacro"
PIE: [
pietxt(2.5,30,0,5,0,"8.3 %")
pietxt(2.5,40,30,15,0,"11.1 %")
pietxt(2.5,60,70,25,0,"16.7 %")
pietxt(2.5,30,130,490,0,"8.3 %")
pietxt(2.5,200,160,13,1,"Rest")
Page 25 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
]
circle rad 2.53 at PIE.c
.PE
The integrated pietxtmacro file contains the basic definitions and has
the following content:
.\"=========================================================
.\"
.\" pietxt: Draw a pie chart, optional dotted lines.
.\" Add a string to each piece.
.\"
.\" The name of the macro is pietxt.
.\" Auxiliary macros are pie, pieaux, pietxaux.
.\"=========================================================
.\" Parameters are:
.\"
.\" cx x-coordinate of the center of the circle.
.\" cy y-coordinate of the center of the circle.
.\" rd Radius of the circle.
.\" phi Angle size of the piece of pie ( >=0,
.\" 360 = full circle).
.\" alfa Rotating angle of the piece (arbitrary,
.\" alfa=0: Start right, horizontal).
.\" h Number of lines per radius to be used for
.\" hatching (h=0: Blank piece). Large h causes
.\" blackening of the piece.
.\" dflag =1: line is dotted. Any other value: line is thru.
.\" str A string attached to the piece of pie.
.\"=========================================================
.\"
.PS
#=========================================================
# Constants and initializations
#=========================================================
pi = atan2(0,-1)
pi2 = pi / 2.0
#=========================================================
# pieaux( cx, cy, rd, phi, alfa, hdist, dfl ):
# Auxiliary macro for 0 <= phi <= pi.
#
# phi, alfa are in radians (2 pi = full circle),
# hdist is the (absolute) distance between hatching lines.
# dfl is a flag that decides if lines are to be dotted.
#=========================================================
define pieaux @
Page 26 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
#---------------------------------------------------------
# Center and radius of circle
#---------------------------------------------------------
cxx = $1
cyy = $2
rdd = $3
#---------------------------------------------------------
# Angles in radians (i.e. 2 pi = full circle)
#---------------------------------------------------------
phix = $4
alfx = $5
#---------------------------------------------------------
# Distance between lines
#---------------------------------------------------------
hdist = $6
#---------------------------------------------------------
# Line-dotting flag
#---------------------------------------------------------
dfl = $7
#---------------------------------------------------------
# Trigonometric quantities that are often used
#---------------------------------------------------------
cosp = cos(phix)
sinp = sin(phix)
tanp = sinp / cosp
rcosp = rdd * cosp
cosa = cos(alfx)
sina = sin(alfx)
#=========================================================
# Action
#=========================================================
#---------------------------------------------------------
# 0 <= phid <= 90 degree
#---------------------------------------------------------
for x = 0.0 to rdd-.01 by hdist do X
if x < rcosp then Y yh = x * tanp Y \
else Y yh = sqrt(rdd * rdd + 0.1 - x * x) Y
Page 27 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
yl = 0
#---------------------------------------------------------
# Turn points (x,yh) and (x,yl) by alfx (2 x 2 matrix)
#---------------------------------------------------------
x1 = cxx + x * cosa - yh * sina
y1 = cyy + x * sina + yh * cosa
x2 = cxx + x * cosa - yl * sina
y2 = cyy + x * sina + yl * cosa
if dfl == 1 then Q line dotted hdist from x1-.01,y1-.01 \
to x2+.01,y2+.01 Q \
else Q line from x1+.01,y1 to x2,y2 Q
X
#---------------------------------------------------------
# 90 < phi <= 180 degree
#---------------------------------------------------------
if phix > pi2 then Z
for xt = hdist to -rcosp by hdist do X
x = -xt
yh = sqrt(rdd * rdd - x * x)
yl = x * tanp
#---------------------------------------------------------
# Turn points (x,yh) and (x,yl) by alfx (2 x 2 matrix)
#---------------------------------------------------------
x1 = cxx + x * cosa - yh * sina
y1 = cyy + x * sina + yh * cosa
x2 = cxx + x * cosa - yl * sina
y2 = cyy + x * sina + yl * cosa
if dfl == 1 then Q line dotted hdist from x1-.01,y1-.01 \
to x2+.01,y2+.01 Q \
else Q line from x1,y1 to x2,y2 Q
X
Z
@
#===================== end of pieaux =====================
Page 28 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
#=========================================================
# pietxaux( cx, cy, rd, phi, alfa, str ): Pie text macro.
#
# str ($6) is a string to be attached to the piece of pie.
#
# phi and alfa are degrees (full circle = 360°).
#=========================================================
#---------------------------------------------------------
# Draw a radial line for the text
#---------------------------------------------------------
define pietxaux &
ccxx = $1
ccyy = $2
rrdd = $3
phii = $4
alff = $5
whspace = rrdd / 8
rd1 = rrdd + whspace
rd2 = rd1 + rrdd / 10
bigr = rd2 + ( rrdd / 20 )
#---------------------------------------------------------
# Compute the 'center' angle and convert it to radians
#---------------------------------------------------------
gamma = ( alff + phii / 2 ) * pi / 180.0
cosg = cos( gamma )
sing = sin( gamma )
xx1 = ccxx + rd1 * cosg
yy1 = ccyy + rd1 * sing
xx2 = ccxx + rd2 * cosg
yy2 = ccyy + rd2 * sing
line from xx1,yy1 to xx2,yy2
#---------------------------------------------------------
# Draw a horizontal line for the text, left or right.
# Add text (1 string).
#---------------------------------------------------------
if cosg < 0 then X
line to ccxx - bigr,yy2
line invis to ccxx - bigr - whspace,yy2
$6 rjust
X \
else X
Page 29 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
line to ccxx + bigr, yy2
line invis to ccxx + bigr + whspace,yy2
$6 ljust
X
&
#===================== end of pietxaux =====================
#=========================================================
# pie( cx, cy, rd, phi, alfa, haux, dflag ):
# Pie chart macro, raw.
#
# Draw a circle at (cx,cy) with radius rd.
# Cut a piece of pie of angle phi turned by alfa.
# h is the number of lines used for hatching.
# dflag is a line-dotting flag (=1).
#
# phi and alfa are degrees (full circle = 360°).
#=========================================================
define pie %
#---------------------------------------------------------
# Center and radius of circle
#---------------------------------------------------------
cx = $1
cy = $2
rd = $3
#---------------------------------------------------------
# Angles for pie (in degrees, i.e. 360° = full circle).
# phid: Size of piece ( >= 0 ).
# alfad: Angle by which the piece is turned (arbitrary).
#---------------------------------------------------------
phid = $4
alfad = $5
#---------------------------------------------------------
# haux: Number of lines for hatching.
# h: Distance between lines.
#---------------------------------------------------------
haux = $6
h = 2 * rd
if haux > 0 then W
h = rd / haux
W
Page 30 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
#---------------------------------------------------------
# Line-dotting flag
#---------------------------------------------------------
dflag = $7
#---------------------------------------------------------
# Angles in radians (i.e. 2 pi = full circle)
#---------------------------------------------------------
phi = phid * pi / 180.0
alfa = alfad * pi / 180.0
beta = alfa + phi
#=========================================================
# Action
#=========================================================
#---------------------------------------------------------
# Draw circle.
# Delimit the piece of pie by lines.
#---------------------------------------------------------
circle rad rd at cx,cy
circle rad rd+.01 at cx,cy
line from cx,cy to cx + rd * cos(alfa),cy + rd * sin(alfa)
line from cx,cy to cx + rd * cos(beta),cy + rd * sin(beta)
#---------------------------------------------------------
# Hatch only if haux > 0 (number of lines for hatching).
#---------------------------------------------------------
if haux > 0 then Y
#---------------------------------------------------------
# 0 <= phid <= 180 degree
#---------------------------------------------------------
if phi <= pi then W
pieaux( cx, cy, rd, phi, alfa, h, dflag )
W
#---------------------------------------------------------
# phid > 180 degree
#---------------------------------------------------------
if phi > pi then W
Page 31 Reliant UNIX 5.44 Printed 11/98
pic(1M) pic(1M)
pieaux( cx, cy, rd, pi, alfa, h, dflag )
pieaux( cx, cy, rd, phi - pi, alfa + pi, h, dflag )
W
Y
%
#===================== end of pie =====================
#=========================================================
# pietxt( rd, phi, alfa, h, dflag, str ):
# Pie chart macro, with text.
#
# Draw a circle with radius rd.
# Cut a piece of pie of angle phi turned by alfa.
# h is the number of lines used for hatching.
# dflag is a line-dotting flag (=1).
# str is a string to be attached to the piece of pie.
#
# phi and alfa are degrees (full circle = 360°).
#=========================================================
define pietxt !
pie( 0, 0, $1, $2, $3, $4, $5 )
pietxaux( 0, 0, $1, $2, $3, $6 )
!
#===================== end of pietxt =====================
.PE
SEE ALSO
grap(1M), troff(1M), troff(5).
REFERENCES
B. W. Kernighan, PIC - A Crude Graphics Language for Typesetting
D. Dougherty, T. O'Reilly, UNIX TEXT PROCESSING, Hayden Books,
Indianapolis, Indiana 46268 USA, ISBN 0-672-46291-5
Page 32 Reliant UNIX 5.44 Printed 11/98