|
|
1.1 root 1: .so ../ADM/mac
2: .XX pic 53 "Pic \(em A Graphics Language for Typesetting"
3: ...\" Wed Sep 24 15:49:34 EDT 1986
4: ....TR 116
5: ....TR 85
6: ....TM 80-1272-2 39199 39199-11
7: .....graphics
8: .TL
9: Pic \(em A Graphics Language for Typesetting
10: .br
11: User Manual\(dg
12: .AU
13: Brian W. Kernighan
14: .AI
15: .MH
16: .AB
17: .PP
18: .IT Pic
19: is a language for drawing simple figures
20: on a typesetter.
21: The basic objects in
22: .IT pic
23: are
24: boxes,
25: circles,
26: ellipses,
27: lines,
28: arrows,
29: arcs,
30: spline curves,
31: and text.
32: These may be placed anywhere,
33: at positions specified absolutely
34: or in terms of previous objects.
35: The example below illustrates the style and basic capabilities
36: of the language.
37: .PS
38: ellipse "document"
39: arrow
40: box "PIC"
41: arrow
42: box "TBL/EQN" "(optional)" dashed
43: arrow
44: box "TROFF"
45: arrow
46: ellipse "typesetter"
47: .PE
48: This picture was created with the input
49: .P1
50: \&.PS
51: ellipse "document"
52: arrow
53: box "PIC"
54: arrow
55: box "TBL/EQN" "(optional)" dashed
56: arrow
57: box "TROFF"
58: arrow
59: ellipse "typesetter"
60: \&.PE
61: .P2
62: .PP
63: .IT Pic
64: is a
65: .IT troff
66: preprocessor;
67: it passes most of its input through untouched, but translates
68: commands between
69: .CW .PS
70: and
71: .CW .PE
72: into
73: .IT troff
74: commands that draw the pictures.
75: .AE
76: .FS
77: \(dg This is a revised version of |reference(pic cstr 116).
78: .FE
79: .NH
80: Introduction
81: .PP
82: .IT Pic
83: is a language for drawing
84: pictures.
85: It operates as yet another
86: .IT troff
87: |reference(latest reference troff)
88: preprocessor
89: (in the same style as
90: .IT eqn
91: |reference(latest eqn) and
92: .IT tbl
93: |reference(latest tbl)),
94: with pictures delimited by
95: .CW .PS
96: and
97: .CW .PE .
98: .PP
99: .IT Pic
100: was inspired partly by Chris Van Wyk's
101: early work on
102: .IT ideal
103: |reference(ideal acm);
104: it has somewhat the same capabilities,
105: but quite a different flavor.
106: In particular,
107: .IT pic
108: is much more procedural\(ema picture
109: is drawn by specifying (sometimes in painful detail)
110: the motions that one goes through to draw it.
111: Other direct influences include the PICTURE language
112: |reference(beatty picture),
113: the V viewgraph language |reference(viewgraph-v),
114: and, more recently, new features from the
115: .IT grap
116: language |reference(bentley kernighan grap)
117: for typesetting graphs.
118: .PP
119: This paper is primarily a user's manual for
120: .IT pic ;
121: a discussion of design issues and user experience
122: may be found in
123: |reference(kernighan pic spe).
124: The next section shows how to use
125: .IT pic
126: in the most simple way.
127: Subsequent sections describe how to change
128: the sizes of objects when the defaults are wrong,
129: and how to change their positions when the standard positioning rules
130: are wrong.
131: An appendix describes the language succinctly and
132: summarizes changes since the last manual.
133: .........
134: .NH
135: Basics
136: .PP
137: .IT Pic
138: provides boxes, lines, arrows, circles, ellipses, arcs,
139: and splines (smooth curves),
140: plus facilities for positioning
141: and labeling them.
142: The picture below shows all of the fundamental objects
143: (except for splines)
144: in their default sizes:
145: .PS
146: box "box"
147: move
148: line "line" above
149: move
150: arrow "arrow" above
151: move
152: circle "circle"
153: move
154: ellipse "ellipse"
155: move down .25 right
156: arc "arc"
157: .PE
158: Each picture begins with
159: .CW .PS
160: and ends with
161: .CW .PE ;
162: between them are commands to describe the picture.
163: Each command is typed on a line by itself.
164: For example
165: .P1
166: \&.PS
167: box "this is" "a box"
168: \&.PE
169: .P2
170: creates a standard box (\(34 inch wide, \(12 inch high)
171: and centers the two pieces of text in it:
172: .PS
173: box "this is" "a box"
174: .PE
175: .PP
176: Each line of text is a separate quoted string.
177: Quotes are mandatory, even if the text contains no blanks.
178: (Of course there needn't be any text at all.)
179: Each line will be
180: printed in the current size and font,
181: centered horizontally, and separated
182: vertically by the current
183: .IT troff
184: line spacing.
185: .IT Pic
186: does
187: not
188: center the complete drawing itself,
189: but the default definitions of
190: .CW .PS
191: and
192: .CW .PE
193: in the
194: .CW -ms
195: macro package do.
196: .PP
197: You can use
198: .CW circle
199: or
200: .CW ellipse
201: in place of
202: .CW box :
203: .PS
204: circle "this is" "a box"
205: move; move
206: ellipse "this is" "a box"
207: .PE
208: .PP
209: Text is centered on lines and arrows; if there is more than one
210: line of text, the lines are centered above and below:
211: .P1
212: line "this is" "a line"
213: .P2
214: .PS
215: line "this is" "a line"
216: .PE
217: .P1
218: arrow "this is" "an arrow"
219: .P2
220: .PS
221: arrow "this is" "an arrow"
222: .PE
223: .PP
224: Boxes and lines may be dashed or dotted;
225: just add the word
226: .CW dashed
227: or
228: .CW dotted
229: after
230: .CW box
231: or
232: .CW line :
233: .P1
234: line dashed "dashed" "line"
235: .P2
236: .PS
237: line dashed "dashed" "line"
238: .PE
239: .PP
240: Arcs by default turn 90 degrees counterclockwise from the current direction;
241: you can make them turn clockwise by saying
242: .CW arc
243: .CW cw :
244: .P1
245: line; arc; arc cw; arrow
246: .P2
247: .PS
248: line; arc; arc cw; arrow
249: .PE
250: A spline might well do this job better; we will return to that shortly.
251: .PP
252: As you might guess,
253: .P1
254: arc; arc; arc; arc
255: .P2
256: draws a circle, though not very efficiently.
257: Notice that several commands can be put on a single line
258: if they are separated by semicolons.
259: .PP
260: Objects are normally drawn one after another,
261: left to right,
262: and connected at the obvious places:
263: .P1
264: arrow; box "input"; arrow; box "process"; arrow; box "output"; arrow
265: .P2
266: .PS
267: arrow; box "input"; arrow; box "process"; arrow; box "output"; arrow
268: .PE
269: One way to leave a space is with
270: .CW move :
271: .P1
272: box; move; box; move; box
273: .P2
274: .PS
275: box; move; box; move; box
276: .PE
277: .PP
278: Although objects are normally connected left to right,
279: this can be changed.
280: If you specify a direction (as a separate object), subsequent objects
281: will be joined in that direction:
282: .P1
283: down; box; arrow; ellipse; arrow; circle
284: .P2
285: .PS
286: down; box; arrow; ellipse; arrow; circle
287: .PE
288: .P1
289: left; box; arrow; ellipse; arrow; circle
290: .P2
291: .PS
292: left; box; arrow; ellipse; arrow; circle
293: .PE
294: Each new picture begins going to the right.
295: .PP
296: Normally, figures are drawn at a fixed scale,
297: with objects of a standard size.
298: It is possible, however, to arrange that a figure be expanded or shrunk
299: to fit a particular width.
300: If the
301: .CW .PS
302: line contains a number, the drawing is forced to be that many inches wide,
303: with the height scaled proportionately.
304: Thus
305: .P1
306: \&.PS 3.5
307: .P2
308: causes the picture to be 3.5 inches wide.
309: If two dimensions are specified, the second is the height.
310: .PP
311: .IT Pic
312: is pretty dumb about the size of text in relation
313: to the size of boxes, circles, and so on.
314: There is no way to say
315: ``make a box that just fits around this text''
316: or ``make this text fit inside this circle''
317: or ``draw a line as long as this text.''
318: Tight fitting of text
319: can generally only be done by trial and error.
320: .PP
321: Speaking of errors,
322: if you make a grammatical error in the way you describe
323: a picture,
324: .IT pic
325: will complain and try to indicate where.
326: For example, the invalid input
327: .P1
328: box arrow box
329: .P2
330: will draw the message
331: .P1
332: pic: syntax error near line 5, file -
333: context is
334: box >>> arrow <<< box
335: .P2
336: The brackets
337: point to the place where the error was first noted;
338: it sometimes follows
339: the word in error, although in this example it's right on target.
340: The filename
341: .CW - ' `
342: is the standard input.
343: .NH
344: Controlling Sizes
345: .PP
346: This section deals with how to
347: control the sizes of objects
348: when the default sizes are not what is wanted.
349: The next section deals with positioning them
350: when the default positions are not right.
351: .PP
352: Each object that
353: .IT pic
354: knows about
355: (boxes, circles, etc.) has
356: associated dimensions, like height, width, radius, and so on.
357: By default,
358: .IT pic
359: tries to choose sensible default values for these dimensions,
360: so that simple pictures can be drawn with a minimum
361: of fuss and bother.
362: All of the figures and motions shown so far
363: have been in their default sizes:
364: .DS
365: .ta 1i
366: box \(34" wide \(mu \(12" high
367: circle \(12" diameter
368: ellipse \(34" wide \(mu \(12" high
369: arc \(12" radius
370: line or arrow \(12" long
371: move \(12" in the current direction
372: .DE
373: .LP
374: When necessary,
375: you can make any object any size you want:
376: .P1
377: box width 3 height 0.1; circle radius 0.1
378: .P2
379: .PS
380: box wid 3 ht 0.1; circle radius 0.1
381: .PE
382: All positions and dimensions are in inches, so
383: the box is 3 inches wide and 1/10 inch high and the circle has radius 1/10 inch.
384: .PP
385: An attribute like
386: .CW width
387: changes only the one instance of the object.
388: You can also change the default size for all objects
389: of a particular type by assigning values to
390: .IT pic
391: variables;
392: this will be discussed in Section 6.
393: .PP
394: The attributes of
395: .CW height
396: (which you can abbreviate to
397: .CW ht )
398: and
399: .CW width
400: (or
401: .CW wid )
402: apply to boxes, circles,
403: ellipses,
404: and to the head on an arrow.
405: The attributes of
406: .CW radius
407: (or
408: .CW rad )
409: and
410: .CW diameter
411: (or
412: .CW diam )
413: can be used for circles and arcs if they seem more natural.
414: .PP
415: Lines and arrows are most easily drawn by specifying
416: the amount of motion from where you are right now,
417: in terms of directions.
418: Accordingly the words
419: .CW up ,
420: .CW down ,
421: .CW left
422: and
423: .CW right
424: and an optional distance can be attached to
425: .CW line ,
426: .CW arrow ,
427: and
428: .CW move :
429: .P1
430: line up 1 right 2
431: arrow left 2
432: move left 0.1
433: line <-> down 1 "height " rjust
434: .P2
435: .PS
436: line up 1 right 2
437: arrow left 2
438: move left 0.1
439: line <-> down 1 "height " rjust
440: .PE
441: The notation
442: .CW <->
443: indicates a two-headed arrow;
444: use
445: .CW ->
446: for a head on the end and
447: .CW <-
448: for one on the start.
449: Lines and arrows are really the same thing;
450: in fact,
451: .CW arrow
452: is a synonym for
453: .CW line
454: .CW -> .
455: .PP
456: If you don't specify any distance after
457: .CW up ,
458: .CW down ,
459: etc.,
460: .IT pic
461: uses the standard distance:
462: .P1
463: line up right; line down; line down left; line up
464: .P2
465: .PS
466: line up right; line down; line down left; line up
467: .PE
468: If you omit the direction associated with a distance,
469: the current direction is used.
470: .PP
471: Boxes and lines may be dotted or dashed:
472: .P1
473: box dotted; line dotted; move; line dashed; box dashed
474: .P2
475: .PS
476: box dotted; line dotted; move; line dashed; box dashed
477: .PE
478: If there is a number after
479: .CW dot ,
480: the dots will be approximately that far apart.
481: You can also control the size of the dashes (at least somewhat):
482: if there is a length after the word
483: .CW dashed ,
484: the dashes will be that long,
485: and the intervening spaces will be as close as possible to that size:
486: .P1
487: line right 5 dashed; move left 5 down .25; right
488: line right 5 dashed 0.25; move left 5 down .25; right
489: line right 5 dashed 0.5; move left 5 down .25; right
490: line right 5 dashed 1
491: .P2
492: .PS
493: line right 5 dashed; move left 5 down .25; right
494: line right 5 dashed 0.25; move left 5 down .25; right
495: line right 5 dashed 0.5; move left 5 down .25; right
496: line right 5 dashed 1
497: .PE
498: Dotted or dashed attributes apply only to lines and boxes.
499: .LP
500: .PP
501: You can make any object invisible by adding the word
502: .CW invis
503: after it.
504: This is particularly useful for positioning things correctly
505: near text:
506: .P1
507: box invis "input"; arrow; box invis "output"
508: .P2
509: .PS
510: box invis "input"; arrow; box invis "output"
511: .PE
512: .PP
513: Text may be positioned on lines and arrows:
514: .P1
515: arrow "on top of"; move
516: arrow "above" "below"; move
517: arrow "above" above; move
518: arrow "below" below; move
519: arrow "above" "on top of" "below"
520: .P2
521: .PS
522: arrow "on top of"; move
523: arrow "above" "below"; move
524: arrow "above" above; move
525: arrow "below" below; move
526: arrow "above" "on top of" "below"
527: .PE
528: .LP
529: .PP
530: The ``width'' of an arrowhead is the distance across
531: its tail;
532: the ``height'' is the distance along the shaft.
533: The arrowheads in this picture are default size and shape.
534: .PP
535: As we said earlier, arcs go 90 degrees counterclockwise
536: from where you are right now, and
537: .CW arc
538: .CW cw
539: changes this to clockwise.
540: The default radius is the same as for circles,
541: but you can change it with the
542: .CW rad
543: attribute.
544: It is also easy to draw arcs between specific places;
545: this will be described in the next section.
546: .PP
547: To put an arrowhead on an arc, use one of
548: .CW <- ,
549: .CW ->
550: or
551: .CW <-> ,
552: as with lines.
553: .LP
554: .PP
555: In all cases,
556: unless an explicit dimension for some object is specified,
557: you will get the default size.
558: If you want an object to have the same size
559: as the previous one of that kind,
560: add the word
561: .CW same .
562: Thus
563: in the set of boxes given by
564: .P1
565: down; box ht 0.2 wid 1.5; move down 0.15; box same; move same; box same
566: .P2
567: .PS
568: down; box ht 0.2 wid 1.5; move down 0.15; box same; move same; box same
569: .PE
570: the dimensions set by the first
571: .CW box
572: are used several times;
573: similarly, the amount of motion for the second
574: .CW move
575: is the same as for the first one.
576: .PP
577: You can change the default sizes of objects
578: by assigning values to the variables that define their values.
579: Here is the list, with their default values:
580: .P1
581: .ta 2i 3.3i
582: boxwid = 0.75; boxht = 0.5
583: linewid = 0.75; lineht = 0.5
584: circlerad = 0.25; arcrad = 0.25
585: ellipsewid = 0.75; ellipseht = 0.5
586: movewid = 0.75; moveht = 0.5
587: textwid = 0; textht = 0
588: arrowwid = 0.05; arrowht = 0.1 \f1(These refer to the arrowhead.)\fP
589: dashwid = 0.05; arrowhead = 2 \f1(Arrowhead fill style)\fP
590: maxpsht = 8.5; maxpswid = 11 \f1(Maximum picture dimensions)\fP
591: fillval = 0.3; scale = 1
592: .P2
593: So if you want all your boxes to be long and skinny, and relatively close together,
594: .P1
595: boxwid = 0.1; boxht = 1
596: movewid = 0.2
597: box; move; box; move; box
598: .P2
599: .PS
600: boxwid = 0.1; boxht = 1
601: movewid = 0.2
602: box; move; box; move; box
603: .PE
604: .nf
605: .PS
606: x = boxwid
607: y = boxht
608: boxwid = 0.1
609: boxht = 1
610: movewid = 0.2
611: boxwid = x
612: boxht = y
613: arrowhead = 7
614: arrowhead = 2
615: .PE
616: .PP
617: Setting the variable
618: .CW arrowhead
619: to a value like 7 causes arrowheads to be filled by overstriking;
620: the default is 2:
621: .P1
622: arrowhead = 7; arrow; move; arrowhead = 2; arrow
623: .P2
624: .PS
625: arrowhead = 7; arrow; move; arrowhead = 2; arrow
626: .PE
627: .PP
628: .IT Pic
629: works internally in inches.
630: Setting the variable
631: .CW scale
632: to some value causes all dimensions to be scaled down
633: by that value.
634: Thus, for example,
635: .CW scale=2.54
636: causes dimensions to be interpreted as centimeters.
637: .PP
638: The numbers given in the
639: .CW .PS
640: line override the dimensions given in the picture;
641: these can be used to force a picture to a particular width and height.
642: Experience indicates that a good way to get a picture
643: of the right size is to enter its dimensions in inches,
644: then if necessary add a width and perhaps height to the
645: .CW .PS
646: line.
647: .PP
648: Once set, variables like
649: .CW boxht
650: retain their values from one picture to the next.
651: You can reset variables to their default values by listing them in a
652: .CW reset
653: statement:
654: .P1
655: reset boxht, boxwid
656: .P2
657: A bare
658: .CW reset
659: resets all variables.
660: .PP
661: There is a minimal facility for filling or shading objects,
662: intended for Postscript output devices.
663: The attribute
664: .CW fill
665: .IT expr
666: sets the gray scale value to
667: .IT expr ;
668: the default, determined by the variable
669: .CW fillval ,
670: is 0.3.
671: Following Postscript, smaller values are darker.
672: Thus:
673: .P1
674: box fill
675: box ht boxht/2 wid boxwid/2 "hello" at last box
676: .P2
677: .PS
678: reset
679: box fill
680: box ht boxht/2 wid boxwid/2 "hello" at last box
681: .PE
682: .CW fill
683: currently only applies to boxes, circles, and ellipses.
684: .NH
685: Controlling Positions
686: .PP
687: You can place things anywhere you want;
688: .IT pic
689: provides a variety of ways to talk about positions.
690: .IT Pic
691: uses a standard Cartesian coordinate system with
692: .IT x
693: increasing rightwards and
694: .IT y
695: increasing upwards,
696: so any point or object has an
697: .IT x
698: and
699: .IT y
700: position, measured in inches.
701: The first object is placed with its start at position 0,0 by default.
702: The
703: .IT x,y
704: position of a box, circle or ellipse is its geometric center;
705: the position of a line or spline or motion is its beginning;
706: the position of an arc is the center of the corresponding circle.
707: .PP
708: Position modifiers like
709: .CW from ,
710: .CW to ,
711: .CW by
712: and
713: .CW at
714: are followed by an
715: .IT x,y
716: pair, and
717: can be attached to boxes, circles, lines, motions, and so on,
718: to specify or modify a position.
719: .PP
720: You can also use
721: .CW up ,
722: .CW down ,
723: .CW right ,
724: and
725: .CW left
726: with
727: .CW line
728: and
729: .CW move :
730: .P1
731: box ht 0.2 wid 0.2 at 0,0 "1"
732: move right 0.5 # or "move to 0.5,0"
733: box ht 0.2 wid 0.2 "2"
734: move right 0.5 # or "move 0.5" or "move same"
735: box ht 0.2 wid 0.2 "3"
736: .P2
737: .PS 2
738: box ht 0.2 wid 0.2 at 0,0 "1"
739: move right 0.5 # or "move to 0.5,0"
740: box ht 0.2 wid 0.2 "2"
741: move right 0.5
742: box ht 0.2 wid 0.2 "3"
743: .PE
744: Comments can be used in pictures;
745: they begin with a
746: .CW #
747: and end at the end of the line.
748: .PP
749: Attributes like
750: .CW ht
751: and
752: .CW wid
753: and positions like
754: .CW at
755: can be written out in any order.
756: So
757: .P1
758: box ht 0.2 wid 0.2 at 0,0
759: box at 0,0 wid 0.2 ht 0.2
760: box ht 0.2 at 0,0 wid 0.2
761: .P2
762: are all equivalent, though the last is harder to read
763: and thus less desirable.
764: .PP
765: The
766: .CW from
767: and
768: .CW to
769: attributes are particularly useful with arcs,
770: to specify the endpoints.
771: By default, arcs are drawn counterclockwise,
772: .P1
773: "+" at 0,0
774: arc -> from 0.5,0 to 0,0.5
775: arc -> cw from 0,0 to 1,0.5
776: .P2
777: .PS
778: "+" at 0,0
779: arc -> from 0.5,0 to 0,0.5
780: arc -> cw from 0,0 to 1,0.5
781: .PE
782: The radius can be made large to provide flat arcs:
783: .P1
784: arc -> cw from 0,0 to 2,0 rad 15
785: .P2
786: .PS
787: arc -> cw from 0,0 to 2,0 rad 15
788: .PE
789: If the circle is under-specified,
790: .IT pic
791: guesses a radius and/or center;
792: you will have to provide them explicitly if the guess is wrong.
793: .LP
794: .PP
795: We said earlier that
796: objects are normally connected left to right.
797: This is an over-simplification.
798: The truth is that objects are connected together
799: in the direction specified by the most recent
800: .CW up ,
801: .CW down ,
802: .CW left
803: or
804: .CW right
805: (either alone or as part of some object).
806: Thus, in
807: .P1
808: arrow left; box; arrow; circle; arrow
809: .P2
810: the
811: .CW left
812: implies connection towards the left:
813: .PS
814: arrow left; box; arrow; circle; arrow
815: .PE
816: This could also be written as
817: .P1
818: left; arrow; box; arrow; circle; arrow
819: .P2
820: .PP
821: Objects are joined in the direction determined by the last
822: .CW up ,
823: .CW down ,
824: etc., with the entry point of the second object attached
825: to the exit point of the first
826: (which is fixed at the time of entry).
827: Entry and exit points for boxes, circles and ellipses are
828: on opposite sides.
829: This automatic connection and direction selection
830: works well if the direction doesn't change but it will occasionally surprise you:
831: .P1
832: arrow; circle; down; arrow
833: .P2
834: .PS
835: arrow; circle; down; arrow
836: .PE
837: The arrow comes out of the right side of the circle, not the bottom,
838: as might be expected.
839: .PP
840: If a set of commands is enclosed in braces
841: .CW {...} ,
842: the current position and direction of motion when the group is finished
843: will be exactly where it was when entered.
844: Nothing else is restored.
845: There is also a more general way to group objects,
846: using
847: .CW [
848: and
849: .CW ] ,
850: which is discussed in Section 9.
851: .NH
852: Labels and Corners
853: .PP
854: Objects can be labelled or named so that you can talk about them later.
855: For example,
856: .P1
857: Box1: box
858: # ... other stuff ...
859: move to Box1
860: .P2
861: Place names
862: .IT must
863: begin with an upper case letter
864: (to distinguish them from variable names,
865: which begin with lower case letters).
866: The name refers to the ``center''
867: of the object,
868: which is the geometric center for most things.
869: .PP
870: Other combinations also work:
871: .P1
872: line from Box1 to Box2
873: move to Box1 up 0.1 right 0.2
874: move to Box1 + 0.2,0.1 # same as previous
875: line to Box1 - 0.5,0
876: .P2
877: The reserved name
878: .CW Here
879: may be used to refer to the current position.
880: .PP
881: Labels can be reset several times in a single picture,
882: so a statement like
883: .P1
884: Box1: Box1 + 1,1
885: .P2
886: is perfectly legal.
887: .LP
888: .PP
889: You can also refer to previously drawn objects of each type,
890: using the word
891: .CW last .
892: For example, given the input
893: .P1
894: box "A"; circle "B"; box "C"
895: .P2
896: then
897: .CW last \& `
898: .CW box '
899: refers to box
900: .CW C ,
901: .CW last \& `
902: .CW circle '
903: refers to circle
904: .CW B ,
905: and
906: .CW 2nd \& `
907: .CW last
908: .CW box '
909: refers to box
910: .CW A .
911: Numbering of objects can also be done from the beginning,
912: so boxes
913: .CW A
914: and
915: .CW C
916: are
917: .CW 1st \& `
918: .CW box '
919: and
920: .CW 2nd \& `
921: .CW box '
922: respectively.
923: .PP
924: To cut down the need for explicit coordinates,
925: objects have ``corners'' named by compass points:
926: .P1
927: B: box "B.c" ht 1 wid 1.5
928: " B.e" at B.e ljust
929: " B.ne" at B.ne ljust
930: " B.se" at B.se ljust
931: "B.s" at B.s below
932: "B.n" at B.n above
933: "B.sw " at B.sw rjust
934: "B.w " at B.w rjust
935: "B.nw " at B.nw rjust
936: .P2
937: .PS
938: B: box "B.c" ht 1 wid 1.5
939: " B.e" at B.e ljust
940: " B.ne" at B.ne ljust
941: " B.se" at B.se ljust
942: "B.s" at B.s below
943: "B.n" at B.n above
944: "B.sw " at B.sw rjust
945: "B.w " at B.w rjust
946: "B.nw " at B.nw rjust
947: .PE
948: Note the use of
949: .CW ljust ,
950: .CW rjust ,
951: .CW above ,
952: and
953: .CW below
954: to alter the default positioning of text,
955: and of a blank within some strings to help space them away from a vertical line.
956: .PP
957: Lines and arrows have a
958: .CW start ,
959: an
960: .CW end
961: and a
962: .CW center
963: in addition to corners.
964: Circles and ellipses have corners too;
965: an arc has the same corners as the circle of which it is a part.
966: The words
967: .CW left ,
968: .CW right ,
969: .CW top ,
970: and
971: .CW bottom
972: are synonyms for
973: .CW west ,
974: .CW east ,
975: .CW north
976: and
977: .CW south .
978: .PP
979: It is often easiest to position objects by positioning
980: some part of one at some part of another,
981: for example the southwest corner of one at the southeast corner
982: of another.
983: The
984: .CW with
985: attribute
986: permits this kind of positioning:
987: .P1
988: box ht 0.75 wid 0.75
989: box ht 0.5 wid 0.5 with .sw at last box.se
990: .P2
991: .PS
992: box ht 0.75 wid 0.75
993: box ht 0.5 wid 0.5 with .sw at last box.se
994: .PE
995: Notice that the corner after
996: .CW with
997: is written
998: .CW .sw .
999: .PP
1000: As another example, consider
1001: .P1
1002: ellipse
1003: ellipse ht .2 wid .3 with .se at 1st ellipse.nw
1004: ellipse ht .2 wid .3 with .sw at 1st ellipse.ne
1005: .P2
1006: .PS
1007: ellipse
1008: ellipse ht .2 wid .3 with .se at 1st ellipse.nw
1009: ellipse ht .2 wid .3 with .sw at 1st ellipse.ne
1010: .PE
1011: .LP
1012: .PP
1013: Sometimes it is desirable to have a line intersect a circle
1014: at a point which is not one of the eight compass points
1015: that
1016: .IT pic
1017: knows about.
1018: In such cases, the proper visual effect can be obtained by using
1019: the attribute
1020: .CW chop
1021: to chop off part of the line:
1022: .P1
1023: circlerad = 0.15; arrowhead = 7
1024: circle "a"
1025: circle "b" at 1st circle - (0.4, 0.6)
1026: circle "c" at 1st circle + (0.4, -0.6)
1027: arrow from 1st circle to 2nd circle chop
1028: arrow from 1st circle to 3rd circle chop
1029: .P2
1030: .PS
1031: circlerad = 0.15; arrowhead = 7
1032: circle "a"
1033: circle "b" at 1st circle - (0.4, 0.6)
1034: circle "c" at 1st circle + (0.4, -0.6)
1035: arrow from 1st circle to 2nd circle chop
1036: arrow from 1st circle to 3rd circle chop
1037: reset
1038: .PE
1039: By default the line is chopped by
1040: .CW circlerad
1041: at each end.
1042: This may be changed:
1043: .P1
1044: line ... chop \f2r\fP
1045: .P2
1046: chops both ends by
1047: \f2r\fP, and
1048: .P1
1049: line ... chop \f2r1\fP chop \f2r2\fP
1050: .P2
1051: chops the beginning by
1052: .IT r1
1053: and the end by
1054: .IT r2 .
1055: More complicated intersections can be computed with
1056: the built-in trigonometric functions listed in the next section.
1057: .PP
1058: There is one other form of positioning that is sometimes useful,
1059: to refer to a point some fraction of the way between
1060: two other points.
1061: This can be expressed in
1062: .IT pic
1063: as
1064: .P1
1065: \f2fraction\fP of the way between \f2position1\fP and \f2position2\fP
1066: .P2
1067: where
1068: .IT fraction
1069: is any expression, and
1070: .IT position1
1071: and
1072: .IT position2
1073: are any positions.
1074: You can abbreviate this rather windy phrase;
1075: ``of the way'' is optional, and the whole thing can
1076: be written instead as
1077: .P1
1078: \f2fraction\fP < \f2position1\fP , \f2position2\fP >
1079: .P2
1080: As a pair of examples:
1081: .P1
1082: box
1083: arrow right from 1/3 of the way between last box.ne and last box.se
1084: arrow right from 2/3 <last box.ne, last box.se>
1085: .P2
1086: .PS
1087: box
1088: arrow right from 1/3 of the way between last box.ne and last box.se
1089: arrow right from 2/3 <last box.ne, last box.se>
1090: .PE
1091: .P1
1092: A: ellipse
1093: ellipse ht .2 wid .3 with .se at 1st ellipse.nw
1094: ellipse ht .2 wid .3 with .sw at 1st ellipse.ne
1095: circle rad .05 at 0.5 <A.nw,A.c>
1096: circle rad .05 at 0.5 <A.ne,A.c>
1097: arc from 0.25 <A.w,A.e> to 0.75 <A.w,A.e>
1098: .P2
1099: .PS
1100: A: ellipse
1101: ellipse ht .2 wid .3 with .se at 1st ellipse.nw
1102: ellipse ht .2 wid .3 with .sw at 1st ellipse.ne
1103: circle rad .05 at 0.5 <A.nw,A.c>
1104: circle rad .05 at 0.5 <A.ne,A.c>
1105: arc from 0.25 <A.w,A.e> to 0.75 <A.w,A.e>
1106: .PE
1107: Naturally,
1108: the distance given by
1109: .IT fraction
1110: can be greater than 1 or less than 0.
1111: .PP
1112: Advice:\
1113: experience suggests that the easiest way to position objects
1114: is by placing them relative to previous objects
1115: and places, using
1116: .CW with ,
1117: .CW at ,
1118: etc.
1119: This is better than using
1120: .CW move ;
1121: you should generally avoid
1122: .CW move .
1123: .NH
1124: Variables, Expressions and Built-in Functions
1125: .PP
1126: It's generally a bad idea to write everything in
1127: absolute coordinates if you are likely
1128: to change things.
1129: .IT Pic
1130: variables let you parameterize your picture:
1131: .P1
1132: a = 0.5; b = 1
1133:
1134: box wid a ht b
1135: ellipse wid a/2 ht 1.5*b
1136: Box2: Box1 - (a/2, b/2)
1137: .P2
1138: Expressions may use the standard operators
1139: .CW + ,
1140: .CW - ,
1141: .CW * ,
1142: .CW / ,
1143: .CW % ,
1144: .CW ^
1145: (exponentiation),
1146: and parentheses for grouping.
1147: .PP
1148: The most important variables are the predefined ones for
1149: controlling the default sizes of objects,
1150: listed in Section 3.
1151: These may be set at any time in any picture,
1152: and retain their values from picture to picture until reset.
1153: .PP
1154: You can use the height, width, radius,
1155: and
1156: .IT x
1157: and
1158: .IT y
1159: coordinates of any object or corner in an expression:
1160: .P1
1161: Box1.x # the \f2x\fP coordinate of the center of Box1
1162: Box1.ne.y # the \f2y\fP coordinate of the northeast corner of Box1
1163: Box1.wid # the width of Box1
1164: Box1.ht # and its height
1165: 2nd last circle.rad # the radius of the 2nd last circle
1166: .P2
1167: .PP
1168: Any pair of expressions enclosed in parentheses
1169: defines a position; furthermore such positions
1170: can be added or subtracted to yield new positions:
1171: .EQ
1172: delim $$
1173: define cw X font CW X
1174: .EN
1175: .P1
1176: (\f2x\fP, \f2y\fP)
1177: ($x sub 1$, $y sub 1$) + ($x sub 2$, $y sub 2$)
1178: .P2
1179: If $p sub 1$ and $p sub 2$ are positions, then
1180: $( p sub 1 , p sub 2 )$
1181: refers to the point
1182: $( p sub 1 font CW .x ,~ p sub 2 font CW .y )$.
1183: .PP
1184: .IT Pic
1185: provides a small collection of standard functions:
1186: .DS
1187: .ta 3i
1188: $cw "sin" (expr)$, $cw "cos" (expr)$, $cw atan2 (y,x)$ (angle in radians)
1189: $cw "log" (expr)$, $cw "exp" (expr)$ (Beware: both base 10)
1190: $cw "sqrt" (expr)$, $cw "max" (e sub 1 , e sub 2 )$, $cw "min" (e sub 1 , e sub 2 )$
1191: $cw "int" (expr)$ (integer part of $expr$)
1192: $cw rand ()$ (random number between 0 and 1)
1193: .DE
1194: .EQ
1195: delim off
1196: .EN
1197: .NH
1198: More on Text
1199: .PP
1200: Normally, text is centered
1201: at the geometric center of the object it is associated with.
1202: The attribute
1203: .CW ljust
1204: causes the left end to be at the specified point
1205: (which means that the text lies to the right of the specified place!),
1206: and
1207: .CW rjust
1208: puts the right end at the place.
1209: .CW above
1210: and
1211: .CW below
1212: center the text one half line space in the given direction.
1213: .PP
1214: Text attributes can be compounded:
1215: .P1
1216: arrow 1 "ljust above" ljust above
1217: .P2
1218: .PS
1219: arrow 1 "ljust above" ljust above
1220: .PE
1221: .LP
1222: .PP
1223: Text is most often an attribute of some other object,
1224: but you can also have self-standing text:
1225: .P1
1226: "origin" "(0,0)" at 0,0
1227: "this is" "(1,1)" at 1,1
1228: box ht 1 wid 1 dotted with .sw at 0,0
1229: .P2
1230: .PS
1231: "origin" "(0,0)" at 0,0
1232: "this is" "(1,1)" at 1,1
1233: box ht 1 wid 1 dotted with .sw at 0,0
1234: .PE
1235: .LP
1236: In effect, \f2n\fP text strings are contained in an invisible box
1237: of width
1238: .CW textwid
1239: and height \f2n\fP \(mu
1240: .CW textht .
1241: The variables
1242: .CW textwid
1243: and
1244: .CW textht
1245: may be set to any values;
1246: they are normally zero.
1247: .PP
1248: A list of numeric expressions can be converted to a formatted string
1249: with the
1250: .CW sprintf
1251: function and used anywhere a quoted string can be:
1252: .P1
1253: B: box wid log(20)
1254: sprintf("width = %g, height = %g ", B.wid, B.ht) rjust at B.w
1255: .P2
1256: .PS
1257: B: box wid log(20)
1258: sprintf("width = %g, height = %g ", B.wid, B.ht) rjust at B.w
1259: .PE
1260: .......
1261: .NH
1262: Lines and Splines
1263: .PP
1264: A ``line'' may actually be a path,
1265: that is, it may consist of connected segments:
1266: .P1
1267: line right 1 then down .5 left 1 then right 1
1268: .P2
1269: .PS
1270: line right 1 then down .5 left 1 then right 1
1271: .PE
1272: The word
1273: .CW then
1274: separates components of the path.
1275: .PP
1276: A spline is a smooth curve guided by a set of straight lines
1277: just like the line above.
1278: It begins at the same place, ends at the same place,
1279: and in between is tangent to the mid-point of each guiding line.
1280: The syntax for a spline is identical to a (path) line
1281: except for using
1282: .CW spline
1283: instead of
1284: .CW line :
1285: .P1
1286: line dashed right 1 then down .5 left 1 then right 1
1287: spline from start of last line \e
1288: right 1 then down .5 left 1 then right 1
1289: .P2
1290: .PS
1291: line dashed right 1 then down .5 left 1 then right 1
1292: spline from start of last line \
1293: right 1 then down .5 left 1 then right 1
1294: .PE
1295: (Long input lines can be split by ending each piece
1296: with a backslash.)
1297: .PP
1298: The elements of a path, whether line or spline,
1299: are specified as a series of points,
1300: either in absolute terms or by
1301: .CW up ,
1302: .CW down ,
1303: etc.
1304: .P1
1305: spline right then up then left then down ->
1306: .P2
1307: .PS
1308: spline right then up then left then down ->
1309: .PE
1310: .P1
1311: spline right then up left then down ->
1312: .P2
1313: .PS
1314: spline right then up left then down ->
1315: .PE
1316: .PP
1317: Notice that arrowheads may be put on the ends
1318: of a line or spline.
1319: .NH
1320: Blocks
1321: .PP
1322: Any sequence of
1323: .IT pic
1324: statements may be enclosed in
1325: brackets
1326: .CW [
1327: and
1328: .CW ]
1329: to form
1330: a block,
1331: which can then be treated as a single object,
1332: and manipulated rather like an ordinary box:
1333: .P1
1334: box "1"
1335: [ box "2"; arrow "3" above; box "4" ] with .n at last box.s - (0,0.1)
1336: "Thing 2: " rjust at last [].w
1337: .P2
1338: .PS
1339: box "1"
1340: [ box "2"; arrow "3" above; box "4" ] with .n at last box.s - (0,0.1)
1341: "Thing 2: " rjust at last [].w
1342: .PE
1343: Notice that
1344: ``last''-type constructs treat blocks as a unit and don't look
1345: inside for objects:
1346: .CW last "" ``
1347: .CW box.s ''
1348: refers to box 1, not box 2 or 4.
1349: You can use
1350: .CW last\ [] ,
1351: etc.,
1352: just like
1353: .CW last\ box .
1354: .PP
1355: Blocks have the same compass corners as
1356: boxes (determined by the bounding box).
1357: It is also
1358: possible to position a block by placing either an absolute
1359: coordinate (like
1360: .CW 0,0 )
1361: or an internal label (like
1362: .CW A )
1363: at some
1364: external point, as in
1365: .P1
1366: [ ...; A: ...; ... ] with .A at ...
1367: .P2
1368: By default, blocks join with other things as boxes do, at the
1369: center of the appropriate side.
1370: .PP
1371: Names of variables and places within a block are local
1372: to that block, and thus do not affect variables and places
1373: of the same name outside.
1374: (In particular, that includes the built-in variables like
1375: .CW boxwid ,
1376: etc.;
1377: if they are set within a block,
1378: they revert to their original values when the block is left.)
1379: You can get at the internal
1380: place names with constructs like
1381: .P1
1382: last [].A
1383: .P2
1384: or
1385: .P1
1386: B.A
1387: .P2
1388: where
1389: .CW B
1390: is a name attached to a block:
1391: .P1
1392: B: [ ... ; A: ...; ]
1393: .P2
1394: When combined with
1395: .CW define
1396: statements (next section), blocks provide
1397: a reasonable simulation of a procedure mechanism.
1398: .PP
1399: Although blocks nest,
1400: it is currently possible to look only one level deep
1401: with constructs like
1402: .CW B.A ,
1403: although
1404: .CW A
1405: may be
1406: further qualified by a corner name (i.e.,
1407: .CW B.A.sw
1408: or
1409: .CW top
1410: .CW of
1411: .CW B.A
1412: are legal).
1413: .PP
1414: The following example illustrates most of the points made above
1415: about how blocks work:
1416: .P1
1417: h = .5; dh = .02; dw = .1
1418: [
1419: Ptr: [
1420: boxht = h; boxwid = dw
1421: A: box
1422: B: box
1423: C: box
1424: box wid 2*boxwid "..."
1425: D: box
1426: ]
1427: Block: [
1428: boxht = 2*dw; boxwid = 2*dw
1429: movewid = 2*dh
1430: A: box; move
1431: B: box; move
1432: C: box; move
1433: box invis "..." wid 2*boxwid; move
1434: D: box
1435: ] with .t at Ptr.s - (0,h/2)
1436: arrow from Ptr.A to Block.A.nw + (dh,0)
1437: arrow from Ptr.B to Block.B.nw + (dh,0)
1438: arrow from Ptr.C to Block.C.nw + (dh,0)
1439: arrow from Ptr.D to Block.D.nw + (dh,0)
1440: ]
1441: box dashed ht last [].ht+dw wid last [].wid+dw at last []
1442: .P2
1443: This produces
1444: .PS
1445: h = .5
1446: dh = .02
1447: dw = .1
1448: [
1449: Ptr: [
1450: boxht = h; boxwid = dw
1451: A: box
1452: B: box
1453: C: box
1454: box wid 2*boxwid "..."
1455: D: box
1456: ]
1457: Block: [
1458: boxht = 2*dw; boxwid = 2*dw
1459: movewid = 2*dh
1460: A: box; move
1461: B: box; move
1462: C: box; move
1463: box invis "..." wid 2*boxwid; move
1464: D: box
1465: ] with .t at Ptr.s - (0,h/2)
1466: arrow from Ptr.A to Block.A.nw + (dh,0)
1467: arrow from Ptr.B to Block.B.nw + (dh,0)
1468: arrow from Ptr.C to Block.C.nw + (dh,0)
1469: arrow from Ptr.D to Block.D.nw + (dh,0)
1470: ]
1471: box dashed ht last [].ht+dw wid last [].wid+dw at last []
1472: .PE
1473: .NH
1474: Macros
1475: .PP
1476: .IT Pic
1477: provides a basic macro facility.
1478: In the simplest form,
1479: .P1
1480: define \f2name\fP { \f2replacement text\fP }
1481: .P2
1482: defines
1483: .IT name
1484: to be the
1485: .IT "replacement text" .
1486: Any subsequent occurrence of
1487: .IT name
1488: will be replaced by
1489: .IT "replacement text" .
1490: .PP
1491: Macros may have arguments.
1492: If the replacement text of a macro definition contains occurrences of
1493: .CW $1 ,
1494: .CW $2 ,
1495: etc.,
1496: these will be replaced by the corresponding actual arguments
1497: when the macro is invoked.
1498: The invocation for a macro with arguments is
1499: .P1
1500: name(arg1, arg2, ...)
1501: .P2
1502: Non-existent arguments are replaced by null strings.
1503: Macro definitions last from picture to picture;
1504: a macro definition can be removed by
1505: .P1
1506: undef \f2macro-name\fP
1507: .P2
1508: .PP
1509: As an example, one might define a
1510: .CW square
1511: by
1512: .P1
1513: define square { box ht $1 wid $1 $2 }
1514: .P2
1515: and use it as
1516: .P1
1517: square(1, "one" "inch")
1518: square(0.5)
1519: square(0.25, "\es-4tiny\es+4" dashed)
1520: .P2
1521: .PS
1522: define square { box ht $1 wid $1 $2 }
1523: square(1, "one" "inch")
1524: square(0.5)
1525: square(0.25, "\s-4tiny\s+4" dashed)
1526: .PE
1527: Notice how the second argument may be used to pass in arbitrary contents.
1528: .PP
1529: Coordinates like
1530: .IT x,y
1531: may be enclosed in parentheses,
1532: as in
1533: .IT x,y ), (
1534: so they can be included in a macro argument.
1535: .NH
1536: File Copy
1537: .PP
1538: The statement
1539: .P1
1540: copy "\f2filename\fP"
1541: .P2
1542: inserts the contents of the named file
1543: at that point in the input.
1544: Any
1545: .CW .PS
1546: or
1547: .CW .PE
1548: lines within the file
1549: are ignored, so previously prepared pictures
1550: can be used as parts of larger ones without editing.
1551: .PP
1552: .IT Pic
1553: also provides the
1554: .CW copy
1555: .CW thru
1556: mechanism found in
1557: .IT grap :
1558: .P1
1559: copy "\f2file\fP" thru \f2macro-name\fP
1560: .P2
1561: copies
1562: .IT file ,
1563: treating each line as an invocation of the named macro
1564: (each field being an argument).
1565: A literal macro may be used instead of a name:
1566: .P1
1567: copy "\f2file\fP" thru { \f2macro replacement text\fP }
1568: .P2
1569: and if no file name is given,
1570: the remainder of the input until the next
1571: .CW .PE
1572: is used.
1573: So to plot a set of circles at points whose coordinates and radii
1574: are included in-line:
1575: .P1
1576: copy thru { circle rad $3 at $1,$2 }
1577: 0 0 .05
1578: 1 1 .1
1579: .2 .3 .03
1580: .4 .7 .05
1581: \&...
1582: .P2
1583: .PS
1584: copy thru { circle rad $3 at $1,$2 }
1585: 0 0 .05
1586: 1 1 .1
1587: .2 .3 .03
1588: .4 .7 .05
1589: .1 .8 .1
1590: .4 .9 .02
1591: .7 .5 .15
1592: 1 .4 .04
1593: .8 0 .075
1594: .5 .25 .03
1595: .PE
1596: .PP
1597: The
1598: .CW sh
1599: command executes an arbitrary commandline:
1600: .P1
1601: sh { \f2anything\fP }
1602: .P2
1603: Macros within
1604: .IT anything
1605: are expanded first.
1606: .NH
1607: Loops and Conditionals
1608: .PP
1609: .IT Pic
1610: provides an
1611: .CW if
1612: statement and a
1613: .CW for
1614: loop.
1615: .P1
1616: pi = atan2(0,-1)
1617: for i = 0 to 2 * pi by 0.1 do {
1618: "\-" at i/2, 0
1619: "s" at i/2, sin(i)/2
1620: "c" at i/2, cos(i)/2
1621: }
1622: .P2
1623: .PS
1624: .ps -2
1625: pi = atan2(0,-1)
1626: for i = 0 to 2 * pi by 0.1 do {
1627: "\-" at i/2, 0
1628: "s" at i/2, sin(i)/2
1629: "c" at i/2, cos(i)/2
1630: }
1631: .ps +2
1632: .PE
1633: The
1634: .CW by
1635: clause is optional;
1636: if the value is preceded by a
1637: .CW * ,
1638: the steps are multiplicative, not additive.
1639: The body of the loop is delimited by braces,
1640: which are also used for definitions,
1641: .CW copy ,
1642: .CW sh
1643: and
1644: .CW if
1645: statements.
1646: .PP
1647: The
1648: .CW if
1649: statement is
1650: .P1
1651: if \f2expression\fP then { \f2anything\fP } else { \f2anything\fP }
1652: .P2
1653: where the
1654: .CW else
1655: clause is optional.
1656: The
1657: .IT expression
1658: may use the usual relational operators:
1659: .CW == ,
1660: .CW != ,
1661: .CW > ,
1662: .CW >= ,
1663: .CW < ,
1664: .CW <= ,
1665: .CW && ,
1666: and
1667: .CW || .
1668: .P1
1669: pi = atan2(0,-1)
1670: for i = 0 to pi by 0.1 do {
1671: if (s = sin(i)) > 0.8 then { s = 0.8 }
1672: "x" at i/2, s/2
1673: }
1674: .P2
1675: .PS
1676: .ps -2
1677: pi = atan2(0,-1)
1678: for i = 0 to pi by 0.1 do {
1679: if (s = sin(i)) > 0.8 then { s = 0.8 }
1680: "x" at i/2, s/2
1681: }
1682: .ps +2
1683: .PE
1684: A string comparison using
1685: .CW ==
1686: or
1687: .CW !=
1688: is also permitted, to compare quoted strings:
1689: .P1
1690: if "\f2string1\fP" == "\f2string2\fP" then ...
1691: .P2
1692: .NH
1693: \fITroff\fP Interface
1694: .PP
1695: .IT Pic
1696: is usually run as a
1697: .IT troff
1698: preprocessor:
1699: .P1
1700: pic file | troff -ms
1701: .P2
1702: Run it before
1703: .IT eqn
1704: if it is also present.
1705: .PP
1706: If the
1707: .CW .PS
1708: line looks like
1709: .P1
1710: \&.PS <file
1711: .P2
1712: then the contents of
1713: .CW file
1714: are inserted in place of the
1715: .CW .PS
1716: line,
1717: whether or not the file contains
1718: .CW .PS
1719: or
1720: .CW .PE .
1721: (This feature is deprecated in favor of the
1722: .CW copy
1723: statement.)
1724: .PP
1725: .IT Pic
1726: copies the
1727: .CW .PS
1728: and
1729: .CW .PE
1730: lines from input to output intact,
1731: except that it adds two things on the same line as the
1732: .CW .PS :
1733: .P1
1734: \&.PS h w
1735: .P2
1736: .CW h
1737: and
1738: .CW w
1739: are the picture height and width in units.
1740: The
1741: .CW -ms
1742: macro package has definitions for
1743: .CW .PS
1744: and
1745: .CW .PE
1746: that cause
1747: pictures to be centered and offset a bit from surrounding text.
1748: (See the appendix.)
1749: .PP
1750: If
1751: .CW .PF '' ``
1752: is used instead of
1753: .CW .PE ,
1754: the position after printing is restored to where
1755: it was before the picture started, instead of being at the bottom.
1756: .CW F '' (``
1757: is for ``flyback.'')
1758: .PP
1759: Any input line that begins with a
1760: period is assumed to be a
1761: .IT troff
1762: command that makes sense at that point;
1763: it is copied to the output at that point in the document.
1764: It is asking for trouble to add vertical space or in any way fiddle with
1765: the line spacing here,
1766: but point size and font changes are generally harmless:
1767: .P1
1768: \&.ps 24
1769: circle radius .4 at 0,0
1770: \&.ps 12
1771: circle radius .2 at 0,0
1772: \&.ps 8
1773: circle radius .1 at 0,0
1774: \&.ps 6
1775: circle radius .05 at 0,0
1776: \&.ps 10 \e" don't forget to restore size
1777: .P2
1778: .PS
1779: .ps 24
1780: circle radius .4 at 0,0
1781: .ps 12
1782: circle radius .2 at 0,0
1783: .ps 8
1784: circle radius .1 at 0,0
1785: .ps 6
1786: circle radius .05 at 0,0
1787: .ps 10 \" don't forget to restore size
1788: .PE
1789: .IT Pic
1790: does preserve the state of
1791: .IT troff 's
1792: fill mode across pictures.
1793: .PP
1794: It is also safe to include sizes, fonts and local motions
1795: within quoted strings
1796: .CW \&"..." ) (
1797: in
1798: .IT pic ,
1799: so long as whatever changes are made are unmade before exiting the string.
1800: For example, to print text in Helvetica Bold 2 points larger:
1801: .P1
1802: ellipse "\es+2\ef(HBSmile!\efP\es-2"
1803: .P2
1804: .PS
1805: ellipse "\s+2\f(HBSmile!\fP\s-2"
1806: .PE
1807: This is essentially the same rule as applies in
1808: .IT eqn .
1809: .PP
1810: There is a subtle problem with complicated equations inside
1811: .IT pic
1812: pictures \(em they come out wrong
1813: if
1814: .IT eqn
1815: has to leave extra vertical space for the equation.
1816: If your equation involves more than subscripts and superscripts,
1817: you must add to the beginning of each equation the extra information
1818: .CW "space 0" :
1819: .P1
1820: arrow
1821: box "$space 0 {H( omega )} over {1 - H( omega )}$"
1822: arrow
1823: .P2
1824: .EQ
1825: delim $$
1826: .EN
1827: .PS
1828: arrow
1829: box "$space 0 {H( omega )} over {1 - H( omega )}$"
1830: arrow
1831: .PE
1832: .NH
1833: Some Examples
1834: .PP
1835: Here are a handful of larger examples:
1836: .KS
1837: .PS
1838: define ndblock X
1839: box wid boxwid/2 ht boxht/2
1840: down; box same with .t at bottom of last box; box same
1841: X
1842: .ps -2
1843: .ft CW
1844: boxht = .2; boxwid = .3; dx = 0.05
1845: down; box; box; box; box ht 3*boxht "." "." "."
1846: L: box; box; box invis wid 2*boxwid "hashtab:" with .e at 1st box .w
1847: right
1848: Start: box wid .5 with .sw at 1st box.ne + (.4,.2) "..."
1849: N1: box wid .2 "n1"; D1: box wid .3 "d1"
1850: N3: box wid .4 "n3"; D3: box wid .3 "d3"
1851: box wid .4 "..."
1852: N2: box wid .5 "n2"; D2: box wid .2 "d2"
1853:
1854: arrow right from 2nd box
1855: ndblock
1856: spline -> right .2 from 3rd last box then to N1.sw + (dx,0)
1857: spline -> right .3 from 2nd last box then to D1.sw + (dx,0)
1858: arrow right from last box
1859: ndblock
1860: spline -> right .2 from 3rd last box to N2.sw-(dx,.2) to N2.sw+(dx,0)
1861: spline -> right .3 from 2nd last box to D2.sw-(dx,.2) to D2.sw+(dx,0)
1862: arrow right 2*linewid from L
1863: ndblock
1864: spline -> right .2 from 3rd last box to N3.sw + (dx,0)
1865: spline -> right .3 from 2nd last box to D3.sw + (dx,0)
1866:
1867: circlerad = .3
1868: circle invis "ndblock" at last box.e + (1.2,.2)
1869: arrow dashed from last circle.w to last box chop 0 chop .3
1870:
1871: box invis wid 2*boxwid "ndtable:" with .e at Start.w
1872: .ps
1873: .ft
1874: .PE
1875: .KE
1876: .sp
1877: .P1
1878: .vs -1p
1879: define ndblock {
1880: box wid boxwid/2 ht boxht/2
1881: down; box same with .t at bottom of last box; box same
1882: }
1883: boxht = .2; boxwid = .3; circlerad = .3; dx = 0.05
1884: down; box; box; box; box ht 3*boxht "." "." "."
1885: L: box; box; box invis wid 2*boxwid "hashtab:" with .e at 1st box .w
1886: right
1887: Start: box wid .5 with .sw at 1st box.ne + (.4,.2) "..."
1888: N1: box wid .2 "n1"; D1: box wid .3 "d1"
1889: N3: box wid .4 "n3"; D3: box wid .3 "d3"
1890: box wid .4 "..."
1891: N2: box wid .5 "n2"; D2: box wid .2 "d2"
1892: arrow right from 2nd box
1893: ndblock
1894: spline -> right .2 from 3rd last box then to N1.sw + (dx,0)
1895: spline -> right .3 from 2nd last box then to D1.sw + (dx,0)
1896: arrow right from last box
1897: ndblock
1898: spline -> right .2 from 3rd last box to N2.sw-(dx,.2) to N2.sw+(dx,0)
1899: spline -> right .3 from 2nd last box to D2.sw-(dx,.2) to D2.sw+(dx,0)
1900: arrow right 2*linewid from L
1901: ndblock
1902: spline -> right .2 from 3rd last box to N3.sw + (dx,0)
1903: spline -> right .3 from 2nd last box to D3.sw + (dx,0)
1904: circlerad = .3
1905: circle invis "ndblock" at last box.e + (1.2,.2)
1906: arrow dashed from last circle.w to last box chop 0 chop .3
1907: box invis wid 2*boxwid "ndtable:" with .e at Start.w
1908: .P2
1909: .sp
1910: .KS
1911: .PS 5
1912: .ps 8
1913: boxht = .5; boxwid = .75
1914: circlerad = .25
1915: arrow "source" "code"
1916: LA: box "lexical" "analyzer"
1917: arrow "tokens" above
1918: P: box "parser"
1919: arrow "intermediate" "code"
1920: Sem: box "semantic" "checker"
1921: arrow
1922:
1923: arrow <-> up from top of LA
1924: LC: box "lexical" "corrector"
1925: arrow <-> up from top of P
1926: Syn: box "syntactic" "corrector"
1927: arrow up
1928: DMP: box "diagnostic" "message" "printer"
1929: arrow <-> right from right of DMP
1930: ST: box "symbol" "table"
1931: arrow from LC.ne to DMP.sw
1932: arrow from Sem.nw to DMP.se
1933: arrow <-> from Sem.top to ST.bot
1934: .PE
1935: .KE
1936: .LP
1937: .P1
1938: \&.PS 5
1939: \&.ps 8
1940: \& arrow "source" "code"
1941: \&LA: box "lexical" "analyzer"
1942: \& arrow "tokens" above
1943: \&P: box "parser"
1944: \& arrow "intermediate" "code"
1945: \&Sem: box "semantic" "checker"
1946: \& arrow
1947: \&
1948: \& arrow <-> up from top of LA
1949: \&LC: box "lexical" "corrector"
1950: \& arrow <-> up from top of P
1951: \&Syn: box "syntactic" "corrector"
1952: \& arrow up
1953: \&DMP: box "diagnostic" "message" "printer"
1954: \& arrow <-> right from right of DMP
1955: \&ST: box "symbol" "table"
1956: \& arrow from LC.ne to DMP.sw
1957: \& arrow from Sem.nw to DMP.se
1958: \& arrow <-> from Sem.top to ST.bot
1959: \&.PE
1960: .P2
1961: .PP
1962: There are eighteen objects (boxes and arrows) in the picture,
1963: and one line of
1964: .IT pic
1965: input for each;
1966: this seems like an acceptable level of verbosity.
1967: .sp
1968: .KS
1969: .PS
1970: .ps -2
1971: circle "DISK"
1972: arrow "character" "defns"
1973: CPU: box "CPU" "(16-bit mini)"
1974: { arrow <- from top of CPU up "input " rjust }
1975: arrow
1976: CRT: " CRT" ljust
1977: line from CRT - 0,0.075 up 0.15 \
1978: then right 0.5 \
1979: then right 0.5 up 0.25 \
1980: then down 0.5+0.15 \
1981: then left 0.5 up 0.25 \
1982: then left 0.5
1983: Paper: CRT + 1.05,0.75
1984: arrow <- from Paper down 1.5
1985: " ... paper" ljust at end of last arrow + 0, 0.25
1986: circle rad 0.05 at Paper + (-0.055, -0.25)
1987: circle rad 0.05 at Paper + (0.055, -0.25)
1988: " rollers" ljust at Paper + (0.1, -0.25)
1989: .ps +2
1990: .PE
1991: .ce
1992: Basic Digital Typesetter
1993: .sp
1994: .KE
1995: .LP
1996: .P1
1997: .vs -1
1998: \&.PS
1999: \&.ps -2
2000: circle "DISK"
2001: arrow "character" "defns"
2002: CPU: box "CPU" "(16-bit mini)"
2003: { arrow <- from top of CPU up "input " rjust }
2004: arrow
2005: CRT: " CRT" ljust
2006: line from CRT - 0,0.075 up 0.15 \e
2007: then right 0.5 \e
2008: then right 0.5 up 0.25 \e
2009: then down 0.5+0.15 \e
2010: then left 0.5 up 0.25 \e
2011: then left 0.5
2012: Paper: CRT + 1.05,0.75
2013: arrow <- from Paper down 1.5
2014: " ... paper" ljust at end of last arrow + 0, 0.25
2015: circle rad 0.05 at Paper + (-0.055, -0.25)
2016: circle rad 0.05 at Paper + (0.055, -0.25)
2017: " rollers" ljust at Paper + (0.1, -0.25)
2018: \&.ps +2
2019: \&.PE
2020: \&.ce
2021: \&Basic Digital Typesetter
2022: .P2
2023: .SH
2024: Acknowledgements
2025: .PP
2026: I am indebted to Chris Van Wyk for ideas from several versions of
2027: .IT ideal .
2028: He and Doug McIlroy have also contributed algorithms
2029: for line and circle drawing,
2030: and made useful suggestions on the design of
2031: .IT pic .
2032: Theo Pavlidis contributed the basic spline algorithm;
2033: Eric Grosse provided code to compute the bounding box of an arc.
2034: Charles Wetherell pointed out reference
2035: [2]
2036: to me, and made several valuable criticisms on an early
2037: draft of the language and manual.
2038: The exposition in this manual has been greatly improved
2039: by suggestions from Jim Blinn and Mark Miller.
2040: I am grateful to
2041: my early users \(em
2042: Brenda Baker,
2043: Dottie Luciani,
2044: and Paul Tukey
2045: \(em
2046: for their suggestions and cheerful use of
2047: an often shaky and clumsy system.
2048: .PP
2049: More recent versions of
2050: .IT pic
2051: have benefited greatly from
2052: adventurous use by
2053: Jon Bentley and Ravi Sethi;
2054: their comments on the manual are also much appreciated.
2055: .SH
2056: References
2057: .LP
2058: |reference_placement
2059: .BP
2060: ........
2061: .SH
2062: Appendix A: \fIPic\fP Reference Manual
2063: .SH
2064: Pictures
2065: .PP
2066: The top-level object in
2067: .IT pic
2068: is the ``picture'':
2069: .P1
2070: \f2picture\fP:
2071: .PS \f2optional-width\fP \f2optional-height\fP
2072: \f2element-list\fP
2073: .PE
2074: .P2
2075: If
2076: .IT optional-width
2077: is present, the picture is made that many inches wide,
2078: regardless of any dimensions used internally.
2079: The height is scaled in the same proportion unless
2080: .IT optional-height
2081: is present.
2082: If instead the line is
2083: .P1
2084: \&.PS <f
2085: .P2
2086: the file
2087: .CW f
2088: is inserted in place of the
2089: .CW .PS
2090: line.
2091: If
2092: .CW .PF
2093: is used instead of
2094: .CW .PE ,
2095: the position after printing is restored to what it was
2096: upon entry.
2097: .PP
2098: In no case will the picture be larger than
2099: .CW maxpsht
2100: \(mu
2101: .CW maxpswid .
2102: .SH
2103: Elements
2104: .PP
2105: An
2106: .IT element-list
2107: is a list of elements (what else?);
2108: the elements are
2109: .P1
2110: \f2element\fP:
2111: \f2primitive attribute-list\fP
2112: \f2placename\fP : \f2element\fP
2113: \f2placename\fP : \f2position\fP
2114: \f2var\fP = \f2expr\fP
2115: \f2direction\fP
2116: { \f2element-list\fP }
2117: [ \f2element-list\fP ]
2118: for \f2var\fP = \f2expr\fP to \f2expr\fP by \f2expr\fP do { \f2anything\fP }
2119: if \f2expr\fP then { \f2anything\fP } else { \f2anything\fP }
2120: copy \f2file\fP
2121: copy thru \f2macro\fP
2122: copy \f2file\fP thru \fPmacro\fP
2123: sh { \f2commandline\fP }
2124: print \f2expr\fP
2125: reset \f2optional var-list\fP
2126: \f2troff-command\fP
2127: .P2
2128: .PP
2129: Elements are separated by newlines or semicolons;
2130: a long element may be continued by ending the line with a backslash.
2131: Comments are introduced by a
2132: .CW #
2133: and terminated by a newline.
2134: .PP
2135: Variable names begin with a lower case letter;
2136: place names begin with upper case.
2137: Place and variable names retain their values
2138: from one picture to the next.
2139: .PP
2140: The current position and direction of motion are saved upon entry
2141: to a
2142: .CW {...}
2143: block and restored upon exit.
2144: .PP
2145: Elements within a block enclosed in
2146: .CW [...]
2147: are treated as a unit;
2148: the dimensions are determined by the extreme points
2149: of the contained objects.
2150: Names, variables, and direction of motion within a block are local to that block.
2151: .PP
2152: .IT troff-command
2153: is any line that begins with a period.
2154: Such a line is assumed to make sense in the context where it appears;
2155: accordingly,
2156: if it doesn't work, don't call.
2157: .SH
2158: Primitives
2159: .PP
2160: The primitive objects are
2161: .P1
2162: \f2primitive\fP:
2163: box
2164: circle
2165: ellipse
2166: arc
2167: line
2168: arrow
2169: spline
2170: move
2171: \f2text-list\fP
2172: .P2
2173: .CW arrow
2174: is a synonym for
2175: .CW line
2176: .CW -> .
2177: .SH
2178: Attributes
2179: .PP
2180: An
2181: .IT attribute-list
2182: is a sequence of zero or more attributes;
2183: each attribute consists of a keyword, perhaps followed by a value.
2184: .P1
2185: .ta .5i 2.5i
2186: \f2attribute\fP:
2187: h(eigh)t \f2expr\fP wid(th) \f2expr\fP
2188: rad(ius) \f2expr\fP diam(eter) \f2expr\fP
2189: up \f2opt-expr\fP down \f2opt-expr\fP
2190: right \f2opt-expr\fP left \f2opt-expr\fP
2191: from \f2position\fP to \f2position\fP
2192: at \f2position\fP with \f2corner\fP
2193: by \f2expr, expr\fP then
2194: dotted \f2opt-expr\fP dashed \f2opt-expr\fP
2195: chop \f2opt-expr\fP -> <- <->
2196: invis solid
2197: fill \f2opt-expr\fP same
2198: \f2text-list\fP \f2expr\fP
2199: .P2
2200: Missing attributes and values are filled in from defaults.
2201: Not all attributes make sense for all primitives;
2202: irrelevant ones are silently ignored.
2203: The attribute
2204: .CW at
2205: causes the geometrical center to be put at the specified place;
2206: .CW with
2207: causes the position on the object to be put at the specified place.
2208: For lines, splines and arcs,
2209: .CW height
2210: and
2211: .CW width
2212: refer to arrowhead size.
2213: A bare
2214: .IT expr
2215: implies motion in the current direction.
2216: .SH
2217: Text
2218: .PP
2219: Text is normally an attribute of some primitive;
2220: by default it is placed at the geometrical center of the object.
2221: Stand-alone text is also permitted.
2222: A
2223: .IT text-list
2224: is a list of text items; a text item is
2225: a quoted string optionally followed by positioning requests:
2226: .P1
2227: \f2text-item\fP:
2228: "..." \f2positioning ...\fP
2229: sprintf("\f2format\fP", \f2expr\fP, \f2...\fP) \f2positioning ...\fP
2230: \f2positioning\fP:
2231: center ljust rjust above below
2232: .P2
2233: If there are multiple text items for some primitive,
2234: they are centered vertically except as qualified.
2235: Positioning requests apply to each item independently.
2236: .PP
2237: Text items can contain
2238: .IT troff
2239: commands for size and font changes, local motions, etc.,
2240: but make sure that these are balanced
2241: so that the entering state is restored before exiting.
2242: .SH
2243: Positions and places
2244: .PP
2245: A position is ultimately an
2246: .IT x,y
2247: coordinate pair, but it may be specified in other ways.
2248: .P1
2249: \f2position\fP:
2250: \f2expr, expr\fP
2251: \f2place\fP \(+- \f2expr, expr\fP
2252: \f2place\fP \(+- ( \f2expr, expr\fP )
2253: ( \f2position\fP,\f2 position\fP )
2254: \f2expr\fP \f2[\fPof the way\f2]\fP between \f2position\fP and \f2position\fP
2255: \f2expr\fP < \f2position\fP , \f2position\fP >
2256: ( \f2position\fP )
2257: .sp .5
2258: \f2place\fP:
2259: \f2placename\fP \f2optional-corner\fP
2260: \f2corner\fP of \f2placename\fP
2261: \f2nth\fP \f2primitive\fP \f2optional-corner\fP
2262: \f2corner\fP of \f2nth\fP \f2primitive\fP
2263: Here
2264: .P2
2265: An
2266: .IT optional-corner
2267: is one of the eight compass points
2268: or the center or the start or end of a primitive.
2269: .P1
2270: \f2optional-corner\fP:
2271: .n .e .w .s .ne .se .nw .sw .c .start .end
2272: \f2corner\fP:
2273: top bot left right start end
2274: .P2
2275: Each object in a picture has an ordinal number;
2276: .IT nth
2277: refers to this.
2278: .P1
2279: \f2nth\fP:
2280: \f2n\fPth
2281: \f2n\fPth last
2282: .P2
2283: Since barbarisms like
2284: .CW 1th
2285: and
2286: .CW 3th
2287: are barbaric,
2288: synonyms like
2289: .CW 1st
2290: and
2291: .CW 3rd
2292: are accepted as well.
2293: .SH
2294: Variables
2295: .PP
2296: The built-in variables and their default values are:
2297: .P1
2298: .ta .5i 2.5i
2299: boxwid 0.75 boxht 0.5
2300: circlerad 0.25 arcrad 0.25
2301: ellipsewid 0.75 ellipseht 0.5
2302: linewid 0.5 lineht 0.5
2303: movewid 0.5 moveht 0.5
2304: textwid 0 textht 0
2305: arrowwid 0.05 arrowht 0.1
2306: dashwid 0.1 arrowhead 2
2307: maxpsht 8.5 maxpswid 11
2308: scale 1 fillval .3
2309: .P2
2310: These may be changed at any time,
2311: and the new values remain in force from picture to picture until changed again
2312: or reset by a
2313: .CW reset
2314: statement.
2315: Variables changed within
2316: .CW [
2317: and
2318: .CW ]
2319: revert to their previous value upon exit from the block.
2320: Dimensions are divided by
2321: .CW scale
2322: during output.
2323: .SH
2324: Expressions
2325: .PP
2326: Expressions in
2327: .IT pic
2328: are evaluated in floating point.
2329: All numbers representing dimensions are taken to be in inches.
2330: .EQ
2331: delim $$
2332: .EN
2333: .P1
2334: \f2expr\fP:
2335: \f2expr\fP \f2op\fP \f2expr\fP
2336: - \f2expr\fP
2337: ! \f2expr\fP
2338: ( \f2expr\fP )
2339: variable
2340: number
2341: \f2place\fP .x
2342: \f2place\fP .y
2343: \f2place\fP .ht
2344: \f2place\fP .wid
2345: \f2place\fP .rad
2346: sin($expr$) cos($expr$) atan2($expr,expr$) log($expr$) exp($expr$)
2347: sqrt($expr$) max($expr,expr$) min($expr,expr$) int($expr$) rand()
2348: \f2op\fP:
2349: + - * / % ^
2350: < <= > >= == != && ||
2351: .P2
2352: .SH
2353: Definitions
2354: .PP
2355: The
2356: .CW define
2357: and
2358: .CW undef
2359: statements are not part of the grammar.
2360: .P1
2361: \f2define\fP:
2362: define \f2name\fP { \f2replacement text\fP }
2363: \f2undef\fP:
2364: undef \f2name\fP
2365: .P2
2366: .EQ
2367: delim off
2368: .EN
2369: Occurrences of
2370: .CW $1 ,
2371: .CW $2 ,
2372: etc.,
2373: in the replacement text
2374: will be replaced by the corresponding arguments if
2375: .IT name
2376: is invoked as
2377: .P1
2378: \f2name\fP(\f2arg1\fP, \f2arg2\fP, ...)
2379: .P2
2380: Non-existent arguments are replaced by null strings.
2381: .IT Replacement
2382: .IT text
2383: may contain newlines.
2384: The
2385: .CW undef
2386: statement removes the definition of a macro.
2387: .SH
2388: The .PS and .PE Macros
2389: .PP
2390: This is the default definition of the
2391: .CW .PS
2392: and
2393: .CW .PE
2394: macros:
2395: .P1
2396: .de PS \e" start picture; $1 is height, $2 is width, in inches
2397: .sp .3
2398: .in (\e\en(.lu-\e\e$2)/2u
2399: .ne \e\e$1
2400: ..
2401: .de PE \e" end of picture
2402: .in
2403: .sp .6
2404: ..
2405: .P2
2406: .SH
2407: Summary of Features Added Since Original Version
2408: .PP
2409: The built-in functions
2410: .CW sin ,
2411: .CW cos ,
2412: .CW atan2 ,
2413: .CW log ,
2414: .CW exp ,
2415: .CW sqrt ,
2416: .CW max ,
2417: .CW min ,
2418: .CW int ,
2419: and
2420: .CW rand
2421: are available.
2422: .PP
2423: The
2424: .CW copy
2425: statement includes data from a file or that follows immediately:
2426: .P1
2427: copy "\f2filename\fP"
2428: copy thru \f2macro\fP
2429: copy "\f2filename\fP" thru \f2macro\fP
2430: .P2
2431: The
2432: .IT macro
2433: may be either the name of a defined macro, or the body of a macro
2434: enclosed in braces.
2435: If no filename is given,
2436: .CW copy
2437: copies the input until the next
2438: .CW .PE .
2439: .PP
2440: The
2441: .CW for
2442: and
2443: .CW if
2444: statements provide loops and decision-making:
2445: .P1
2446: for \f2var\fP=\f2expr\fP to \f2expr\fP by \f2expr\fP do { \f2anything\fP }
2447: if \f2expr\fP then { \f2anything\fP } else { \f2anything\fP }
2448: .P2
2449: The
2450: .CW by
2451: and
2452: .CW else
2453: clauses are optional.
2454: The
2455: .IT expr
2456: in an
2457: .CW if
2458: may use the usual relational operators
2459: or the tests
2460: .IT str1
2461: .CW ==
2462: (or
2463: .CW != )
2464: .IT str2
2465: for two quoted strings.
2466: .PP
2467: The
2468: .CW sh
2469: command executes any sequence of commands, after expanding any defined names:
2470: .P1
2471: sh { \f2anything\fP }
2472: .P2
2473: .PP
2474: In all of the above,
2475: any single character that does not occur within the body
2476: may be used to enclose a body,
2477: instead of
2478: braces, as in
2479: .P1
2480: define name X replacement text X
2481: .P2
2482: .PP
2483: Text strings are first-class citizens:
2484: a statement beginning with a sequence of text strings is treated
2485: as an invisible box with the strings positioned at its center.
2486: The variable
2487: .CW textht
2488: and
2489: .CW textwid
2490: may be set to any values to control positioning.
2491: The height of \f2n\fP such strings is \f2n\fP \(mu
2492: .CW textht .
2493: .PP
2494: It is possible to convert expressions to formatted strings:
2495: .P1
2496: sprintf("\f2format\fP", \f2expr\fP, \f2expr\fP, ...)
2497: .P2
2498: is equivalent to a quoted string in any context.
2499: Variants of
2500: .CW %f
2501: and
2502: .CW %g
2503: are the only sensible format conversions.
2504: .PP
2505: Built-in variables may be reset to default values with
2506: .CW reset .
2507: .PP
2508: The
2509: .CW undef
2510: statement removes a macro definition.
2511: .PP
2512: Arrowheads may be filled with the
2513: .CW arrowhead
2514: variable;
2515: their positioning is improved on arcs.
2516: .PP
2517: The width and height of the generated picture
2518: may be set independently from the
2519: .CW .PS
2520: line;
2521: the maximum height and width are set from
2522: .CW maxpsht
2523: and
2524: .CW maxpswid .
2525: .PP
2526: The state of
2527: .IT troff 's
2528: fill or no-fill mode is preserved around a picture.
2529: .PP
2530: Input numbers may be expressed in
2531: .CW E
2532: notation.
2533: .PP
2534: Numerous internal changes have been made as well.
2535: Any number of objects, text strings, etc., may be used;
2536: the only limit is total available memory.
2537: Output is now produced in inches instead of units
2538: for a particular typesetter,
2539: so the
2540: .CW -T
2541: option has gone away.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.