aspic-1.05/0000755000222100022210000000000011534125704010626 5ustar ph10ph10aspic-1.05/doc/0000755000222100022210000000000011534125704011373 5ustar ph10ph10aspic-1.05/doc/pic46.aspic0000644000222100022210000000012011534125704013332 0ustar ph10ph10circlefill 0.5; circle; circlefill 0.8 0.2 0.1; circle; circlefill -1; circle; aspic-1.05/doc/pic02.aspic0000644000222100022210000000006311534125704013330 0ustar ph10ph10line "first" "second"; line down "third" "fourth"; aspic-1.05/doc/pic09.aspic0000644000222100022210000000004511534125704013337 0ustar ph10ph10box "A"; box depth 50 join left "B"; aspic-1.05/doc/pic15.aspic0000644000222100022210000000011511534125704013332 0ustar ph10ph10arc "A"; arc angle 180 radius 20 "B"; arc clockwise angle 270 radius 40 "C"; aspic-1.05/doc/pic21.aspic0000644000222100022210000000010311534125704013324 0ustar ph10ph10AA: box; arcarrow from 0.1 right of AA to 0.2 top of AA angle 270; aspic-1.05/doc/Build0000755000222100022210000000023711534125704012362 0ustar ph10ph10#! /bin/sh for pic in `ls pic*.aspic` ; do base=`expr match $pic '\([^.]\+\)'` aspic $pic $base.eps done xfpt aspic.xfpt sdop aspic.xml ps2pdf aspic.ps aspic-1.05/doc/pic28.aspic0000644000222100022210000000016711534125704013345 0ustar ph10ph10iline right shapefilled 0.5; iline down shapefilled 0.5; iline down left shapefilled 0.5; iline right shapefilled 0.5; aspic-1.05/doc/pic34.aspic0000644000222100022210000000037411534125704013342 0ustar ph10ph10A: arc "A"; B: arc clockwise radius 20 angle 180 "B"; C: arc dashed from start of A to end of B angle 190 "C"; arc clockwise dashed from start of A to end of A radius 75 "D"; arc to start depth 30 "E"; arc clockwise to middle of C via middle of A "F"; aspic-1.05/doc/pic40.aspic0000644000222100022210000000007611534125704013336 0ustar ph10ph10box greyness 0.5 filled 0.8; iline right 10; ibox filled 0.8; aspic-1.05/doc/pic47.aspic0000644000222100022210000000006311534125704013341 0ustar ph10ph10box "one" "two"; textdepth 24; box "three" "four"; aspic-1.05/doc/pic03.aspic0000644000222100022210000000007111534125704013330 0ustar ph10ph10box width 100 depth 20; line right 40; circle radius 10; aspic-1.05/doc/pic16.aspic0000644000222100022210000000004211534125704013332 0ustar ph10ph10line; arcarrow from end to start; aspic-1.05/doc/pic22.aspic0000644000222100022210000000005011534125704013326 0ustar ph10ph10line; arrow up from middle plus (20,5); aspic-1.05/doc/pic29.aspic0000644000222100022210000000014011534125704013335 0ustar ph10ph10A: circle filled 0.5; line right from centre of A level 1; line left from centre of A level -1; aspic-1.05/doc/pic35.aspic0000644000222100022210000000001211534125704013330 0ustar ph10ph10arcarrow; aspic-1.05/doc/pic41.aspic0000644000222100022210000000015111534125704013331 0ustar ph10ph10push; shapefill 0.9 0.5 0.1; arc; arc; line left; line down 10; line right; line right; line up 10; pop; aspic-1.05/doc/pic48.aspic0000644000222100022210000000020711534125704013342 0ustar ph10ph10 hlinelength 36; box "input" "file"; arrow; A: box "SGCAL"; arrow; box "GCODE" "file"; arrow both down from A; box "ASPIC"; aspic-1.05/doc/pic04.aspic0000644000222100022210000000011211534125704013325 0ustar ph10ph10down; box "A"; line; circle "B"; line right 40; line left 20 up 20; line; aspic-1.05/doc/pic10.aspic0000644000222100022210000000021711534125704013330 0ustar ph10ph10BOXA: box "A"; BOXB: box "B"; circle radius 10 join centre to centre of BOXA; box width 20 depth 20 join centre to centre of BOXB; aspic-1.05/doc/pic17.aspic0000644000222100022210000000010411534125704013332 0ustar ph10ph10BOXA: box "A"; line; ellipse "E"; arcarrow from top to top of BOXA; aspic-1.05/doc/pic23.aspic0000644000222100022210000000016011534125704013331 0ustar ph10ph10BOXA: box "A"; line down 5; arc; arrow right 10; box "B"; line up align centre of BOXA; arrow to right of BOXA; aspic-1.05/doc/pic36.aspic0000644000222100022210000000002411534125704013334 0ustar ph10ph10arc; arrow left 10; aspic-1.05/doc/pic42.aspic0000644000222100022210000000020711534125704013334 0ustar ph10ph10box filled 0.5; box at centre plus (10,10) filled 0.5; iline right 10; box filled 0.5; box at centre plus (10,10) filled 0.5 level -1; aspic-1.05/doc/pic05.aspic0000644000222100022210000000005311534125704013332 0ustar ph10ph10line; line up right; line left; line down; aspic-1.05/doc/pic11.aspic0000644000222100022210000000003011534125704013322 0ustar ph10ph10line; ellipse join top; aspic-1.05/doc/pic18.aspic0000644000222100022210000000035411534125704013342 0ustar ph10ph10AA: line; arc from end to start "1"; arc from end of AA to start of AA angle 180 "2"; arc clockwise from end of AA to start of AA radius 100 "3"; BB: arc to start depth 24 "4"; arc clockwise to start via middle of BB plus (10,-10) "5"; aspic-1.05/doc/pic24.aspic0000644000222100022210000000014311534125704013333 0ustar ph10ph10box "A"; iline right 30 down 10; box "B"; ibox width 150 "iboxes are helpful" "for centring text"; aspic-1.05/doc/pic30.aspic0000644000222100022210000000006711534125704013335 0ustar ph10ph10boundingbox 10; ibox "first"; arcarrow; ibox "second"; aspic-1.05/doc/pic37.aspic0000644000222100022210000000006611534125704013343 0ustar ph10ph10box "A"; box depth 50 "B"; box width 50 join top "C"; aspic-1.05/doc/pic43.aspic0000644000222100022210000000021611534125704013335 0ustar ph10ph10macro diag { A&$: box; line from top right to bottom left; line from top left of A&$ to bottom right of A&$; goto A&$; }; diag; arrow; diag; aspic-1.05/doc/pic06.aspic0000644000222100022210000000011211534125704013327 0ustar ph10ph10box "A"; box "B"; box "C"; line; down; circle "D"; circle "E"; line left; aspic-1.05/doc/pic12.aspic0000644000222100022210000000006711534125704013335 0ustar ph10ph10ellipse width 100 depth 20; ellipse width 20 depth 60; aspic-1.05/doc/pic19.aspic0000644000222100022210000000010511534125704013335 0ustar ph10ph10AA: line up; BB: line right; line from middle of AA to middle of BB; aspic-1.05/doc/pic25.aspic0000644000222100022210000000004511534125704013335 0ustar ph10ph10box filled 0.5; circle filled 1 0 0; aspic-1.05/doc/pic31.aspic0000644000222100022210000000025211534125704013332 0ustar ph10ph10macro item { B&$: box &1 &2; line down; line right 20 from right of B&$; }; item "first" "second"; MID: item "third"; item "fourth" "fifth"; arrow up 20 from MID; aspic-1.05/doc/pic38.aspic0000644000222100022210000000020411534125704013336 0ustar ph10ph10A: box "A"; L: line right; B: box "B"; line down from bottom of A; line right align middle of L; line up align right of A; aspic-1.05/doc/pic44.aspic0000644000222100022210000000007211534125704013336 0ustar ph10ph10right; box "A"; arc "1"; box "B"; down; arc "2"; box "C"; aspic-1.05/doc/pic07.aspic0000644000222100022210000000010711534125704013334 0ustar ph10ph10box "A"; box join top left "B"; circle join centre; box join left "C"; aspic-1.05/doc/pic13.aspic0000644000222100022210000000010211534125704013324 0ustar ph10ph10line dashed; arrow down; arrow left both; arrow down back dashed; aspic-1.05/doc/aspic.10000644000222100022210000000322711534125704012560 0ustar ph10ph10.TH ASPIC 1 .SH NAME aspic - a line-art processor .SH SYNOPSIS .rs .sp .B aspic [] [ []] . . .SH DESCRIPTION .rs .sp \fBAspic\fP is a program that processes a textual description of a line art graphic, and converts it into a form that is suitable for inclusion in another document. The default output format is Encapsulated PostScript, but there is also support for Scalable Vector Graphics (SVG), and there is legacy support for the SGCAL text processor. For a full specification, see the reference manual. This man page contains only a description of the command line interface. .P If no source or destination file names are given, Aspic reads from the standard input and writes to the standard output. Alternatively, a single hyphen character may be given as a file name to indicate the standard input or output streams. Error messages are written to the standard error stream. . . .SH OPTIONS .rs .TP 10 \fB-help\fP Give some help information and exit. .TP \fB-nv\fP Disable the use of Aspic variables (dollar is no longer special). .TP \fB-ps\fP Output is encapsulated PostScript. This is the default. .TP \fB-svg\fP Output is Scalar Vector Graphics (SVG), an XML application. .TP \fB-sgcal\fP Output is input for the SGCAL text formatter (not generally released). .TP \fB-tr\fP Translate certain characters (e.g. grave accent becomes opening quote). .TP \fB-v\fP Verify the Aspic version number, and exit. . . .SH AUTHOR .rs .sp .nf Philip Hazel .fi . . .SH REVISION .rs .sp .nf Last updated: 01 March 2008 Copyright (c) 2008 University of Cambridge. .fi aspic-1.05/doc/pic26.aspic0000644000222100022210000000005311534125704013335 0ustar ph10ph10line shapefilled 0.5; arc shapefilled 0.5; aspic-1.05/doc/pic32.aspic0000644000222100022210000000011511534125704013331 0ustar ph10ph10macro slotbox { box width 200 depth 20 }; slotbox dashed "text for slotbox"; aspic-1.05/doc/pic39.aspic0000644000222100022210000000010411534125704013336 0ustar ph10ph10line; text at end "ABC"; iline right 20; line; text at end "ABC"/l; aspic-1.05/doc/pic45.aspic0000644000222100022210000000012511534125704013336 0ustar ph10ph10linethickness 1; linegreyness 0.5; boxthickness 4; boxgreyness 0.8; line; box; line; aspic-1.05/doc/aspic.xfpt0000644000222100022210000025372711534125704013415 0ustar ph10ph10. ///////////////////////////////////////////////////////////////////////////// . This is the primary source of the Aspic Manual. It is an xfpt document that . is converted into DocBook XML for subsequent conversion into PostScript or . PDF formats. I use SDoP to make PostScript, and ps2pdf to turn that into PDF. . Other output formats are unsuitable because of the many included graphics, . which are Encapsulated PostScript. The markup used herein is "standard" . xfpt markup. . ///////////////////////////////////////////////////////////////////////////// .include stdflags .include stdmacs . ///////////////////////////////////////////////////////////////////////////// . This outputs the standard DocBook boilerplate. . ///////////////////////////////////////////////////////////////////////////// .docbook . ///////////////////////////////////////////////////////////////////////////// . These literal XML lines are processing instructions for SDoP. They adjust . the contents of the page footers, allow table cells to overflow without . warning if there is no overprinting. . ///////////////////////////////////////////////////////////////////////////// .literal xml .literal off . ///////////////////////////////////////////////////////////////////////////// . This macro is used for including the example pictures. It first includes the . source of the picture as a literal, then the processed image, at 80% size and . centered. We follow it with a paragraph containing only a zero-width space. . This is treated specially by SDop, inserting just a little vertical space. . The final ".literal off" is used to force a paragraph termination. A blank . line is normally inserted after the source, but can be suppressed by giving . a non-empty second argument (it matters not what the argument is). . ///////////////////////////////////////////////////////////////////////////// .macro pic .code .include ./pic$1.aspic .arg -2 . The blank line that follows is important! Do not remove. .endarg .endd .figure .image ./pic$1.eps 80 center .endfigure ​ .literal off .endmacro . ///////////////////////////////////////////////////////////////////////////// . These macros specify the informal table that is used for command definitions. . ///////////////////////////////////////////////////////////////////////////// .macro otable .itable none 0 0 3 20 left 72 left 200 left .endmacro .macro o .row "" "&*$1*&" "$2" .endmacro . ///////////////////////////////////////////////////////////////////////////// . This generate the outermost element that wraps the entire document. . ///////////////////////////////////////////////////////////////////////////// .book . //////////////////////////////////////////////////////////////////////////// . The element is provided as raw XML. It must be updated for each . new edition of this document. . //////////////////////////////////////////////////////////////////////////// .literal xml Aspic: A Line-Art Processor Aspic 04 March 2008 PhilipHazel PH 1.05 04 March 2008 PH 2008University of Cambridge .literal off . ///////////////////////////////////////////////////////////////////////////// . ///////////////////////////////////////////////////////////////////////////// .chapter "Introduction to Aspic" Aspic is a program that converts a textual description of a line drawing into instructions that can be processed by standard software in order to draw the picture. This method of defining line art graphics is the same as that of the PIC system, described by Kernighan in &'Software &-- Practice and Experience'&, &*12*&, pages 1&--21 (1982), though the details of the Aspic commands are quite different. The default output format is Encapsulated PostScript (EPS). There is also support for output in Scalable Vector Graphics (SVG) format. Aspic was originally developed for use with the SGCAL typesetter (which is not widely released), and it still contains some legacy support for that application (see chapter &<>&). Although Aspic supports the inclusion of text in drawings, it does no text processing of its own, in the sense that it contains no code for finding the displayed length of text strings. The implementation of operations such as text justification or centering (which can be specified in Aspic) are therefore left to the back-end processor. Aspic uses the font size to guess how much vertical space to leave between lines, but this can be increased by the user if required. Character encoding is discussed in chapter &<>&. .section "The aspic command" The command to run Aspic is as follows: .display &`aspic`& [&'options'&] &'input-file'& &'output-file'& .endd If a single hyphen character is given as a file name, it refers to the standard input or output. If no file names are given, Aspic reads from the standard input and writes to the standard output. If only one name is given, it is taken as the input, and output is again to the standard output. Error messages are always written to the standard error stream. The options are as follows: &*-help*& causes Aspic to display usage information on the standard output, and then exit. &*-nv*& disables the use of Aspic variables. This means that dollar characters in the input file are no longer treated specially. The option is useful when there are dollar characters in an Aspic source that does not make use of Aspic variables. &*-ps*& (the default) causes Aspic to write Encapsulated PostScript output. This can be viewed with a PostScript viewer such as &'gv'& and included in PostScript documents (which can easily be converted to PDF). &*-sgcal*& causes Aspic to generate SGCAL input as its output (see chapter &<>& for details). &*-svg*& causes Aspic to generate Scalable Vector Graphics (SVG) output. This can be viewed with an SVG viewer such as &'xsvg'& and included in XML documents. &*-tr*& causes Aspic to translate certain input characters; for example, a grave accent is translated into a typographic opening quote. Details are given in section &<>&. &*-v*& causes Aspic to display its version number on the standard output, and then exit. . ///////////////////////////////////////////////////////////////////////////// . ///////////////////////////////////////////////////////////////////////////// .chapter "Simple Aspic examples" This chapter uses some simple examples to introduce the various facilities that are available in Aspic. Subsequent chapters contain reference material that explains things in more detail. Aspic operates in a traditional Cartesian coordinate system, with the positive directions to the right and upwards. For PostScript output the units of length used in Aspic commands are printers' points. There are 72 points to an inch. SVG output contains the same dimensions without specifying a unit. The interpretation is left to the rendering software. On a screen, SVG dimensions are likely to be treated as pixels. The examples below all show examples of Aspic source, followed by the resulting picture. We start with a simple diagram: .pic 01 nospace Each Aspic command is terminated by a semicolon, so there are three commands in this example: .olist The &*box*& command causes a box to be drawn, containing the text at its centre. The default box size is 72 by 36 points (that is, 1" × 0.5"). There are commands to change the default &-- see chapter &<>& &-- and the size of an individual box can of course be specified (see below). There is also a &*magnify*& command that affects the sizes of all shapes (but not the size of any text). In this document, all the pictures are reduced by a factor of 0.8, so the size of the box above is actually 0.8" × 0.4". .next The &*line*& command draws a straight line; as nothing else is specified, the line is drawn in the current direction of motion, which defaults to the right. The length is the standard horizontal line length, which defaults to 72 points (1 inch). .next The &*circle*& command draws a circle; as nothing was specified as to how it should join onto its predecessor, the `obvious' joining position is chosen. The circle is drawn at a standard size. (Again, there are commands for changing this.) Aspic provides for ellipses as well as circles. .endlist Each Aspic command that causes a shape to be drawn may have any number of text strings associated with it. In the above example, the box and the circle each have one associated string. For closed shapes such as these, the strings are centred in the shape. For horizontal lines, the strings are centred above and below the line, while for other kinds of line they are positioned near the middle of the line. For example: .pic 02 The commands introduced above may be used with options that change the size of the shape that is drawn. For example: .pic 03 The current direction of motion can be changed by the commands &*up*&, &*down*&, &*left*&, and &*right*&. In addition, an individual line may be drawn in any direction and of any length (without changing the defaults) by means of appropriate options: .pic 04 The length values for lines are interpreted as distances in the Cartesian coordinate directions rather than the actual length of the line drawn. There are separate standard values for the horizontal and vertical lengths, which are 72 and 36 points, respectively, by default. .pic 05 If a sequence of closed shapes occurs, the shapes are joined together according to the current direction of motion, but a closed shape following a line joins according to the direction of the line. .pic 06 nospace There is a &*join*& option for specifying where a closed shape joins its predecessor: .pic 07 The argument for &*join*& specifies a point on the new shape that is to be joined to a point on the previous shape. Thus, in the above example, the top left-hand corner of the second box is the point which is joined to the first box. The joining point on the previous shape is the complementary position by default, but it can be also specified explicitly. For example: .pic 08 There are nine possible joining points &-- the four corners, the midpoints of the four edges, and the centre point. The midpoints of the edges are identified by the unqualified names of the edges. Thus, if the only joining information is an edge name, two boxes are joined with the midpoints of the edges aligned: .pic 09 Joins can refer to items other than their immediate predecessors, by using &'labels'&. For example: .pic 10 The &*join*& option may also be used for specifying how a closed shape joins onto a line: .pic 11 nospace When a circle or an ellipse is being joined, the `corner' joining points refer to points on the circumference, not the corners of the bounding box. The size of an ellipse is specified as a width and a depth, which determine the lengths of the horizontal and vertical axes. For example: .pic 12 nospace Lines may be drawn dashed, and, by using the &*arrow*& command, with arrowheads on one or both ends. .pic 13 By default, &*arrow*& requests an arrowhead on the end of the line. The option &*both*& gives arrowheads on both ends, whereas &*back*& gives a backward-pointing arrowhead only. Circular arcs are the other form of non-closed shape that Aspic supports. By default an arc is drawn in an anti-clockwise direction, for 90 degrees, and at a standard radius (default 36). If an arc follows a line or another arc, it continues in the same direction by default. If the very first shape is an arc, its initial direction is upwards. .pic 14 The options &*up*&, &*down*&, &*left*&, and &*right*& can be used to specify a different initial direction for the arc: .pic 14a nospace The angle subtended, the radius, and clockwise drawing can be specified: .pic 15 Arcs can be drawn from and to particular points, and, by using the &*arcarrow*& command, with arrowheads. .pic 16 In this example, the positions `end' and `start' are taken to refer to the last-drawn shape. To refer to other shapes, labels are used: .pic 17 When an arc of this type is drawn, &'either'& the radius &'or'& the angle subtended at the centre of the arc &'or'& the `depth' of the arc &'or'& a point through which the arc is to pass may be specified, but only one of these. The `depth' of an arc is the length of the line from the middle of the arc to the middle of the line joining the endpoints. If none of the above parameters is specified, a subtended angle of 90 degrees is used. Here is an example that shows the different ways of specifying arcs: .pic 18 The fifth arc in this example passes through a point that is defined as .code middle of BB plus (10,-10) .endd The `middle of BB' is halfway along the fourth arc; the &*plus*& qualifier applies a relative offset that is 10 points to the right and 10 points down from this midpoint. The starting and ending points of straight lines can also be specified explicitly; if both are specified, that determines the length of the line. .pic 19 Positions on a line or arc may be specified as &*start*&, &*middle*&, or &*end*& (the word &*centre*& is reserved for the centre of a closed shape, or for the centre point of a circular arc). More precise positioning can be achieved by specifying a fraction of the way along the line from a named position: .pic 20 The upward arrow starts at a point that is 0.2 of the way along the line from the start, and the downward arrow starts at a point that is 0.3 of the way along the line from the end. This feature also applies to the edges of boxes: .pic 21 Positions along the top and bottom are measured from the left; positions on the sides are measured from the bottom. If these options are used with a circle or an ellipse, the positions used are those of the circumscribing box. Any position can be further modified by an explicit distance, specified as a vector enclosed in parentheses following &*plus*&. In the next example, the arrow starts at a position 20 points to the right of the middle of the line, and 5 points above it: .pic 22 nospace There is one further positioning feature that is useful for horizontal or vertical lines. It allows the end of such a line to be aligned with a given point, which is often the easiest way to describe certain kinds of drawing: .pic 23 The &*align*& option is used in place of &*to*&; it defines a position, but only one of its coordinates is used as a coordinate of the end of the line. In the example above, a vertical line was specified, and so only the vertical coordinate of `&`centre of BOXA`&' was used. Aspic pictures are best specified as a sequence of shapes whose positions are inter-related. This makes the pictures easy to adjust as they are being created, and also easy to change subsequently. However, many pictures contain shapes that are not connected to other shapes in the picture. Aspic does allow absolute positioning for shapes, but it is often more useful to position these shapes in relation to the others. This can be done using &'invisible'& lines, boxes, and arcs. If you use &*iline*&, &*ibox*&, and &*iarc*& instead of &*line*&, &*box*&, and &*arc*&, the relevant lines are not drawn. There are also &*icircle*& and &*iellipse*& commands. .pic 24 The shapes in the examples shown so far have all been just outlines, but Aspic also contains facilities for causing closed shapes to be filled with colour or shaded with grey. The commands that define closed shapes (&*box*&, &*circle*&, and &*ellipse*&) can be specified with a &*filled*& option. If it is followed by one number, that specifies a grey level. Otherwise, it must be followed by three numbers that specify a colour in terms of red, green, and blue levels. The numbers are separated by commas and/or spaces. In all cases, the numbers lie between 0 and 1. For example: .pic 25 In this example, visible closed shapes are used, so their outlines are drawn. If an invisible shape is filled, no outline is drawn. Arbitrary shapes can be filled by specifying the &*shapefilled*& option with the same colour or greylevel value on a sequence of lines and/or curves. The end of the shape is marked by an item with a different &*shapefilled*& value (or the end of the input). The shape is automatically closed, if necessary, by an invisible straight edge from the endpoint to the startpoint. For example: .pic 26 nospace Sometimes it is necessary to supply a dummy item with a different &*shapefilled*& value to terminate one shape, when another that is to be filled with the same colour follows immediately afterwards. A line of zero length can be used for this. For example: .pic 27 Without the dummy, zero-length line, the result is: .pic 28 When a long sequence of commands all have the same &*shapefilled*& value, you can save typing by using the &*shapefill*& command to set a default (see chapter &<>&). Filling a shape obliterates items that are `beneath' it. To make it easy to specify which filled shapes are `above' others, there is a &*level*& option that can be used on any drawing command. The default level is zero; items with a higher value are drawn `above' (later), whereas items with a lower (negative) level are drawn `below' (earlier). The order in which the items are defined does not matter. For example: .pic 29 Aspic can be requested to draw a frame round any picture, by means of the &*boundingbox*& command. This is followed by one dimension, which specifies the space to be left between the bounding box of the picture and the frame. In this example the bounding box of the picture is determined by the invisible boxes that contain the text: .pic 30 This chapter has introduced many, but not all, of the features of Aspic. The remaining chapters specify the form of the input more rigorously, and list each command, together with its options. . ///////////////////////////////////////////////////////////////////////////// . ///////////////////////////////////////////////////////////////////////////// .chapter "General operation of Aspic" Aspic processes its input in order, interpreting commands that are instructions for moving about on the plane and causing shapes to be drawn and text to be printed. There are many parameters for controlling the size and style of the shapes that are drawn; all of them have defaults, and most of these can be altered. Aspic builds up data structures in main memory that represent the final image. When it reaches the end of the input file, it outputs a description of the picture in the appropriate output language. For PostScript output, the units of length used by Aspic are printers' &'points'&, of which there are 72 to an inch. For SVG output, the units are interpreted by the SVG processor, and on screen displays, they are often taken as pixels. Aspic distinguishes between closed and open shapes. The closed shapes are boxes, circles, and ellipses, and the open shapes are lines and circular arcs. There are default sizes for everything, and text strings may be associated with each shape. Unless explicitly positioned, each shape is placed adjacent to its predecessor, taking note of the &'current direction'&, whose default is to the right. For example, the sequence: .code box; arrow; box; .endd places the three items in a horizontal row. There are commands to change the current direction, and, for the drawing commands, options to override it for individual items. Only very simple pictures can be drawn as a series of shapes in which each shape is positioned relative to its predecessor. Aspic allows shapes to be labelled so that branches in the sequence of shapes may be constructed, and cross-references between different parts of the picture may be expressed. The previous chapter contains several examples. .section "Position of the coordinate origin" It is possible to specify absolute positions on the drawing plane, but it is better to describe a picture in terms of relative positions between the shapes that comprise it, because such a description is much easier to adjust while you are creating the picture. If the first item in a picture is specified without an absolute position &-- this is normally the case &-- it is positioned as follows: .ilist A closed shape is placed with its centre at the origin. .next A straight line starts at the origin. .next A circular arc is placed with the centre of the arc at the origin. .endlist However, for most pictures, it is not necessary to worry about absolute coordinates or the position of the origin. .section "The bounding box" Aspic computes a bounding box for the entire picture, and arranges that the bottom left of the bounding box is positioned at the bottom of the picture's space on the output page. This means that the origin is not necessarily at the bottom left of the final picture. The coordinates of the bounding box are included in the output file and are used by programs that process it to determine the size of the image. Invisible items that are not part of the boundary of a filled shape, and which have no associated text, are ignored when Aspic is computing the bounding box. The idea is that such items are assumed to be used for positioning purposes only. Occasionally you may want an invisible item to be included in the bounding box calculation. You can do this by providing it with an empty text string. Because Aspic does not process text strings itself, it can only guess the size of a string when computing the bounding box. This matters only when a string extends beyond the box defined by the graphic shapes. A string's width is guessed as one half the font size times the number of characters in the string. . ///////////////////////////////////////////////////////////////////////////// . ///////////////////////////////////////////////////////////////////////////// .chapter "Aspic input" Aspic input consists of a sequence of commands, each of which must be terminated by a semicolon. Newlines and other white space may appear between the components of a command in the usual way. If a sharp (or `hash') character (#) is encountered when a command is expected, the remainder of the input line is ignored. This provides a facility for including comments in Aspic input. Each input line is processed for variable substitutions before any other processing takes place (see chapter &<>& below). .section "Command format" An Aspic command consists of four components: .itable none 0 0 4 40 centre 60 centre 120 centre 140 centre .row "&'label'&" "&'command'&" "&'options'&" "&'strings'&" .row "&`A:`&" "&`box`&" "&`dashed width 100`&" '&`"first" "second";`&' .endtable The case of letters is significant in all the components. Only the command name is mandatory. .olist Commands that define lines or closed shapes may start with one or more labels, each terminated by a colon. A label consists of a sequence of letters and digits, starting with a letter. Upper case letters are commonly used in labels as it makes them stand out. Other commands may not be labelled. .next All commands contain a command name. .next Many commands have optional option specifications that follow the command name. Each option consists of a keyword, possibly followed by a value. They may appear in any order. .next Following the options, on commands that define lines or closed shapes, and on the &*text*& command, there may be any number of text strings, each enclosed in double quotes. The double-quote character itself may be included by doubling. There are some options that can follow a text string; these are described in chapter &<>&. The strings specify text that is to be output at an appropriate position relative to the item that is drawn (the &*text*& command in effect draws a null item). Details of text positioning are given below with the commands for each type of item. Strings may not extend over line boundaries in the input. .endlist Strings are interpreted as a sequence of Unicode characters. The inclusion of characters by name and by number is supported. Details of how the sequence of input bytes is decoded are given in section &<>&. Aspic does no typographic processing of strings. This means that any string-specific processing, such as measuring the string in order to centre it, has to take place in the backend processor. In PostScript output, PostScript operators are used to do this. In SVG output, an appropriate setting of the &*text-anchor*& attribute is generated. .section "File inclusion" The &*include*& command can be used to insert the contents of a given file into the sequence of Aspic commands. This can be used, for example, to include a standard header file (which might define fonts or give names to colours) in a number of different pictures. The command name is followed by a file name, which is not quoted. For example: .code include /home/me/MyAspicHeader; .endd If &*include*& appears inside a macro (see chapter &<>&), it is evaluated every time the macro is called, so can be used to include different files on different occasions. Included files may contain further inclusions. . ///////////////////////////////////////////////////////////////////////////// . ///////////////////////////////////////////////////////////////////////////// .chapter "Aspic variables" CHAPVARIABLE Aspic supports simple variables, which can be used to save repetition in the input. This feature can, however, be disabled by use of the &*-nv*& command line option. If you are not using Aspic variables, but are making use of dollar ($) characters in strings, you should use &*-nv*&, because otherwise the dollars will be misinterpreted by Aspic. When variables are not disabled, a dollar character in an input line introduces a variable substitution. There is, however, one exception: the special sequence &`&&$`& that is used in Aspic macros &-- see chapter &<>&. In all other cases, a dollar character must either be followed by another dollar (indicating a single literal dollar character), or be followed by a variable name, optionally enclosed in brace (curly bracket) characters. Variable names start with a letter and contain letters and digits. Braces are required if the character that follows the variable name is a letter or a digit. When each input line is read, the values of any variables that are mentioned are substituted before any other processing takes place. A variable must be defined before it is used. The contents of a macro (see chapter &<>&) are &'not'& reprocessed for variable substitutions when the macro is called. (They are, of course, processed for substitutions of the macro's arguments.) Variables are given values by means of the &*set*& command, which is followed by a variable name (without a dollar) and a string value. The value of a variable can be changed as many times as you like during the course of a picture description. For example, this command defines the variable &*red*& to contain the three colour values for the colour red: .code set red "1,0,0"; .endd Later in the input file, the variable could be used like this: .code box filled $red; .endd &*&'Special variables'&*& At the start of an Aspic run, the variable &*$date*& is initialized to contain the date and time, and the variables &*$creator*& and &*$title*& are each set to the string `Unknown'. These three variables are used to create comments at the start of PostScript and SGV output, but otherwise they are treated like any other variable, and you can change them as required. For example, you might like to set &*$date*& to the date on which the picture was defined. . ///////////////////////////////////////////////////////////////////////////// . ///////////////////////////////////////////////////////////////////////////// .chapter "Aspic macros" CHAPMACRO To save a lot of command repetition, Aspic contains a simple macro facility that allows you to define compound commands. A macro is defined by the command &*macro*&, which is followed by a name and a macro body. Macro names must not be the same as the names of inbuilt commands. The body consists &'either'& of all the following text up to the first non-quoted semicolon, &'or'&, if the first character after the name is an opening brace, all the text up to the next non-quoted closing brace, which must be followed by a semicolon. For example: .code macro bigbox box width 100 depth 100; macro box2 { box; box; }; .endd A macro definition may extend over more than one line. Variables are substituted into the contents of a macro when it is defined; there is no re-substitution when the macro is called. If you need such a facility, it can be obtained by passing variables as arguments to macro calls. Macros are called by using their names as command names. They can be called with arguments, which are treated as character strings. White space is used to delimit macro arguments, unless they are enclosed in either single or double quotes. If double quotes are used, they are retained when the contents of an argument are substituted into the macro body. Macro arguments are referenced in the macro body by items of the form &`&&1`&, &`&&2`&, etc. These references are replaced by the actual argument values each time the macro is called. If the character &`&&`& is required for another purpose in a macro body, it must be doubled. If the special string &`&&$`& appears in a macro body, it is replaced by a sequence number that is incremented for each macro called. This can be used to generate unique labels for shapes that are drawn as a result of macro calls. The following example starts with the definition of a macro that draws a box containing text given as one or two arguments, with two lines attached to it. This macro is then used to generate an array of boxes. Because Aspic allows multiple labels on shapes, these compound items can themselves be labelled, as shown in this example: .pic 31 Note the use of &`&&$`& to generate a unique label within the macro. Because the macro was not defined with double quotes surrounding the argument references, double quotes had to be used when calling it in order to supply strings to the &*box*& command. If the quotes had been present in the definition, they could not be have been used in the calls, but single quotes could have been used if the arguments contained spaces. If an argument that has not been supplied is referenced, nothing is substituted; thus the second call of &*item*& above expands into a call to &*box*& with only a single string argument. If too many arguments are supplied, the surplus ones are left in the input following the substituted text. It is not necessary to include a semicolon before a terminating brace when defining a macro. If the semicolon is present, it is included in the replacement text when the macro is called. Sometimes it is useful to be able to set up a macro that generates part of a command, so that additional options can be added on each call. This can be done by omitting the terminating semicolon. In this example, any text following the macro name is added to the command: .pic 32 When such additional text is required, and also not all the arguments of a macro are to be supplied, the vertical bar character can be used to mark the end of the arguments. For example: .pic 33 In the first call, the two strings are taken as arguments of the macro; in the second call, the second string is added onto the end of the replacement text, and therefore goes with the &*arrow*& command. . ///////////////////////////////////////////////////////////////////////////// . ///////////////////////////////////////////////////////////////////////////// .chapter "Types of value used in commands" CHAPTOV Unless explicitly stated to be an integer, a number may always be specified with an optional decimal point and fractional part. Negative numbers are preceded by a minus sign. Non-integer numbers are held in a fixed-point format to three decimal places. In the descriptions of the commands that follow, the following types of value are used: .section A non-negative number, specifying an angle in degrees. .section One of the phrases &'top, bottom, left, right, centre, bottom left, bottom right, top left'&, or &'top right'&. The first four refer to the midpoints of the respective sides of a box; the last four refer to the corners. .section Three numbers in the range 0.0 to 1.0, separated by spaces and/or commas. They specify the colour components for red, green, and blue, respectively. .section A number in the range 0.0 to 1.0, where 0.0 is black and 1.0 is white. .section A positive or negative integer. .section