1# statement 2 3## Rules 4 5 * *object-definition* 6 * LABEL **:** *object-definition* 7 * LABEL **:** *place* 8 * *direction* 9 * VARIABLE *assignment-op* *expr* 10 * **define** VARIABLE CODEBLOCK 11 * **print** *print-argument* (**,** *print-argument*)\* 12 * **assert (** *expr* **==** *expr* **)** 13 * **assert (** *position* **==** *position* **)** 14 15 16## Labels 17 18A label can be attached to either an *object* or a *place* so that 19the object or place can be more easily referenced by subsequent statements. 20Labels always begin with an upper-case ASCII character. 21 22Labels do not have to be unique. When there are two or more 23labels with the same name, the later one takes precedence. 24This allows a label to be effectively redefined. New labels do not 25come into existence until after the object or place to which they are 26attached has been completely parsed and analyzed. This allows labels 27to be redefined in terms of themselves. Consider an example: 28 29~~~~~ 30/* 01 */ down 31/* 02 */ Root: dot "First \"Root\"" above color red 32/* 03 */ circle wid 50% at Root + (1.5cm, -1.5cm) 33/* 04 */ arrow dashed from previous to Root chop 34/* 05 */ Root: 3cm right of Root // Move the location of Root 3cm right 35/* 06 */ arrow from last circle to Root chop 36/* 07 */ dot "Second \"Root\"" above color blue at Root 37~~~~~ 38 39Line 05 redefines Root in terms of itself. 40In the rendering below, you can see that the dashed arrow drawn before 41Root was redefined goes to the original Root, but the solid arrow drawn 42afterwards goes to the revised location for Root. 43 44~~~~~ pikchr center toggle 45/* 01 */ down 46/* 02 */ Root: dot "First \"Root\"" above color red 47/* 03 */ circle wid 50% at Root + (1.5cm, -1.5cm) 48/* 04 */ arrow dashed from previous to Root chop 49/* 05 */ Root: 3cm right of Root // Move the location of Root 3cm right 50/* 06 */ arrow from last circle to Root chop 51/* 07 */ dot "Second \"Root\"" above color blue at Root 52~~~~~ 53 54## Variables 55 56Variable names begin with a lower-case ASCII letter or with "`$`" 57or with "`@`". The $- and @- variable names are a Pikchr extension 58designed to help prevent collisions between variable names and the 59(numerous) keywords in the Pikchr language. 60 61Pikchr has built-in variables as follows: 62 63> 64| Variable Name | Initial Value |: Purpose | 65------------------------------------------------------------------------------ 66| arcrad |: 0.250 :| Default arc radius | 67| arrowhead |: 2.000 :| *Not used by Pikchr* | 68| arrowht |: 0.080 :| Length of arrowheads | 69| arrowwid |: 0.060 :| Width of arrowheads | 70| boxht |: 0.500 :| Default height of "box" objects | 71| boxrad |: 0.000 :| Default corner radius for "box" objects | 72| boxwid |: 0.750 :| Default width for "box" objects | 73| charht |: 0.140 :| Average height of a character | 74| charwid |: 0.080 :| Average width of a character | 75| circlerad |: 0.250 :| Default radius for "circle" objects | 76| color |: 0.000 :| Default foreground color | 77| cylht |: 0.500 :| Default height for "cylinder" objects | 78| cylrad |: 0.075 :| Default minor axis for ellipses in a cylinder | 79| cylwid |: 0.750 :| Default width of a "cylinder" object | 80| dashwid |: 0.050 :| Default width of dashes in dashed lines | 81| dotrad |: 0.015 :| Default radius for a "dot" object | 82| ellipseht |: 0.500 :| Default height for "ellipse" objects | 83| ellipsewid |: 0.750 :| Default width for "ellipse" objects | 84| fileht |: 0.750 :| Default height for "file" objects | 85| filerad |: 0.150 :| Default corner fold length for "file" objects | 86| filewid |: 0.500 :| Default width for "file" objects | 87| fill |: -1.00 :| Default fill color. Negative means "none" | 88| lineht |: 0.500 :| Default length for lines drawn up or down | 89| linewid |: 0.500 :| Default length for lines drawn left or right | 90| movewid |: 0.500 :| Default distance traversed by a "move" | 91| ovalht |: 0.500 :| Default height of an "oval" object | 92| ovalwid |: 1.000 :| Default width of an "oval" object | 93| scale |: 1.000 :| Scale factor for drawing. Larger is bigger. | 94| textht |: 0.500 :| *Not used by Pikchr* | 95| textwid |: 0.750 :| *Not used by Pikchr* | 96| thickness |: 0.015 :| Default line thickness for all objects | 97 98In addition to the above, Pikchr recognizes the following variables 99which are not initially defined, but if they are defined by the script 100have special properties: 101 102> 103| Variable Name |: Purpose | 104------------------------------------------------------------------------------ 105| bottommargin | Extra border space added to the bottom of the diagram | 106| fgcolor | Use this foreground color in place of black | 107| fontscale | Scale factor applied to the font size of text | 108| layer | The default layer for all subsequent objects | 109| leftmargin | Extra border space added to the left of the diagram | 110| margin | Extra border space added to all four sides of the diagram | 111| rightmargin | Extra border space added to the right side of the diagram | 112| topmargin | Extra border space added to top top side of the diagram | 113 114 115The "VARIABLE *assignment-op* *expr*" syntax is able to modify the value 116of built-in variables, or create new variables. In legacy-PIC, the only 117*assignment-op* was "`=`". Pikchr adds "`+=`", "`-=`", "`*=`", and 118"`/=`" to make it easier to scale existing variables up or down. 119 120### Conflicts between variable names and keywords 121 122Some of the built-in variables have names that conflict with keywords: 123 124 * color 125 * fill 126 * thickness 127 128To access such variables as part of an expression, simply put them inside 129of parentheses. For example, to set the thickness of a box to be twice 130the default thinkness: 131 132~~~ pikchr center toggle source 133 box "Normal" 134 move 135 box "Double" "Thick" thickness 2*(thickness) 136~~~ 137 138## Define 139 140The "`define`" statement creates a [macro](./macro.md) 141that can then be called in subsequent text. 142 143## Print 144 145The "`print`" statement prints the strings and the values of the expressions 146in its argument into the generated output in front of the 147"`<svg>`" element for the diagram. This facility is intended for testing 148and debugging purposes. There is no known practical use for "`print`" in 149a production Pikchr script. 150 151The following Pikchr script demonstrates the effect of "print". 152Click to toggle between the script and its rendering. 153 154~~~ pikchr toggle source indent 155 oval "Hello, World!" fit 156 print "Oval at: ",previous.x, ",", previous.y 157 line 158 oval "2nd oval" fit 159 print "2nd oval at: ",previous.x, ",", previous.y 160~~~ 161 162## Assert 163 164The "`assert`" statement is intended for testing and debugging of Pikchr 165scripts. An assert() is a no-op if the equality comparison in its 166argument is true. But it raises an error if the condition is false. 167 168Consider this script: 169 170~~~ 171 oval "Hello, World!" fit 172 assert( last oval.w == last oval.e ); # <-- should fail 173~~~ 174 175And its rendering: 176 177~~~ pikchr 178 oval "Hello, World!" fit 179 assert( last oval.w == last oval.e ); # <-- should fail 180~~~ 181