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