summaryrefslogtreecommitdiffstats
path: root/doc/pic.ms
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 19:44:05 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 19:44:05 +0000
commitd318611dd6f23fcfedd50e9b9e24620b102ba96a (patch)
tree8b9eef82ca40fdd5a8deeabf07572074c236095d /doc/pic.ms
parentInitial commit. (diff)
downloadgroff-upstream/1.23.0.tar.xz
groff-upstream/1.23.0.zip
Adding upstream version 1.23.0.upstream/1.23.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'doc/pic.ms')
-rw-r--r--doc/pic.ms3287
1 files changed, 3287 insertions, 0 deletions
diff --git a/doc/pic.ms b/doc/pic.ms
new file mode 100644
index 0000000..51c710f
--- /dev/null
+++ b/doc/pic.ms
@@ -0,0 +1,3287 @@
+.\" Copyright (C) 2006-2020 Free Software Foundation, Inc.
+.\" Written by Eric S. Raymond <esr@thyrsus.com>
+.\"
+.\" This file is part of groff.
+.\"
+.\" groff is free software; you can redistribute it and/or modify it under
+.\" the terms of the GNU General Public License as published by the Free
+.\" Software Foundation, either version 3 of the License, or
+.\" (at your option) any later version.
+.\"
+.\" groff is distributed in the hope that it will be useful, but WITHOUT ANY
+.\" WARRANTY; without even the implied warranty of MERCHANTABILITY or
+.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+.\" for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program. If not, see <http://www.gnu.org/licenses/>.
+.\"
+.\" For tolerably obvious reason, this needs to be processed through PIC.
+.\" It also needs to be processed through TBL and EQN. Use "groff -p -e -t".
+.\" There is no hope that this will ever look right under nroff.
+.\"
+.\" Comments beginning with %% are cut lines so portions of this
+.\" document can be automatically extracted. %%TUTORIAL%% begins the
+.\" tutorial part; %%REFERENCE%% the reference part. %%POSTLUDE%% the
+.\" bibliography and end matter after the reference part.
+.\"
+.\" This document was written for free use and redistribution by
+.\" Eric S. Raymond <esr@thyrsus.com> in August 1995. It has been put
+.\" under the GPL in March 2006.
+.\"
+.
+.
+.\" Set a proper TeX and LaTeX
+.ie t \{\
+. ds tx T\h'-.1667m'\v'.224m'E\v'-.224m'\h'-.125m'X\"
+. ds lx L\h'-0.36m'\v'-0.22v'\s-2A\s0\h'-0.15m'\v'0.22v'\*(tx\"
+.\}
+.el \{\
+. ds tx TeX\"
+. ds lx LaTeX\"
+.\}
+.
+.\" Centered caption for figure. Assumes previous .KS
+.de CE
+. ce 1
+Figure \\n[H1]-\\$1
+. sp 1
+. KE
+..
+.
+.\" Definitions end here
+.
+.
+.TL
+Making Pictures With GNU PIC
+.AU
+Eric S. Raymond
+.AI
+\[la]\fIesr@snark.thyrsus.com\fP\[ra]
+.AB
+The \fBpic\fP language is a \fBtroff\fP extension that makes it easy
+to create and alter box-and-arrow diagrams of the kind frequently used
+in technical papers and textbooks.
+This paper is both an introduction to and reference for \fIgpic\/\fP(1),
+the implementation distributed by the Free Software Foundation for use
+with \fIgroff\/\fP(1).
+It also catalogs other implementations and explains the differences
+among them.
+.AE
+.\"%%TUTORIAL%%
+.
+.
+.NH 1
+Introduction to PIC
+.
+.NH 2
+Why PIC?
+.PP
+The \fBpic\fP language provides an easy way to write procedural
+box-and-arrow diagrams to be included in \fBtroff\fP documents.
+The language is sufficiently flexible to be quite useful for state
+charts, Petri-net diagrams, flow charts, simple circuit schematics,
+jumper layouts, and other kinds of illustration involving repetitive
+uses of simple geometric forms and splines.
+Because these descriptions are procedural and object-based, they are
+both compact and easy to modify.
+.PP
+The phrase \[lq]GNU pic\[rq] may refer to either of two \fBpic\fP
+implementations distributed by the Free Software Foundation and
+intended to accept the same input language.
+The \fIgpic\/\fP(1) implementation is for use with the \fIgroff\/\fP(1)
+implementation of \fBtroff\fP.
+The \fIpic2plot\/\fP(1) implementation runs standalone and is part of
+the \fBplotutils\fR package.
+Because both implementations are widely available in source form for
+free, they are good bets for writing very portable documentation.
+.
+.NH 2
+PIC Versions
+.PP
+The original 1984 pre-\fIditroff\/\fP(1) version of \fBpic\fP is long
+obsolete.
+The rewritten 1991 version is still available as part of the
+Documenter's Work Bench module of System V.
+.PP
+Where differences between Documenter's Work Bench (1991) \fBpic\fP and GNU
+\fBpic\fP need to be described, original \fBpic\fP is referred to as
+\[lq]DWB pic\[rq].
+Details on the history of the program are given at the end of this
+document.
+.PP
+The \fBpic2plot\fR program does not require the rest of the
+\fIgroff\/\fP(1) toolchain to render graphics.
+It can display \fBpic\fR diagrams in an X\~window, or generate output
+plots in a large number of other formats.
+These formats include: PNG, PBM, PGM, PPM, GIF, SVG, Adobe Illustrator
+format, idraw-editable Postscript, the WebCGM format for Web-based
+vector graphics, the format used by the \fBxfig\fP drawing editor, the
+Hewlett-Packard PCL\~5 printer language, the Hewlett-Packard Graphics
+Language (by default, HP-GL/2), the ReGIS (remote graphics instruction
+set) format developed by DEC, Tektronix format, and device-independent
+GNU graphics metafile format.
+.PP
+In this document, \fIgpic\/\fP(1) and \fIpic2plot\/\fP(1) extensions are
+marked as such.
+.
+.
+.NH 1
+Invoking PIC
+.PP
+Every \fBpic\fP description is a little program describing drawing
+actions.
+The \fB[gtn]roff\fP-dependent versions compile the program by
+\fIpic\/\fP(1) into \fIgtroff\/\fP(1) macros; the \fIpic2plot\/\fP(1)
+implementation uses a plotting library to draw the picture directly.
+Programs that process or display
+\fIgtroff\/\fP(1) output need not know or care that parts of the image
+began life as \fBpic\fP descriptions.
+.PP
+The \fIpic\/\fP(1) program tries to translate anything between \fB.PS\fP
+and \fB.PE\fP markers, and passes through everything else.
+The normal definitions of \fB.PS\fP and \fB.PE\fP in the \fIms\fP macro
+package and elsewhere have also the side-effect of centering the
+\fBpic\fP output on the page.
+.
+.KS
+.NH 2
+PIC Error Messages
+.PP
+If you make a mistake in \fBpic\fP input such that the program cannot
+interpret what you mean,
+\fIgpic\/\fP(1) issues a diagnostic message in the format prescribed by
+the GNU Coding Standards.
+.
+A typical error message looks like
+.
+.
+.ds FAM C
+.DS
+pic:\fIfile\fP:\fInnn\fP: syntax error before \[aq]\fItoken\fP\[aq]
+pic:\fIfile\fP:\fInnn\fP: giving up on this picture
+.DE
+.ds FAM T
+.
+.
+.LP
+where
+.I file
+is the name of the file being processed,
+.I nnn
+is a line number within that file,
+and
+.I token
+is a symbol in the \fBpic\fP language
+(often a keyword)
+near
+(usually just after)
+the error location.
+.KE
+.
+.
+.NH 1
+Basic PIC Concepts
+.PP
+Pictures are described procedurally, as collections of objects
+connected by motions.
+Normally, \fBpic\fP tries to string together objects left-to-right in
+the sequence they are described, joining them at visually natural
+points.
+Here is an example illustrating the flow of data in \fBpic\fP
+processing:
+.KS
+.PS
+ellipse "document";
+arrow;
+box width 0.6 "\fIgpic\/\fP(1)"
+arrow;
+box width 1.1 "\fIgtbl\/\fP(1) or \fIgeqn\/\fP(1)" "(optional)" dashed;
+arrow;
+box width 0.6 "\fIgtroff\/\fP(1)";
+arrow;
+ellipse "PostScript"
+.PE
+.CE "1: Flow of \fBpic\fP data"
+.PP
+This was produced from the following \fBpic\fP program:
+.KS
+.DS
+.ps -1
+.vs -1
+.CW
+\&.PS
+ellipse "document";
+arrow;
+box width 0.6 "\efIgpic\e/\efP(1)"
+arrow;
+box width 1.1 "\efIgtbl\e/\efP(1) or \efIgeqn\e/\efP(1)" "(optional)" dashed;
+arrow;
+box width 0.6 "\efIgtroff\e/\efP(1)";
+arrow;
+ellipse "PostScript"
+\&.PE
+.DE
+.R
+.KE
+.LP
+This little program illustrates several \fBpic\fP basics.
+Firstly, we see how to invoke three object types; ellipses, arrows, and
+boxes.
+We see how to declare text lines to go within an object (and that text
+can have font changes in it).
+We see how to change the line style of an object from solid (the
+default) to dashed.
+And we see that a box can be made wider than its default size to
+accommodate more text (we'll discuss this facility in detail in the next
+section).
+.PP
+We also get to see \fBpic\fP's simple syntax.
+Statements are ended by newlines or semicolons.
+String quotes are required around all text arguments, whether or not
+they contain spaces.
+In general, the order of command arguments and modifiers like \[lq]width
+1.2\[rq] or \[lq]dashed\[rq] doesn't matter, except that the order of
+text arguments is significant.
+.PP
+Here are all but one of the basic \fBpic\fP objects at their default sizes:
+.KS
+.PS
+box "box";
+move;
+line "line" "";
+move;
+arrow "arrow" "";
+move;
+circle "circle";
+move;
+ellipse "ellipse";
+move;
+arc; down; move; "arc"
+.PE
+.CE "2: Basic \fBpic\fP objects"
+.PP
+The missing simple object type is a \fIspline\fP.
+There is also a way to collect objects into \fIblock composites\fP which
+allows you to treat the whole group as a single object (resembling a
+box) for many purposes.
+We'll describe both of these later on.
+.PP
+The box, ellipse, circle, and block composite objects are \fIclosed\/\fR;
+lines, arrows, arcs and splines are \fIopen\fP.
+This distinction is often important in explaining command modifiers.
+.PP
+Figure \n[H1]-2 was produced by the following \fBpic\fP program,
+which introduces some more basic concepts:
+.KS
+.DS
+.CW
+\&.PS
+box "box";
+move;
+line "line" "";
+move;
+arrow "arrow" "";
+move;
+circle "circle";
+move;
+ellipse "ellipse";
+move;
+arc; down; move; "arc"
+\&.PE
+.DE
+.ft R
+.KE
+.PP
+The first thing to notice is the \fImove\fP command, which moves a
+default distance (1/2 inch) in the current movement direction.
+.PP
+Secondly, see how we can also decorate lines and arrows with text.
+The line and arrow commands each take two arguments here, specifying
+text to go above and below the object.
+If you wonder why one argument would not do, contemplate the output of
+\fBarrow "ow!"\fP:
+.KS
+.PS
+arrow "ow!"
+.PE
+.CE "3: Text centered on an arrow"
+.PP
+When a command takes one text string, \fBpic\fP tries to place it at
+the object's geometric center.
+As you add more strings, \fBpic\fP treats them as a vertical block to be
+centered.
+The program
+.KS
+.DS
+.CW
+line "1";
+line "1" "2";
+line "1" "2" "3";
+line "1" "2" "3" "4";
+line "1" "2" "3" "4" "5";
+.DE
+.ft R
+.KE
+.LP
+for example, gives you this:
+.KS
+.sp 2
+.PS
+line "1";
+line "1" "2";
+line "1" "2" "3";
+line "1" "2" "3" "4";
+line "1" "2" "3" "4" "5";
+.PE
+.sp 2
+.CE "4: Effects of multiple text arguments"
+.PP
+The last line of Figure 3-2's program, `\fBarc; down; move;
+"arc"\fP', describing the captioned arc, introduces several new ideas.
+Firstly, we see how to change the direction in which objects are
+joined.
+Had we written \fBarc; move; "arc"\fP, omitting \fBdown\fP the caption
+would have been joined to the top of the arc, like this:
+.KS
+.PS
+arc; move; "arc";
+.PE
+.CE "5: Result of \fBarc; move; ""arc""\fP"
+.PP
+This is because drawing an arc changes the default direction to the
+one its exit end points at.
+To reinforce this point, consider:
+.KS
+.PS
+arc cw; move; "arc";
+.PE
+.CE "6: Result of \fBarc cw; move; ""arc""\fP"
+.PP
+All we've done differently here is specify \[lq]cw\[rq] for a clockwise arc
+(\[lq]ccw\[rq] specifies counter-clockwise direction).
+Observe how it changes the default direction to down, rather than up.
+.PP
+Another good way to see this via with the following program:
+.KS
+.DS
+.CW
+line; arc; arc cw; line
+.DE
+.ft R
+.KE
+.LP
+which yields:
+.KS
+.PS
+line; arc; arc cw; line;
+.PE
+.CE "7: Result of \fBline; arc; arc cw; line\fP"
+.LP
+Notice that we did not have to specify \[lq]up\[rq] for the second arc to be
+joined to the end of the first.
+.PP
+Finally, observe that a string, alone, is treated as text to be
+surrounded by an invisible box of a size either specified by width
+and height attributes or by the defaults \fBtextwid\fR and
+\fBtextht\fR.
+Both are initially zero (because we don't know the default font size).
+.
+.
+.NH 1
+Sizes and Spacing
+.PP
+Sizes are specified in inches.
+If you don't like inches, it's possible to set a global style variable
+\fBscale\fP that changes the unit.
+Setting \fBscale = 2.54\fP effectively changes the internal unit to
+centimeters (all other size variable values are scaled correspondingly).
+.
+.NH 2
+Default Sizes of Objects
+.PP
+Here are the default sizes for \fBpic\fP objects:
+.TS H
+center, tab(@), linesize(2);
+lb | lb
+l | l.
+.sp 2p
+Object@Default Size
+.sp 2p
+_
+.sp 2p
+.TH
+box@0.75" wide by 0.5" high
+circle@0.5" diameter
+ellipse@0.75" wide by 0.5" high
+arc@0.5" radius
+line@0.5" long
+arrow@0.5" long
+.sp 5p
+_
+.TE
+.PP
+The simplest way to think about these defaults is that they make the
+other basic objects fit snugly into a default-sized box.
+.PP
+\fIpic2plot\/\fP(1) does not necessarily emit a physical inch for
+each virtual inch in its drawing coordinate system.
+Instead, it draws on a canvas 8\~virtual inches by 8\~virtual inches
+wide.
+If its output page size is \[lq]letter\[rq], these virtual inches will
+map to real ones.
+Specifying a different page size (such as, say, \[lq]a4\[rq]) will scale
+virtual inches so they are output as one eighth of the page width.
+Also, \fIpic2plot\/\fP(1) centers all images by default, though the
+\fB\-n\fP option can be used to prevent this.
+.
+.NH 2
+Objects Do Not Stretch!
+.PP
+Text is rendered in the current font with normal troff line spacing.
+Boxes, circles, and ellipses do \fInot\fP automatically resize to fit
+enclosed text.
+Thus, if you say \fBbox "this text far too long for a default box"\fP
+you'll get this:
+.KS
+.PS
+box "this text is far too long for a default box"
+.PE
+.CE "1: Boxes do not automatically resize"
+.LP
+which is probably not the effect you want.
+.
+.NH 2
+Resizing Boxes
+.PP
+To change the box size, you can specify a box width with the \[lq]width\[rq]
+modifier:
+.KS
+.PS
+box width 3 "this text is far too long for a default box"
+.PE
+.CE "2: Result of \fBbox width 3 ""text far too long""\fP"
+.PP
+This modifier takes a dimension in inches.
+There is also a \[lq]height\[rq] modifier that changes a box's height.
+The \fBwidth\fP keyword may be abbreviated to \fBwid\fP; the
+\fBheight\fP keyword to \fBht\fP.
+.
+.NH 2
+Resizing Other Object Types
+.PP
+To change the size of a circle, give it a \fBrad[ius]\fP or
+\fBdiam[eter]\fP modifier; this changes the radius or diameter of the
+circle, according to the numeric argument that follows.
+.KS
+.PS
+{circle rad 0.1; move down 0.2 from last circle .s; "0.1"};
+move; circle rad 0.2 "0.2"; move; circle rad 0.3 "0.3";
+.PE
+.CE "3: Circles with increasing radii"
+.PP
+The \fBmove\fP command can also take a dimension, which just tells
+it how many inches to move in the current direction.
+.PP
+Ellipses are sized to fit in the rectangular box defined by their
+axes, and can be resized with \fBwidth\fP and \fBheight\fP like boxes.
+.PP
+You can also change the radius of curvature of an arc with \fBrad[ius]\fP
+(which specifies the radius of the circle of which the arc is a segment).
+Larger values yield flatter arcs.
+.KS
+.PS
+{arc rad 0.1; move down 0.3 from last arc .center; "0.1"};
+move;
+{arc rad 0.2; move down 0.4 from last arc .center; "0.2"};
+move;
+{arc rad 0.3; move down 0.5 from last arc .center; "0.3"};
+.PE
+.CE "4: \fBarc rad\fP with increasing radii"
+.PP
+Observe that because an arc is defined as a quarter circle, increasing
+the radius also increases the size of the arc's bounding box.
+.
+.NH 2
+The `same' Keyword
+.PP
+In place of a dimension specification, you can use the keyword
+\fBsame\fR.
+This gives the object the same size as the previous one
+of its type.
+As an example, the program
+.KS
+.DS
+.CW
+\&.PS
+box; box wid 1 ht 1; box same; box
+\&.PE
+.R
+.DE
+.KE
+.LP
+gives you
+.KS
+.PS
+box; box wid 1 ht 1; box same; box
+.PE
+.CE "5: The \fBsame\fP keyword"
+.
+.
+.NH 1
+Generalized Lines and Splines
+.
+.NH 2
+Diagonal Lines
+.PP
+It is possible to specify diagonal lines or arrows by adding multiple \fBup\fP,
+\fBdown\fP, \fBleft\fP, and \fBright\fP modifiers to the line object.
+Any of these can have a multiplier.
+To understand the effects, think of the drawing area as being gridded
+with standard-sized boxes.
+.KS
+.PS
+# Draw a demonstration up left arrow with grid box overlay
+define gridarrow
+{
+ move right 0.5
+ [
+ {arrow up left $1;}
+ box wid 0.5 ht 0.5 dotted with .nw at last arrow .end;
+ for i = 2 to ($1 / 0.5) do {
+ box wid 0.5 ht 0.5 dotted with .sw at last box .se;
+ }
+ move down from last arrow .center;
+ [
+ sprintf("\fBarrow up left %g\fP", $1)
+ ]
+ ]
+ move right 0.1 from last [] .e;
+}
+gridarrow(0.5);
+gridarrow(1);
+gridarrow(1.5);
+gridarrow(2);
+undef gridarrow
+.PE
+.CE "1: Diagonal arrows (dotted boxes show the implied 0.5-inch grid)"
+.
+.NH 2
+Multi-Segment Line Objects
+.PP
+A \[lq]line\[rq] or \[lq]arrow\[rq] object may actually be a path
+consisting of any number of segments of varying lengths and directions.
+To describe a path, connect several line or arrow commands with the
+keyword \fBthen\fP.
+.KS
+.PS
+define zigzag { $1 right 1 then down .5 left 1 then right 1 }
+zigzag(line);
+.PE
+.CE "2: \fBline right 1 then down .5 left 1 then right 1\fP"
+.PP
+If a path starts with \fBthen\fP, the first segment is assumed to be into
+the current direction, using the default length.
+.
+.NH 2
+Spline Objects
+.PP
+If you start a path with the \fBspline\fP keyword, the path vertices
+are treated as control points for a spline curve fit.
+.KS
+.PS
+[zigzag(spline);]
+move down 0.2 from last [] .s;
+"The spline curve..."
+move right from last [] .e;
+[
+ zigzag(line dashed);
+ spline from start of last line right 1 then down .5 left 1 then right 1;
+ "1" at last spline .start + (-0.1, 0);
+ "2" at last spline .start + (1.1, 0);
+ "3" at last spline .end + (-1.1, 0);
+ "4" at last spline .end + (0.1, 0);
+]
+move down 0.2 from last [] .s;
+"...with tangents displayed"
+undef zigzag;
+.PE
+.CE "3: \fBspline right 1 then down .5 left 1 then right 1\fP"
+.PP
+You can describe many natural-looking but irregular curves this
+way.
+For example:
+.KS
+.PS
+[spline right then up then left then down ->;]
+move down 0.2 from last [] .s;
+["\fBspline right then up then left then down ->;\fP"]
+move right 3 from last [] .se;
+"\fBspline left then up right then down right ->;\fP"
+move up 0.2;
+[spline left then up right then down right ->;]
+.PE
+.CE "4: Two more spline examples"
+.LP
+Note the arrow decorations.
+Arrowheads can be applied naturally to any path-based object, line or
+spline.
+We'll see how in the next section.
+.
+.
+.NH 1
+Decorating Objects
+.
+.NH 2
+Text Special Effects
+.PP
+All \fBpic\fP implementations support the following font-styling
+escapes within text objects:
+.IP "\efR, \ef1" \w'\efR,\~\ef3'u+2n
+Set Roman style (the default)
+.IP "\efI, \ef2"
+Set Italic style
+.IP "\efB, \ef3"
+Set Bold style
+.IP \efP
+Revert to previous style; only works one level deep, does not stack.
+.PP
+In the \fBpic\fP implementations that are preprocessors for a
+toolchain that include \fB[gtn]roff\fP, text objects may also contain
+\fB[gtn]roff\fP vertical- and horizontal-motion escapes such as \eh or \ev.
+Troff special glyphs are also available.
+All \e-escapes will be passed through to the postprocessing stage and
+have their normal effects.
+The base font family is set by the \fB[gtn]roff\fP environment at the
+time the picture is rendered.
+.PP
+\fBpic2plot\fP replaces \fB[gtn]roff\fP horizontal- and vertical-motion
+escapes with \e-escapes of its own.
+Troff special glyphs are not available, but in most back ends Latin-1
+special characters and a square-root radical will be.
+See the \fBpic2plot\fP documentation for full details.
+.
+.NH 2
+Dashed Objects
+.PP
+We've already seen that the modifier \fBdashed\fP can change the line
+style of an object from solid to dashed.
+GNU \fBgpic\fP permits you to dot or dash ellipses, circles, and arcs
+(and splines in \*[tx] mode only); some versions of DWB may only permit
+dashing of lines and boxes.
+It's possible to change the dash interval by specifying a
+number after the modifier.
+.PP
+.KS
+.PS
+box dashed "default";
+move;
+box dashed 0.05 "0.05";
+move;
+box dashed 0.1 "0.1";
+move;
+box dashed 0.15 "0.15";
+move;
+box dashed 0.2 "0.2";
+.PE
+.CE "1: Dashed objects"
+.
+.NH 2
+Dotted Objects
+.PP
+Another available qualifier is \fBdotted\fP.
+GNU \fBgpic\fP permits you to dot or dash ellipses, circles, and arcs
+(and splines in \*[tx] mode only); some versions of DWB may only permit
+dashing of lines and boxes.
+It too can be suffixed with a number to specify the interval between
+dots:
+.KS
+.PS
+box dotted "default";
+move;
+box dotted 0.05 "0.05";
+move;
+box dotted 0.1 "0.1";
+move;
+box dotted 0.15 "0.15";
+move;
+box dotted 0.2 "0.2";
+.PE
+.CE "2: Dotted objects"
+.
+.NH 2
+Rounding Box Corners
+.PP
+It is also possible, in GNU \fBgpic\fP only, to modify a box so it has
+rounded corners:
+.KS
+.PS
+box rad 0.05 "rad 0.05";
+move;
+box rad 0.1 "rad 0.1";
+move;
+box rad 0.15 "rad 0.15";
+move;
+box rad 0.2 "rad 0.2";
+move;
+box rad 0.25 "rad 0.25";
+.PE
+.CE "3: \fBbox rad\fP with increasing radius values"
+.PP
+Radius values higher than half the minimum box dimension are silently
+truncated to that value.
+.
+.NH 2
+Slanted Boxes
+.PP
+GNU \fBgpic\fP supports slanted boxes:
+.KS
+.PS
+box wid 1.2 xslanted 0.1 "xslanted 0.1";
+move;
+box wid 1.2 yslanted -0.1 "yslanted -0.1";
+move;
+box wid 1.2 xslanted -0.2 yslanted 0.1 "xslanted -0.2" "yslanted 0.1";
+.PE
+.CE "4: Various slanted boxes."
+.PP
+The \fBxslanted\fP and \fByslanted\fP attributes specify the x and
+y\~offset, respectively, of the box's upper right corner from its default
+position.
+.
+.NH 2
+Arrowheads
+.PP
+Lines and arcs can be decorated as well.
+Any line or arc (and any spline as well) can be decorated with
+arrowheads by adding one or more as modifiers:
+.KS
+.PS
+line <- ->
+.PE
+.CE "5: Double-headed line made with \fBline <- ->\fP"
+.PP
+In fact, the \fBarrow\fP command is just shorthand for \fBline ->\fP.
+And there is a double-head modifier <->, so the figure above could have
+been made with \fBline <->\fP.
+.PP
+Arrowheads have a \fBwidth\fP attribute, the distance across the rear;
+and a \fBheight\fP attribute, the length of the arrowhead along the shaft.
+.PP
+Arrowhead style is controlled by the style variable \fBarrowhead\fP.
+The DWB and GNU versions interpret it differently.
+DWB defaults to open arrowheads and an \fBarrowhead\fP value of\~2; the
+Kernighan paper says a value of\~7 makes solid arrowheads.
+GNU \fBgpic\fP defaults to solid arrowheads and an \fBarrowhead\fP value
+of\~1; a value of\~0 produces open arrowheads.
+Note that solid arrowheads are always filled with the current outline
+color.
+.
+.NH 2
+Line Thickness
+.PP
+It's also possible to change the line thickness of an object (this is
+a GNU extension, DWB \fBpic\fP doesn't support it).
+The default thickness of the lines used to draw objects is controlled by the
+.B linethick
+variable.
+This gives the thickness of lines in points.
+A negative value means use the default thickness:
+in \*[tx] output mode, this means use a thickness of 8 milliinches;
+in \*[tx] output mode with the
+.B -c
+option, this means use the line thickness specified by
+.B .ps
+lines; in troff output mode, this means use a thickness proportional
+to the pointsize.
+A zero value means draw the thinnest possible line supported by the
+output device.
+Initially it has a value of -1.
+There is also a \fBthickness\fP attribute (which can be abbreviated to
+\fBthick\fP).
+For example, \fBcircle thickness 1.5\fP would draw a circle using a line
+with a thickness of 1.5 points.
+The thickness of lines is not affected by the value of the
+.B scale
+variable, nor by any width or height given in the
+.B .PS
+line.
+.
+.NH 2
+Invisible Objects
+.PP
+The modifier \fBinvis[ible]\fP makes an object entirely invisible.
+This used to be useful for positioning text in an invisible object that
+is properly joined to neighboring ones.
+Newer DWB versions and GNU \fBpic\fP treat stand-alone text in exactly
+this way.
+.
+.NH 2
+Filled Objects
+.PP
+It is possible to fill boxes, circles, and ellipses.
+The modifier \fBfill[ed]\fP accomplishes this.
+You can suffix it with a fill value; the default is given by the style
+variable \fBfillval\fP.
+.PP
+DWB \fBpic\fP and \fBgpic\fP have opposite conventions for fill values
+and different defaults.
+DWB \fBfillval\fP defaults to 0.3 and smaller values are darker; GNU
+\fBfillval\fP uses 0 for white and 1 for black.
+.KS
+.PS
+circle fill; move; circle fill 0.4; move; circle fill 0.9;
+.PE
+.CE "6: \fBcircle fill; move; circle fill 0.4; move; circle fill 0.9;\fR"
+.PP
+GNU \fBgpic\fP makes some additional guarantees.
+A fill value greater than 1 can also be used: this means fill with the
+shade of gray that is currently being used for text and lines.
+Normally this is black, but output devices may provide a mechanism for
+changing this.
+The invisible attribute does not affect the filling of objects.
+Any text associated with a filled object is added after the object has
+been filled, so that the text is not obscured by the filling.
+.
+.NH 2
+Colored Objects
+.PP
+As a GNU extension, three additional modifiers are available to specify
+colored objects.
+\fBoutline\fP sets the color of the outline, \fBshaded\fP the fill
+color, and \fBcolor\fP sets both.
+All three keywords expect a suffix specifying the color.
+Example:
+.KS
+.PS
+box color "yellow"; arrow color "cyan"; circle shaded "green" outline "black";
+.PE
+.CE "7: \fBbox color ""yellow""; arrow color ""cyan""; \
+circle shaded ""green"" outline ""black"";\fR"
+.PP
+Alternative spellings are \fBcolour\fP, \fBcolored\fP, \fBcoloured\fP,
+and \fBoutlined\fP.
+.PP
+Predefined color names for \fI[gtn]roff\/\fP-based \fBpic\fP
+implementations are defined in the device macro files, for example
+\f(CWps.tmac\fP; additional colors can be defined with the
+\fB.defcolor\fP request (see the manual page of GNU \fItroff\/\fP(1)
+for more details).
+Currently, color support is not available at all in \*[tx] mode.
+.PP
+The \fIpic2plot\/\fP(1) carries with its own set of color names,
+essentially those recognized by the X\~window system with \[lq]grey\[rq]
+accepted as a variant of \[lq]gray\[rq].
+.PP
+\fBpic\fP assumes that at the beginning of a picture both glyph and fill
+color are set to the default value.
+.
+.
+.NH 1
+More About Text Placement
+.PP
+By default, text is centered at the geometric center of the object it is
+associated with.
+The modifier \fBljust\fP causes the left end to be at the specified
+point (which means that the text lies to the right of the specified
+place!), the modifier \fBrjust\fP puts the right end at the place.
+The modifiers \fBabove\fP and \fBbelow\fP center the text one half line
+space in the given direction.
+.PP
+Text attributes can be combined:
+.KS
+.PS
+[line up "ljust text" ljust;]
+move 1.5;
+[line up "rjust text" rjust;]
+move;
+[arrow 1 "ljust above" ljust above;]
+move;
+[arrow 1 "rjust below" rjust below;]
+.PE
+.CE "1: Text attributes"
+.PP
+What actually happens is that \fIn\fP text strings are centered in a box
+that is \fBtextwid\fP wide by \fBtextht\fP high.
+Both these variables are initially zero (that is \fBpic\fR's way of not
+making assumptions about \fI[tg]roff\/\fP(1)'s default point size).
+.PP
+In GNU \fBgpic\fR, objects can have an
+.B aligned
+attribute.
+This only works if the postprocessor is
+\fBgrops\fP or \fBgropdf\fP.
+Any text associated with an object having the
+.B aligned
+attribute is rotated about the center of the object
+so that it is aligned in the direction from the start point
+to the end point of the object.
+Note that this attribute has no effect for objects whose start and
+end points are coincident.
+.
+.
+.NH 1
+More About Direction Changes
+.PP
+We've already seen how to change the direction in which objects are
+composed from rightwards to downwards.
+Here are some more illustrative examples:
+.KS
+.PS
+down;
+[
+ "\fBright; box; arrow; circle; arrow; ellipse\fP";
+ move 0.2;
+ [right; box; arrow; circle; arrow; ellipse;]
+]
+move down 0.3 from last [] .s;
+[
+ "\fBleft; box; arrow; circle; arrow; ellipse\fP"
+ move 0.2;
+ [left; box; arrow; circle; arrow; ellipse;]
+]
+# move down 0.3 from last [] .sw;
+# To re-join this illustrations, delete everything from here down to
+# the next #-comment, and uncomment the move line above
+.PE
+.CE "1: Effects of different motion directions (right and left)"
+.KS
+.PS
+# To re-join this illustrations, delete everything down to here, then
+# comment out the next `down' line.
+# Don't forget to re-number the figures following!
+down;
+[
+ "\fBdown; box; arrow; circle; arrow; ellipse;\fP"
+ move 0.2;
+ box; arrow; circle; arrow; ellipse;
+]
+move right 2 from last [] .e;
+[
+ up; box; arrow; circle; arrow; ellipse;
+ move 0.2;
+ "\fBup; box; arrow; circle; arrow; ellipse;\fP"
+]
+.PE
+.CE "2: Effects of different motion directions (up and down)"
+.PP
+Something that may appear surprising happens if you change directions
+in the obvious way:
+.KS
+.PS
+box; arrow; circle; down; arrow; ellipse
+.PE
+.CE "3: \fBbox; arrow; circle; down; arrow; ellipse\fP"
+.LP
+You might have expected that program to yield this:
+.KS
+.PS
+box; arrow; circle; move to last circle .s; down; arrow; ellipse
+.PE
+.CE "4: More intuitive?"
+.LP
+But, in fact, to get Figure \*[SN]3 you have to do this:
+.KS
+.DS
+.CW
+\&.PS
+box;
+arrow;
+circle;
+move to last circle .s;
+down;
+arrow;
+ellipse
+\&.PE
+.R
+.DE
+.KE
+.LP
+Why is this?
+Because the exit point for the current direction is already set when you
+draw the object.
+The second arrow in Figure \*[SN]2 dropped downwards from the circle's
+attachment point for an
+object to be joined to the right.
+.PP
+The meaning of the command \fBmove to last circle \&.s\fP should be
+obvious.
+In order to see how it generalizes, we'll need to go into detail on two
+important topics; locations and object names.
+.
+.
+.NH 1
+Naming Objects
+.PP
+The most natural way to name locations in \fBpic\fP is relative to
+objects.
+In order to do this, you have to be able to name
+objects.
+The \fBpic\fP language has rich facilities for this that try to emulate
+the syntax of English.
+.
+.NH 2
+Naming Objects By Order Of Drawing
+.PP
+The simplest (and generally the most useful) way to name an object is
+with a \fBlast\fP clause.
+It needs to be followed by an object type name; \fBbox\fP, \fBcircle\fP,
+\fBellipse\fP, \fBline\fP, \fBarrow\fP, \fBspline\fP, \fB""\fP, or
+\fB[]\fP (the last type refers to a \fIcomposite object\fP which we'll
+discuss later).
+So, for example, the \fBlast circle\fP clause in the program attached to
+Figure \*[SN]3 refers to the last circle drawn.
+.PP
+More generally, objects of a given type are implicitly numbered
+(starting from\~1).
+You can refer to (say) the third ellipse in the current picture with
+\fB3rd ellipse\fP, or to the first box as \fB1st box\fP, or to the fifth
+text string (which isn't an attribute to another object) as \fB5th
+""\fP.
+.PP
+Objects are also numbered backwards by type from the last one.
+You can say \fB2nd last box\fP to get the second-to-last box, or
+\fB3rd last ellipse\fP to get the third-to-last ellipse.
+.PP
+In places where \fIn\/\fBth\fR is allowed, \fB`\fIexpr\/\fB'th\fR is
+also allowed.
+Note that
+.B 'th
+is a single token: no space is allowed between the
+.B '
+and the \fBth\fP.
+For example,
+.IP
+.KS
+.DS
+.CW
+for i = 1 to 4 do {
+ line from `i'th box.nw to `i+1'th box.se
+}
+.DE
+.R
+.KE
+.
+.NH 2
+Naming Objects With Labels
+.PP
+You can also specify an object by referring to a label.
+A label is a word (which must begin with a capital letter) followed by a
+colon; you declare it by placing it immediately before the object
+drawing command.
+For example, the program
+.KS
+.DS
+.CW
+\&.PS
+A: box "first" "object"
+move;
+B: ellipse "second" "object"
+move;
+arrow right at A .r;
+\&.PE
+.R
+.DE
+.KE
+.LP
+declares labels \fBA\fP and \fBB\fP for its first and second objects.
+Here's what that looks like:
+.KS
+.PS
+A: box "first" "object"
+move;
+B: ellipse "second" "object"
+move;
+arrow right at A .r;
+.PE
+.CE "1: Example of label use"
+The \fBat\fP statement in the fourth line uses the label \fBA\fP (the
+behavior of \fBat\fP is explained in the next section).
+We'll see later on that labels are most useful for referring to block
+composite objects.
+.PP
+Labels are not constants but variables (you can view colon as a sort
+of assignment).
+You can say something like \fBA: A + (1,0);\fP and the effect is to
+reassign the label \fBA\fR to designate a position one inch to the right
+of its old value.
+.
+.
+.NH 1
+Describing locations
+.PP
+The location of points can be described in many different ways.
+All these forms are interchangeable as for as the \fBpic\fP language
+syntax is concerned; where you can use one, any of the others that would
+make semantic sense are allowed.
+.PP
+The special label \fBHere\fR always refers to the current position.
+.
+.NH 2
+Absolute Coordinates
+.PP
+The simplest is absolute coordinates in inches; \fBpic\fP uses a
+Cartesian system with (0,0) at the lower left corner of the virtual
+drawing surface for each picture (that is, X\~increases to the right
+and Y\~increases upwards).
+An absolute location may always be written in the conventional form as
+two comma-separated numbers surrounded by parentheses (and this is
+recommended for clarity).
+In contexts where it creates no ambiguity, the pair of X and
+Y\~coordinates suffices without parentheses.
+.PP
+It is a good idea to avoid absolute coordinates, however.
+They tend to make picture descriptions difficult to understand and
+modify.
+Instead, there are quite a number of ways to specify locations
+relative to \fBpic\fP objects and previous locations.
+.PP
+Another possibility of surprise is the fact that \fBpic\fP crops the
+picture to the smallest bounding box before writing it out.
+For example, if you have a picture consisting of a small box with its
+lower left corner at (2,2) and another small box with its upper right
+corner at (5,5), the width and height of the image are both 3\~units and
+not\~5.
+To get the origin at (0,0) included, simply add an invisible object to
+the picture, positioning the object's left corner at (0,0).
+.
+.NH 2
+Locations Relative to Objects
+.PP
+The symbol \fBHere\fP always refers to the position of the last object
+drawn or the destination of the last \fBmove\fP.
+.PP
+Alone and unqualified, a \fBlast circle\fP or any other way of
+specifying a closed-object or arc location refers as a position to the
+geometric center of the object.
+Unqualified, the name of a line or spline object refers to the position
+of the object start.
+.PP
+Also, \fBpic\fP objects have quite a few named locations
+associated with them.
+One of these is the object center, which can be indicated (redundantly)
+with the suffix \fB.center\fP (or just \fB.c\fP).
+Thus, \fBlast circle \&.center\fP is equivalent to \fBlast
+circle\fP.
+.NH 3
+Locations Relative to Closed Objects
+.PP
+Every closed object (box, circle, ellipse, or block composite) also
+has eight compass points associated with it;
+.KS
+.PS
+define dot {circle fill rad 0.02 at $1}
+
+define compass { [
+ ME: $1;
+ dot(ME.c); "\fB .c\fP" at ME .c ljust;
+ dot(ME.n); "\fB.n\fP" at ME .n above
+ dot(ME.ne); "\fB .ne\fP" at ME .ne above
+ dot(ME.e); "\fB .e\fP" at ME .e ljust
+ dot(ME.se); "\fB .se\fP" at ME .se below
+ dot(ME.s); "\fB.s\fP" at ME .s below
+ dot(ME.sw); "\fB.sw \fP" at ME .sw below
+ dot(ME.w); "\fB.w \fP" at ME .w rjust
+ dot(ME.nw); "\fB.nw \fP" at ME .nw above
+] }
+compass(box wid 1.5 ht 1);
+move right from last [] .e;
+compass(circle diam 1);
+move right from last [] .e;
+compass(ellipse wid 1.5 ht 1);
+.PE
+.CE "1: Compass points"
+.LP
+these are the locations where eight compass rays from the geometric center
+would intersect the figure.
+So when we say \fBlast circle \&.s\fP we are referring to the south
+compass point of the last circle drawn.
+The explanation of Figure 8-3's program is now complete.
+.PP
+(In case you dislike compass points, the names \fB.top\fP,
+\&\fB.bottom\fP, \fB.left\fP and \fB.right\fP are synonyms for \fB.n\fP,
+\&\fB.s\fP, \fB.e\fP, and \fB.w\fP respectively; they can even be
+abbreviated to \fB.t\fP, \fB.b\fP, \fB.l\fP and \fB.r\fP).
+.PP
+The names \fBcenter\fP, \fBtop\fP, \fBbottom\fP, \fBleft\fP, \fBright\fP,
+\fBnorth\fP, \fBsouth\fP, \fBeast\fP, and \fBwest\fP can also be used
+(without the leading dot) in a prefix form marked by \fBof\fP; thus,
+\fBcenter of last circle\fP and \fBtop of 2nd last ellipse\fP are both
+valid object references.
+Finally, the names \fBleft\fP and \fBright\fP can be prefixed with
+\fBupper\fP and \fBlower\fP which both have the obvious meaning.
+.PP
+Arc objects also have compass points; they are the compass points of
+the implied circle.
+.PP
+Non-closed objects (line, arrow, or spline) have compass points too, but
+the locations of them are completely arbitrary.
+In particular, different \fBpic\fP implementations return different
+locations.
+.NH 3
+Locations Relative to Open Objects
+.PP
+Every open object (line, arrow, arc, or spline) has three named
+points: \fB.start\fP, \fB.center\fP (or \fB.c\fP), and \fB.end\fP.
+They can also be used without leading dots in the \fBof\fP prefix form.
+The center of an arc is the center of its circle, but the center of
+a line, path, or spline is halfway between its endpoints.
+.KS
+.PS
+define critical {
+ [ ME: $1;
+ dot(ME.c); "\fB.center\fP" rjust at ME.center + (-0.1, 0.1)
+ dot(ME.start); "\fB.start\fP" rjust at ME.start + (-0.1, 0.1)
+ dot(ME.end); "\fB.end\fP" rjust at ME.end + (-0.1, 0.1)
+ ]
+}
+critical(line up right 1);
+move right 1 from last [] .e;
+critical(arc rad 0.5 cw);
+move down 0.5 from 2nd last [] .s;
+critical(line right 1 then down .5 left 1 then right 1);
+move right 1 from last [] .e;
+critical(spline right 1 then up right then left then left 1);
+.PE
+.CE "2: Special points on open objects"
+.PP
+.
+.NH 2
+Ways of Composing Positions
+.PP
+Once you have two positions to work with, there are several ways to
+combine them to specify new positions.
+.NH 3
+Vector Sums and Displacements
+.PP
+Positions may be added or subtracted to yield a new position (to be
+more precise, you can only add a position and an expression pair; the
+latter must be on the right side of the addition or subtraction sign).
+The result is the conventional vector sum or difference of coordinates.
+For example, \fBlast box \&.ne + (0.1, 0)\fP is a valid position.
+This example illustrates a common use, to define a position slightly
+offset from a named one (say, for captioning purposes).
+.NH 3
+Interpolation Between Positions
+.PP
+A position may be interpolated between any two positions.
+The syntax is `\fIfraction\fP \fBof the way between\fP \fIposition1\fP
+\fBand\fP \fIposition2\fP'.
+For example, you can say \fB1/3 of the way between Here and last ellipse
+\&.ne\fP.
+The fraction may be in numerator/denominator form or may be an ordinary
+number (values are \fInot\fP restricted to [0,1]).
+As an alternative to this verbose syntax, you can say `\fIfraction\fP
+\fB<\,\fP\fIposition1\fP \fB,\fP \fIposition2\/\fP\fB>\fP'; thus, the
+example could also be written as \fB1/3 <Here, last ellipse>\fP.
+.KS
+.PS
+arrow up right;
+P: 1/3 of the way between last arrow .start and last arrow .end;
+dot(P); move right 0.1; "P";
+.PE
+.CE "3: \fBP: 1/3 of the way between last arrow .start and last arrow .end\fP"
+.PP
+This facility can be used, for example, to draw double connections.
+.KS
+.PS
+A: box "yin"; move;
+B: box "yang";
+arrow right at 1/4 <A.e,A.ne>;
+arrow left at 1/4 <B.w,B.sw>;
+.PE
+.CE "4: Doubled arrows"
+.LP
+You can get Figure \n[H1]-4 from the following program:
+.KS
+.DS
+.CW
+\&.PS
+A: box "yin"; move;
+B: box "yang";
+arrow right at 1/4 <A.e,A.ne>;
+arrow left at 1/4 <B.w,B.sw>;
+\&.PE
+.R
+.DE
+.KE
+.LP
+Note the use of the short form for interpolating points.
+.NH 3
+Projections of Points
+.PP
+Given two positions \fIp\fP and \fIq\fP, the position
+\fB(\,\fP\fIp\fP\fB,\fP \fIq\fP\fB)\fP has the X\~coordinate of \fIp\fP
+and the Y coordinate of \fIq\fP.
+This can be helpful in placing an object at one of the corners of the
+virtual box defined by two other objects.
+.KS
+.PS
+box invis wid 2 height 1;
+dot(last box .ne); "\fB(B,A)\fP is here" ljust at last circle + (0.1, 0.1);
+dot(last box .se); "B" ljust at last circle + (0.1, -0.1)
+dot(last box .sw); "\fB(A,B)\fP is here" rjust at last circle + (-0.1, -0.1);
+dot(last box .nw); "A" ljust at last circle + (-0.1, 0.1)
+.PE
+.CE "5: Using (\fIx\fP, \fIy\fP) composition"
+.
+.NH 2
+Using Locations
+.PP
+There are four ways to use locations; \fBat\fP, \fBfrom\fP, \fBto\fP,
+and \fBwith\fP.
+All four are object modifiers; that is, you use them as suffixes to a
+drawing command.
+.PP
+The \fBat\fP modifier says to draw a closed object or arc with its
+center at the following location, or to draw a line/spline/arrow
+starting at the following location.
+.PP
+The \fBto\fP modifier can be used alone to specify a move destination.
+The \fBfrom\fP modifier can be used alone in the same way as \fBat\fP.
+.PP
+The \fBfrom\fP and \fBto\fP modifiers can be used with a \fBline\fR or
+\fBarc\fR command to specify start and end points of the object.
+In conjunction with named locations, this offers a very flexible
+mechanism for connecting objects.
+For example, the following program
+.KS
+.DS
+.CW
+\&.PS
+box "from"
+move 0.75;
+ellipse "to"
+arc cw from 1/3 of the way \e
+ between last box .n and last box .ne to last ellipse .n;
+\&.PE
+.R
+.DE
+.KE
+.LP
+yields:
+.KS
+.PS
+box "from"
+move 0.75;
+ellipse "to"
+arc cw from 1/3 of the way \
+ between last box .n and last box .ne to last ellipse .n;
+.PE
+.CE "6: A tricky connection specified with English-like syntax"
+.PP
+The \fBwith\fP modifier allows you to identify a named attachment
+point of an object (or a position within the object) with another point.
+This is very useful for connecting objects in a natural way.
+For an example, consider these two programs:
+.KS
+.PS
+[
+ [
+ box wid 0.5 ht 0.5;
+ box wid 0.75 ht 0.75;
+ ]
+ move 0.1 down 0.3 from last [] .s;
+ "\fBbox wid 0.5 ht 0.5; box wid 0.75 ht 0.75\fP"
+]
+move from last [].e 1.5
+[
+ [
+ box wid 0.5 ht 0.5;
+ box wid 0.75 ht 0.75 with .sw at last box .se;
+ ]
+ move 0.1 down 0.3 from last [] .s;
+ box invisible "\fBbox wid 0.5 ht 0.5;\fP" \
+ "\fBbox wid 0.75 ht 0.75 with .sw at last box .se;\fP"
+]
+.PE
+.CE "7: Using the \fBwith\fP modifier for attachments"
+.
+.NH 2
+The `chop' Modifier
+.PP
+When drawing lines between circles that don't intersect them at a
+compass point, it is useful to be able to shorten a line by the radius
+of the circle at either or both ends.
+Consider the following program:
+.KS
+.DS
+.CW
+\&.PS
+circle "x"
+circle "y" at 1st circle - (0.4, 0.6)
+circle "z" at 1st circle + (0.4, -0.6)
+arrow from 1st circle to 2nd circle chop
+arrow from 2nd circle to 3rd circle chop
+arrow from 3rd circle to 1st circle chop
+\&.PE
+.DE
+.R
+.KE
+.LP
+It yields the following:
+.KS
+.PS
+circle "x"
+circle "y" at 1st circle - (0.4, 0.6)
+circle "z" at 1st circle + (0.4, -0.6)
+arrow from 1st circle to 2nd circle chop
+arrow from 2nd circle to 3rd circle chop
+arrow from 3rd circle to 1st circle chop
+.PE
+.CE "8: The \fBchop\fR modifier"
+.LP
+Notice that the \fBchop\fR attribute moves arrowheads rather than
+stepping on them.
+By default, the \fBchop\fR modifier shortens both ends of the line by
+\fBcirclerad\fR.
+By suffixing it with a number you can change the amount of chopping.
+.PP
+If you say \fBline \&.\|.\|.\& chop \fIr1\fP chop \fIr2\fP\fR with
+\fIr1\fP and \fIr2\fP both numbers, you can vary the amount of chopping
+at both ends.
+You can use this in combination with trigonometric functions to write
+code that deals with more complex intersections.
+.
+.
+.NH 1
+Object Groups
+.PP
+There are two different ways to group objects in \fBpic\fP; \fIbrace
+grouping\fP and \fIblock composites\fP.
+.
+.NH 2
+Brace Grouping
+.PP
+The simpler method is simply to group a set of objects within curly
+bracket or brace characters.
+On exit from this grouping, the current position and direction are
+restored to their value when the opening brace was encountered.
+.
+.NH 2
+Block Composites
+.PP
+A block composite object is created a series of commands enclosed by
+square brackets.
+The composite can be treated for most purposes like a single closed
+object, with the size and shape of its bounding box.
+Here is an example.
+The program fragment
+.KS
+.DS
+.CW
+A: [
+ circle;
+ line up 1 at last circle .n;
+ line down 1 at last circle .s;
+ line right 1 at last circle .e;
+ line left 1 at last circle .w;
+ box dashed with .nw at last circle .se + (0.2, -0.2);
+ Caption: center of last box;
+]
+.R
+.DE
+.KE
+.LP
+yields the block in figure \n[H1]-1, which we show both with and
+without its attachment points.
+The block's location becomes the value of \fBA\fP.
+.KS
+.PS
+define junction {
+ circle;
+ line up 1 at last circle .n;
+ line down 1 at last circle .s;
+ line right 1 at last circle .e;
+ line left 1 at last circle .w;
+ box dashed with .nw at last circle .se + (0.2, -0.2);
+ Caption: center of last box;
+}
+[junction();]
+move;
+compass([junction()]);
+.PE
+.CE "1: A sample composite object"
+.LP
+To refer to one of the composite's attachment points, you can say
+(for example) \fBA \&.s\fP.
+For purposes of object naming, composites are a class.
+You could write \fBlast [] \&.s\fP as an equivalent reference, usable
+anywhere a location is needed.
+This construction is very important for putting together large,
+multi-part diagrams.
+.PP
+Blocks are also a variable-scoping mechanism, like a \fIgroff\/\fP(1)
+environment.
+All variable assignments done inside a block are undone at the end of it.
+To get at values within a block, write a name of the block followed by a
+dot, followed by the label you want.
+For example, we could refer the center of the box in the above composite as
+\fBlast [] \&.Caption\fP or \fBA.Caption\fP.
+.PP
+This kind of reference to a label can be used in any way any other
+location can be.
+For example, if we added \fB"Hi!" at A.Caption\fP
+the result would look like this:
+.KS
+.PS
+A: [junction();]
+"Hi!" at A.Caption;
+.PE
+.CE "2: Adding a caption using interior labeling"
+.PP
+You can also use interior labels in either part of a \fBwith\fR
+modifier.
+This means that the example composite could be placed relative to its
+caption box by a command containing \fBwith A.Caption at\fP.
+.PP
+Note that both width and height of the block composite object are always
+positive:
+.KS
+.PS
+[
+ [
+ box wid -0.5 ht 0.5
+ box wid 0.75 ht 0.75
+ ]
+ move 0.1 down 0.3 from last [].s
+ "\fBbox wid -0.5 ht 0.5; box wid 0.75 ht 0.75\fP"
+]
+move from last [].e 2
+[
+ [
+ [ box wid -0.5 ht 0.5 ]
+ box wid 0.75 ht 0.75
+ ]
+ move 0.1 down 0.3 from last [].s
+ "\fB[box wid -0.5 ht 0.5]; box wid 0.75 ht 0.75\fP"
+]
+.PE
+.CE "3: Composite block objects always have positive width and height"
+.PP
+Blocks may be nested.
+This means you can use block attachment points to build up complex
+diagrams hierarchically, from the inside out.
+Note that \fBlast\fP and the other sequential naming mechanisms
+don't look inside blocks, so if you have a program that looks
+like
+.KS
+.DS
+.CW
+\&.PS
+P: [box "foo"; ellipse "bar"];
+Q: [
+ [box "baz"; ellipse "quxx"]
+ "random text";
+ ]
+arrow from 2nd last [];
+\&.PE
+.R
+.DE
+.KE
+.LP
+the arrow in the last line is attached to object \fBP\fP, not
+object \fBQ\fP.
+.PP
+In DWB \fBpic\fP, only references one level deep into enclosed blocks
+were permitted.
+GNU \fBgpic\fP removes this restriction.
+.PP
+The combination of block variable scoping, assignability of labels and
+the macro facility that we'll describe later on can be used to
+simulate functions with local variables (just wrap the macro body in
+block braces).
+.
+.
+.NH 1
+Style Variables
+.PP
+There are a number of global style variables in \fBpic\fR that can be used to
+change its overall behavior.
+We've mentioned several of them in previous sections.
+They're all described here.
+For each variable, the default is given.
+.TS H
+center, tab(@), linesize(2);
+lb | lb | lb
+l | n | l.
+.sp 2p
+Style Variable@Default@What It Does
+.sp 2p
+_
+.sp 2p
+.TH
+boxht@0.5@Default height of a box
+boxwid@0.75@Default width of a box
+lineht@0.5@Default length of vertical line
+linewid@0.75@Default length of horizontal line
+linethick@-1@Default line thickness
+arcrad @0.25@Default radius of an arc
+circlerad@0.25@Default radius of a circle
+ellipseht@0.5@Default height of an ellipse
+ellipsewid@0.75@Default width of an ellipse
+moveht@0.5@Default length of vertical move
+movewid@0.75@Default length of horizontal move
+textht@0@Default height of box enclosing a text object
+textwid@0@Default width of box enclosing a text object
+arrowht@0.1@Length of arrowhead along shaft
+arrowwid@0.05@Width of rear of arrowhead
+arrowhead@1@Enable/disable arrowhead filling
+dashwid@0.05@Interval for dashed lines
+maxpswid@8.5@Maximum width of picture
+maxpsht@11@Maximum height of picture
+scale@1@Unit scale factor
+fillval@0.5@Default fill value
+.sp 5p
+_
+.TE
+Any of these variables can be set with a simple assignment statement.
+For example:
+.KS
+.PS
+[boxht=1; boxwid=0.3; movewid=0.2; box; move; box; move; box; move; box;]
+.PE
+.CE "1: \fBboxht=1; boxwid=0.3; movewid=0.2; box; move; box; move; box; move; box;\fP"
+.PP
+In GNU \fBpic\fR, setting the \fBscale\fR variable re-scales all
+size-related state variables so that their values remain equivalent in
+the new units.
+.PP
+The command \fBreset\fP resets all style variables to their defaults.
+You can give it a list of variable names as arguments (optionally
+separated by commas), in which case it resets only those.
+.PP
+State variables retain their values across pictures until reset.
+.
+.
+.NH 1
+Expressions, Variables, and Assignment
+.PP
+A number is a valid expression, of course (all numbers are stored
+internally as floating-point).
+Decimal-point notation is acceptable;
+in GNU \fBgpic\fR, scientific notation in C's `e' format (like
+\f(CW5e-2\fP) is accepted.
+.PP
+Anywhere a number is expected, the language also accepts a
+variable.
+Variables may be the built-in style variable described in the last
+section, or new variables created by assignment.
+.PP
+DWB \fBpic\fP supports only the ordinary assignment via \fB=\fP, which
+defines the variable (on the left side of the equal sign) in the current
+block if it is not already defined there, and then changes the value (on
+the right side) in the current block.
+The variable is not visible outside of the block.
+This is similar to the C\~programming language where a variable within a
+block shadows a variable with the same name outside of the block.
+.PP
+GNU \fBgpic\fP supports an alternate form of assignment using \fB:=\fP.
+The variable must already be defined, and the value is assigned to
+that variable without creating a variable local to the current block.
+For example, this
+.KS
+.DS
+.CW
+x=5
+y=5
+[
+ x:=3
+ y=3
+]
+print x " " y
+.DE
+.KE
+.LP
+prints \fB3 5\fP.
+.PP
+You can use the height, width, radius, and x and y coordinates of any
+object or corner in expressions.
+If \fBA\fP is an object label or name, all the following are valid:
+.KS
+.DS
+.CW
+A.x # x coordinate of the center of A
+A.ne.y # y coordinate of the northeast corner of A
+A.wid # the width of A
+A.ht # and its height
+2nd last circle.rad # the radius of the 2nd last circle
+.R
+.DE
+.KE
+.LP
+Note the second expression, showing how to extract a corner coordinate.
+.PP
+Basic arithmetic resembling those of C operators are available; \fB+\fP,
+\fB*\fP, \fB-\fP, \fB/\fP, and \fB%\fP.
+So is \fB^\fP for exponentiation.
+Grouping is permitted in the usual way using parentheses.
+GNU \fBgpic\fP allows logical operators to appear in expressions;
+\fB!\&\fP (logical negation, not factorial), \fB&&\fP, \fB|\||\fP,
+\fB==\fP, \fB!=\fP, \fB>=\fP, \fB<=\fP, \fB<\fP, \fB>\fP.
+.PP
+Various built-in functions are supported: \fBsin(\fIx\fB)\fR,
+\fBcos(\fIx\fB)\fR, \fBlog(\fIx\fB)\fR, \fBexp(\fIx\fB)\fR,
+\fBsqrt(\fIx\fB)\fR, \fBmax(\fIx\fB,\fIy\fB)\fR,
+\fBatan2(\fIx\fB,\fIy\fB)\fR, \fBmin(\fIx\fB,\fIy\fB)\fR,
+\fBint(\fIx\fB)\fR, \fBrand()\fP, and \fBsrand()\fP.
+Both \fBexp\fP and \fBlog\fP are
+base\~10; \fBint\fP does integer truncation; \fBrand()\fP returns a
+random number in [0-1), and \fBsrand()\fP sets the seed for
+a new sequence of pseudo-random numbers to be returned by \fBrand()\fP
+(\fBsrand()\fP is a GNU extension).
+.PP
+GNU \fBgpic\fP also documents a one-argument form or rand,
+\fBrand(\fIx\fB)\fR, which returns a random number between 1 and
+\fIx\fP, but this is deprecated and may be removed in a future
+version.
+.PP
+The function \fBsprintf()\fP behaves like a C \fIsprintf\/\fP(3)
+function that only takes %%, %e, %E, %f, %g, and %G conversion
+specifications.
+.
+.
+.NH 1
+Macros
+.PP
+You can define macros in \fBpic\fP, with up to 32 arguments (up to 16
+on EBCDIC platforms).
+This is useful for diagrams with repetitive parts.
+In conjunction with the scope rules for block composites, it effectively
+gives you the ability to write functions.
+.PP
+The syntax is
+.DS
+.CW
+\fBdefine\fP \fIname\fP \fB{\fP \fIreplacement text \fB}\fP
+.R
+.DE
+.LP
+This defines \fIname\fR as a macro to be replaced by the replacement
+text (not including the braces).
+The macro may be called as
+.DS
+.CW
+\fIname\fB(\fIarg1, arg2, \|.\|.\|.\& argn\fB)\fR
+.R
+.DE
+.LP
+The arguments (if any) are substituted for tokens \fB$1\fP, \fB$2\fP
+\&.\|.\|.\& \fB$n\fP
+appearing in the replacement text.
+.PP
+As an example of macro use, consider this:
+.KS
+.DS
+.CW
+.ps -1
+.vs -1
+\&.PS
+# Plot a single jumper in a box, $1 is the on-off state.
+define jumper { [
+ shrinkfactor = 0.8;
+ Outer: box invis wid 0.45 ht 1;
+
+ # Count on end ] to reset these
+ boxwid = Outer.wid * shrinkfactor / 2;
+ boxht = Outer.ht * shrinkfactor / 2;
+
+ box fill (!$1) with .s at center of Outer;
+ box fill ($1) with .n at center of Outer;
+] }
+
+# Plot a block of six jumpers.
+define jumperblock {
+ jumper($1);
+ jumper($2);
+ jumper($3);
+ jumper($4);
+ jumper($5);
+ jumper($6);
+
+ jwidth = last [].Outer.wid;
+ jheight = last [].Outer.ht;
+
+ box with .nw at 6th last [].nw wid 6*jwidth ht jheight;
+
+ # Use {} to avoid changing position from last box draw.
+ # This is necessary so move in any direction works as expected
+ {"Jumpers in state $1$2$3$4$5$6" at last box .s + (0,-0.2);}
+}
+
+# Sample macro invocations.
+jumperblock(1,1,0,0,1,0);
+move;
+jumperblock(1,0,1,0,1,1);
+\&.PE
+.ps
+.vs
+.R
+.DE
+.KE
+.LP
+It yields the following:
+.KS
+.PS
+# Plot a single jumper in a box, $1 is the on-off state.
+define jumper { [
+ shrinkfactor = 0.8;
+ Outer: box invis wid 0.45 ht 1;
+
+ # Count on end ] to reset these
+ boxwid = Outer.wid * shrinkfactor / 2;
+ boxht = Outer.ht * shrinkfactor / 2;
+
+ box fill (!$1) with .s at center of Outer;
+ box fill ($1) with .n at center of Outer;
+] }
+
+# Plot a block of six jumpers
+define jumperblock {
+ jumper($1);
+ jumper($2);
+ jumper($3);
+ jumper($4);
+ jumper($5);
+ jumper($6);
+
+ jwidth = last [].Outer.wid;
+ jheight = last [].Outer.ht;
+
+ box with .nw at 6th last [].nw wid 6*jwidth ht jheight;
+
+ # Use {} to avoid changing position from last box draw.
+ # This is necessary so move in any direction works as expected
+ {"Jumpers in state $1$2$3$4$5$6" at last box .s + (0,-0.2);}
+}
+
+# Sample macro invocations
+jumperblock(1,1,0,0,1,0);
+move 0.25;
+jumperblock(1,0,1,0,1,1);
+.PE
+.CE "1: Sample use of a macro"
+.LP
+This macro example illustrates how you can combine [], brace grouping,
+and variable assignment to write true functions.
+.PP
+One detail the example above does not illustrate is the fact that
+macro argument parsing is not token-oriented.
+If you call \fBjumper(\~1\~)\fP, the value of $1 is \fB"\~1\~"\fP.
+You could even call \fBjumper(big\~string)\fP to give $1 the value
+\fB"big\~string"\fP.
+.PP
+If you want to pass in a coordinate pair, you can avoid getting
+tripped up by the comma by wrapping the pair in parentheses.
+.PP
+Macros persist through pictures.
+To undefine a macro, say \fBundef\fP \fIname\fR; for example,
+.DS
+\f(CWundef jumper\fP
+\f(CWundef jumperblock\fP
+.DE
+.LP
+would undefine the two macros in the jumper block example.
+.
+.
+.NH 1
+Import/Export Commands
+.PP
+Commands that import or export data between \fBpic\fR and its
+environment are described here.
+.
+.NH 2
+File and Table Insertion
+.PP
+The statement
+.DS
+\f(CWcopy\fP \fIfilename\fR
+.DE
+.LP
+inserts the contents of \fIfilename\fR in the \fBpic\fP input stream.
+Any \fB.PS\fP/\fB.PE\fP pair in the file is ignored.
+You can use this to include pre-generated images.
+.PP
+A variant of this statement replicates the \fBcopy thru\fP feature of
+\fIgrap\/\fP(1).
+The call
+.DS
+\f(CWcopy\fP \fIfilename\fR \f(CWthru\fP \fImacro\fP
+.DE
+.LP
+calls \fImacro\fP (which may be either a name or replacement text)
+on the arguments obtained by breaking each line of the file into
+blank-separated fields.
+The macro may have up to 9\~arguments.
+The replacement text may be delimited by braces or by a pair of
+instances of any character not appearing in the rest of the text.
+.PP
+If you write
+.DS
+\f(CWcopy\fP \f(CWthru\fP \fImacro\fP
+.DE
+.LP
+omitting the filename, lines to be parsed are taken from the input
+source up to the next \fB.PE\fP.
+.PP
+In either of the last two \fBcopy\fP commands, GNU \fBgpic\fP permits a
+trailing `\fBuntil\fP \fIword\/\fP' clause to be added which terminates
+the copy when the first word matches the argument (the default
+behavior is therefore equivalent to \fBuntil \&.PE\fP).
+.PP
+Accordingly, the command
+.RS
+.KS
+.IP
+.CW
+.nf
+\&.PS
+copy thru % circle at ($1,$2) % until "END"
+1 2
+3 4
+5 6
+END
+box
+\&.PE
+.R
+.fi
+.KE
+.RE
+.LP
+is equivalent to
+.RS
+.KS
+.IP
+.CW
+.nf
+\&.PS
+circle at (1,2)
+circle at (3,4)
+circle at (5,6)
+box
+\&.PE
+.R
+.fi
+.KE
+.RE
+.
+.NH 2
+Debug Messages
+.PP
+The command \fBprint\fR accepts any number of arguments, concatenates
+their output forms, and writes the result to standard error.
+Each argument must be an expression, a position, or a text string.
+.
+.NH 2
+Escape to Post-Processor
+.PP
+If you write
+.DS
+\fBcommand\fR \fIarg\fR\|.\|.\|.
+.DE
+.LP
+\fBpic\fP concatenates the arguments and pass them through as a line
+to troff or \*[tx].
+Each
+.I arg
+must be an expression, a position, or text.
+This has a similar effect to a line beginning with
+.B .
+or
+\fB\e\fR\|,
+but allows the values of variables to be passed through.
+.LP
+For example,
+.KS
+.DS
+.CW
+.nf
+\&.PS
+x = 14
+command ".ds string x is " x "."
+\&.PE
+\e*[string]
+.DE
+.R
+.KE
+.LP
+prints
+.DS
+.CW
+x is 14.
+.R
+.DE
+.
+.NH 2
+Executing Shell Commands
+.PP
+The command
+.DS
+\f(CWsh\fP \f(CW{\fP \fIanything.\|.\|.\fP \f(CW}\fP
+.DE
+.LP
+macro-expands the text in braces, then executes it as a shell command.
+This could be used to generate images or data tables for later
+inclusion.
+The delimiters shown as {} here may also be two copies of any one
+character not present in the shell command text.
+In either case, the body may contain balanced {} pairs.
+Strings in the body may contain balanced or unbalanced braces in any
+case.
+.
+.
+.NH 1
+Control-flow constructs
+.PP
+The \fBpic\fP language provides conditionals and looping.
+For example,
+.KS
+.DS
+.CW
+pi = atan2(0,-1);
+for i = 0 to 2 * pi by 0.1 do {
+ "-" at (i/2, 0);
+ "." at (i/2, sin(i)/2);
+ ":" at (i/2, cos(i)/2);
+}
+.R
+.DE
+.KE
+.LP
+which yields this:
+.KS
+.PS
+pi = atan2(0,-1);
+for i = 0 to 2 * pi by 0.1 do {
+ "-" at (i/2, 0);
+ "." at (i/2, sin(i)/2);
+ ":" at (i/2, cos(i)/2);
+}
+.PE
+.CE "1: Plotting with a \fBfor\fP loop"
+.LP
+The syntax of the \fBfor\fP statement is:
+.DS
+\fBfor\fR \fIvariable\fR \fB=\fR \fIexpr1\/\fR \fBto\fR \fIexpr2\/\fR \
+[\fBby\fR [\fB*\fR]\fIexpr3\/\fR] \fBdo\fR \fIX\fR \fIbody\fR \fIX\fR
+.DE
+The semantics are as follows: Set
+.I variable
+to \fIexpr1\fR.
+While the value of
+.I variable
+is less than or equal to
+\fIexpr2\fR,
+do
+.I body
+and increment
+.I variable
+by
+\fIexpr3\fR;
+if
+.B by
+is not given, increment
+.I variable
+by\~1.
+If
+.I expr3
+is prefixed by\~\c
+.B *
+then
+.I variable
+is multiplied instead by
+\fIexpr3\fR.
+The value of
+.I expr3
+can be negative for the additive case;
+.I variable
+is then tested whether it is greater than or equal to
+\fIexpr2\fR.
+For the multiplicative case,
+.I expr3
+must be greater than zero.
+If the constraints aren't met, the loop isn't executed.
+.I X
+can be any character not occurring in
+\fIbody\fR; or the two \fIX\/\fPs may be paired braces (as in the
+\fBsh\fR command).
+.PP
+The syntax of the \fBif\fP statement is as follows:
+.DS
+\fBif\fR \fIexpr\fR \fBthen\fR \fIX\fR \fIif-true\fR \fIX\fR \
+[\fBelse\fR \fIY\fR \fIif-false\fR \fIY\/\fR]
+.DE
+Its semantics are as follows: Evaluate
+\fIexpr\fR;
+if it is non-zero then do
+\fIif-true\fR,
+otherwise do
+\fIif-false\fR.
+.I X
+can be any character not occurring in
+\fIif-true\fR.
+.I Y
+can be any character not occurring in
+\fIif-false\fR.
+.PP
+Eithe or both of the
+.I X
+or
+.I Y
+pairs may instead be balanced pairs of
+braces ({ and\~}) as in the \fBsh\fR command.
+In either case, the \fIif-true\fR may contain balanced pairs of braces.
+None of these delimiters are seen inside strings.
+.PP
+All the usual relational operators my be used in conditional expressions;
+\fB!\&\fP (logical negation, not factorial), \fB&&\fP, \fB|\||\fP, \fB==\fP,
+\fB!=\fP, \fB>=\fP, \fB<=\fP, \fB<\fP, \fB>\fP.
+.PP
+String comparison is also supported using \fB==\fP and \fB!=\fP.
+String comparisons may need to be parenthesized to avoid syntactic
+ambiguities.
+.
+.
+.NH 1
+Interface To [gt]roff
+.PP
+The output of \fBpic\fP is \fB[gt]roff\fP drawing commands.
+The GNU \fIgpic\/\fP(1) command warns that it relies on drawing
+extensions present in \fIgroff\/\fP(1) that are not present in
+\fItroff\/\fP(1).
+.
+.NH 2
+Scaling Arguments
+.PP
+The DWB \fIpic\/\fP(1) program accepts one or two arguments to
+\&\fB.PS\fP, which is interpreted as a width and height in inches to
+which the results of \fIpic\/\fP(1) should be scaled (width and height
+scale independently).
+If there is only one argument, it is interpreted as a width to scale the
+picture to, and height is scaled by the same proportion.
+.PP
+GNU \fBgpic\fP is less general; it accepts a single width to scale
+to, or a zero width and a maximum height to scale to.
+With two non-zero arguments, it scales to the maximum height.
+.
+.NH 2
+How Scaling is Handled
+.PP
+When \fBpic\fP processes a picture description on input, it passes
+\fB.PS\fP, \fB.PE\fP, and \fB.PF\fP through to the postprocessor.
+The \fB.PS\fP gets decorated with two numeric arguments which are the X
+and Y\~dimensions of the picture in inches.
+The post-processor can use these to reserve space for the picture and
+center it.
+.PP
+The GNU incarnation of the \fBms\fP macro package, for example, includes
+the following definitions:
+.KS
+.DS
+.ps -1
+.vs -1
+.CW
+\&.de PS
+\&.br
+\&.sp \e\en[DD]u
+\&.ie \e\en[.$]<2 .@error bad arguments to PS (not preprocessed with pic?)
+\&.el \e{\e
+\&. ds@need (u;\e\e$1)+1v
+\&. in +(u;\e\en[.l]-\e\en[.i]-\e\e$2/2>?0)
+\&.\e}
+\&..
+\&.de PE
+\&.par@reset
+\&.sp \e\en[DD]u+.5m
+\&..
+.R
+.DE
+.ps
+.vs
+.KE
+.LP
+Equivalent definitions of these and of \fB.PF\fP are supplied by GNU
+\fIpic\/\fP(1) if you use the \-mpic option; this should make it usable
+with macro pages other than \fIms\/\fR(1).
+.PP
+If \fB.PF\fP is used instead of \fB.PE\fP, the \fBtroff\fP position is
+restored to what it was at the picture start (Kernighan notes that
+the\~F stands for \[lq]flyback\[rq]).
+.PP
+The invocation
+.DS
+\&\fB.PS <\,\fP\fIfile\fP
+.DE
+.LP
+causes the contents of \fIfile\fP to replace the \fB.PS\fP line.
+This feature is deprecated; use `\fBcopy\fP \fIfile\fR' instead.
+.
+.NH 2
+PIC and [gt]roff commands
+.PP
+By default, input lines that begin with a period are passed to the
+postprocessor, embedded at the corresponding point in the output.
+Messing with horizontal or vertical spacing is an obvious recipe for
+bugs, but point size and font changes are usually safe.
+.PP
+Point sizes and font changes are also safe within text strings, as
+long as they are undone before the end of string.
+.PP
+The enablement of output line filling by \fB[gt]roff\fP is preserved
+across pictures.
+.
+.NH 2
+PIC and EQN
+.PP
+The Kernighan paper notes that there is a subtle problem with
+complicated equations inside \fBpic\fR pictures; they come out wrong if
+\fIeqn\/\fP(1) has to leave extra vertical space for the equation.
+If your equation involves more than subscripts and superscripts, you
+must add to the beginning of each equation the extra information
+\fBspace\~0\fP.
+He gives the following example:
+.KS
+.DS
+.CW
+arrow
+box "$space 0 {H( omega )} over {1 - H( omega )}$"
+arrow
+.R
+.DE
+.KE
+.EQ
+delim @@
+.EN
+.KS
+.PS
+arrow
+box "@space 0 {H( omega )} over {1 - H( omega )}@"
+arrow
+.PE
+.CE "1: Equations within pictures"
+.
+.NH 2
+Absolute Positioning of Pictures
+.PP
+A \fBpic\fP picture is positioned vertically by troff at the current
+position.
+The topmost position possible on a page is not the paper edge
+but a position which is one baseline lower so that the first row of glyphs
+is visible.
+To make a picture really start at the paper edge you have to make the
+baseline-to-baseline distance zero, this is, you must set the vertical
+spacing to\~0 (using \fB.vs\fP) before starting the picture.
+.
+.
+.NH 1
+Interface to TeX
+.PP
+.PP
+\*[tx] mode is enabled by the
+.B \-t
+option.
+In \*[tx] mode, pic defines a vbox called
+.B \egraph
+for each picture; the name can be changed with the pseudo-variable
+.B figname
+(which is actually a specially parsed command).
+You must yourself print that vbox using, for example, the command
+.RS
+.LP
+.CW
+\ecenterline{\ebox\egraph}
+.RE
+.LP
+Actually, since the vbox has a height of zero (it is defined with \evtop)
+this produces slightly more vertical space above the picture than
+below it;
+.RS
+.LP
+.CW
+\ecenterline{\eraise 1em\ebox\egraph}
+.RE
+.LP
+would avoid this.
+.PP
+To make the vbox having a positive height and a depth of zero (as used
+e.g.\& by \*(lx's \f(CW\%graphics.sty\fP), define the following macro in
+your document:
+.KS
+.DS
+.CW
+\edef\egpicbox#1{%
+ \evbox{\eunvbox\ecsname #1\eendcsname\ekern 0pt}}
+.R
+.DE
+.KE
+.LP
+Now you can simply say
+.B \egpicbox{graph}
+instead of \ebox\egraph.
+.PP
+You must use a \*[tx] driver that supports the
+.B tpic
+specials, version\~2.
+.PP
+Lines beginning with
+.B \e
+are passed through transparently; a
+.B %
+is added to the end of the line to avoid unwanted spaces.
+You can safely use this feature to change fonts or to
+change the value of \fB\ebaselineskip\fP.
+Anything else may well produce undesirable results; use at your own risk.
+Lines beginning with a period are not given any special treatment.
+.PP
+The \*[tx] mode of \fIpic\/\fP(1) does \fInot\fP translate \fBtroff\fP
+font and size changes included in text strings!
+.PP
+Here an example how to use \fBfigname\fP.
+.KS
+.DS
+.CW
+\&.PS
+figname = foo;
+\&...
+\&.PE
+
+\&.PS
+figname = bar;
+\&...
+\&.PE
+
+\ecenterline{\ebox\efoo \ehss \ebox\ebar}
+.DE
+.R
+.KE
+.LP
+Use this feature sparsingly and only if really needed:
+A different name means a new box register in \*[tx], and the maximum number
+of box registers is only 256.
+Also be careful not to use a predefined \*[tx] or \*[lx] macro name as
+an argument to \fBfigname\fP since this inevitably causes an error.
+.
+.
+.NH 1
+Obsolete Commands
+.PP
+GNU \fIgpic\/\fP(1) has a command
+.DS
+\fBplot\fR \fIexpr\fR [\fB"\fItext\fB"\fR]
+.DE
+This is a text object which is constructed by using
+.I text
+as a format string for sprintf
+with an argument of
+\fIexpr\fP.
+If
+.I text
+is omitted a format string of \fB"%g"\fP is used.
+Attributes can be specified in the same way as for a normal text
+object.
+Be very careful that you specify an appropriate format string;
+\fBpic\fP does only very limited checking of the string.
+This is deprecated in favour of
+\fBsprintf\fP.
+.
+.
+.NH 1
+Some Larger Examples
+.PP
+Here are a few larger examples, with complete source code.
+One of our earlier examples is generated in an instructive way using a
+for loop:
+.KS
+.DS
+.ps -1
+.vs -1
+.CW
+\&.PS
+# Draw a demonstration up left arrow with grid box overlay
+define gridarrow
+{
+ move right 0.1
+ [
+ {arrow up left $1;}
+ box wid 0.5 ht 0.5 dotted with .nw at last arrow .end;
+ for i = 2 to ($1 / 0.5) do
+ {
+ box wid 0.5 ht 0.5 dotted with .sw at last box .se;
+ }
+ move down from last arrow .center;
+ [
+ sprintf("\efBarrow up left %g\efP", $1)
+ ]
+ ]
+ move right 0.1 from last [] .e;
+}
+gridarrow(0.5);
+gridarrow(1);
+gridarrow(1.5);
+gridarrow(2);
+undef gridarrow
+\&.PE
+.R
+.DE
+.ps
+.vs
+.KE
+.KS
+.PS
+# Draw a demonstration up left arrow with grid box overlay
+define gridarrow
+{
+ move right 0.5
+ [
+ {arrow up left $1;}
+ box wid 0.5 ht 0.5 dotted with .nw at last arrow .end;
+ for i = 2 to ($1 / 0.5) do {
+ box wid 0.5 ht 0.5 dotted with .sw at last box .se;
+ }
+ move down from last arrow .center;
+ [
+ sprintf("\fBarrow up left %g\fP", $1)
+ ]
+ ]
+ move right 0.1 from last [] .e;
+}
+gridarrow(0.5);
+gridarrow(1);
+gridarrow(1.5);
+gridarrow(2);
+undef gridarrow
+.PE
+.CE "1: Diagonal arrows (dotted boxes show the implied 0.5-inch grid)"
+.PP
+Here's an example concocted to demonstrate layout of a large,
+multiple-part pattern:
+.KS
+.DS
+.ps -1
+.vs -1
+.CW
+\&.PS
+define filter {box ht 0.25 rad 0.125}
+lineht = 0.25;
+Top: [
+ right;
+ box "\efBms\efR" "sources";
+ move;
+ box "\efBHTML\efR" "sources";
+ move;
+ box "\efBlinuxdoc-sgml\efP" "sources" wid 1.5;
+ move;
+ box "\efBTexinfo\efP" "sources";
+
+ line down from 1st box .s lineht;
+ A: line down;
+ line down from 2nd box .s; filter "\efBhtml2ms\efP";
+ B: line down;
+ line down from 3rd box .s; filter "\efBformat\efP";
+ C: line down;
+ line down from 4th box .s; filter "\efBtexi2roff\efP";
+ D: line down;
+]
+move down 1 from last [] .s;
+Anchor: box wid 1 ht 0.75 "\efBms\efR" "intermediate" "form";
+arrow from Top.A.end to Anchor.nw;
+arrow from Top.B.end to 1/3 of the way between Anchor.nw and Anchor.ne;
+arrow from Top.C.end to 2/3 of the way between Anchor.nw and Anchor.ne;
+arrow from Top.D.end to Anchor.ne
+{
+ # PostScript column
+ move to Anchor .sw;
+ line down left then down ->;
+ filter "\efBpic\efP";
+ arrow;
+ filter "\efBeqn\efP";
+ arrow;
+ filter "\efBtbl\efP";
+ arrow;
+ filter "\efBgroff\efP";
+ arrow;
+ box "PostScript";
+
+ # HTML column
+ move to Anchor .se;
+ line down right then down ->;
+ A: filter dotted "\efBpic2img\efP";
+ arrow;
+ B: filter dotted "\efBeqn2html\efP";
+ arrow;
+ C: filter dotted "\efBtbl2html\efP";
+ arrow;
+ filter "\efBms2html\efP";
+ arrow;
+ box "HTML";
+
+ # Nonexistence caption
+ box dashed wid 1 at B + (2,0) "These tools" "don't yet exist";
+ line chop 0 chop 0.1 dashed from last box .nw to A.e ->;
+ line chop 0 chop 0.1 dashed from last box .w to B.e ->;
+ line chop 0 chop 0.1 dashed from last box .sw to C.e ->;
+}
+\&.PE
+.R
+.DE
+.ps
+.vs
+.KE
+.KS
+.PS
+define filter {box ht 0.25 rad 0.125}
+lineht = 0.25;
+Top: [
+ right;
+ box "\fBms\fR" "sources";
+ move;
+ box "\fBHTML\fR" "sources";
+ move;
+ box "\fBlinuxdoc-sgml\fP" "sources" wid 1.5;
+ move;
+ box "\fBTexinfo\fP" "sources";
+
+ line down from 1st box .s lineht;
+ A: line down;
+ line down from 2nd box .s; filter "\fBhtml2ms\fP";
+ B: line down;
+ line down from 3rd box .s; filter "\fBformat\fP";
+ C: line down;
+ line down from 4th box .s; filter "\fBtexi2roff\fP";
+ D: line down;
+]
+move down 1 from last [] .s;
+Anchor: box wid 1 ht 0.75 "\fBms\fR" "intermediate" "form";
+arrow from Top.A.end to Anchor.nw;
+arrow from Top.B.end to 1/3 of the way between Anchor.nw and Anchor.ne;
+arrow from Top.C.end to 2/3 of the way between Anchor.nw and Anchor.ne;
+arrow from Top.D.end to Anchor.ne
+{
+ # PostScript column
+ move to Anchor .sw;
+ line down left then down ->;
+ filter "\fBpic\fP";
+ arrow;
+ filter "\fBeqn\fP";
+ arrow;
+ filter "\fBtbl\fP";
+ arrow;
+ filter "\fBgroff\fP";
+ arrow;
+ box "PostScript";
+
+ # HTML column
+ move to Anchor .se;
+ line down right then down ->;
+ A: filter dotted "\fBpic2img\fP";
+ arrow;
+ B: filter dotted "\fBeqn2html\fP";
+ arrow;
+ C: filter dotted "\fBtbl2html\fP";
+ arrow;
+ filter "\fBms2html\fP";
+ arrow;
+ box "HTML";
+
+ # Nonexistence caption
+ box dashed wid 1 at B + (2,0) "These tools" "don't yet exist";
+ line chop 0 chop 0.1 dashed from last box .nw to A.e ->;
+ line chop 0 chop 0.1 dashed from last box .w to B.e ->;
+ line chop 0 chop 0.1 dashed from last box .sw to C.e ->;
+}
+.PE
+.CE "2: Hypothetical production flow for dual-mode publishing"
+.PP
+.KS
+.PS
+# a three-dimensional block
+#
+# tblock(<width>, <height>, <text>)
+
+define tblock { [
+ box ht $2 wid $1 \
+ color "gold" outlined "black" \
+ xslanted 0 yslanted 0 \
+ $3;
+ box ht .1 wid $1 \
+ color "yellow" outlined "black" \
+ xslanted .1 yslanted 0 \
+ with .sw at last box .nw;
+ box ht $2 wid .1 \
+ color "goldenrod" outlined "black" \
+ xslanted 0 yslanted .1 \
+ with .nw at 2nd last box .ne;
+] }
+
+tblock(1, .5, "Master" "1");
+move -.1
+tblock(.5, 1, "Slave");
+.PE
+.CE "3: Three-dimensional Boxes"
+.PP
+Here the source code for figure \n[H1]-3:
+.KS
+.DS
+.CW
+\&.PS
+# a three-dimensional block
+#
+# tblock(<width>, <height>, <text>)
+
+define tblock { [
+ box ht $2 wid $1 \e
+ color "gold" outlined "black" \e
+ xslanted 0 yslanted 0 \e
+ $3;
+ box ht .1 wid $1 \e
+ color "yellow" outlined "black" \e
+ xslanted .1 yslanted 0 \e
+ with .sw at last box .nw;
+ box ht $2 wid .1 \e
+ color "goldenrod" outlined "black" \e
+ xslanted 0 yslanted .1 \e
+ with .nw at 2nd last box .ne;
+] }
+
+tblock(1, .5, "Master" "1");
+move -.1
+tblock(.5, 1, "Slave");
+\&.PE
+.DE
+.ft R
+.KE
+.
+.
+.
+.NH 1
+PIC Reference
+.PP
+This is an annotated grammar of \fBpic\fP.
+.
+.NH 2
+Lexical Items
+.PP
+In general, \fBpic\fP is a free-format, token-oriented language that
+ignores whitespace outside strings.
+But certain lines and constructs are specially interpreted at the
+lexical level:
+.PP
+A comment begins with \fB#\fP and continues to \fB\en\fP (comments may
+also follow text in a line).
+A line beginning with a period or backslash may be interpreted as text
+to be passed through to the post-processor, depending on command-line
+options.
+An end-of-line backslash is interpreted as a request to continue the
+line; the backslash and following newline are ignored.
+.PP
+.RS
+Here are the grammar terminals:
+.IP \s[-1]INT\s[0]
+A positive integer.
+.IP \s[-1]NUMBER\s[0]
+A floating point numeric constant.
+May contain a decimal point or be expressed in scientific notation in
+the style of \fIprintf\/\fP(3)'s %e escape.
+A trailing `i' or `I' (indicating the unit `inch') is ignored.
+.IP \s[-1]TEXT\s[0]
+A string enclosed in double quotes.
+A double quote within \s[-1]TEXT\s[0] must be preceded by a backslash.
+Instead of \s[-1]TEXT\s[0] you can use
+.DS
+.CW
+sprintf ( TEXT [, <expr> ...] )
+.R
+.DE
+.IP
+except after the `until' and `last' keywords, and after all ordinal
+keywords (`th' and friends).
+.IP \s[-1]VARIABLE\s[0]
+A string starting with a character from the set [a-z], optionally
+followed by one or more characters of the set [a-zA-Z0-9_].
+(Values of variables are preserved across pictures.)
+.IP \s[-1]LABEL\s[0]
+A string starting with a character from the set [A-Z], optionally
+followed by one or more characters of the set [a-zA-Z0-9_].
+.IP \s[-1]COMMAND-LINE\s[0]
+A line starting with a command character (`.' in groff mode, `\e' in
+\*[tx] mode).
+.IP \s[-1]BALANCED-TEXT\s[0]
+A string either enclosed by `{' and `}' or with \fIX\fP and \fIX\fP,
+where \fIX\fP doesn't occur in the string.
+.IP \s[-1]BALANCED-BODY\s[0]
+Delimiters as in \s[-1]BALANCED-TEXT\s[0]; the body is interpreted as
+`\fB\[la]command\[ra].\|.\|.\fP'.
+.IP \s[-1]FILENAME\s[0]
+The name of a file.
+This has the same semantics as \s[-1]TEXT\s[0].
+.IP \s[-1]MACRONAME\s[0]
+Either \s[-1]VARIABLE\s[0] or \s[-1]LABEL\s[0].
+.RE
+.
+.NH 2
+Semi-Formal Grammar
+.PP
+Tokens not enclosed in \[la]\|\[ra] are literals, except:
+.IP 1.
+\fB\en\fP is a newline.
+.IP 2.
+Three dots is a suffix meaning `replace with 0 or more repetitions
+of the preceding element(s).
+.IP 3.
+An enclosure in square brackets has its usual meaning of `this clause is
+optional'.
+.IP 4.
+Square-bracket-enclosed portions within tokens are optional.
+Thus, `h\^[eigh]\^t' matches either `height' or `ht'.
+.LP
+If one of these special tokens has to be referred to literally, it is
+surrounded with single quotes.
+.PP
+The top-level \fBpic\fP object is a picture.
+.DS
+.CW
+<picture> ::=
+ .PS [NUMBER [NUMBER]]\en
+ <statement> ...
+ .PE \en
+.R
+.DE
+.PP
+The arguments, if present, represent the width and height of the picture,
+causing \fBpic\fR to attempt to scale it to the given dimensions in
+inches.
+In no case, however, the X and Y\~dimensions of the picture exceed the
+values of the style variables \fBmaxpswid\fP and \fBmaxpsheight\fP
+(which default to the normal 8.5\^i by 11\^i page size).
+.PP
+If the ending `.PE' is replaced by `.PF', the page vertical position is
+restored to its value at the time `.PS' was encountered.
+Another alternate form of invocation is `.PS\~<\s[-1]FILENAME\s[0]',
+which replaces the `.PS' line with a file to be interpreted by \fBpic\fR
+(but this feature is deprecated).
+.PP
+The `.PS', `.PE', and `.PF' macros to perform centering and scaling are
+normally supplied by the post-processor.
+.PP
+In the following, either `|' or a new line starts an alternative.
+.DS
+.CW
+<statement> ::=
+ <command> ;
+ <command> \en
+.R
+.DE
+.DS
+.CW
+<command> ::=
+ <primitive> [<attribute>]
+ LABEL : [;] <command>
+ LABEL : [;] <command> [<position>]
+ { <command> ... }
+ VARIABLE [:] = <any-expr>
+ figname = MACRONAME
+ up | down | left | right
+ COMMAND-LINE
+ command <print-arg> ...
+ print <print-arg> ...
+ sh BALANCED-TEXT
+ copy FILENAME
+ copy [FILENAME] thru MACRONAME [until TEXT]
+ copy [FILENAME] thru BALANCED-BODY [until TEXT]
+ for VARIABLE = <expr> to <expr> [by [*] <expr>] do BALANCED-BODY
+ if <any-expr> then BALANCED-BODY [else BALANCED-BODY]
+ reset [VARIABLE [[,] VARIABLE ...]]
+.R
+.DE
+.DS
+.CW
+<print-arg> ::=
+ TEXT
+ <expr>
+ <position>
+.R
+.DE
+.PP
+The current position and direction are saved on entry to a
+ `{\~.\|.\|.\~}' construction and restored on exit from it.
+.PP
+Note that in `if' constructions, newlines can only occur in
+\s[-1]BALANCED-BODY\s[0].
+This means that
+.DS
+.CW
+if
+{ ... }
+else
+{ ... }
+.R
+.DE
+.PP
+fails.
+You have to use the braces on the same line as the keywords:
+.DS
+.CW
+if {
+\&...
+} else {
+\&...
+}
+.R
+.DE
+.PP
+This restriction doesn't hold for the body after the `do' in a `for'
+construction.
+.PP
+At the beginning of each picture, `figname' is reset to the vbox name
+`graph'; this command has only a meaning in \*[tx] mode.
+While the grammar rules allow digits and the underscore in the value of
+`figname', \*[tx] normally accepts uppercase and lowercase letters only
+as box names (you have to use `\ecsname' if you really need to
+circumvent this limitation).
+.DS
+.CW
+<any-expr> ::=
+ <expr>
+ <text-expr>
+ <any-expr> <logical-op> <any-expr>
+ ! <any-expr>
+.R
+.DE
+.DS
+.CW
+<logical-op> ::=
+ == | != | && | '||'
+.R
+.DE
+.DS
+.CW
+<text-expr> ::=
+ TEXT == TEXT
+ TEXT != TEXT
+.R
+.DE
+.PP
+Logical operators are handled specially by \fBpic\fP since they can
+deal with text strings also.
+\fBpic\fP uses \%\fIstrcmp\/\fP(3) to test for equality of strings; an
+empty string is considered as `false' for `&&' and `|\||'.
+.DS
+.CW
+<primitive> ::=
+ box \fR# closed object \[em] rectangle\fP
+ circle \fR# closed object \[em] circle\fP
+ ellipse \fR# closed object \[em] ellipse\fP
+ arc \fR# open object \[em] quarter-circle\fP
+ line \fR# open object \[em] line\fP
+ arrow \fR# open object \[em] line with arrowhead\fP
+ spline \fR# open object \[em] spline curve\fP
+ move
+ TEXT TEXT ... \fR# text within invisible box\fP
+ plot <expr> TEXT \fR# formatted text\fP
+ '[' <command> ... ']'
+.R
+.DE
+.PP
+Drawn objects within `[\~.\|.\|.\~]' are treated as a single composite
+object with a rectangular shape (that of the bounding box of all the
+elements).
+Variable and label assignments within a block are local to the block.
+Current direction of motion is restored to the value at start of block
+upon exit.
+Position is \fInot\fR restored (unlike `{\~}');
+instead, the current position becomes the exit position for the current
+direction on the block's bounding box.
+.DS
+.CW
+<attribute> ::=
+ h[eigh]t <expr> \fR# set height of closed figure\fP
+ wid[th] <expr> \fR# set width of closed figure\fP
+ rad[ius] <expr> \fR# set radius of circle/arc\fP
+ diam[eter] <expr> \fR# set diameter of circle/arc\fP
+ up [<expr>] \fR# move up\fP
+ down [<expr>] \fR# move down\fP
+ left [<expr>] \fR# move left\fP
+ right [<expr>] \fR# move right\fP
+ from <position> \fR# set from position of open figure\fP
+ to <position> \fR# set to position of open figure\fP
+ at <position> \fR# set center of open figure\fP
+ with <path> \fR# fix corner/named point at specified location\fP
+ with <position> \fR# fix position of object at specified location\fP
+ by <expr-pair> \fR# set object's attachment point\fP
+ then \fR# sequential segment composition\fP
+ dotted [<expr>] \fR# set dotted line style\fP
+ dashed [<expr>] \fR# set dashed line style\fP
+ thick[ness] <expr> \fR# set thickness of lines\fP
+ chop [<expr>] \fR# chop end(s) of segment\fP
+ '->' | '<-' | '<->' \fR# decorate with arrows\fP
+ invis[ible] \fR# make primitive invisible\fP
+ solid \fR# set solid line style\fP
+ fill[ed] [<expr>] \fR# fill closed figure with optional density\fP
+ xscaled <expr> \fR# slant box into x direction\fP
+ yscaled <expr> \fR# slant box into y direction\fP
+ colo[u]r[ed] TEXT \fR# set fill and outline color for figure\fP
+ outline[d] TEXT \fR# set outline color for figure\fP
+ shaded TEXT \fR# set fill color for figure\fP
+ same \fR# copy size of previous object\fP
+ cw | ccw \fR# set orientation of curves\fP
+ ljust | rjust \fR# adjust text horizontally\fP
+ above | below \fR# adjust text vertically\fP
+ aligned \fR# align parallel to object\fP
+ TEXT TEXT ... \fR# text within object\fP
+ <expr> \fR# motion in the current direction\fR
+.R
+.DE
+.PP
+Missing attributes are supplied from defaults; inappropriate ones are
+silently ignored.
+For lines, splines, and arcs, height and width refer to arrowhead size.
+.PP
+The `at' primitive sets the center of the current object.
+The `with' attribute fixes the specified feature of the given object to
+a specified location.
+(Note that `with' is incorrectly described in the Kernighan paper.)
+.PP
+The `by' primitive is not documented in the tutorial portion of
+the Kernighan paper, and should probably be considered unreliable.
+.PP
+The primitive `arrow' is a synonym for `line\~->'.
+.PP
+Text is normally an attribute of some object, in which case successive
+strings are vertically stacked and centered on the object's center by
+default.
+Standalone text is treated as though placed in an invisible box.
+.PP
+A text item consists of a string or sprintf-expression, optionally
+followed by positioning information.
+Text (or strings specified with `sprintf') may contain font changes,
+size changes, and local motions, provided those changes are undone
+before the end of the current item.
+Text may also contain \e-escapes denoting special characters.
+The base font and specific set of escapes supported is implementation
+dependent, but supported escapes always include the following:
+.IP "\efR, \ef1" \w'\efR,\~\ef3'u+2n
+Set Roman style (the default)
+.IP "\efI, \ef2"
+Set Italic style
+.IP "\efB, \ef3"
+Set Bold style
+.IP \efP
+Revert to previous style; only works one level deep, does not stack.
+.PP
+Color names are dependent on the \gBpic\fR implementation, but in
+all modern versions color names recognized by the X\~window system are
+supported.
+.PP
+A position is an (x,y) coordinate pair.
+There are lots of different ways to specify positions:
+.DS
+.CW
+<position> ::=
+ <position-not-place>
+ <place>
+ ( <position> )
+.R
+.DE
+.DS
+.CW
+<position-not-place> ::=
+ <expr-pair>
+ <position> + <expr-pair>
+ <position> - <expr-pair>
+ ( <position> , <position> )
+ <expr> [of the way] between <position> and <position>
+ <expr> '<' <position> , <position> '>'
+.R
+.DE
+.DS
+.CW
+<expr-pair> ::=
+ <expr> , <expr>
+ ( expr-pair )
+.R
+.DE
+.DS
+.CW
+<place> ::=
+ <label>
+ <label> <corner>
+ <corner> [of] <label>
+ Here
+.R
+.DE
+.DS
+.CW
+<label> ::=
+ LABEL [. LABEL ...]
+ <nth-primitive>
+.R
+.DE
+.DS
+.CW
+<corner> ::=
+ .n | .e | .w | .s
+ .ne | .se | .nw | .sw
+ .c[enter] | .start | .end
+ .t[op] | .b[ot[tom]] | .l[eft] | .r[ight]
+ left | right | <top-of> | <bottom-of>
+ <north-of> | <south-of> | <east-of> | <west-of>
+ <center-of> | <start-of> | <end-of>
+ upper left | lower left | upper right | lower right
+.R
+.DE
+.DS
+.CW
+<\,\f(CIxxx\/\fP-of> ::=
+ \f(CIxxx\fP \fR# followed by `of'\fP
+.R
+.DE
+.DS
+.CW
+<nth-primitive> ::=
+ <ordinal> <object-type>
+ [<ordinal>] last <object-type>
+.R
+.DE
+.DS
+.CW
+<ordinal> ::=
+ INT th
+ INT st | INT nd | INT rd
+ ` <any-expr> 'th
+.R
+.DE
+.DS
+.CW
+<object-type> ::=
+ box
+ circle
+ ellipse
+ arc
+ line
+ arrow
+ spline
+ '[]'
+ TEXT
+.R
+.DE
+.PP
+As Kernighan notes, \[lq]since barbarisms like \fB1th\fP and \fB3th\fP are
+barbaric, synonyms like \fB1st\fP and \fB3rd\fP are accepted as well.\[rq]
+Objects of a given type are numbered from 1 upwards in order of
+declaration; the \fBlast\fP modifier counts backwards.
+.PP
+The \[lq]'th\[rq] form (which allows you to select a previous object with
+an expression, as opposed to a numeric literal) is not documented in DWB's
+\fIpic\/\fR(1).
+.PP
+The \[la]\,\fIxxx\/\fP-of\|\[ra] rule is special: The lexical parser checks whether
+\fIxxx\fP is followed by the token `of' without eliminating it so that
+the grammar parser can still see `of'.
+Valid examples of specifying a place with corner and label are thus
+.DS
+.CW
+A .n
+\&.n of A
+\&.n A
+north of A
+.R
+.DE
+.LP
+while
+.DS
+.CW
+north A
+A north
+.R
+.DE
+both cause a syntax error.
+(DWB \fBpic\fP also allows the weird form `A\~north\~of'.)
+.PP
+Here the special rules for the `with' keyword using a path:
+.DS
+.CW
+<path> ::=
+ <relative-path>
+ ( <relative-path> , <relative-path> )
+.R
+.DE
+.DS
+.CW
+<relative-path> ::=
+ <corner>
+ . LABEL [. LABEL ...] [<corner>]
+.R
+.DE
+.PP
+The following style variables control output:
+.TS H
+center tab(@), linesize(2);
+lb | lb | lb
+l | n | l.
+.sp 2p
+Style Variable@Default@What It Does
+.sp 2p
+_
+.sp 2p
+.TH
+boxht@0.5@Default height of a box
+boxwid@0.75@Default width of a box
+lineht@0.5@Default length of vertical line
+linewid@0.75@Default length of horizontal line
+arcrad @0.25@Default radius of an arc
+circlerad@0.25@Default radius of a circle
+ellipseht@0.5@Default height of an ellipse
+ellipsewid@0.75@Default width of an ellipse
+moveht@0.5@Default length of vertical move
+movewid@0.75@Default length of horizontal move
+textht@0@Default height of box enclosing a text object
+textwid@0@Default width of box enclosing a text object
+arrowht@0.1@Length of arrowhead along shaft
+arrowwid@0.05@Width of rear of arrowhead
+arrowhead@1@Enable/disable arrowhead filling
+dashwid@0.05@Interval for dashed lines
+maxpswid@8.5@Maximum width of picture
+maxpsht@11@Maximum height of picture
+scale@1@Unit scale factor
+fillval@0.5@Default fill value
+.sp 5p
+_
+.TE
+Any of these can be set by assignment, or reset using the \fBreset\fP
+statement.
+Style variables assigned within `[\~]' blocks are restored to their
+beginning-of-block value on exit; top-level assignments persist across
+pictures.
+Dimensions are divided by \fBscale\fR on output.
+.PP
+All \fBpic\fP expressions are evaluated in floating point; units
+are always inches (a trailing `i' or `I' is ignored).
+Expressions have the following simple grammar, with semantics very
+similar to C\~expressions:
+.DS
+.CW
+<expr> ::=
+ VARIABLE
+ NUMBER
+ <place> <place-attribute>
+ <expr> <op> <expr>
+ - <expr>
+ ( <any-expr> )
+ ! <expr>
+ <func1> ( <any-expr> )
+ <func2> ( <any-expr> , <any-expr> )
+ rand ( )
+.R
+.DE
+.DS
+.CW
+<place-attribute>
+ .x | .y | .h[eigh]t | .wid[th] | .rad
+.R
+.DE
+.DS
+.CW
+<op> ::=
+ + | - | * | / | % | ^ | '<' | '>' | '<=' | '>='
+.R
+.DE
+.DS
+.CW
+<func1> ::=
+ sin | cos | log | exp | sqrt | int | rand | srand
+.R
+.DE
+.DS
+.CW
+<func2> ::=
+ atan2 | max | min
+.R
+.DE
+.LP
+Both \fBexp\fP and \fBlog\fP are base 10; \fBint\fP does integer
+truncation; and \fBrand()\fP returns a random number in [0-1).
+.PP
+There are \fBdefine\fP and \fBundef\fR statements which are not part
+of the grammar (they behave as pre-processor macros to the language).
+These may be used to define pseudo-functions.
+.DS
+.CW
+\fBdefine\fP \fIname\fP \fB{\fP \fIreplacement-text\fP \fB}\fP
+.R
+.DE
+.LP
+This defines \fIname\fR as a macro to be replaced by the replacement
+text (not including the braces).
+The macro may be called as
+.DS
+.CW
+\fIname\/\fB(\,\fIarg1, arg2, .\|.\|., argn\fB\/)\fR
+.R
+.DE
+.LP
+The arguments (if any) are substituted for tokens $1, $2 \&.\|.\|.\& $n
+appearing in the replacement text.
+To undefine a macro, say \fBundef\fP \fIname\fR, specifying the name to
+be undefined.
+.\"%%POSTLUDE%%
+.
+.
+.NH 1
+History and Acknowledgements
+.PP
+Original \fBpic\fP was written to go with Joseph Ossanna's original
+\fItroff\/\fP(1) by Brian Kernighan, and later re-written by Kernighan
+with substantial enhancements (apparently as part of the evolution of
+\fItroff\/\fP(1) into \fIditroff\/\fP(1) to generate
+device-independent output).
+.PP
+The language had been inspired by some earlier graphics languages
+including \fBideal\fP and \fBgrap\fP.
+Kernighan credits Chris van Wyk (the designer of \fBideal\fP) with many
+of the ideas that went into
+\fBpic\fP.
+.PP
+.\" the original definitions of EQ and EN cause insertion of vertical
+.\" space which is not appropriate here
+.de EQ
+..
+.de EN
+..
+.EQ
+delim $$
+.EN
+The \fBpic\fP language was originally described by Brian Kernighan in
+Bell Labs Computing Science Technical Report #116 (you can obtain a
+PostScript copy of the revised version, [1], by sending a mail message to
+\fInetlib@research.att.com\fP with a body of `send 116 from
+research/cstr').
+There have been two revisions, in 1984 and 1991.
+.PP
+The document you are reading effectively subsumes Kernighan's
+description; it was written to fill in lacun\[ae] in the exposition and
+integrate in descriptions of the GNU \fIgpic\/\fP(1) and
+\fIpic2plot\/\fP(1) features.
+.PP
+The GNU \fBgpic\fR implementation was written by James Clark
+\[la]\,\fIjjc@jclark.com\/\fP\[ra].
+.PP
+The GNU \fBpic2plot\fR implementation is based on James Clark's parser
+code and maintained by Robert Maier, principal author of \fBplotutils\fP.
+.
+.
+.NH 1
+Bibliography
+.IP 1.
+Kernighan, B. W.
+\fBPIC \[em] A Graphics Language for Typesetting
+(Revised User Manual)\fP.
+Bell Labs Computing Science Technical Report #116, December 1991.
+.IP 2.
+Van Wyk, C. J.
+\fBA high-level language for specifying pictures\fP.
+\fIACM Transactions On Graphics\fP 1,2 (1982) 163-182.
+.
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
+.\" vim: filetype=groff: