Fossil SCM

Include pikchr source text in the generated SVG.

drh 2020-09-15 13:24 trunk
Commit 041390d3f88afd480c03b0c0ad0901de0d226eb3247d441bdafa7b6d416e676b
2 files changed +1 -1 +293 -269
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -335,11 +335,11 @@
335335
const char *zSrc, int nSrc, /* The Pikchr source text */
336336
const char *zArg, int nArg /* Addition arguments */
337337
){
338338
int w = 0, h = 0;
339339
char *zIn = fossil_strndup(zSrc, nSrc);
340
- char *zOut = pikchr(zIn, "pikchr", 0, &w, &h);
340
+ char *zOut = pikchr(zIn, "pikchr", PIKCHR_INCLUDE_SOURCE, &w, &h);
341341
fossil_free(zIn);
342342
if( w>0 && h>0 ){
343343
const char *zNonce = safe_html_nonce(1);
344344
Blob css;
345345
blob_init(&css,0,0);
346346
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -335,11 +335,11 @@
335 const char *zSrc, int nSrc, /* The Pikchr source text */
336 const char *zArg, int nArg /* Addition arguments */
337 ){
338 int w = 0, h = 0;
339 char *zIn = fossil_strndup(zSrc, nSrc);
340 char *zOut = pikchr(zIn, "pikchr", 0, &w, &h);
341 fossil_free(zIn);
342 if( w>0 && h>0 ){
343 const char *zNonce = safe_html_nonce(1);
344 Blob css;
345 blob_init(&css,0,0);
346
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -335,11 +335,11 @@
335 const char *zSrc, int nSrc, /* The Pikchr source text */
336 const char *zArg, int nArg /* Addition arguments */
337 ){
338 int w = 0, h = 0;
339 char *zIn = fossil_strndup(zSrc, nSrc);
340 char *zOut = pikchr(zIn, "pikchr", PIKCHR_INCLUDE_SOURCE, &w, &h);
341 fossil_free(zIn);
342 if( w>0 && h>0 ){
343 const char *zNonce = safe_html_nonce(1);
344 Blob css;
345 blob_init(&css,0,0);
346
+293 -269
--- src/pikchr.c
+++ src/pikchr.c
@@ -29,11 +29,11 @@
2929
** of PIKCHR language text and generates a second string of SVG output that
3030
** renders the drawing defined by the input. Space to hold the returned
3131
** string is obtained from malloc() and should be freed by the caller.
3232
** NULL might be returned if there is a memory allocation error.
3333
**
34
-** If there are error in the PIKCHR input, the output will consist of an
34
+** If there are errors in the PIKCHR input, the output will consist of an
3535
** error message and the original PIKCHR input text (inside of <pre>...</pre>).
3636
**
3737
** The subroutine implemented by this file is intended to be stand-alone.
3838
** It uses no external routines other than routines commonly found in
3939
** the standard C library.
@@ -72,11 +72,11 @@
7272
**
7373
** The input is a sequence of objects or "elements". Each element is
7474
** parsed into a PElem object. These are stored on an extensible array
7575
** called PEList. All parameters to each PElem are computed as the
7676
** object is parsed. (Hence, the parameters to a PElem may only refer
77
-** to prior elements.) Once the PElem is completely assemblied, it is
77
+** to prior elements.) Once the PElem is completely assembled, it is
7878
** added to the end of a PEList and never changes thereafter - except,
7979
** PElem objects that are part of a "[...]" block might have their
8080
** absolute position shifted when the outer [...] block is positioned.
8181
** But apart from this repositioning, PElem objects are unchanged once
8282
** they are added to the list. The order of elements on a PEList does
@@ -90,12 +90,12 @@
9090
**
9191
** Each PElem is on a "layer". (The common case is that all PElem's are
9292
** on a single layer, but multiple layers are possible.) A separate pass
9393
** is made through the list for each layer.
9494
**
95
-** After all output is generated, the Pik object, and the all the PEList
96
-** and PElem objects are deallocated and the generate output string is
95
+** After all output is generated, the Pik object and all the PEList
96
+** and PElem objects are deallocated and the generated output string is
9797
** returned. Upon any error, the Pik.nErr flag is set, processing quickly
9898
** stops, and the stack unwinds. No attempt is made to continue reading
9999
** input after an error.
100100
**
101101
** Most elements begin with a class name like "box" or "arrow" or "move".
@@ -105,18 +105,18 @@
105105
** its subelements, all gathered onto a separate PEList object.
106106
**
107107
** Variables go into PVar objects that form a linked list.
108108
**
109109
** Each PElem has zero or one names. Input constructs that attempt
110
-** to assign a new name from an older name, like:
110
+** to assign a new name from an older name, for example:
111111
**
112112
** Abc: Abc + (0.5cm, 0)
113113
**
114
-** These generate a new "noop" object at the specified place and with
115
-** the specified name. As place-names are searched by scanning the list
116
-** in reverse order, this has the effect of overriding the "Abc" name
117
-** when referenced by subsequent objects.
114
+** Statements like these generate a new "noop" object at the specified
115
+** place and with the given name. As place-names are searched by scanning
116
+** the list in reverse order, this has the effect of overriding the "Abc"
117
+** name when referenced by subsequent objects.
118118
*/
119119
#include <stdio.h>
120120
#include <stdlib.h>
121121
#include <string.h>
122122
#include <ctype.h>
@@ -235,12 +235,12 @@
235235
short int eCode; /* Auxiliary code */
236236
unsigned char eType; /* The numeric parser code */
237237
unsigned char eEdge; /* Corner value for corner keywords */
238238
};
239239
240
-/* Return negative, zero, or positive if pToken is less then, equal to
241
-** or greater than zero-terminated string z[]
240
+/* Return negative, zero, or positive if pToken is less than, equal to
241
+** or greater than the zero-terminated string z[]
242242
*/
243243
static int pik_token_eq(PToken *pToken, const char *z){
244244
int c = strncmp(pToken->z,z,pToken->n);
245245
if( c==0 && z[pToken->n]!=0 ) c = -1;
246246
return c;
@@ -260,11 +260,11 @@
260260
#define ValidDir(X) ((X)>=0 && (X)<=3)
261261
#define IsUpDown(X) (((X)&1)==1)
262262
#define IsLeftRight(X) (((X)&1)==0)
263263
264264
/* Bitmask for the various attributes for PElem. These bits are
265
-** collected in PElem.mProp and PElem.mCalc to check for contraint
265
+** collected in PElem.mProp and PElem.mCalc to check for constraint
266266
** errors. */
267267
#define A_WIDTH 0x000001
268268
#define A_HEIGHT 0x000002
269269
#define A_RADIUS 0x000004
270270
#define A_THICKNESS 0x000008
@@ -288,27 +288,23 @@
288288
PToken errTok; /* Reference token for error messages */
289289
PPoint ptAt; /* Reference point for the object */
290290
PPoint ptEnter, ptExit; /* Entry and exit points */
291291
PEList *pSublist; /* Substructure for [...] elements */
292292
char *zName; /* Name assigned to this element */
293
- PNum w; /* width */
294
- PNum h; /* height */
295
- PNum rad; /* radius */
296
- PNum sw; /* stroke width ("thinkness") */
297
- PNum dotted; /* dotted: <=0.0 for off */
298
- PNum dashed; /* dashed: <=0.0 for off */
299
- PNum fill; /* fill color. Negative for off */
300
- PNum color; /* Stroke color */
301
- PNum top; /* Top edge */
302
- PNum bottom; /* Bottom edge */
303
- PNum left; /* Left edge */
304
- PNum right; /* Right edge */
293
+ PNum w; /* "width" property */
294
+ PNum h; /* "height" property */
295
+ PNum rad; /* "radius" property */
296
+ PNum sw; /* "thickness" property. (Mnemonic: "stroke width")*/
297
+ PNum dotted; /* "dotted" property. <=0.0 for off */
298
+ PNum dashed; /* "dashed" property. <=0.0 for off */
299
+ PNum fill; /* "fill" property. Negative for off */
300
+ PNum color; /* "color" property */
305301
PPoint with; /* Position constraint from WITH clause */
306302
char eWith; /* Type of heading point on WITH clause */
307303
char cw; /* True for clockwise arc */
308
- char larrow; /* Arrow at beginning */
309
- char rarrow; /* Arrow at end */
304
+ char larrow; /* Arrow at beginning (<- or <->) */
305
+ char rarrow; /* Arrow at end (-> or <->) */
310306
char bClose; /* True if "close" is seen */
311307
char bChop; /* True if "chop" is seen */
312308
unsigned char nTxt; /* Number of text values */
313309
unsigned mProp; /* Masks of properties set so far */
314310
unsigned mCalc; /* Values computed from other constraints */
@@ -336,10 +332,11 @@
336332
unsigned int nIn; /* Number of bytes in zIn */
337333
char *zOut; /* Result accumulates here */
338334
unsigned int nOut; /* Bytes written to zOut[] so far */
339335
unsigned int nOutAlloc; /* Space allocated to zOut[] */
340336
unsigned char eDir; /* Current direction */
337
+ unsigned int mFlags; /* Flags passed to pikchr() */
341338
PElem *cur; /* Element under construction */
342339
PEList *list; /* Element list under construction */
343340
PVar *pVar; /* Application-defined variables */
344341
PBox bbox; /* Bounding box around all elements */
345342
/* Cache of layout values. <=0.0 for unknown... */
@@ -358,13 +355,24 @@
358355
int nTPath; /* Number of entries on aTPath[] */
359356
int mTPath; /* For last entry, 1: x set, 2: y set */
360357
PPoint aTPath[1000]; /* Path under construction */
361358
};
362359
360
+
361
+/*
362
+** Flag values for Pik.mFlags (to be picked up by makeheaders on systems
363
+** that use makeheaders.
364
+*/
365
+#undef INTERFACE
366
+#define INTERFACE 1
367
+#if INTERFACE
368
+#define PIKCHR_INCLUDE_SOURCE 0x0001 /* Include Pikchr src in SVG output */
369
+#endif /* INTERFACE */
370
+
363371
/*
364372
** The behavior of an object class is defined by an instance of
365
-** this structure. This it the "virtual method" table.
373
+** this structure. This is the "virtual method" table.
366374
*/
367375
struct PClass {
368376
const char *zName; /* Name of class */
369377
char isLine; /* True if a line class */
370378
char eJust; /* Use box-style text justification */
@@ -445,11 +453,11 @@
445453
static void pik_behind(Pik*,PElem*);
446454
static PElem *pik_assert(Pik*,PNum,PToken*,PNum);
447455
static PElem *pik_place_assert(Pik*,PPoint*,PToken*,PPoint*);
448456
449457
450
-#line 476 "pikchr.c"
458
+#line 484 "pikchr.c"
451459
/**************** End of %include directives **********************************/
452460
/* These constants specify the various numeric values for terminal symbols.
453461
***************** Begin token definitions *************************************/
454462
#ifndef T_ID
455463
#define T_ID 1
@@ -1621,22 +1629,22 @@
16211629
** inside the C code.
16221630
*/
16231631
/********* Begin destructor definitions ***************************************/
16241632
case 94: /* element_list */
16251633
{
1626
-#line 465 "pikchr.y"
1634
+#line 473 "pikchr.y"
16271635
pik_elist_free(p,(yypminor->yy72));
1628
-#line 1653 "pikchr.c"
1636
+#line 1661 "pikchr.c"
16291637
}
16301638
break;
16311639
case 95: /* element */
16321640
case 96: /* unnamed_element */
16331641
case 97: /* basetype */
16341642
{
1635
-#line 467 "pikchr.y"
1643
+#line 475 "pikchr.y"
16361644
pik_elem_free(p,(yypminor->yy254));
1637
-#line 1662 "pikchr.c"
1645
+#line 1670 "pikchr.c"
16381646
}
16391647
break;
16401648
/********* End destructor definitions *****************************************/
16411649
default: break; /* If no destructor action specified: do nothing */
16421650
}
@@ -1850,14 +1858,14 @@
18501858
#endif
18511859
while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
18521860
/* Here code is inserted which will execute if the parser
18531861
** stack every overflows */
18541862
/******** Begin %stack_overflow code ******************************************/
1855
-#line 498 "pikchr.y"
1863
+#line 506 "pikchr.y"
18561864
18571865
pik_error(p, 0, "parser stack overflow");
1858
-#line 1883 "pikchr.c"
1866
+#line 1891 "pikchr.c"
18591867
/******** End %stack_overflow code ********************************************/
18601868
pik_parserARG_STORE /* Suppress warning about unused %extra_argument var */
18611869
pik_parserCTX_STORE
18621870
}
18631871
@@ -2322,593 +2330,593 @@
23222330
** break;
23232331
*/
23242332
/********** Begin reduce actions **********************************************/
23252333
YYMINORTYPE yylhsminor;
23262334
case 0: /* document ::= element_list */
2327
-#line 502 "pikchr.y"
2335
+#line 510 "pikchr.y"
23282336
{pik_render(p,yymsp[0].minor.yy72);}
2329
-#line 2354 "pikchr.c"
2337
+#line 2362 "pikchr.c"
23302338
break;
23312339
case 1: /* element_list ::= element */
2332
-#line 505 "pikchr.y"
2340
+#line 513 "pikchr.y"
23332341
{ yylhsminor.yy72 = pik_elist_append(p,0,yymsp[0].minor.yy254); }
2334
-#line 2359 "pikchr.c"
2342
+#line 2367 "pikchr.c"
23352343
yymsp[0].minor.yy72 = yylhsminor.yy72;
23362344
break;
23372345
case 2: /* element_list ::= element_list EOL element */
2338
-#line 507 "pikchr.y"
2346
+#line 515 "pikchr.y"
23392347
{ yylhsminor.yy72 = pik_elist_append(p,yymsp[-2].minor.yy72,yymsp[0].minor.yy254); }
2340
-#line 2365 "pikchr.c"
2348
+#line 2373 "pikchr.c"
23412349
yymsp[-2].minor.yy72 = yylhsminor.yy72;
23422350
break;
23432351
case 3: /* element ::= */
2344
-#line 510 "pikchr.y"
2352
+#line 518 "pikchr.y"
23452353
{ yymsp[1].minor.yy254 = 0; }
2346
-#line 2371 "pikchr.c"
2354
+#line 2379 "pikchr.c"
23472355
break;
23482356
case 4: /* element ::= direction */
2349
-#line 511 "pikchr.y"
2357
+#line 519 "pikchr.y"
23502358
{ pik_set_direction(p,yymsp[0].minor.yy0.eCode); yylhsminor.yy254=0; }
2351
-#line 2376 "pikchr.c"
2359
+#line 2384 "pikchr.c"
23522360
yymsp[0].minor.yy254 = yylhsminor.yy254;
23532361
break;
23542362
case 5: /* element ::= lvalue ASSIGN rvalue */
2355
-#line 512 "pikchr.y"
2363
+#line 520 "pikchr.y"
23562364
{pik_set_var(p,&yymsp[-2].minor.yy0,yymsp[0].minor.yy73,&yymsp[-1].minor.yy0); yylhsminor.yy254=0;}
2357
-#line 2382 "pikchr.c"
2365
+#line 2390 "pikchr.c"
23582366
yymsp[-2].minor.yy254 = yylhsminor.yy254;
23592367
break;
23602368
case 6: /* element ::= PLACENAME COLON unnamed_element */
2361
-#line 514 "pikchr.y"
2369
+#line 522 "pikchr.y"
23622370
{ yylhsminor.yy254 = yymsp[0].minor.yy254; pik_elem_setname(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0); }
2363
-#line 2388 "pikchr.c"
2371
+#line 2396 "pikchr.c"
23642372
yymsp[-2].minor.yy254 = yylhsminor.yy254;
23652373
break;
23662374
case 7: /* element ::= PLACENAME COLON position */
2367
-#line 516 "pikchr.y"
2375
+#line 524 "pikchr.y"
23682376
{ yylhsminor.yy254 = pik_elem_new(p,0,0,0);
23692377
if(yylhsminor.yy254){ yylhsminor.yy254->ptAt = yymsp[0].minor.yy139; pik_elem_setname(p,yylhsminor.yy254,&yymsp[-2].minor.yy0); }}
2370
-#line 2395 "pikchr.c"
2378
+#line 2403 "pikchr.c"
23712379
yymsp[-2].minor.yy254 = yylhsminor.yy254;
23722380
break;
23732381
case 8: /* element ::= unnamed_element */
2374
-#line 518 "pikchr.y"
2382
+#line 526 "pikchr.y"
23752383
{yylhsminor.yy254 = yymsp[0].minor.yy254;}
2376
-#line 2401 "pikchr.c"
2384
+#line 2409 "pikchr.c"
23772385
yymsp[0].minor.yy254 = yylhsminor.yy254;
23782386
break;
23792387
case 9: /* element ::= print prlist */
2380
-#line 519 "pikchr.y"
2388
+#line 527 "pikchr.y"
23812389
{pik_append(p,"<br>\n",5); yymsp[-1].minor.yy254=0;}
2382
-#line 2407 "pikchr.c"
2390
+#line 2415 "pikchr.c"
23832391
break;
23842392
case 10: /* element ::= ASSERT LP expr EQ expr RP */
2385
-#line 524 "pikchr.y"
2393
+#line 532 "pikchr.y"
23862394
{yymsp[-5].minor.yy254=pik_assert(p,yymsp[-3].minor.yy73,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy73);}
2387
-#line 2412 "pikchr.c"
2395
+#line 2420 "pikchr.c"
23882396
break;
23892397
case 11: /* element ::= ASSERT LP place EQ place RP */
2390
-#line 526 "pikchr.y"
2398
+#line 534 "pikchr.y"
23912399
{yymsp[-5].minor.yy254=pik_place_assert(p,&yymsp[-3].minor.yy139,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy139);}
2392
-#line 2417 "pikchr.c"
2400
+#line 2425 "pikchr.c"
23932401
break;
23942402
case 12: /* rvalue ::= PLACENAME */
2395
-#line 537 "pikchr.y"
2403
+#line 545 "pikchr.y"
23962404
{yylhsminor.yy73 = pik_lookup_color(p,&yymsp[0].minor.yy0);}
2397
-#line 2422 "pikchr.c"
2405
+#line 2430 "pikchr.c"
23982406
yymsp[0].minor.yy73 = yylhsminor.yy73;
23992407
break;
24002408
case 13: /* pritem ::= FILL */
24012409
case 14: /* pritem ::= COLOR */ yytestcase(yyruleno==14);
24022410
case 15: /* pritem ::= THICKNESS */ yytestcase(yyruleno==15);
2403
-#line 542 "pikchr.y"
2411
+#line 550 "pikchr.y"
24042412
{pik_append_num(p,"",pik_value(p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.n,0));}
2405
-#line 2430 "pikchr.c"
2413
+#line 2438 "pikchr.c"
24062414
break;
24072415
case 16: /* pritem ::= rvalue */
2408
-#line 545 "pikchr.y"
2416
+#line 553 "pikchr.y"
24092417
{pik_append_num(p,"",yymsp[0].minor.yy73);}
2410
-#line 2435 "pikchr.c"
2418
+#line 2443 "pikchr.c"
24112419
break;
24122420
case 17: /* pritem ::= STRING */
2413
-#line 546 "pikchr.y"
2421
+#line 554 "pikchr.y"
24142422
{pik_append_text(p,yymsp[0].minor.yy0.z+1,yymsp[0].minor.yy0.n-2,0);}
2415
-#line 2440 "pikchr.c"
2423
+#line 2448 "pikchr.c"
24162424
break;
24172425
case 18: /* prsep ::= COMMA */
2418
-#line 547 "pikchr.y"
2426
+#line 555 "pikchr.y"
24192427
{pik_append(p, " ", 1);}
2420
-#line 2445 "pikchr.c"
2428
+#line 2453 "pikchr.c"
24212429
break;
24222430
case 19: /* unnamed_element ::= basetype attribute_list */
2423
-#line 550 "pikchr.y"
2431
+#line 558 "pikchr.y"
24242432
{yylhsminor.yy254 = yymsp[-1].minor.yy254; pik_after_adding_attributes(p,yylhsminor.yy254);}
2425
-#line 2450 "pikchr.c"
2433
+#line 2458 "pikchr.c"
24262434
yymsp[-1].minor.yy254 = yylhsminor.yy254;
24272435
break;
24282436
case 20: /* basetype ::= CLASSNAME */
2429
-#line 552 "pikchr.y"
2437
+#line 560 "pikchr.y"
24302438
{yylhsminor.yy254 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); }
2431
-#line 2456 "pikchr.c"
2439
+#line 2464 "pikchr.c"
24322440
yymsp[0].minor.yy254 = yylhsminor.yy254;
24332441
break;
24342442
case 21: /* basetype ::= STRING textposition */
2435
-#line 554 "pikchr.y"
2443
+#line 562 "pikchr.y"
24362444
{yymsp[-1].minor.yy0.eCode = yymsp[0].minor.yy74; yylhsminor.yy254 = pik_elem_new(p,0,&yymsp[-1].minor.yy0,0); }
2437
-#line 2462 "pikchr.c"
2445
+#line 2470 "pikchr.c"
24382446
yymsp[-1].minor.yy254 = yylhsminor.yy254;
24392447
break;
24402448
case 22: /* basetype ::= LB savelist element_list RB */
2441
-#line 556 "pikchr.y"
2449
+#line 564 "pikchr.y"
24422450
{ p->list = yymsp[-2].minor.yy72; yymsp[-3].minor.yy254 = pik_elem_new(p,0,0,yymsp[-1].minor.yy72); if(yymsp[-3].minor.yy254) yymsp[-3].minor.yy254->errTok = yymsp[0].minor.yy0; }
2443
-#line 2468 "pikchr.c"
2451
+#line 2476 "pikchr.c"
24442452
break;
24452453
case 23: /* savelist ::= */
2446
-#line 561 "pikchr.y"
2454
+#line 569 "pikchr.y"
24472455
{yymsp[1].minor.yy72 = p->list; p->list = 0;}
2448
-#line 2473 "pikchr.c"
2456
+#line 2481 "pikchr.c"
24492457
break;
24502458
case 24: /* relexpr ::= expr */
2451
-#line 568 "pikchr.y"
2459
+#line 576 "pikchr.y"
24522460
{yylhsminor.yy60.rAbs = yymsp[0].minor.yy73; yylhsminor.yy60.rRel = 0;}
2453
-#line 2478 "pikchr.c"
2461
+#line 2486 "pikchr.c"
24542462
yymsp[0].minor.yy60 = yylhsminor.yy60;
24552463
break;
24562464
case 25: /* relexpr ::= expr PERCENT */
2457
-#line 569 "pikchr.y"
2465
+#line 577 "pikchr.y"
24582466
{yylhsminor.yy60.rAbs = 0; yylhsminor.yy60.rRel = yymsp[-1].minor.yy73/100;}
2459
-#line 2484 "pikchr.c"
2467
+#line 2492 "pikchr.c"
24602468
yymsp[-1].minor.yy60 = yylhsminor.yy60;
24612469
break;
24622470
case 26: /* optrelexpr ::= */
2463
-#line 571 "pikchr.y"
2471
+#line 579 "pikchr.y"
24642472
{yymsp[1].minor.yy60.rAbs = 0; yymsp[1].minor.yy60.rRel = 1.0;}
2465
-#line 2490 "pikchr.c"
2473
+#line 2498 "pikchr.c"
24662474
break;
24672475
case 27: /* attribute_list ::= relexpr alist */
2468
-#line 573 "pikchr.y"
2476
+#line 581 "pikchr.y"
24692477
{pik_add_direction(p,0,&yymsp[-1].minor.yy60);}
2470
-#line 2495 "pikchr.c"
2478
+#line 2503 "pikchr.c"
24712479
break;
24722480
case 28: /* attribute ::= numproperty relexpr */
2473
-#line 577 "pikchr.y"
2481
+#line 585 "pikchr.y"
24742482
{ pik_set_numprop(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy60); }
2475
-#line 2500 "pikchr.c"
2483
+#line 2508 "pikchr.c"
24762484
break;
24772485
case 29: /* attribute ::= dashproperty expr */
2478
-#line 578 "pikchr.y"
2486
+#line 586 "pikchr.y"
24792487
{ pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy73); }
2480
-#line 2505 "pikchr.c"
2488
+#line 2513 "pikchr.c"
24812489
break;
24822490
case 30: /* attribute ::= dashproperty */
2483
-#line 579 "pikchr.y"
2491
+#line 587 "pikchr.y"
24842492
{ pik_set_dashed(p,&yymsp[0].minor.yy0,0); }
2485
-#line 2510 "pikchr.c"
2493
+#line 2518 "pikchr.c"
24862494
break;
24872495
case 31: /* attribute ::= colorproperty rvalue */
2488
-#line 580 "pikchr.y"
2496
+#line 588 "pikchr.y"
24892497
{ pik_set_clrprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy73); }
2490
-#line 2515 "pikchr.c"
2498
+#line 2523 "pikchr.c"
24912499
break;
24922500
case 32: /* attribute ::= go direction optrelexpr */
2493
-#line 581 "pikchr.y"
2501
+#line 589 "pikchr.y"
24942502
{ pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy60);}
2495
-#line 2520 "pikchr.c"
2503
+#line 2528 "pikchr.c"
24962504
break;
24972505
case 33: /* attribute ::= go direction even position */
2498
-#line 582 "pikchr.y"
2506
+#line 590 "pikchr.y"
24992507
{pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy139);}
2500
-#line 2525 "pikchr.c"
2508
+#line 2533 "pikchr.c"
25012509
break;
25022510
case 34: /* attribute ::= CLOSE */
2503
-#line 583 "pikchr.y"
2511
+#line 591 "pikchr.y"
25042512
{ pik_close_path(p,&yymsp[0].minor.yy0); }
2505
-#line 2530 "pikchr.c"
2513
+#line 2538 "pikchr.c"
25062514
break;
25072515
case 35: /* attribute ::= CHOP */
2508
-#line 584 "pikchr.y"
2516
+#line 592 "pikchr.y"
25092517
{ p->cur->bChop = 1; }
2510
-#line 2535 "pikchr.c"
2518
+#line 2543 "pikchr.c"
25112519
break;
25122520
case 36: /* attribute ::= FROM position */
2513
-#line 585 "pikchr.y"
2521
+#line 593 "pikchr.y"
25142522
{ pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy139); }
2515
-#line 2540 "pikchr.c"
2523
+#line 2548 "pikchr.c"
25162524
break;
25172525
case 37: /* attribute ::= TO position */
2518
-#line 586 "pikchr.y"
2526
+#line 594 "pikchr.y"
25192527
{ pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy139); }
2520
-#line 2545 "pikchr.c"
2528
+#line 2553 "pikchr.c"
25212529
break;
25222530
case 38: /* attribute ::= THEN */
2523
-#line 587 "pikchr.y"
2531
+#line 595 "pikchr.y"
25242532
{ pik_then(p, &yymsp[0].minor.yy0, p->cur); }
2525
-#line 2550 "pikchr.c"
2533
+#line 2558 "pikchr.c"
25262534
break;
25272535
case 39: /* attribute ::= THEN optrelexpr HEADING expr */
25282536
case 41: /* attribute ::= GO optrelexpr HEADING expr */ yytestcase(yyruleno==41);
2529
-#line 589 "pikchr.y"
2537
+#line 597 "pikchr.y"
25302538
{pik_move_hdg(p,&yymsp[-2].minor.yy60,&yymsp[-1].minor.yy0,yymsp[0].minor.yy73,0,&yymsp[-3].minor.yy0);}
2531
-#line 2556 "pikchr.c"
2539
+#line 2564 "pikchr.c"
25322540
break;
25332541
case 40: /* attribute ::= THEN optrelexpr EDGEPT */
25342542
case 42: /* attribute ::= GO optrelexpr EDGEPT */ yytestcase(yyruleno==42);
2535
-#line 590 "pikchr.y"
2543
+#line 598 "pikchr.y"
25362544
{pik_move_hdg(p,&yymsp[-1].minor.yy60,0,0,&yymsp[0].minor.yy0,&yymsp[-2].minor.yy0);}
2537
-#line 2562 "pikchr.c"
2545
+#line 2570 "pikchr.c"
25382546
break;
25392547
case 43: /* attribute ::= AT position */
2540
-#line 595 "pikchr.y"
2548
+#line 603 "pikchr.y"
25412549
{ pik_set_at(p,0,&yymsp[0].minor.yy139,&yymsp[-1].minor.yy0); }
2542
-#line 2567 "pikchr.c"
2550
+#line 2575 "pikchr.c"
25432551
break;
25442552
case 44: /* attribute ::= SAME */
2545
-#line 597 "pikchr.y"
2553
+#line 605 "pikchr.y"
25462554
{pik_same(p,0,&yymsp[0].minor.yy0);}
2547
-#line 2572 "pikchr.c"
2555
+#line 2580 "pikchr.c"
25482556
break;
25492557
case 45: /* attribute ::= SAME AS object */
2550
-#line 598 "pikchr.y"
2558
+#line 606 "pikchr.y"
25512559
{pik_same(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0);}
2552
-#line 2577 "pikchr.c"
2560
+#line 2585 "pikchr.c"
25532561
break;
25542562
case 46: /* attribute ::= STRING textposition */
2555
-#line 599 "pikchr.y"
2563
+#line 607 "pikchr.y"
25562564
{pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy74);}
2557
-#line 2582 "pikchr.c"
2565
+#line 2590 "pikchr.c"
25582566
break;
25592567
case 47: /* attribute ::= FIT */
2560
-#line 600 "pikchr.y"
2568
+#line 608 "pikchr.y"
25612569
{pik_size_to_fit(p,&yymsp[0].minor.yy0); }
2562
-#line 2587 "pikchr.c"
2570
+#line 2595 "pikchr.c"
25632571
break;
25642572
case 48: /* attribute ::= BEHIND object */
2565
-#line 601 "pikchr.y"
2573
+#line 609 "pikchr.y"
25662574
{pik_behind(p,yymsp[0].minor.yy254);}
2567
-#line 2592 "pikchr.c"
2575
+#line 2600 "pikchr.c"
25682576
break;
25692577
case 49: /* withclause ::= DOT_E edge AT position */
25702578
case 50: /* withclause ::= edge AT position */ yytestcase(yyruleno==50);
2571
-#line 609 "pikchr.y"
2579
+#line 617 "pikchr.y"
25722580
{ pik_set_at(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy139,&yymsp[-1].minor.yy0); }
2573
-#line 2598 "pikchr.c"
2581
+#line 2606 "pikchr.c"
25742582
break;
25752583
case 51: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2576
-#line 613 "pikchr.y"
2584
+#line 621 "pikchr.y"
25772585
{yylhsminor.yy0 = yymsp[0].minor.yy0;}
2578
-#line 2603 "pikchr.c"
2586
+#line 2611 "pikchr.c"
25792587
yymsp[0].minor.yy0 = yylhsminor.yy0;
25802588
break;
25812589
case 52: /* boolproperty ::= CW */
2582
-#line 624 "pikchr.y"
2590
+#line 632 "pikchr.y"
25832591
{p->cur->cw = 1;}
2584
-#line 2609 "pikchr.c"
2592
+#line 2617 "pikchr.c"
25852593
break;
25862594
case 53: /* boolproperty ::= CCW */
2587
-#line 625 "pikchr.y"
2595
+#line 633 "pikchr.y"
25882596
{p->cur->cw = 0;}
2589
-#line 2614 "pikchr.c"
2597
+#line 2622 "pikchr.c"
25902598
break;
25912599
case 54: /* boolproperty ::= LARROW */
2592
-#line 626 "pikchr.y"
2600
+#line 634 "pikchr.y"
25932601
{p->cur->larrow=1; p->cur->rarrow=0; }
2594
-#line 2619 "pikchr.c"
2602
+#line 2627 "pikchr.c"
25952603
break;
25962604
case 55: /* boolproperty ::= RARROW */
2597
-#line 627 "pikchr.y"
2605
+#line 635 "pikchr.y"
25982606
{p->cur->larrow=0; p->cur->rarrow=1; }
2599
-#line 2624 "pikchr.c"
2607
+#line 2632 "pikchr.c"
26002608
break;
26012609
case 56: /* boolproperty ::= LRARROW */
2602
-#line 628 "pikchr.y"
2610
+#line 636 "pikchr.y"
26032611
{p->cur->larrow=1; p->cur->rarrow=1; }
2604
-#line 2629 "pikchr.c"
2612
+#line 2637 "pikchr.c"
26052613
break;
26062614
case 57: /* boolproperty ::= INVIS */
2607
-#line 629 "pikchr.y"
2615
+#line 637 "pikchr.y"
26082616
{p->cur->sw = 0.0;}
2609
-#line 2634 "pikchr.c"
2617
+#line 2642 "pikchr.c"
26102618
break;
26112619
case 58: /* boolproperty ::= THICK */
2612
-#line 630 "pikchr.y"
2620
+#line 638 "pikchr.y"
26132621
{p->cur->sw *= 1.5;}
2614
-#line 2639 "pikchr.c"
2622
+#line 2647 "pikchr.c"
26152623
break;
26162624
case 59: /* boolproperty ::= THIN */
2617
-#line 631 "pikchr.y"
2625
+#line 639 "pikchr.y"
26182626
{p->cur->sw *= 0.67;}
2619
-#line 2644 "pikchr.c"
2627
+#line 2652 "pikchr.c"
26202628
break;
26212629
case 60: /* textposition ::= */
2622
-#line 633 "pikchr.y"
2630
+#line 641 "pikchr.y"
26232631
{yymsp[1].minor.yy74 = 0;}
2624
-#line 2649 "pikchr.c"
2632
+#line 2657 "pikchr.c"
26252633
break;
26262634
case 61: /* textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL */
2627
-#line 636 "pikchr.y"
2635
+#line 644 "pikchr.y"
26282636
{yylhsminor.yy74 = pik_text_position(p,yymsp[-1].minor.yy74,&yymsp[0].minor.yy0);}
2629
-#line 2654 "pikchr.c"
2637
+#line 2662 "pikchr.c"
26302638
yymsp[-1].minor.yy74 = yylhsminor.yy74;
26312639
break;
26322640
case 62: /* position ::= expr COMMA expr */
2633
-#line 639 "pikchr.y"
2641
+#line 647 "pikchr.y"
26342642
{yylhsminor.yy139.x=yymsp[-2].minor.yy73; yylhsminor.yy139.y=yymsp[0].minor.yy73;}
2635
-#line 2660 "pikchr.c"
2643
+#line 2668 "pikchr.c"
26362644
yymsp[-2].minor.yy139 = yylhsminor.yy139;
26372645
break;
26382646
case 63: /* position ::= place PLUS expr COMMA expr */
2639
-#line 641 "pikchr.y"
2647
+#line 649 "pikchr.y"
26402648
{yylhsminor.yy139.x=yymsp[-4].minor.yy139.x+yymsp[-2].minor.yy73; yylhsminor.yy139.y=yymsp[-4].minor.yy139.y+yymsp[0].minor.yy73;}
2641
-#line 2666 "pikchr.c"
2649
+#line 2674 "pikchr.c"
26422650
yymsp[-4].minor.yy139 = yylhsminor.yy139;
26432651
break;
26442652
case 64: /* position ::= place MINUS expr COMMA expr */
2645
-#line 642 "pikchr.y"
2653
+#line 650 "pikchr.y"
26462654
{yylhsminor.yy139.x=yymsp[-4].minor.yy139.x-yymsp[-2].minor.yy73; yylhsminor.yy139.y=yymsp[-4].minor.yy139.y-yymsp[0].minor.yy73;}
2647
-#line 2672 "pikchr.c"
2655
+#line 2680 "pikchr.c"
26482656
yymsp[-4].minor.yy139 = yylhsminor.yy139;
26492657
break;
26502658
case 65: /* position ::= place PLUS LP expr COMMA expr RP */
2651
-#line 644 "pikchr.y"
2659
+#line 652 "pikchr.y"
26522660
{yylhsminor.yy139.x=yymsp[-6].minor.yy139.x+yymsp[-3].minor.yy73; yylhsminor.yy139.y=yymsp[-6].minor.yy139.y+yymsp[-1].minor.yy73;}
2653
-#line 2678 "pikchr.c"
2661
+#line 2686 "pikchr.c"
26542662
yymsp[-6].minor.yy139 = yylhsminor.yy139;
26552663
break;
26562664
case 66: /* position ::= place MINUS LP expr COMMA expr RP */
2657
-#line 646 "pikchr.y"
2665
+#line 654 "pikchr.y"
26582666
{yylhsminor.yy139.x=yymsp[-6].minor.yy139.x-yymsp[-3].minor.yy73; yylhsminor.yy139.y=yymsp[-6].minor.yy139.y-yymsp[-1].minor.yy73;}
2659
-#line 2684 "pikchr.c"
2667
+#line 2692 "pikchr.c"
26602668
yymsp[-6].minor.yy139 = yylhsminor.yy139;
26612669
break;
26622670
case 67: /* position ::= LP position COMMA position RP */
2663
-#line 647 "pikchr.y"
2671
+#line 655 "pikchr.y"
26642672
{yymsp[-4].minor.yy139.x=yymsp[-3].minor.yy139.x; yymsp[-4].minor.yy139.y=yymsp[-1].minor.yy139.y;}
2665
-#line 2690 "pikchr.c"
2673
+#line 2698 "pikchr.c"
26662674
break;
26672675
case 68: /* position ::= LP position RP */
2668
-#line 648 "pikchr.y"
2676
+#line 656 "pikchr.y"
26692677
{yymsp[-2].minor.yy139=yymsp[-1].minor.yy139;}
2670
-#line 2695 "pikchr.c"
2678
+#line 2703 "pikchr.c"
26712679
break;
26722680
case 69: /* position ::= expr between position AND position */
2673
-#line 650 "pikchr.y"
2681
+#line 658 "pikchr.y"
26742682
{yylhsminor.yy139 = pik_position_between(p,yymsp[-4].minor.yy73,yymsp[-2].minor.yy139,yymsp[0].minor.yy139);}
2675
-#line 2700 "pikchr.c"
2683
+#line 2708 "pikchr.c"
26762684
yymsp[-4].minor.yy139 = yylhsminor.yy139;
26772685
break;
26782686
case 70: /* position ::= expr LT position COMMA position GT */
2679
-#line 652 "pikchr.y"
2687
+#line 660 "pikchr.y"
26802688
{yylhsminor.yy139 = pik_position_between(p,yymsp[-5].minor.yy73,yymsp[-3].minor.yy139,yymsp[-1].minor.yy139);}
2681
-#line 2706 "pikchr.c"
2689
+#line 2714 "pikchr.c"
26822690
yymsp[-5].minor.yy139 = yylhsminor.yy139;
26832691
break;
26842692
case 71: /* position ::= expr ABOVE position */
2685
-#line 653 "pikchr.y"
2693
+#line 661 "pikchr.y"
26862694
{yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.y += yymsp[-2].minor.yy73;}
2687
-#line 2712 "pikchr.c"
2695
+#line 2720 "pikchr.c"
26882696
yymsp[-2].minor.yy139 = yylhsminor.yy139;
26892697
break;
26902698
case 72: /* position ::= expr BELOW position */
2691
-#line 654 "pikchr.y"
2699
+#line 662 "pikchr.y"
26922700
{yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.y -= yymsp[-2].minor.yy73;}
2693
-#line 2718 "pikchr.c"
2701
+#line 2726 "pikchr.c"
26942702
yymsp[-2].minor.yy139 = yylhsminor.yy139;
26952703
break;
26962704
case 73: /* position ::= expr LEFT OF position */
2697
-#line 655 "pikchr.y"
2705
+#line 663 "pikchr.y"
26982706
{yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.x -= yymsp[-3].minor.yy73;}
2699
-#line 2724 "pikchr.c"
2707
+#line 2732 "pikchr.c"
27002708
yymsp[-3].minor.yy139 = yylhsminor.yy139;
27012709
break;
27022710
case 74: /* position ::= expr RIGHT OF position */
2703
-#line 656 "pikchr.y"
2711
+#line 664 "pikchr.y"
27042712
{yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.x += yymsp[-3].minor.yy73;}
2705
-#line 2730 "pikchr.c"
2713
+#line 2738 "pikchr.c"
27062714
yymsp[-3].minor.yy139 = yylhsminor.yy139;
27072715
break;
27082716
case 75: /* position ::= expr ON HEADING EDGEPT OF position */
2709
-#line 658 "pikchr.y"
2717
+#line 666 "pikchr.y"
27102718
{yylhsminor.yy139 = pik_position_at_hdg(p,yymsp[-5].minor.yy73,&yymsp[-2].minor.yy0,yymsp[0].minor.yy139);}
2711
-#line 2736 "pikchr.c"
2719
+#line 2744 "pikchr.c"
27122720
yymsp[-5].minor.yy139 = yylhsminor.yy139;
27132721
break;
27142722
case 76: /* position ::= expr HEADING EDGEPT OF position */
2715
-#line 660 "pikchr.y"
2723
+#line 668 "pikchr.y"
27162724
{yylhsminor.yy139 = pik_position_at_hdg(p,yymsp[-4].minor.yy73,&yymsp[-2].minor.yy0,yymsp[0].minor.yy139);}
2717
-#line 2742 "pikchr.c"
2725
+#line 2750 "pikchr.c"
27182726
yymsp[-4].minor.yy139 = yylhsminor.yy139;
27192727
break;
27202728
case 77: /* position ::= expr EDGEPT OF position */
2721
-#line 662 "pikchr.y"
2729
+#line 670 "pikchr.y"
27222730
{yylhsminor.yy139 = pik_position_at_hdg(p,yymsp[-3].minor.yy73,&yymsp[-2].minor.yy0,yymsp[0].minor.yy139);}
2723
-#line 2748 "pikchr.c"
2731
+#line 2756 "pikchr.c"
27242732
yymsp[-3].minor.yy139 = yylhsminor.yy139;
27252733
break;
27262734
case 78: /* position ::= expr ON HEADING expr FROM position */
2727
-#line 664 "pikchr.y"
2735
+#line 672 "pikchr.y"
27282736
{yylhsminor.yy139 = pik_position_at_angle(p,yymsp[-5].minor.yy73,yymsp[-2].minor.yy73,yymsp[0].minor.yy139);}
2729
-#line 2754 "pikchr.c"
2737
+#line 2762 "pikchr.c"
27302738
yymsp[-5].minor.yy139 = yylhsminor.yy139;
27312739
break;
27322740
case 79: /* position ::= expr HEADING expr FROM position */
2733
-#line 666 "pikchr.y"
2741
+#line 674 "pikchr.y"
27342742
{yylhsminor.yy139 = pik_position_at_angle(p,yymsp[-4].minor.yy73,yymsp[-2].minor.yy73,yymsp[0].minor.yy139);}
2735
-#line 2760 "pikchr.c"
2743
+#line 2768 "pikchr.c"
27362744
yymsp[-4].minor.yy139 = yylhsminor.yy139;
27372745
break;
27382746
case 80: /* place ::= edge OF object */
2739
-#line 678 "pikchr.y"
2747
+#line 686 "pikchr.y"
27402748
{yylhsminor.yy139 = pik_place_of_elem(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0);}
2741
-#line 2766 "pikchr.c"
2749
+#line 2774 "pikchr.c"
27422750
yymsp[-2].minor.yy139 = yylhsminor.yy139;
27432751
break;
27442752
case 81: /* place2 ::= object */
2745
-#line 679 "pikchr.y"
2753
+#line 687 "pikchr.y"
27462754
{yylhsminor.yy139 = pik_place_of_elem(p,yymsp[0].minor.yy254,0);}
2747
-#line 2772 "pikchr.c"
2755
+#line 2780 "pikchr.c"
27482756
yymsp[0].minor.yy139 = yylhsminor.yy139;
27492757
break;
27502758
case 82: /* place2 ::= object DOT_E edge */
2751
-#line 680 "pikchr.y"
2759
+#line 688 "pikchr.y"
27522760
{yylhsminor.yy139 = pik_place_of_elem(p,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
2753
-#line 2778 "pikchr.c"
2761
+#line 2786 "pikchr.c"
27542762
yymsp[-2].minor.yy139 = yylhsminor.yy139;
27552763
break;
27562764
case 83: /* place2 ::= NTH VERTEX OF object */
2757
-#line 681 "pikchr.y"
2765
+#line 689 "pikchr.y"
27582766
{yylhsminor.yy139 = pik_nth_vertex(p,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,yymsp[0].minor.yy254);}
2759
-#line 2784 "pikchr.c"
2767
+#line 2792 "pikchr.c"
27602768
yymsp[-3].minor.yy139 = yylhsminor.yy139;
27612769
break;
27622770
case 84: /* object ::= nth */
2763
-#line 693 "pikchr.y"
2771
+#line 701 "pikchr.y"
27642772
{yylhsminor.yy254 = pik_find_nth(p,0,&yymsp[0].minor.yy0);}
2765
-#line 2790 "pikchr.c"
2773
+#line 2798 "pikchr.c"
27662774
yymsp[0].minor.yy254 = yylhsminor.yy254;
27672775
break;
27682776
case 85: /* object ::= nth OF|IN object */
2769
-#line 694 "pikchr.y"
2777
+#line 702 "pikchr.y"
27702778
{yylhsminor.yy254 = pik_find_nth(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0);}
2771
-#line 2796 "pikchr.c"
2779
+#line 2804 "pikchr.c"
27722780
yymsp[-2].minor.yy254 = yylhsminor.yy254;
27732781
break;
27742782
case 86: /* objectname ::= PLACENAME */
2775
-#line 696 "pikchr.y"
2783
+#line 704 "pikchr.y"
27762784
{yylhsminor.yy254 = pik_find_byname(p,0,&yymsp[0].minor.yy0);}
2777
-#line 2802 "pikchr.c"
2785
+#line 2810 "pikchr.c"
27782786
yymsp[0].minor.yy254 = yylhsminor.yy254;
27792787
break;
27802788
case 87: /* objectname ::= objectname DOT_U PLACENAME */
2781
-#line 698 "pikchr.y"
2789
+#line 706 "pikchr.y"
27822790
{yylhsminor.yy254 = pik_find_byname(p,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
2783
-#line 2808 "pikchr.c"
2791
+#line 2816 "pikchr.c"
27842792
yymsp[-2].minor.yy254 = yylhsminor.yy254;
27852793
break;
27862794
case 88: /* nth ::= NTH CLASSNAME */
2787
-#line 700 "pikchr.y"
2795
+#line 708 "pikchr.y"
27882796
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-1].minor.yy0); }
2789
-#line 2814 "pikchr.c"
2797
+#line 2822 "pikchr.c"
27902798
yymsp[-1].minor.yy0 = yylhsminor.yy0;
27912799
break;
27922800
case 89: /* nth ::= NTH LAST CLASSNAME */
2793
-#line 701 "pikchr.y"
2801
+#line 709 "pikchr.y"
27942802
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-2].minor.yy0); }
2795
-#line 2820 "pikchr.c"
2803
+#line 2828 "pikchr.c"
27962804
yymsp[-2].minor.yy0 = yylhsminor.yy0;
27972805
break;
27982806
case 90: /* nth ::= LAST CLASSNAME */
2799
-#line 702 "pikchr.y"
2807
+#line 710 "pikchr.y"
28002808
{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.eCode = -1;}
2801
-#line 2826 "pikchr.c"
2809
+#line 2834 "pikchr.c"
28022810
break;
28032811
case 91: /* nth ::= LAST */
2804
-#line 703 "pikchr.y"
2812
+#line 711 "pikchr.y"
28052813
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -1;}
2806
-#line 2831 "pikchr.c"
2814
+#line 2839 "pikchr.c"
28072815
yymsp[0].minor.yy0 = yylhsminor.yy0;
28082816
break;
28092817
case 92: /* nth ::= NTH LB RB */
2810
-#line 704 "pikchr.y"
2818
+#line 712 "pikchr.y"
28112819
{yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-2].minor.yy0);}
2812
-#line 2837 "pikchr.c"
2820
+#line 2845 "pikchr.c"
28132821
yymsp[-2].minor.yy0 = yylhsminor.yy0;
28142822
break;
28152823
case 93: /* nth ::= NTH LAST LB RB */
2816
-#line 705 "pikchr.y"
2824
+#line 713 "pikchr.y"
28172825
{yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-3].minor.yy0);}
2818
-#line 2843 "pikchr.c"
2826
+#line 2851 "pikchr.c"
28192827
yymsp[-3].minor.yy0 = yylhsminor.yy0;
28202828
break;
28212829
case 94: /* nth ::= LAST LB RB */
2822
-#line 706 "pikchr.y"
2830
+#line 714 "pikchr.y"
28232831
{yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; }
2824
-#line 2849 "pikchr.c"
2832
+#line 2857 "pikchr.c"
28252833
break;
28262834
case 95: /* expr ::= expr PLUS expr */
2827
-#line 708 "pikchr.y"
2835
+#line 716 "pikchr.y"
28282836
{yylhsminor.yy73=yymsp[-2].minor.yy73+yymsp[0].minor.yy73;}
2829
-#line 2854 "pikchr.c"
2837
+#line 2862 "pikchr.c"
28302838
yymsp[-2].minor.yy73 = yylhsminor.yy73;
28312839
break;
28322840
case 96: /* expr ::= expr MINUS expr */
2833
-#line 709 "pikchr.y"
2841
+#line 717 "pikchr.y"
28342842
{yylhsminor.yy73=yymsp[-2].minor.yy73-yymsp[0].minor.yy73;}
2835
-#line 2860 "pikchr.c"
2843
+#line 2868 "pikchr.c"
28362844
yymsp[-2].minor.yy73 = yylhsminor.yy73;
28372845
break;
28382846
case 97: /* expr ::= expr STAR expr */
2839
-#line 710 "pikchr.y"
2847
+#line 718 "pikchr.y"
28402848
{yylhsminor.yy73=yymsp[-2].minor.yy73*yymsp[0].minor.yy73;}
2841
-#line 2866 "pikchr.c"
2849
+#line 2874 "pikchr.c"
28422850
yymsp[-2].minor.yy73 = yylhsminor.yy73;
28432851
break;
28442852
case 98: /* expr ::= expr SLASH expr */
2845
-#line 711 "pikchr.y"
2853
+#line 719 "pikchr.y"
28462854
{
28472855
if( yymsp[0].minor.yy73==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy73 = 0.0; }
28482856
else{ yylhsminor.yy73 = yymsp[-2].minor.yy73/yymsp[0].minor.yy73; }
28492857
}
2850
-#line 2875 "pikchr.c"
2858
+#line 2883 "pikchr.c"
28512859
yymsp[-2].minor.yy73 = yylhsminor.yy73;
28522860
break;
28532861
case 99: /* expr ::= MINUS expr */
2854
-#line 715 "pikchr.y"
2862
+#line 723 "pikchr.y"
28552863
{yymsp[-1].minor.yy73=-yymsp[0].minor.yy73;}
2856
-#line 2881 "pikchr.c"
2864
+#line 2889 "pikchr.c"
28572865
break;
28582866
case 100: /* expr ::= PLUS expr */
2859
-#line 716 "pikchr.y"
2867
+#line 724 "pikchr.y"
28602868
{yymsp[-1].minor.yy73=yymsp[0].minor.yy73;}
2861
-#line 2886 "pikchr.c"
2869
+#line 2894 "pikchr.c"
28622870
break;
28632871
case 101: /* expr ::= LP expr RP */
2864
-#line 717 "pikchr.y"
2872
+#line 725 "pikchr.y"
28652873
{yymsp[-2].minor.yy73=yymsp[-1].minor.yy73;}
2866
-#line 2891 "pikchr.c"
2874
+#line 2899 "pikchr.c"
28672875
break;
28682876
case 102: /* expr ::= NUMBER */
2869
-#line 718 "pikchr.y"
2877
+#line 726 "pikchr.y"
28702878
{yylhsminor.yy73=pik_atof(p,&yymsp[0].minor.yy0);}
2871
-#line 2896 "pikchr.c"
2879
+#line 2904 "pikchr.c"
28722880
yymsp[0].minor.yy73 = yylhsminor.yy73;
28732881
break;
28742882
case 103: /* expr ::= ID */
2875
-#line 719 "pikchr.y"
2883
+#line 727 "pikchr.y"
28762884
{yylhsminor.yy73=pik_get_var(p,&yymsp[0].minor.yy0);}
2877
-#line 2902 "pikchr.c"
2885
+#line 2910 "pikchr.c"
28782886
yymsp[0].minor.yy73 = yylhsminor.yy73;
28792887
break;
28802888
case 104: /* expr ::= FUNC1 LP expr RP */
2881
-#line 720 "pikchr.y"
2889
+#line 728 "pikchr.y"
28822890
{yylhsminor.yy73 = pik_func(p,&yymsp[-3].minor.yy0,yymsp[-1].minor.yy73,0.0);}
2883
-#line 2908 "pikchr.c"
2891
+#line 2916 "pikchr.c"
28842892
yymsp[-3].minor.yy73 = yylhsminor.yy73;
28852893
break;
28862894
case 105: /* expr ::= FUNC2 LP expr COMMA expr RP */
2887
-#line 721 "pikchr.y"
2895
+#line 729 "pikchr.y"
28882896
{yylhsminor.yy73 = pik_func(p,&yymsp[-5].minor.yy0,yymsp[-3].minor.yy73,yymsp[-1].minor.yy73);}
2889
-#line 2914 "pikchr.c"
2897
+#line 2922 "pikchr.c"
28902898
yymsp[-5].minor.yy73 = yylhsminor.yy73;
28912899
break;
28922900
case 106: /* expr ::= place2 DOT_XY X */
2893
-#line 722 "pikchr.y"
2901
+#line 730 "pikchr.y"
28942902
{yylhsminor.yy73 = yymsp[-2].minor.yy139.x;}
2895
-#line 2920 "pikchr.c"
2903
+#line 2928 "pikchr.c"
28962904
yymsp[-2].minor.yy73 = yylhsminor.yy73;
28972905
break;
28982906
case 107: /* expr ::= place2 DOT_XY Y */
2899
-#line 723 "pikchr.y"
2907
+#line 731 "pikchr.y"
29002908
{yylhsminor.yy73 = yymsp[-2].minor.yy139.y;}
2901
-#line 2926 "pikchr.c"
2909
+#line 2934 "pikchr.c"
29022910
yymsp[-2].minor.yy73 = yylhsminor.yy73;
29032911
break;
29042912
case 108: /* expr ::= object DOT_L numproperty */
29052913
case 109: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==109);
29062914
case 110: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==110);
2907
-#line 724 "pikchr.y"
2915
+#line 732 "pikchr.y"
29082916
{yylhsminor.yy73=pik_property_of(p,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
2909
-#line 2934 "pikchr.c"
2917
+#line 2942 "pikchr.c"
29102918
yymsp[-2].minor.yy73 = yylhsminor.yy73;
29112919
break;
29122920
default:
29132921
/* (111) lvalue ::= ID */ yytestcase(yyruleno==111);
29142922
/* (112) lvalue ::= FILL */ yytestcase(yyruleno==112);
@@ -3007,18 +3015,18 @@
30073015
){
30083016
pik_parserARG_FETCH
30093017
pik_parserCTX_FETCH
30103018
#define TOKEN yyminor
30113019
/************ Begin %syntax_error code ****************************************/
3012
-#line 491 "pikchr.y"
3020
+#line 499 "pikchr.y"
30133021
30143022
if( TOKEN.z && TOKEN.z[0] ){
30153023
pik_error(p, &TOKEN, "syntax error");
30163024
}else{
30173025
pik_error(p, 0, "syntax error");
30183026
}
3019
-#line 3044 "pikchr.c"
3027
+#line 3052 "pikchr.c"
30203028
/************ End %syntax_error code ******************************************/
30213029
pik_parserARG_STORE /* Suppress warning about unused %extra_argument variable */
30223030
pik_parserCTX_STORE
30233031
}
30243032
@@ -3247,11 +3255,11 @@
32473255
#else
32483256
(void)iToken;
32493257
return 0;
32503258
#endif
32513259
}
3252
-#line 729 "pikchr.y"
3260
+#line 737 "pikchr.y"
32533261
32543262
32553263
32563264
/* Chart of the 140 official HTML color names with their
32573265
** corresponding RGB value.
@@ -3855,11 +3863,11 @@
38553863
static void fileInit(Pik *p, PElem *pElem){
38563864
pElem->w = pik_value(p, "filewid",7,0);
38573865
pElem->h = pik_value(p, "fileht",6,0);
38583866
pElem->rad = pik_value(p, "filerad",7,0);
38593867
}
3860
-/* Return offset from the center of the box to the compass point
3868
+/* Return offset from the center of the file to the compass point
38613869
** given by parameter cp */
38623870
static PPoint fileOffset(Pik *p, PElem *pElem, int cp){
38633871
PPoint pt;
38643872
PNum w2 = 0.5*pElem->w;
38653873
PNum h2 = 0.5*pElem->h;
@@ -4004,11 +4012,11 @@
40044012
pElem->h = pik_value(p, "lineht",6,0);
40054013
pElem->rad = 1000;
40064014
pElem->fill = -1.0; /* Disable fill by default */
40074015
}
40084016
/* Return a point along the path from "f" to "t" that is r units
4009
-** prior to reach "t", except if the path is less than 2*r total,
4017
+** prior to reaching "t", except if the path is less than 2*r total,
40104018
** return the midpoint.
40114019
*/
40124020
static PPoint radiusMidpoint(PPoint f, PPoint t, PNum r, int *pbMid){
40134021
PNum dx = t.x - f.x;
40144022
PNum dy = t.y - f.y;
@@ -4368,11 +4376,11 @@
43684376
** * The space character is changed into non-breaking space (U+0080)
43694377
** if mFlags has the 0x01 bit set. This is needed when outputting
43704378
** text to preserve leading and trailing whitespace. Turns out we
43714379
** cannot use &nbsp; as that is an HTML-ism and is not valid in XML.
43724380
**
4373
-** * The "&" character is changed into "&amp;" if mFlags as the
4381
+** * The "&" character is changed into "&amp;" if mFlags has the
43744382
** 0x02 bit set. This is needed when generating error message text.
43754383
**
43764384
** * Except for the above, only "<" and ">" are escaped.
43774385
*/
43784386
static void pik_append_text(Pik *p, const char *zText, int n, int mFlags){
@@ -4484,11 +4492,11 @@
44844492
44854493
/* Append a style="..." text. But, leave the quote unterminated, in case
44864494
** the caller wants to add some more.
44874495
*/
44884496
static void pik_append_style(Pik *p, PElem *pElem){
4489
- pik_append(p, "style=\"", -1);
4497
+ pik_append(p, " style=\"", -1);
44904498
if( pElem->fill>=0 ){
44914499
pik_append_clr(p, "fill:", pElem->fill, ";");
44924500
}else{
44934501
pik_append(p,"fill:none;",-1);
44944502
}
@@ -4542,11 +4550,11 @@
45424550
aTxt[i].eCode = (aTxt[i].eCode & ~TP_VMASK) | TP_ABOVE2;
45434551
break;
45444552
}
45454553
}
45464554
}
4547
- /* If more than one TP_BELOW, change the last to TP_BELOW2 */
4555
+ /* If there is more than one TP_BELOW, change the last to TP_BELOW2 */
45484556
for(j=mJust=0, i=0; i<n; i++){
45494557
if( aTxt[i].eCode & TP_BELOW ){
45504558
if( j==0 ){
45514559
j++;
45524560
mJust = aTxt[i].eCode & TP_JMASK;
@@ -4585,20 +4593,17 @@
45854593
}
45864594
}
45874595
}
45884596
}
45894597
4590
-/* Append multiple <text> SGV element for the text fields of the PElem.
4598
+/* Append multiple <text> SVG element for the text fields of the PElem.
45914599
** Parameters:
45924600
**
45934601
** p The Pik object into which we are rendering
45944602
**
45954603
** pElem Object containing the text to be rendered
45964604
**
4597
-** jw LJUST text is shifted to the left by this amount.
4598
-** RJUST text is shifted to the right.
4599
-**
46004605
** pBox If not NULL, do no rendering at all. Instead
46014606
** expand the box object so that it will include all
46024607
** of the text.
46034608
*/
46044609
static void pik_append_txt(Pik *p, PElem *pElem, PBox *pBox){
@@ -4771,11 +4776,11 @@
47714776
47724777
/*
47734778
** Process an "assert( place1 == place2 )" statement. Always return NULL.
47744779
*/
47754780
static PElem *pik_place_assert(Pik *p, PPoint *e1, PToken *pEq, PPoint *e2){
4776
- char zE1[100], zE2[100], zMsg[200];
4781
+ char zE1[100], zE2[100], zMsg[210];
47774782
47784783
/* Convert the numbers to strings using %g for comparison. This
47794784
** limits the precision of the comparison to account for rounding error. */
47804785
snprintf(zE1, sizeof(zE1), "(%g,%g)", e1->x, e1->y); zE1[sizeof(zE1)-1] = 0;
47814786
snprintf(zE2, sizeof(zE2), "(%g,%g)", e2->x, e2->y); zE1[sizeof(zE2)-1] = 0;
@@ -4874,11 +4879,11 @@
48744879
if( pA->ne.x<pB->ne.x ) pA->ne.x = pB->ne.x;
48754880
if( pA->ne.y<pB->ne.y ) pA->ne.y = pB->ne.y;
48764881
}
48774882
48784883
/* Enlarge the PBox of the first argument, if necessary, so that
4879
-** it contains the PPoint in the second argument
4884
+** it contains the point described by the 2nd and 3rd arguments.
48804885
*/
48814886
static void pik_bbox_add_xy(PBox *pA, PNum x, PNum y){
48824887
if( pik_bbox_isempty(pA) ){
48834888
pA->ne.x = x;
48844889
pA->ne.y = y;
@@ -5189,11 +5194,11 @@
51895194
}
51905195
return;
51915196
}
51925197
51935198
/*
5194
-** Set a "dashed" property like "dash 0.05" or "chop"
5199
+** Set a "dashed" property like "dash 0.05"
51955200
**
51965201
** Use the value supplied by pVal if available. If pVal==0, use
51975202
** a default.
51985203
*/
51995204
void pik_set_dashed(Pik *p, PToken *pId, PNum *pVal){
@@ -5351,11 +5356,11 @@
53515356
53525357
/* Process a movement attribute of the form "right until even with ..."
53535358
**
53545359
** pDir is the first keyword, "right" or "left" or "up" or "down".
53555360
** The movement is in that direction until its closest approach to
5356
-** point specified by pPoint.
5361
+** the point specified by pPoint.
53575362
*/
53585363
static void pik_evenwith(Pik *p, PToken *pDir, PPoint *pPlace){
53595364
PElem *pElem = p->cur;
53605365
int n;
53615366
if( !pElem->type->isLine ){
@@ -5521,15 +5526,16 @@
55215526
else iRes = (iRes &~TP_SZMASK)|TP_SMALL; break;
55225527
}
55235528
return iRes;
55245529
}
55255530
5526
-/* Return an estimate of the actually number of displayed characters
5531
+/* Return an estimate of the actual number of displayed characters
55275532
** in a character string.
55285533
**
55295534
** Omit "\" used to escape characters. And count entities like
5530
-** "&lt;" as a single character.
5535
+** "&lt;" as a single character. Multi-byte UTF8 characters count
5536
+** as a single character.
55315537
*/
55325538
static int pik_text_length(const PToken *pToken){
55335539
int n = pToken->n;
55345540
const char *z = pToken->z;
55355541
int cnt, j;
@@ -5545,11 +5551,11 @@
55455551
}
55465552
}
55475553
return cnt;
55485554
}
55495555
5550
-/* Adjust the width, height, and or radius of the object so that
5556
+/* Adjust the width, height, and/or radius of the object so that
55515557
** it fits around the text that has been added so far.
55525558
**
55535559
** (1) Only text specified prior to this attribute is considered.
55545560
** (2) The text size is estimated based on the charht and charwid
55555561
** variable settings.
@@ -5856,12 +5862,12 @@
58565862
pik_error(p, pName, "no such object");
58575863
return 0;
58585864
}
58595865
58605866
/* Change most of the settings for the current object to be the
5861
-** same as the pElem object, or the most recent element of the same
5862
-** type if pElem is NULL.
5867
+** same as the pOther object, or the most recent element of the same
5868
+** type if pOther is NULL.
58635869
*/
58645870
static void pik_same(Pik *p, PElem *pOther, PToken *pErrTok){
58655871
PElem *pElem = p->cur;
58665872
if( p->nErr ) return;
58675873
if( pOther==0 ){
@@ -5947,11 +5953,11 @@
59475953
return out;
59485954
}
59495955
59505956
/* Compute the position that is dist away from pt at an heading angle of r
59515957
**
5952
-** The angle is compass heading in degrees. North is 0 (or 360).
5958
+** The angle is a compass heading in degrees. North is 0 (or 360).
59535959
** East is 90. South is 180. West is 270. And so forth.
59545960
*/
59555961
static PPoint pik_position_at_angle(Pik *p, PNum dist, PNum r, PPoint pt){
59565962
r *= 0.017453292519943295769; /* degrees to radians */
59575963
pt.x += dist*sin(r);
@@ -6366,10 +6372,23 @@
63666372
h = p->bbox.ne.y - p->bbox.sw.y;
63676373
p->wSVG = (int)(p->rScale*w);
63686374
p->hSVG = (int)(p->rScale*h);
63696375
pik_append_dis(p, " viewBox=\"0 0 ",w,"");
63706376
pik_append_dis(p, " ",h,"\">\n");
6377
+ if( (p->mFlags & PIKCHR_INCLUDE_SOURCE)!=0 ){
6378
+ /* emit original pikchr source code as metadata */
6379
+ /* FIXME: emit this only if a certain p->mFlags is set. */
6380
+ pik_append(p, "<metadata>\n", 11);
6381
+ pik_append(p, "<pikchr:pikchr xmlns:pikchr="
6382
+ "\"https://pikchr.org/home/doc/trunk/doc/grammar.md\">\n",
6383
+ -1);
6384
+ pik_append(p, "<pikchr:src><![CDATA[", 21);
6385
+ pik_append(p, p->zIn, (int)p->nIn);
6386
+ pik_append(p, "]]></pikchr:src>\n", 17);
6387
+ pik_append(p, "</pikchr:pikchr>\n", 17);
6388
+ pik_append(p, "</metadata>\n", 12);
6389
+ }
63716390
pik_elist_render(p, pEList);
63726391
pik_append(p,"</svg>\n", -1);
63736392
}else{
63746393
p->wSVG = -1;
63756394
p->hSVG = -1;
@@ -6482,11 +6501,11 @@
64826501
{ "x", 1, T_X, 0, 0 },
64836502
{ "y", 1, T_Y, 0, 0 },
64846503
};
64856504
64866505
/*
6487
-** Search a PikWordlist for the given keyword. A pointer to the
6506
+** Search a PikWordlist for the given keyword. Return a pointer to the
64886507
** element found. Or return 0 if not found.
64896508
*/
64906509
static const PikWord *pik_find_word(
64916510
const char *zIn, /* Word to search for */
64926511
int n, /* Length of zIn */
@@ -6809,11 +6828,11 @@
68096828
** Parse the PIKCHR script contained in zText[]. Return a rendering. Or
68106829
** if an error is encountered, return the error text. The error message
68116830
** is HTML formatted. So regardless of what happens, the return text
68126831
** is safe to be insertd into an HTML output stream.
68136832
**
6814
-** If pnWidth and pnHeight are NULL, then this routine writes the
6833
+** If pnWidth and pnHeight are not NULL, then this routine writes the
68156834
** width and height of the <SVG> object into the integers that they
68166835
** point to. A value of -1 is written if an error is seen.
68176836
**
68186837
** If zClass is not NULL, then it is a class name to be included in
68196838
** the <SVG> markup.
@@ -6837,10 +6856,11 @@
68376856
memset(&s, 0, sizeof(s));
68386857
s.zIn = zText;
68396858
s.nIn = (unsigned int)strlen(zText);
68406859
s.eDir = DIR_RIGHT;
68416860
s.zClass = zClass;
6861
+ s.mFlags = mFlags;
68426862
pik_parserInit(&sParse, &s);
68436863
#if 0
68446864
pik_parserTrace(stdout, "parser: ");
68456865
#endif
68466866
for(i=0; zText[i] && s.nErr==0; i+=sz){
@@ -6911,11 +6931,12 @@
69116931
** input text and the rendered SVG for all files named on the command
69126932
** line.
69136933
*/
69146934
int main(int argc, char **argv){
69156935
int i;
6916
- int bNoEcho = 0; /* Do not the text of the script */
6936
+ int bNoEcho = 0; /* Do not the text of the script */
6937
+ int mPikchrFlags = 0; /* Flags passed into pikchr() */
69176938
printf(
69186939
"<!DOCTYPE html>\n"
69196940
"<html lang=\"en-US\">\n"
69206941
"<head>\n<title>PIKCHR Test</title>\n"
69216942
"<meta charset=\"utf-8\">\n"
@@ -6936,10 +6957,13 @@
69366957
z++;
69376958
if( z[0]=='-' ) z++;
69386959
if( strcmp(z,"no-echo")==0 ){
69396960
bNoEcho = 1;
69406961
}else
6962
+ if( strcmp(z,"include-source")==0 ){
6963
+ mPikchrFlags |= PIKCHR_INCLUDE_SOURCE;
6964
+ }else
69416965
{
69426966
fprintf(stderr,"unknown option: \"%s\"\n", argv[i]);
69436967
exit(1);
69446968
}
69456969
continue;
@@ -6980,11 +7004,11 @@
69807004
break;
69817005
}
69827006
}
69837007
printf("</pre></blockquote>\n");
69847008
}
6985
- zOut = pikchr(zIn, "pikchr", 0, &w, &h);
7009
+ zOut = pikchr(zIn, "pikchr", mPikchrFlags, &w, &h);
69867010
free(zIn);
69877011
if( zOut ){
69887012
if( w<0 ){
69897013
printf("<p>ERROR:</p>\n");
69907014
}else if( bNoEcho==0 ){
@@ -6999,6 +7023,6 @@
69997023
printf("</body></html>\n");
70007024
return 0;
70017025
}
70027026
#endif /* PIKCHR_SHELL */
70037027
7004
-#line 7029 "pikchr.c"
7028
+#line 7053 "pikchr.c"
70057029
--- src/pikchr.c
+++ src/pikchr.c
@@ -29,11 +29,11 @@
29 ** of PIKCHR language text and generates a second string of SVG output that
30 ** renders the drawing defined by the input. Space to hold the returned
31 ** string is obtained from malloc() and should be freed by the caller.
32 ** NULL might be returned if there is a memory allocation error.
33 **
34 ** If there are error in the PIKCHR input, the output will consist of an
35 ** error message and the original PIKCHR input text (inside of <pre>...</pre>).
36 **
37 ** The subroutine implemented by this file is intended to be stand-alone.
38 ** It uses no external routines other than routines commonly found in
39 ** the standard C library.
@@ -72,11 +72,11 @@
72 **
73 ** The input is a sequence of objects or "elements". Each element is
74 ** parsed into a PElem object. These are stored on an extensible array
75 ** called PEList. All parameters to each PElem are computed as the
76 ** object is parsed. (Hence, the parameters to a PElem may only refer
77 ** to prior elements.) Once the PElem is completely assemblied, it is
78 ** added to the end of a PEList and never changes thereafter - except,
79 ** PElem objects that are part of a "[...]" block might have their
80 ** absolute position shifted when the outer [...] block is positioned.
81 ** But apart from this repositioning, PElem objects are unchanged once
82 ** they are added to the list. The order of elements on a PEList does
@@ -90,12 +90,12 @@
90 **
91 ** Each PElem is on a "layer". (The common case is that all PElem's are
92 ** on a single layer, but multiple layers are possible.) A separate pass
93 ** is made through the list for each layer.
94 **
95 ** After all output is generated, the Pik object, and the all the PEList
96 ** and PElem objects are deallocated and the generate output string is
97 ** returned. Upon any error, the Pik.nErr flag is set, processing quickly
98 ** stops, and the stack unwinds. No attempt is made to continue reading
99 ** input after an error.
100 **
101 ** Most elements begin with a class name like "box" or "arrow" or "move".
@@ -105,18 +105,18 @@
105 ** its subelements, all gathered onto a separate PEList object.
106 **
107 ** Variables go into PVar objects that form a linked list.
108 **
109 ** Each PElem has zero or one names. Input constructs that attempt
110 ** to assign a new name from an older name, like:
111 **
112 ** Abc: Abc + (0.5cm, 0)
113 **
114 ** These generate a new "noop" object at the specified place and with
115 ** the specified name. As place-names are searched by scanning the list
116 ** in reverse order, this has the effect of overriding the "Abc" name
117 ** when referenced by subsequent objects.
118 */
119 #include <stdio.h>
120 #include <stdlib.h>
121 #include <string.h>
122 #include <ctype.h>
@@ -235,12 +235,12 @@
235 short int eCode; /* Auxiliary code */
236 unsigned char eType; /* The numeric parser code */
237 unsigned char eEdge; /* Corner value for corner keywords */
238 };
239
240 /* Return negative, zero, or positive if pToken is less then, equal to
241 ** or greater than zero-terminated string z[]
242 */
243 static int pik_token_eq(PToken *pToken, const char *z){
244 int c = strncmp(pToken->z,z,pToken->n);
245 if( c==0 && z[pToken->n]!=0 ) c = -1;
246 return c;
@@ -260,11 +260,11 @@
260 #define ValidDir(X) ((X)>=0 && (X)<=3)
261 #define IsUpDown(X) (((X)&1)==1)
262 #define IsLeftRight(X) (((X)&1)==0)
263
264 /* Bitmask for the various attributes for PElem. These bits are
265 ** collected in PElem.mProp and PElem.mCalc to check for contraint
266 ** errors. */
267 #define A_WIDTH 0x000001
268 #define A_HEIGHT 0x000002
269 #define A_RADIUS 0x000004
270 #define A_THICKNESS 0x000008
@@ -288,27 +288,23 @@
288 PToken errTok; /* Reference token for error messages */
289 PPoint ptAt; /* Reference point for the object */
290 PPoint ptEnter, ptExit; /* Entry and exit points */
291 PEList *pSublist; /* Substructure for [...] elements */
292 char *zName; /* Name assigned to this element */
293 PNum w; /* width */
294 PNum h; /* height */
295 PNum rad; /* radius */
296 PNum sw; /* stroke width ("thinkness") */
297 PNum dotted; /* dotted: <=0.0 for off */
298 PNum dashed; /* dashed: <=0.0 for off */
299 PNum fill; /* fill color. Negative for off */
300 PNum color; /* Stroke color */
301 PNum top; /* Top edge */
302 PNum bottom; /* Bottom edge */
303 PNum left; /* Left edge */
304 PNum right; /* Right edge */
305 PPoint with; /* Position constraint from WITH clause */
306 char eWith; /* Type of heading point on WITH clause */
307 char cw; /* True for clockwise arc */
308 char larrow; /* Arrow at beginning */
309 char rarrow; /* Arrow at end */
310 char bClose; /* True if "close" is seen */
311 char bChop; /* True if "chop" is seen */
312 unsigned char nTxt; /* Number of text values */
313 unsigned mProp; /* Masks of properties set so far */
314 unsigned mCalc; /* Values computed from other constraints */
@@ -336,10 +332,11 @@
336 unsigned int nIn; /* Number of bytes in zIn */
337 char *zOut; /* Result accumulates here */
338 unsigned int nOut; /* Bytes written to zOut[] so far */
339 unsigned int nOutAlloc; /* Space allocated to zOut[] */
340 unsigned char eDir; /* Current direction */
 
341 PElem *cur; /* Element under construction */
342 PEList *list; /* Element list under construction */
343 PVar *pVar; /* Application-defined variables */
344 PBox bbox; /* Bounding box around all elements */
345 /* Cache of layout values. <=0.0 for unknown... */
@@ -358,13 +355,24 @@
358 int nTPath; /* Number of entries on aTPath[] */
359 int mTPath; /* For last entry, 1: x set, 2: y set */
360 PPoint aTPath[1000]; /* Path under construction */
361 };
362
 
 
 
 
 
 
 
 
 
 
 
363 /*
364 ** The behavior of an object class is defined by an instance of
365 ** this structure. This it the "virtual method" table.
366 */
367 struct PClass {
368 const char *zName; /* Name of class */
369 char isLine; /* True if a line class */
370 char eJust; /* Use box-style text justification */
@@ -445,11 +453,11 @@
445 static void pik_behind(Pik*,PElem*);
446 static PElem *pik_assert(Pik*,PNum,PToken*,PNum);
447 static PElem *pik_place_assert(Pik*,PPoint*,PToken*,PPoint*);
448
449
450 #line 476 "pikchr.c"
451 /**************** End of %include directives **********************************/
452 /* These constants specify the various numeric values for terminal symbols.
453 ***************** Begin token definitions *************************************/
454 #ifndef T_ID
455 #define T_ID 1
@@ -1621,22 +1629,22 @@
1621 ** inside the C code.
1622 */
1623 /********* Begin destructor definitions ***************************************/
1624 case 94: /* element_list */
1625 {
1626 #line 465 "pikchr.y"
1627 pik_elist_free(p,(yypminor->yy72));
1628 #line 1653 "pikchr.c"
1629 }
1630 break;
1631 case 95: /* element */
1632 case 96: /* unnamed_element */
1633 case 97: /* basetype */
1634 {
1635 #line 467 "pikchr.y"
1636 pik_elem_free(p,(yypminor->yy254));
1637 #line 1662 "pikchr.c"
1638 }
1639 break;
1640 /********* End destructor definitions *****************************************/
1641 default: break; /* If no destructor action specified: do nothing */
1642 }
@@ -1850,14 +1858,14 @@
1850 #endif
1851 while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
1852 /* Here code is inserted which will execute if the parser
1853 ** stack every overflows */
1854 /******** Begin %stack_overflow code ******************************************/
1855 #line 498 "pikchr.y"
1856
1857 pik_error(p, 0, "parser stack overflow");
1858 #line 1883 "pikchr.c"
1859 /******** End %stack_overflow code ********************************************/
1860 pik_parserARG_STORE /* Suppress warning about unused %extra_argument var */
1861 pik_parserCTX_STORE
1862 }
1863
@@ -2322,593 +2330,593 @@
2322 ** break;
2323 */
2324 /********** Begin reduce actions **********************************************/
2325 YYMINORTYPE yylhsminor;
2326 case 0: /* document ::= element_list */
2327 #line 502 "pikchr.y"
2328 {pik_render(p,yymsp[0].minor.yy72);}
2329 #line 2354 "pikchr.c"
2330 break;
2331 case 1: /* element_list ::= element */
2332 #line 505 "pikchr.y"
2333 { yylhsminor.yy72 = pik_elist_append(p,0,yymsp[0].minor.yy254); }
2334 #line 2359 "pikchr.c"
2335 yymsp[0].minor.yy72 = yylhsminor.yy72;
2336 break;
2337 case 2: /* element_list ::= element_list EOL element */
2338 #line 507 "pikchr.y"
2339 { yylhsminor.yy72 = pik_elist_append(p,yymsp[-2].minor.yy72,yymsp[0].minor.yy254); }
2340 #line 2365 "pikchr.c"
2341 yymsp[-2].minor.yy72 = yylhsminor.yy72;
2342 break;
2343 case 3: /* element ::= */
2344 #line 510 "pikchr.y"
2345 { yymsp[1].minor.yy254 = 0; }
2346 #line 2371 "pikchr.c"
2347 break;
2348 case 4: /* element ::= direction */
2349 #line 511 "pikchr.y"
2350 { pik_set_direction(p,yymsp[0].minor.yy0.eCode); yylhsminor.yy254=0; }
2351 #line 2376 "pikchr.c"
2352 yymsp[0].minor.yy254 = yylhsminor.yy254;
2353 break;
2354 case 5: /* element ::= lvalue ASSIGN rvalue */
2355 #line 512 "pikchr.y"
2356 {pik_set_var(p,&yymsp[-2].minor.yy0,yymsp[0].minor.yy73,&yymsp[-1].minor.yy0); yylhsminor.yy254=0;}
2357 #line 2382 "pikchr.c"
2358 yymsp[-2].minor.yy254 = yylhsminor.yy254;
2359 break;
2360 case 6: /* element ::= PLACENAME COLON unnamed_element */
2361 #line 514 "pikchr.y"
2362 { yylhsminor.yy254 = yymsp[0].minor.yy254; pik_elem_setname(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0); }
2363 #line 2388 "pikchr.c"
2364 yymsp[-2].minor.yy254 = yylhsminor.yy254;
2365 break;
2366 case 7: /* element ::= PLACENAME COLON position */
2367 #line 516 "pikchr.y"
2368 { yylhsminor.yy254 = pik_elem_new(p,0,0,0);
2369 if(yylhsminor.yy254){ yylhsminor.yy254->ptAt = yymsp[0].minor.yy139; pik_elem_setname(p,yylhsminor.yy254,&yymsp[-2].minor.yy0); }}
2370 #line 2395 "pikchr.c"
2371 yymsp[-2].minor.yy254 = yylhsminor.yy254;
2372 break;
2373 case 8: /* element ::= unnamed_element */
2374 #line 518 "pikchr.y"
2375 {yylhsminor.yy254 = yymsp[0].minor.yy254;}
2376 #line 2401 "pikchr.c"
2377 yymsp[0].minor.yy254 = yylhsminor.yy254;
2378 break;
2379 case 9: /* element ::= print prlist */
2380 #line 519 "pikchr.y"
2381 {pik_append(p,"<br>\n",5); yymsp[-1].minor.yy254=0;}
2382 #line 2407 "pikchr.c"
2383 break;
2384 case 10: /* element ::= ASSERT LP expr EQ expr RP */
2385 #line 524 "pikchr.y"
2386 {yymsp[-5].minor.yy254=pik_assert(p,yymsp[-3].minor.yy73,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy73);}
2387 #line 2412 "pikchr.c"
2388 break;
2389 case 11: /* element ::= ASSERT LP place EQ place RP */
2390 #line 526 "pikchr.y"
2391 {yymsp[-5].minor.yy254=pik_place_assert(p,&yymsp[-3].minor.yy139,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy139);}
2392 #line 2417 "pikchr.c"
2393 break;
2394 case 12: /* rvalue ::= PLACENAME */
2395 #line 537 "pikchr.y"
2396 {yylhsminor.yy73 = pik_lookup_color(p,&yymsp[0].minor.yy0);}
2397 #line 2422 "pikchr.c"
2398 yymsp[0].minor.yy73 = yylhsminor.yy73;
2399 break;
2400 case 13: /* pritem ::= FILL */
2401 case 14: /* pritem ::= COLOR */ yytestcase(yyruleno==14);
2402 case 15: /* pritem ::= THICKNESS */ yytestcase(yyruleno==15);
2403 #line 542 "pikchr.y"
2404 {pik_append_num(p,"",pik_value(p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.n,0));}
2405 #line 2430 "pikchr.c"
2406 break;
2407 case 16: /* pritem ::= rvalue */
2408 #line 545 "pikchr.y"
2409 {pik_append_num(p,"",yymsp[0].minor.yy73);}
2410 #line 2435 "pikchr.c"
2411 break;
2412 case 17: /* pritem ::= STRING */
2413 #line 546 "pikchr.y"
2414 {pik_append_text(p,yymsp[0].minor.yy0.z+1,yymsp[0].minor.yy0.n-2,0);}
2415 #line 2440 "pikchr.c"
2416 break;
2417 case 18: /* prsep ::= COMMA */
2418 #line 547 "pikchr.y"
2419 {pik_append(p, " ", 1);}
2420 #line 2445 "pikchr.c"
2421 break;
2422 case 19: /* unnamed_element ::= basetype attribute_list */
2423 #line 550 "pikchr.y"
2424 {yylhsminor.yy254 = yymsp[-1].minor.yy254; pik_after_adding_attributes(p,yylhsminor.yy254);}
2425 #line 2450 "pikchr.c"
2426 yymsp[-1].minor.yy254 = yylhsminor.yy254;
2427 break;
2428 case 20: /* basetype ::= CLASSNAME */
2429 #line 552 "pikchr.y"
2430 {yylhsminor.yy254 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); }
2431 #line 2456 "pikchr.c"
2432 yymsp[0].minor.yy254 = yylhsminor.yy254;
2433 break;
2434 case 21: /* basetype ::= STRING textposition */
2435 #line 554 "pikchr.y"
2436 {yymsp[-1].minor.yy0.eCode = yymsp[0].minor.yy74; yylhsminor.yy254 = pik_elem_new(p,0,&yymsp[-1].minor.yy0,0); }
2437 #line 2462 "pikchr.c"
2438 yymsp[-1].minor.yy254 = yylhsminor.yy254;
2439 break;
2440 case 22: /* basetype ::= LB savelist element_list RB */
2441 #line 556 "pikchr.y"
2442 { p->list = yymsp[-2].minor.yy72; yymsp[-3].minor.yy254 = pik_elem_new(p,0,0,yymsp[-1].minor.yy72); if(yymsp[-3].minor.yy254) yymsp[-3].minor.yy254->errTok = yymsp[0].minor.yy0; }
2443 #line 2468 "pikchr.c"
2444 break;
2445 case 23: /* savelist ::= */
2446 #line 561 "pikchr.y"
2447 {yymsp[1].minor.yy72 = p->list; p->list = 0;}
2448 #line 2473 "pikchr.c"
2449 break;
2450 case 24: /* relexpr ::= expr */
2451 #line 568 "pikchr.y"
2452 {yylhsminor.yy60.rAbs = yymsp[0].minor.yy73; yylhsminor.yy60.rRel = 0;}
2453 #line 2478 "pikchr.c"
2454 yymsp[0].minor.yy60 = yylhsminor.yy60;
2455 break;
2456 case 25: /* relexpr ::= expr PERCENT */
2457 #line 569 "pikchr.y"
2458 {yylhsminor.yy60.rAbs = 0; yylhsminor.yy60.rRel = yymsp[-1].minor.yy73/100;}
2459 #line 2484 "pikchr.c"
2460 yymsp[-1].minor.yy60 = yylhsminor.yy60;
2461 break;
2462 case 26: /* optrelexpr ::= */
2463 #line 571 "pikchr.y"
2464 {yymsp[1].minor.yy60.rAbs = 0; yymsp[1].minor.yy60.rRel = 1.0;}
2465 #line 2490 "pikchr.c"
2466 break;
2467 case 27: /* attribute_list ::= relexpr alist */
2468 #line 573 "pikchr.y"
2469 {pik_add_direction(p,0,&yymsp[-1].minor.yy60);}
2470 #line 2495 "pikchr.c"
2471 break;
2472 case 28: /* attribute ::= numproperty relexpr */
2473 #line 577 "pikchr.y"
2474 { pik_set_numprop(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy60); }
2475 #line 2500 "pikchr.c"
2476 break;
2477 case 29: /* attribute ::= dashproperty expr */
2478 #line 578 "pikchr.y"
2479 { pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy73); }
2480 #line 2505 "pikchr.c"
2481 break;
2482 case 30: /* attribute ::= dashproperty */
2483 #line 579 "pikchr.y"
2484 { pik_set_dashed(p,&yymsp[0].minor.yy0,0); }
2485 #line 2510 "pikchr.c"
2486 break;
2487 case 31: /* attribute ::= colorproperty rvalue */
2488 #line 580 "pikchr.y"
2489 { pik_set_clrprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy73); }
2490 #line 2515 "pikchr.c"
2491 break;
2492 case 32: /* attribute ::= go direction optrelexpr */
2493 #line 581 "pikchr.y"
2494 { pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy60);}
2495 #line 2520 "pikchr.c"
2496 break;
2497 case 33: /* attribute ::= go direction even position */
2498 #line 582 "pikchr.y"
2499 {pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy139);}
2500 #line 2525 "pikchr.c"
2501 break;
2502 case 34: /* attribute ::= CLOSE */
2503 #line 583 "pikchr.y"
2504 { pik_close_path(p,&yymsp[0].minor.yy0); }
2505 #line 2530 "pikchr.c"
2506 break;
2507 case 35: /* attribute ::= CHOP */
2508 #line 584 "pikchr.y"
2509 { p->cur->bChop = 1; }
2510 #line 2535 "pikchr.c"
2511 break;
2512 case 36: /* attribute ::= FROM position */
2513 #line 585 "pikchr.y"
2514 { pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy139); }
2515 #line 2540 "pikchr.c"
2516 break;
2517 case 37: /* attribute ::= TO position */
2518 #line 586 "pikchr.y"
2519 { pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy139); }
2520 #line 2545 "pikchr.c"
2521 break;
2522 case 38: /* attribute ::= THEN */
2523 #line 587 "pikchr.y"
2524 { pik_then(p, &yymsp[0].minor.yy0, p->cur); }
2525 #line 2550 "pikchr.c"
2526 break;
2527 case 39: /* attribute ::= THEN optrelexpr HEADING expr */
2528 case 41: /* attribute ::= GO optrelexpr HEADING expr */ yytestcase(yyruleno==41);
2529 #line 589 "pikchr.y"
2530 {pik_move_hdg(p,&yymsp[-2].minor.yy60,&yymsp[-1].minor.yy0,yymsp[0].minor.yy73,0,&yymsp[-3].minor.yy0);}
2531 #line 2556 "pikchr.c"
2532 break;
2533 case 40: /* attribute ::= THEN optrelexpr EDGEPT */
2534 case 42: /* attribute ::= GO optrelexpr EDGEPT */ yytestcase(yyruleno==42);
2535 #line 590 "pikchr.y"
2536 {pik_move_hdg(p,&yymsp[-1].minor.yy60,0,0,&yymsp[0].minor.yy0,&yymsp[-2].minor.yy0);}
2537 #line 2562 "pikchr.c"
2538 break;
2539 case 43: /* attribute ::= AT position */
2540 #line 595 "pikchr.y"
2541 { pik_set_at(p,0,&yymsp[0].minor.yy139,&yymsp[-1].minor.yy0); }
2542 #line 2567 "pikchr.c"
2543 break;
2544 case 44: /* attribute ::= SAME */
2545 #line 597 "pikchr.y"
2546 {pik_same(p,0,&yymsp[0].minor.yy0);}
2547 #line 2572 "pikchr.c"
2548 break;
2549 case 45: /* attribute ::= SAME AS object */
2550 #line 598 "pikchr.y"
2551 {pik_same(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0);}
2552 #line 2577 "pikchr.c"
2553 break;
2554 case 46: /* attribute ::= STRING textposition */
2555 #line 599 "pikchr.y"
2556 {pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy74);}
2557 #line 2582 "pikchr.c"
2558 break;
2559 case 47: /* attribute ::= FIT */
2560 #line 600 "pikchr.y"
2561 {pik_size_to_fit(p,&yymsp[0].minor.yy0); }
2562 #line 2587 "pikchr.c"
2563 break;
2564 case 48: /* attribute ::= BEHIND object */
2565 #line 601 "pikchr.y"
2566 {pik_behind(p,yymsp[0].minor.yy254);}
2567 #line 2592 "pikchr.c"
2568 break;
2569 case 49: /* withclause ::= DOT_E edge AT position */
2570 case 50: /* withclause ::= edge AT position */ yytestcase(yyruleno==50);
2571 #line 609 "pikchr.y"
2572 { pik_set_at(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy139,&yymsp[-1].minor.yy0); }
2573 #line 2598 "pikchr.c"
2574 break;
2575 case 51: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2576 #line 613 "pikchr.y"
2577 {yylhsminor.yy0 = yymsp[0].minor.yy0;}
2578 #line 2603 "pikchr.c"
2579 yymsp[0].minor.yy0 = yylhsminor.yy0;
2580 break;
2581 case 52: /* boolproperty ::= CW */
2582 #line 624 "pikchr.y"
2583 {p->cur->cw = 1;}
2584 #line 2609 "pikchr.c"
2585 break;
2586 case 53: /* boolproperty ::= CCW */
2587 #line 625 "pikchr.y"
2588 {p->cur->cw = 0;}
2589 #line 2614 "pikchr.c"
2590 break;
2591 case 54: /* boolproperty ::= LARROW */
2592 #line 626 "pikchr.y"
2593 {p->cur->larrow=1; p->cur->rarrow=0; }
2594 #line 2619 "pikchr.c"
2595 break;
2596 case 55: /* boolproperty ::= RARROW */
2597 #line 627 "pikchr.y"
2598 {p->cur->larrow=0; p->cur->rarrow=1; }
2599 #line 2624 "pikchr.c"
2600 break;
2601 case 56: /* boolproperty ::= LRARROW */
2602 #line 628 "pikchr.y"
2603 {p->cur->larrow=1; p->cur->rarrow=1; }
2604 #line 2629 "pikchr.c"
2605 break;
2606 case 57: /* boolproperty ::= INVIS */
2607 #line 629 "pikchr.y"
2608 {p->cur->sw = 0.0;}
2609 #line 2634 "pikchr.c"
2610 break;
2611 case 58: /* boolproperty ::= THICK */
2612 #line 630 "pikchr.y"
2613 {p->cur->sw *= 1.5;}
2614 #line 2639 "pikchr.c"
2615 break;
2616 case 59: /* boolproperty ::= THIN */
2617 #line 631 "pikchr.y"
2618 {p->cur->sw *= 0.67;}
2619 #line 2644 "pikchr.c"
2620 break;
2621 case 60: /* textposition ::= */
2622 #line 633 "pikchr.y"
2623 {yymsp[1].minor.yy74 = 0;}
2624 #line 2649 "pikchr.c"
2625 break;
2626 case 61: /* textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL */
2627 #line 636 "pikchr.y"
2628 {yylhsminor.yy74 = pik_text_position(p,yymsp[-1].minor.yy74,&yymsp[0].minor.yy0);}
2629 #line 2654 "pikchr.c"
2630 yymsp[-1].minor.yy74 = yylhsminor.yy74;
2631 break;
2632 case 62: /* position ::= expr COMMA expr */
2633 #line 639 "pikchr.y"
2634 {yylhsminor.yy139.x=yymsp[-2].minor.yy73; yylhsminor.yy139.y=yymsp[0].minor.yy73;}
2635 #line 2660 "pikchr.c"
2636 yymsp[-2].minor.yy139 = yylhsminor.yy139;
2637 break;
2638 case 63: /* position ::= place PLUS expr COMMA expr */
2639 #line 641 "pikchr.y"
2640 {yylhsminor.yy139.x=yymsp[-4].minor.yy139.x+yymsp[-2].minor.yy73; yylhsminor.yy139.y=yymsp[-4].minor.yy139.y+yymsp[0].minor.yy73;}
2641 #line 2666 "pikchr.c"
2642 yymsp[-4].minor.yy139 = yylhsminor.yy139;
2643 break;
2644 case 64: /* position ::= place MINUS expr COMMA expr */
2645 #line 642 "pikchr.y"
2646 {yylhsminor.yy139.x=yymsp[-4].minor.yy139.x-yymsp[-2].minor.yy73; yylhsminor.yy139.y=yymsp[-4].minor.yy139.y-yymsp[0].minor.yy73;}
2647 #line 2672 "pikchr.c"
2648 yymsp[-4].minor.yy139 = yylhsminor.yy139;
2649 break;
2650 case 65: /* position ::= place PLUS LP expr COMMA expr RP */
2651 #line 644 "pikchr.y"
2652 {yylhsminor.yy139.x=yymsp[-6].minor.yy139.x+yymsp[-3].minor.yy73; yylhsminor.yy139.y=yymsp[-6].minor.yy139.y+yymsp[-1].minor.yy73;}
2653 #line 2678 "pikchr.c"
2654 yymsp[-6].minor.yy139 = yylhsminor.yy139;
2655 break;
2656 case 66: /* position ::= place MINUS LP expr COMMA expr RP */
2657 #line 646 "pikchr.y"
2658 {yylhsminor.yy139.x=yymsp[-6].minor.yy139.x-yymsp[-3].minor.yy73; yylhsminor.yy139.y=yymsp[-6].minor.yy139.y-yymsp[-1].minor.yy73;}
2659 #line 2684 "pikchr.c"
2660 yymsp[-6].minor.yy139 = yylhsminor.yy139;
2661 break;
2662 case 67: /* position ::= LP position COMMA position RP */
2663 #line 647 "pikchr.y"
2664 {yymsp[-4].minor.yy139.x=yymsp[-3].minor.yy139.x; yymsp[-4].minor.yy139.y=yymsp[-1].minor.yy139.y;}
2665 #line 2690 "pikchr.c"
2666 break;
2667 case 68: /* position ::= LP position RP */
2668 #line 648 "pikchr.y"
2669 {yymsp[-2].minor.yy139=yymsp[-1].minor.yy139;}
2670 #line 2695 "pikchr.c"
2671 break;
2672 case 69: /* position ::= expr between position AND position */
2673 #line 650 "pikchr.y"
2674 {yylhsminor.yy139 = pik_position_between(p,yymsp[-4].minor.yy73,yymsp[-2].minor.yy139,yymsp[0].minor.yy139);}
2675 #line 2700 "pikchr.c"
2676 yymsp[-4].minor.yy139 = yylhsminor.yy139;
2677 break;
2678 case 70: /* position ::= expr LT position COMMA position GT */
2679 #line 652 "pikchr.y"
2680 {yylhsminor.yy139 = pik_position_between(p,yymsp[-5].minor.yy73,yymsp[-3].minor.yy139,yymsp[-1].minor.yy139);}
2681 #line 2706 "pikchr.c"
2682 yymsp[-5].minor.yy139 = yylhsminor.yy139;
2683 break;
2684 case 71: /* position ::= expr ABOVE position */
2685 #line 653 "pikchr.y"
2686 {yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.y += yymsp[-2].minor.yy73;}
2687 #line 2712 "pikchr.c"
2688 yymsp[-2].minor.yy139 = yylhsminor.yy139;
2689 break;
2690 case 72: /* position ::= expr BELOW position */
2691 #line 654 "pikchr.y"
2692 {yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.y -= yymsp[-2].minor.yy73;}
2693 #line 2718 "pikchr.c"
2694 yymsp[-2].minor.yy139 = yylhsminor.yy139;
2695 break;
2696 case 73: /* position ::= expr LEFT OF position */
2697 #line 655 "pikchr.y"
2698 {yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.x -= yymsp[-3].minor.yy73;}
2699 #line 2724 "pikchr.c"
2700 yymsp[-3].minor.yy139 = yylhsminor.yy139;
2701 break;
2702 case 74: /* position ::= expr RIGHT OF position */
2703 #line 656 "pikchr.y"
2704 {yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.x += yymsp[-3].minor.yy73;}
2705 #line 2730 "pikchr.c"
2706 yymsp[-3].minor.yy139 = yylhsminor.yy139;
2707 break;
2708 case 75: /* position ::= expr ON HEADING EDGEPT OF position */
2709 #line 658 "pikchr.y"
2710 {yylhsminor.yy139 = pik_position_at_hdg(p,yymsp[-5].minor.yy73,&yymsp[-2].minor.yy0,yymsp[0].minor.yy139);}
2711 #line 2736 "pikchr.c"
2712 yymsp[-5].minor.yy139 = yylhsminor.yy139;
2713 break;
2714 case 76: /* position ::= expr HEADING EDGEPT OF position */
2715 #line 660 "pikchr.y"
2716 {yylhsminor.yy139 = pik_position_at_hdg(p,yymsp[-4].minor.yy73,&yymsp[-2].minor.yy0,yymsp[0].minor.yy139);}
2717 #line 2742 "pikchr.c"
2718 yymsp[-4].minor.yy139 = yylhsminor.yy139;
2719 break;
2720 case 77: /* position ::= expr EDGEPT OF position */
2721 #line 662 "pikchr.y"
2722 {yylhsminor.yy139 = pik_position_at_hdg(p,yymsp[-3].minor.yy73,&yymsp[-2].minor.yy0,yymsp[0].minor.yy139);}
2723 #line 2748 "pikchr.c"
2724 yymsp[-3].minor.yy139 = yylhsminor.yy139;
2725 break;
2726 case 78: /* position ::= expr ON HEADING expr FROM position */
2727 #line 664 "pikchr.y"
2728 {yylhsminor.yy139 = pik_position_at_angle(p,yymsp[-5].minor.yy73,yymsp[-2].minor.yy73,yymsp[0].minor.yy139);}
2729 #line 2754 "pikchr.c"
2730 yymsp[-5].minor.yy139 = yylhsminor.yy139;
2731 break;
2732 case 79: /* position ::= expr HEADING expr FROM position */
2733 #line 666 "pikchr.y"
2734 {yylhsminor.yy139 = pik_position_at_angle(p,yymsp[-4].minor.yy73,yymsp[-2].minor.yy73,yymsp[0].minor.yy139);}
2735 #line 2760 "pikchr.c"
2736 yymsp[-4].minor.yy139 = yylhsminor.yy139;
2737 break;
2738 case 80: /* place ::= edge OF object */
2739 #line 678 "pikchr.y"
2740 {yylhsminor.yy139 = pik_place_of_elem(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0);}
2741 #line 2766 "pikchr.c"
2742 yymsp[-2].minor.yy139 = yylhsminor.yy139;
2743 break;
2744 case 81: /* place2 ::= object */
2745 #line 679 "pikchr.y"
2746 {yylhsminor.yy139 = pik_place_of_elem(p,yymsp[0].minor.yy254,0);}
2747 #line 2772 "pikchr.c"
2748 yymsp[0].minor.yy139 = yylhsminor.yy139;
2749 break;
2750 case 82: /* place2 ::= object DOT_E edge */
2751 #line 680 "pikchr.y"
2752 {yylhsminor.yy139 = pik_place_of_elem(p,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
2753 #line 2778 "pikchr.c"
2754 yymsp[-2].minor.yy139 = yylhsminor.yy139;
2755 break;
2756 case 83: /* place2 ::= NTH VERTEX OF object */
2757 #line 681 "pikchr.y"
2758 {yylhsminor.yy139 = pik_nth_vertex(p,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,yymsp[0].minor.yy254);}
2759 #line 2784 "pikchr.c"
2760 yymsp[-3].minor.yy139 = yylhsminor.yy139;
2761 break;
2762 case 84: /* object ::= nth */
2763 #line 693 "pikchr.y"
2764 {yylhsminor.yy254 = pik_find_nth(p,0,&yymsp[0].minor.yy0);}
2765 #line 2790 "pikchr.c"
2766 yymsp[0].minor.yy254 = yylhsminor.yy254;
2767 break;
2768 case 85: /* object ::= nth OF|IN object */
2769 #line 694 "pikchr.y"
2770 {yylhsminor.yy254 = pik_find_nth(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0);}
2771 #line 2796 "pikchr.c"
2772 yymsp[-2].minor.yy254 = yylhsminor.yy254;
2773 break;
2774 case 86: /* objectname ::= PLACENAME */
2775 #line 696 "pikchr.y"
2776 {yylhsminor.yy254 = pik_find_byname(p,0,&yymsp[0].minor.yy0);}
2777 #line 2802 "pikchr.c"
2778 yymsp[0].minor.yy254 = yylhsminor.yy254;
2779 break;
2780 case 87: /* objectname ::= objectname DOT_U PLACENAME */
2781 #line 698 "pikchr.y"
2782 {yylhsminor.yy254 = pik_find_byname(p,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
2783 #line 2808 "pikchr.c"
2784 yymsp[-2].minor.yy254 = yylhsminor.yy254;
2785 break;
2786 case 88: /* nth ::= NTH CLASSNAME */
2787 #line 700 "pikchr.y"
2788 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-1].minor.yy0); }
2789 #line 2814 "pikchr.c"
2790 yymsp[-1].minor.yy0 = yylhsminor.yy0;
2791 break;
2792 case 89: /* nth ::= NTH LAST CLASSNAME */
2793 #line 701 "pikchr.y"
2794 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-2].minor.yy0); }
2795 #line 2820 "pikchr.c"
2796 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2797 break;
2798 case 90: /* nth ::= LAST CLASSNAME */
2799 #line 702 "pikchr.y"
2800 {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.eCode = -1;}
2801 #line 2826 "pikchr.c"
2802 break;
2803 case 91: /* nth ::= LAST */
2804 #line 703 "pikchr.y"
2805 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -1;}
2806 #line 2831 "pikchr.c"
2807 yymsp[0].minor.yy0 = yylhsminor.yy0;
2808 break;
2809 case 92: /* nth ::= NTH LB RB */
2810 #line 704 "pikchr.y"
2811 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-2].minor.yy0);}
2812 #line 2837 "pikchr.c"
2813 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2814 break;
2815 case 93: /* nth ::= NTH LAST LB RB */
2816 #line 705 "pikchr.y"
2817 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-3].minor.yy0);}
2818 #line 2843 "pikchr.c"
2819 yymsp[-3].minor.yy0 = yylhsminor.yy0;
2820 break;
2821 case 94: /* nth ::= LAST LB RB */
2822 #line 706 "pikchr.y"
2823 {yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; }
2824 #line 2849 "pikchr.c"
2825 break;
2826 case 95: /* expr ::= expr PLUS expr */
2827 #line 708 "pikchr.y"
2828 {yylhsminor.yy73=yymsp[-2].minor.yy73+yymsp[0].minor.yy73;}
2829 #line 2854 "pikchr.c"
2830 yymsp[-2].minor.yy73 = yylhsminor.yy73;
2831 break;
2832 case 96: /* expr ::= expr MINUS expr */
2833 #line 709 "pikchr.y"
2834 {yylhsminor.yy73=yymsp[-2].minor.yy73-yymsp[0].minor.yy73;}
2835 #line 2860 "pikchr.c"
2836 yymsp[-2].minor.yy73 = yylhsminor.yy73;
2837 break;
2838 case 97: /* expr ::= expr STAR expr */
2839 #line 710 "pikchr.y"
2840 {yylhsminor.yy73=yymsp[-2].minor.yy73*yymsp[0].minor.yy73;}
2841 #line 2866 "pikchr.c"
2842 yymsp[-2].minor.yy73 = yylhsminor.yy73;
2843 break;
2844 case 98: /* expr ::= expr SLASH expr */
2845 #line 711 "pikchr.y"
2846 {
2847 if( yymsp[0].minor.yy73==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy73 = 0.0; }
2848 else{ yylhsminor.yy73 = yymsp[-2].minor.yy73/yymsp[0].minor.yy73; }
2849 }
2850 #line 2875 "pikchr.c"
2851 yymsp[-2].minor.yy73 = yylhsminor.yy73;
2852 break;
2853 case 99: /* expr ::= MINUS expr */
2854 #line 715 "pikchr.y"
2855 {yymsp[-1].minor.yy73=-yymsp[0].minor.yy73;}
2856 #line 2881 "pikchr.c"
2857 break;
2858 case 100: /* expr ::= PLUS expr */
2859 #line 716 "pikchr.y"
2860 {yymsp[-1].minor.yy73=yymsp[0].minor.yy73;}
2861 #line 2886 "pikchr.c"
2862 break;
2863 case 101: /* expr ::= LP expr RP */
2864 #line 717 "pikchr.y"
2865 {yymsp[-2].minor.yy73=yymsp[-1].minor.yy73;}
2866 #line 2891 "pikchr.c"
2867 break;
2868 case 102: /* expr ::= NUMBER */
2869 #line 718 "pikchr.y"
2870 {yylhsminor.yy73=pik_atof(p,&yymsp[0].minor.yy0);}
2871 #line 2896 "pikchr.c"
2872 yymsp[0].minor.yy73 = yylhsminor.yy73;
2873 break;
2874 case 103: /* expr ::= ID */
2875 #line 719 "pikchr.y"
2876 {yylhsminor.yy73=pik_get_var(p,&yymsp[0].minor.yy0);}
2877 #line 2902 "pikchr.c"
2878 yymsp[0].minor.yy73 = yylhsminor.yy73;
2879 break;
2880 case 104: /* expr ::= FUNC1 LP expr RP */
2881 #line 720 "pikchr.y"
2882 {yylhsminor.yy73 = pik_func(p,&yymsp[-3].minor.yy0,yymsp[-1].minor.yy73,0.0);}
2883 #line 2908 "pikchr.c"
2884 yymsp[-3].minor.yy73 = yylhsminor.yy73;
2885 break;
2886 case 105: /* expr ::= FUNC2 LP expr COMMA expr RP */
2887 #line 721 "pikchr.y"
2888 {yylhsminor.yy73 = pik_func(p,&yymsp[-5].minor.yy0,yymsp[-3].minor.yy73,yymsp[-1].minor.yy73);}
2889 #line 2914 "pikchr.c"
2890 yymsp[-5].minor.yy73 = yylhsminor.yy73;
2891 break;
2892 case 106: /* expr ::= place2 DOT_XY X */
2893 #line 722 "pikchr.y"
2894 {yylhsminor.yy73 = yymsp[-2].minor.yy139.x;}
2895 #line 2920 "pikchr.c"
2896 yymsp[-2].minor.yy73 = yylhsminor.yy73;
2897 break;
2898 case 107: /* expr ::= place2 DOT_XY Y */
2899 #line 723 "pikchr.y"
2900 {yylhsminor.yy73 = yymsp[-2].minor.yy139.y;}
2901 #line 2926 "pikchr.c"
2902 yymsp[-2].minor.yy73 = yylhsminor.yy73;
2903 break;
2904 case 108: /* expr ::= object DOT_L numproperty */
2905 case 109: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==109);
2906 case 110: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==110);
2907 #line 724 "pikchr.y"
2908 {yylhsminor.yy73=pik_property_of(p,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
2909 #line 2934 "pikchr.c"
2910 yymsp[-2].minor.yy73 = yylhsminor.yy73;
2911 break;
2912 default:
2913 /* (111) lvalue ::= ID */ yytestcase(yyruleno==111);
2914 /* (112) lvalue ::= FILL */ yytestcase(yyruleno==112);
@@ -3007,18 +3015,18 @@
3007 ){
3008 pik_parserARG_FETCH
3009 pik_parserCTX_FETCH
3010 #define TOKEN yyminor
3011 /************ Begin %syntax_error code ****************************************/
3012 #line 491 "pikchr.y"
3013
3014 if( TOKEN.z && TOKEN.z[0] ){
3015 pik_error(p, &TOKEN, "syntax error");
3016 }else{
3017 pik_error(p, 0, "syntax error");
3018 }
3019 #line 3044 "pikchr.c"
3020 /************ End %syntax_error code ******************************************/
3021 pik_parserARG_STORE /* Suppress warning about unused %extra_argument variable */
3022 pik_parserCTX_STORE
3023 }
3024
@@ -3247,11 +3255,11 @@
3247 #else
3248 (void)iToken;
3249 return 0;
3250 #endif
3251 }
3252 #line 729 "pikchr.y"
3253
3254
3255
3256 /* Chart of the 140 official HTML color names with their
3257 ** corresponding RGB value.
@@ -3855,11 +3863,11 @@
3855 static void fileInit(Pik *p, PElem *pElem){
3856 pElem->w = pik_value(p, "filewid",7,0);
3857 pElem->h = pik_value(p, "fileht",6,0);
3858 pElem->rad = pik_value(p, "filerad",7,0);
3859 }
3860 /* Return offset from the center of the box to the compass point
3861 ** given by parameter cp */
3862 static PPoint fileOffset(Pik *p, PElem *pElem, int cp){
3863 PPoint pt;
3864 PNum w2 = 0.5*pElem->w;
3865 PNum h2 = 0.5*pElem->h;
@@ -4004,11 +4012,11 @@
4004 pElem->h = pik_value(p, "lineht",6,0);
4005 pElem->rad = 1000;
4006 pElem->fill = -1.0; /* Disable fill by default */
4007 }
4008 /* Return a point along the path from "f" to "t" that is r units
4009 ** prior to reach "t", except if the path is less than 2*r total,
4010 ** return the midpoint.
4011 */
4012 static PPoint radiusMidpoint(PPoint f, PPoint t, PNum r, int *pbMid){
4013 PNum dx = t.x - f.x;
4014 PNum dy = t.y - f.y;
@@ -4368,11 +4376,11 @@
4368 ** * The space character is changed into non-breaking space (U+0080)
4369 ** if mFlags has the 0x01 bit set. This is needed when outputting
4370 ** text to preserve leading and trailing whitespace. Turns out we
4371 ** cannot use &nbsp; as that is an HTML-ism and is not valid in XML.
4372 **
4373 ** * The "&" character is changed into "&amp;" if mFlags as the
4374 ** 0x02 bit set. This is needed when generating error message text.
4375 **
4376 ** * Except for the above, only "<" and ">" are escaped.
4377 */
4378 static void pik_append_text(Pik *p, const char *zText, int n, int mFlags){
@@ -4484,11 +4492,11 @@
4484
4485 /* Append a style="..." text. But, leave the quote unterminated, in case
4486 ** the caller wants to add some more.
4487 */
4488 static void pik_append_style(Pik *p, PElem *pElem){
4489 pik_append(p, "style=\"", -1);
4490 if( pElem->fill>=0 ){
4491 pik_append_clr(p, "fill:", pElem->fill, ";");
4492 }else{
4493 pik_append(p,"fill:none;",-1);
4494 }
@@ -4542,11 +4550,11 @@
4542 aTxt[i].eCode = (aTxt[i].eCode & ~TP_VMASK) | TP_ABOVE2;
4543 break;
4544 }
4545 }
4546 }
4547 /* If more than one TP_BELOW, change the last to TP_BELOW2 */
4548 for(j=mJust=0, i=0; i<n; i++){
4549 if( aTxt[i].eCode & TP_BELOW ){
4550 if( j==0 ){
4551 j++;
4552 mJust = aTxt[i].eCode & TP_JMASK;
@@ -4585,20 +4593,17 @@
4585 }
4586 }
4587 }
4588 }
4589
4590 /* Append multiple <text> SGV element for the text fields of the PElem.
4591 ** Parameters:
4592 **
4593 ** p The Pik object into which we are rendering
4594 **
4595 ** pElem Object containing the text to be rendered
4596 **
4597 ** jw LJUST text is shifted to the left by this amount.
4598 ** RJUST text is shifted to the right.
4599 **
4600 ** pBox If not NULL, do no rendering at all. Instead
4601 ** expand the box object so that it will include all
4602 ** of the text.
4603 */
4604 static void pik_append_txt(Pik *p, PElem *pElem, PBox *pBox){
@@ -4771,11 +4776,11 @@
4771
4772 /*
4773 ** Process an "assert( place1 == place2 )" statement. Always return NULL.
4774 */
4775 static PElem *pik_place_assert(Pik *p, PPoint *e1, PToken *pEq, PPoint *e2){
4776 char zE1[100], zE2[100], zMsg[200];
4777
4778 /* Convert the numbers to strings using %g for comparison. This
4779 ** limits the precision of the comparison to account for rounding error. */
4780 snprintf(zE1, sizeof(zE1), "(%g,%g)", e1->x, e1->y); zE1[sizeof(zE1)-1] = 0;
4781 snprintf(zE2, sizeof(zE2), "(%g,%g)", e2->x, e2->y); zE1[sizeof(zE2)-1] = 0;
@@ -4874,11 +4879,11 @@
4874 if( pA->ne.x<pB->ne.x ) pA->ne.x = pB->ne.x;
4875 if( pA->ne.y<pB->ne.y ) pA->ne.y = pB->ne.y;
4876 }
4877
4878 /* Enlarge the PBox of the first argument, if necessary, so that
4879 ** it contains the PPoint in the second argument
4880 */
4881 static void pik_bbox_add_xy(PBox *pA, PNum x, PNum y){
4882 if( pik_bbox_isempty(pA) ){
4883 pA->ne.x = x;
4884 pA->ne.y = y;
@@ -5189,11 +5194,11 @@
5189 }
5190 return;
5191 }
5192
5193 /*
5194 ** Set a "dashed" property like "dash 0.05" or "chop"
5195 **
5196 ** Use the value supplied by pVal if available. If pVal==0, use
5197 ** a default.
5198 */
5199 void pik_set_dashed(Pik *p, PToken *pId, PNum *pVal){
@@ -5351,11 +5356,11 @@
5351
5352 /* Process a movement attribute of the form "right until even with ..."
5353 **
5354 ** pDir is the first keyword, "right" or "left" or "up" or "down".
5355 ** The movement is in that direction until its closest approach to
5356 ** point specified by pPoint.
5357 */
5358 static void pik_evenwith(Pik *p, PToken *pDir, PPoint *pPlace){
5359 PElem *pElem = p->cur;
5360 int n;
5361 if( !pElem->type->isLine ){
@@ -5521,15 +5526,16 @@
5521 else iRes = (iRes &~TP_SZMASK)|TP_SMALL; break;
5522 }
5523 return iRes;
5524 }
5525
5526 /* Return an estimate of the actually number of displayed characters
5527 ** in a character string.
5528 **
5529 ** Omit "\" used to escape characters. And count entities like
5530 ** "&lt;" as a single character.
 
5531 */
5532 static int pik_text_length(const PToken *pToken){
5533 int n = pToken->n;
5534 const char *z = pToken->z;
5535 int cnt, j;
@@ -5545,11 +5551,11 @@
5545 }
5546 }
5547 return cnt;
5548 }
5549
5550 /* Adjust the width, height, and or radius of the object so that
5551 ** it fits around the text that has been added so far.
5552 **
5553 ** (1) Only text specified prior to this attribute is considered.
5554 ** (2) The text size is estimated based on the charht and charwid
5555 ** variable settings.
@@ -5856,12 +5862,12 @@
5856 pik_error(p, pName, "no such object");
5857 return 0;
5858 }
5859
5860 /* Change most of the settings for the current object to be the
5861 ** same as the pElem object, or the most recent element of the same
5862 ** type if pElem is NULL.
5863 */
5864 static void pik_same(Pik *p, PElem *pOther, PToken *pErrTok){
5865 PElem *pElem = p->cur;
5866 if( p->nErr ) return;
5867 if( pOther==0 ){
@@ -5947,11 +5953,11 @@
5947 return out;
5948 }
5949
5950 /* Compute the position that is dist away from pt at an heading angle of r
5951 **
5952 ** The angle is compass heading in degrees. North is 0 (or 360).
5953 ** East is 90. South is 180. West is 270. And so forth.
5954 */
5955 static PPoint pik_position_at_angle(Pik *p, PNum dist, PNum r, PPoint pt){
5956 r *= 0.017453292519943295769; /* degrees to radians */
5957 pt.x += dist*sin(r);
@@ -6366,10 +6372,23 @@
6366 h = p->bbox.ne.y - p->bbox.sw.y;
6367 p->wSVG = (int)(p->rScale*w);
6368 p->hSVG = (int)(p->rScale*h);
6369 pik_append_dis(p, " viewBox=\"0 0 ",w,"");
6370 pik_append_dis(p, " ",h,"\">\n");
 
 
 
 
 
 
 
 
 
 
 
 
 
6371 pik_elist_render(p, pEList);
6372 pik_append(p,"</svg>\n", -1);
6373 }else{
6374 p->wSVG = -1;
6375 p->hSVG = -1;
@@ -6482,11 +6501,11 @@
6482 { "x", 1, T_X, 0, 0 },
6483 { "y", 1, T_Y, 0, 0 },
6484 };
6485
6486 /*
6487 ** Search a PikWordlist for the given keyword. A pointer to the
6488 ** element found. Or return 0 if not found.
6489 */
6490 static const PikWord *pik_find_word(
6491 const char *zIn, /* Word to search for */
6492 int n, /* Length of zIn */
@@ -6809,11 +6828,11 @@
6809 ** Parse the PIKCHR script contained in zText[]. Return a rendering. Or
6810 ** if an error is encountered, return the error text. The error message
6811 ** is HTML formatted. So regardless of what happens, the return text
6812 ** is safe to be insertd into an HTML output stream.
6813 **
6814 ** If pnWidth and pnHeight are NULL, then this routine writes the
6815 ** width and height of the <SVG> object into the integers that they
6816 ** point to. A value of -1 is written if an error is seen.
6817 **
6818 ** If zClass is not NULL, then it is a class name to be included in
6819 ** the <SVG> markup.
@@ -6837,10 +6856,11 @@
6837 memset(&s, 0, sizeof(s));
6838 s.zIn = zText;
6839 s.nIn = (unsigned int)strlen(zText);
6840 s.eDir = DIR_RIGHT;
6841 s.zClass = zClass;
 
6842 pik_parserInit(&sParse, &s);
6843 #if 0
6844 pik_parserTrace(stdout, "parser: ");
6845 #endif
6846 for(i=0; zText[i] && s.nErr==0; i+=sz){
@@ -6911,11 +6931,12 @@
6911 ** input text and the rendered SVG for all files named on the command
6912 ** line.
6913 */
6914 int main(int argc, char **argv){
6915 int i;
6916 int bNoEcho = 0; /* Do not the text of the script */
 
6917 printf(
6918 "<!DOCTYPE html>\n"
6919 "<html lang=\"en-US\">\n"
6920 "<head>\n<title>PIKCHR Test</title>\n"
6921 "<meta charset=\"utf-8\">\n"
@@ -6936,10 +6957,13 @@
6936 z++;
6937 if( z[0]=='-' ) z++;
6938 if( strcmp(z,"no-echo")==0 ){
6939 bNoEcho = 1;
6940 }else
 
 
 
6941 {
6942 fprintf(stderr,"unknown option: \"%s\"\n", argv[i]);
6943 exit(1);
6944 }
6945 continue;
@@ -6980,11 +7004,11 @@
6980 break;
6981 }
6982 }
6983 printf("</pre></blockquote>\n");
6984 }
6985 zOut = pikchr(zIn, "pikchr", 0, &w, &h);
6986 free(zIn);
6987 if( zOut ){
6988 if( w<0 ){
6989 printf("<p>ERROR:</p>\n");
6990 }else if( bNoEcho==0 ){
@@ -6999,6 +7023,6 @@
6999 printf("</body></html>\n");
7000 return 0;
7001 }
7002 #endif /* PIKCHR_SHELL */
7003
7004 #line 7029 "pikchr.c"
7005
--- src/pikchr.c
+++ src/pikchr.c
@@ -29,11 +29,11 @@
29 ** of PIKCHR language text and generates a second string of SVG output that
30 ** renders the drawing defined by the input. Space to hold the returned
31 ** string is obtained from malloc() and should be freed by the caller.
32 ** NULL might be returned if there is a memory allocation error.
33 **
34 ** If there are errors in the PIKCHR input, the output will consist of an
35 ** error message and the original PIKCHR input text (inside of <pre>...</pre>).
36 **
37 ** The subroutine implemented by this file is intended to be stand-alone.
38 ** It uses no external routines other than routines commonly found in
39 ** the standard C library.
@@ -72,11 +72,11 @@
72 **
73 ** The input is a sequence of objects or "elements". Each element is
74 ** parsed into a PElem object. These are stored on an extensible array
75 ** called PEList. All parameters to each PElem are computed as the
76 ** object is parsed. (Hence, the parameters to a PElem may only refer
77 ** to prior elements.) Once the PElem is completely assembled, it is
78 ** added to the end of a PEList and never changes thereafter - except,
79 ** PElem objects that are part of a "[...]" block might have their
80 ** absolute position shifted when the outer [...] block is positioned.
81 ** But apart from this repositioning, PElem objects are unchanged once
82 ** they are added to the list. The order of elements on a PEList does
@@ -90,12 +90,12 @@
90 **
91 ** Each PElem is on a "layer". (The common case is that all PElem's are
92 ** on a single layer, but multiple layers are possible.) A separate pass
93 ** is made through the list for each layer.
94 **
95 ** After all output is generated, the Pik object and all the PEList
96 ** and PElem objects are deallocated and the generated output string is
97 ** returned. Upon any error, the Pik.nErr flag is set, processing quickly
98 ** stops, and the stack unwinds. No attempt is made to continue reading
99 ** input after an error.
100 **
101 ** Most elements begin with a class name like "box" or "arrow" or "move".
@@ -105,18 +105,18 @@
105 ** its subelements, all gathered onto a separate PEList object.
106 **
107 ** Variables go into PVar objects that form a linked list.
108 **
109 ** Each PElem has zero or one names. Input constructs that attempt
110 ** to assign a new name from an older name, for example:
111 **
112 ** Abc: Abc + (0.5cm, 0)
113 **
114 ** Statements like these generate a new "noop" object at the specified
115 ** place and with the given name. As place-names are searched by scanning
116 ** the list in reverse order, this has the effect of overriding the "Abc"
117 ** name when referenced by subsequent objects.
118 */
119 #include <stdio.h>
120 #include <stdlib.h>
121 #include <string.h>
122 #include <ctype.h>
@@ -235,12 +235,12 @@
235 short int eCode; /* Auxiliary code */
236 unsigned char eType; /* The numeric parser code */
237 unsigned char eEdge; /* Corner value for corner keywords */
238 };
239
240 /* Return negative, zero, or positive if pToken is less than, equal to
241 ** or greater than the zero-terminated string z[]
242 */
243 static int pik_token_eq(PToken *pToken, const char *z){
244 int c = strncmp(pToken->z,z,pToken->n);
245 if( c==0 && z[pToken->n]!=0 ) c = -1;
246 return c;
@@ -260,11 +260,11 @@
260 #define ValidDir(X) ((X)>=0 && (X)<=3)
261 #define IsUpDown(X) (((X)&1)==1)
262 #define IsLeftRight(X) (((X)&1)==0)
263
264 /* Bitmask for the various attributes for PElem. These bits are
265 ** collected in PElem.mProp and PElem.mCalc to check for constraint
266 ** errors. */
267 #define A_WIDTH 0x000001
268 #define A_HEIGHT 0x000002
269 #define A_RADIUS 0x000004
270 #define A_THICKNESS 0x000008
@@ -288,27 +288,23 @@
288 PToken errTok; /* Reference token for error messages */
289 PPoint ptAt; /* Reference point for the object */
290 PPoint ptEnter, ptExit; /* Entry and exit points */
291 PEList *pSublist; /* Substructure for [...] elements */
292 char *zName; /* Name assigned to this element */
293 PNum w; /* "width" property */
294 PNum h; /* "height" property */
295 PNum rad; /* "radius" property */
296 PNum sw; /* "thickness" property. (Mnemonic: "stroke width")*/
297 PNum dotted; /* "dotted" property. <=0.0 for off */
298 PNum dashed; /* "dashed" property. <=0.0 for off */
299 PNum fill; /* "fill" property. Negative for off */
300 PNum color; /* "color" property */
 
 
 
 
301 PPoint with; /* Position constraint from WITH clause */
302 char eWith; /* Type of heading point on WITH clause */
303 char cw; /* True for clockwise arc */
304 char larrow; /* Arrow at beginning (<- or <->) */
305 char rarrow; /* Arrow at end (-> or <->) */
306 char bClose; /* True if "close" is seen */
307 char bChop; /* True if "chop" is seen */
308 unsigned char nTxt; /* Number of text values */
309 unsigned mProp; /* Masks of properties set so far */
310 unsigned mCalc; /* Values computed from other constraints */
@@ -336,10 +332,11 @@
332 unsigned int nIn; /* Number of bytes in zIn */
333 char *zOut; /* Result accumulates here */
334 unsigned int nOut; /* Bytes written to zOut[] so far */
335 unsigned int nOutAlloc; /* Space allocated to zOut[] */
336 unsigned char eDir; /* Current direction */
337 unsigned int mFlags; /* Flags passed to pikchr() */
338 PElem *cur; /* Element under construction */
339 PEList *list; /* Element list under construction */
340 PVar *pVar; /* Application-defined variables */
341 PBox bbox; /* Bounding box around all elements */
342 /* Cache of layout values. <=0.0 for unknown... */
@@ -358,13 +355,24 @@
355 int nTPath; /* Number of entries on aTPath[] */
356 int mTPath; /* For last entry, 1: x set, 2: y set */
357 PPoint aTPath[1000]; /* Path under construction */
358 };
359
360
361 /*
362 ** Flag values for Pik.mFlags (to be picked up by makeheaders on systems
363 ** that use makeheaders.
364 */
365 #undef INTERFACE
366 #define INTERFACE 1
367 #if INTERFACE
368 #define PIKCHR_INCLUDE_SOURCE 0x0001 /* Include Pikchr src in SVG output */
369 #endif /* INTERFACE */
370
371 /*
372 ** The behavior of an object class is defined by an instance of
373 ** this structure. This is the "virtual method" table.
374 */
375 struct PClass {
376 const char *zName; /* Name of class */
377 char isLine; /* True if a line class */
378 char eJust; /* Use box-style text justification */
@@ -445,11 +453,11 @@
453 static void pik_behind(Pik*,PElem*);
454 static PElem *pik_assert(Pik*,PNum,PToken*,PNum);
455 static PElem *pik_place_assert(Pik*,PPoint*,PToken*,PPoint*);
456
457
458 #line 484 "pikchr.c"
459 /**************** End of %include directives **********************************/
460 /* These constants specify the various numeric values for terminal symbols.
461 ***************** Begin token definitions *************************************/
462 #ifndef T_ID
463 #define T_ID 1
@@ -1621,22 +1629,22 @@
1629 ** inside the C code.
1630 */
1631 /********* Begin destructor definitions ***************************************/
1632 case 94: /* element_list */
1633 {
1634 #line 473 "pikchr.y"
1635 pik_elist_free(p,(yypminor->yy72));
1636 #line 1661 "pikchr.c"
1637 }
1638 break;
1639 case 95: /* element */
1640 case 96: /* unnamed_element */
1641 case 97: /* basetype */
1642 {
1643 #line 475 "pikchr.y"
1644 pik_elem_free(p,(yypminor->yy254));
1645 #line 1670 "pikchr.c"
1646 }
1647 break;
1648 /********* End destructor definitions *****************************************/
1649 default: break; /* If no destructor action specified: do nothing */
1650 }
@@ -1850,14 +1858,14 @@
1858 #endif
1859 while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
1860 /* Here code is inserted which will execute if the parser
1861 ** stack every overflows */
1862 /******** Begin %stack_overflow code ******************************************/
1863 #line 506 "pikchr.y"
1864
1865 pik_error(p, 0, "parser stack overflow");
1866 #line 1891 "pikchr.c"
1867 /******** End %stack_overflow code ********************************************/
1868 pik_parserARG_STORE /* Suppress warning about unused %extra_argument var */
1869 pik_parserCTX_STORE
1870 }
1871
@@ -2322,593 +2330,593 @@
2330 ** break;
2331 */
2332 /********** Begin reduce actions **********************************************/
2333 YYMINORTYPE yylhsminor;
2334 case 0: /* document ::= element_list */
2335 #line 510 "pikchr.y"
2336 {pik_render(p,yymsp[0].minor.yy72);}
2337 #line 2362 "pikchr.c"
2338 break;
2339 case 1: /* element_list ::= element */
2340 #line 513 "pikchr.y"
2341 { yylhsminor.yy72 = pik_elist_append(p,0,yymsp[0].minor.yy254); }
2342 #line 2367 "pikchr.c"
2343 yymsp[0].minor.yy72 = yylhsminor.yy72;
2344 break;
2345 case 2: /* element_list ::= element_list EOL element */
2346 #line 515 "pikchr.y"
2347 { yylhsminor.yy72 = pik_elist_append(p,yymsp[-2].minor.yy72,yymsp[0].minor.yy254); }
2348 #line 2373 "pikchr.c"
2349 yymsp[-2].minor.yy72 = yylhsminor.yy72;
2350 break;
2351 case 3: /* element ::= */
2352 #line 518 "pikchr.y"
2353 { yymsp[1].minor.yy254 = 0; }
2354 #line 2379 "pikchr.c"
2355 break;
2356 case 4: /* element ::= direction */
2357 #line 519 "pikchr.y"
2358 { pik_set_direction(p,yymsp[0].minor.yy0.eCode); yylhsminor.yy254=0; }
2359 #line 2384 "pikchr.c"
2360 yymsp[0].minor.yy254 = yylhsminor.yy254;
2361 break;
2362 case 5: /* element ::= lvalue ASSIGN rvalue */
2363 #line 520 "pikchr.y"
2364 {pik_set_var(p,&yymsp[-2].minor.yy0,yymsp[0].minor.yy73,&yymsp[-1].minor.yy0); yylhsminor.yy254=0;}
2365 #line 2390 "pikchr.c"
2366 yymsp[-2].minor.yy254 = yylhsminor.yy254;
2367 break;
2368 case 6: /* element ::= PLACENAME COLON unnamed_element */
2369 #line 522 "pikchr.y"
2370 { yylhsminor.yy254 = yymsp[0].minor.yy254; pik_elem_setname(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0); }
2371 #line 2396 "pikchr.c"
2372 yymsp[-2].minor.yy254 = yylhsminor.yy254;
2373 break;
2374 case 7: /* element ::= PLACENAME COLON position */
2375 #line 524 "pikchr.y"
2376 { yylhsminor.yy254 = pik_elem_new(p,0,0,0);
2377 if(yylhsminor.yy254){ yylhsminor.yy254->ptAt = yymsp[0].minor.yy139; pik_elem_setname(p,yylhsminor.yy254,&yymsp[-2].minor.yy0); }}
2378 #line 2403 "pikchr.c"
2379 yymsp[-2].minor.yy254 = yylhsminor.yy254;
2380 break;
2381 case 8: /* element ::= unnamed_element */
2382 #line 526 "pikchr.y"
2383 {yylhsminor.yy254 = yymsp[0].minor.yy254;}
2384 #line 2409 "pikchr.c"
2385 yymsp[0].minor.yy254 = yylhsminor.yy254;
2386 break;
2387 case 9: /* element ::= print prlist */
2388 #line 527 "pikchr.y"
2389 {pik_append(p,"<br>\n",5); yymsp[-1].minor.yy254=0;}
2390 #line 2415 "pikchr.c"
2391 break;
2392 case 10: /* element ::= ASSERT LP expr EQ expr RP */
2393 #line 532 "pikchr.y"
2394 {yymsp[-5].minor.yy254=pik_assert(p,yymsp[-3].minor.yy73,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy73);}
2395 #line 2420 "pikchr.c"
2396 break;
2397 case 11: /* element ::= ASSERT LP place EQ place RP */
2398 #line 534 "pikchr.y"
2399 {yymsp[-5].minor.yy254=pik_place_assert(p,&yymsp[-3].minor.yy139,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy139);}
2400 #line 2425 "pikchr.c"
2401 break;
2402 case 12: /* rvalue ::= PLACENAME */
2403 #line 545 "pikchr.y"
2404 {yylhsminor.yy73 = pik_lookup_color(p,&yymsp[0].minor.yy0);}
2405 #line 2430 "pikchr.c"
2406 yymsp[0].minor.yy73 = yylhsminor.yy73;
2407 break;
2408 case 13: /* pritem ::= FILL */
2409 case 14: /* pritem ::= COLOR */ yytestcase(yyruleno==14);
2410 case 15: /* pritem ::= THICKNESS */ yytestcase(yyruleno==15);
2411 #line 550 "pikchr.y"
2412 {pik_append_num(p,"",pik_value(p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.n,0));}
2413 #line 2438 "pikchr.c"
2414 break;
2415 case 16: /* pritem ::= rvalue */
2416 #line 553 "pikchr.y"
2417 {pik_append_num(p,"",yymsp[0].minor.yy73);}
2418 #line 2443 "pikchr.c"
2419 break;
2420 case 17: /* pritem ::= STRING */
2421 #line 554 "pikchr.y"
2422 {pik_append_text(p,yymsp[0].minor.yy0.z+1,yymsp[0].minor.yy0.n-2,0);}
2423 #line 2448 "pikchr.c"
2424 break;
2425 case 18: /* prsep ::= COMMA */
2426 #line 555 "pikchr.y"
2427 {pik_append(p, " ", 1);}
2428 #line 2453 "pikchr.c"
2429 break;
2430 case 19: /* unnamed_element ::= basetype attribute_list */
2431 #line 558 "pikchr.y"
2432 {yylhsminor.yy254 = yymsp[-1].minor.yy254; pik_after_adding_attributes(p,yylhsminor.yy254);}
2433 #line 2458 "pikchr.c"
2434 yymsp[-1].minor.yy254 = yylhsminor.yy254;
2435 break;
2436 case 20: /* basetype ::= CLASSNAME */
2437 #line 560 "pikchr.y"
2438 {yylhsminor.yy254 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); }
2439 #line 2464 "pikchr.c"
2440 yymsp[0].minor.yy254 = yylhsminor.yy254;
2441 break;
2442 case 21: /* basetype ::= STRING textposition */
2443 #line 562 "pikchr.y"
2444 {yymsp[-1].minor.yy0.eCode = yymsp[0].minor.yy74; yylhsminor.yy254 = pik_elem_new(p,0,&yymsp[-1].minor.yy0,0); }
2445 #line 2470 "pikchr.c"
2446 yymsp[-1].minor.yy254 = yylhsminor.yy254;
2447 break;
2448 case 22: /* basetype ::= LB savelist element_list RB */
2449 #line 564 "pikchr.y"
2450 { p->list = yymsp[-2].minor.yy72; yymsp[-3].minor.yy254 = pik_elem_new(p,0,0,yymsp[-1].minor.yy72); if(yymsp[-3].minor.yy254) yymsp[-3].minor.yy254->errTok = yymsp[0].minor.yy0; }
2451 #line 2476 "pikchr.c"
2452 break;
2453 case 23: /* savelist ::= */
2454 #line 569 "pikchr.y"
2455 {yymsp[1].minor.yy72 = p->list; p->list = 0;}
2456 #line 2481 "pikchr.c"
2457 break;
2458 case 24: /* relexpr ::= expr */
2459 #line 576 "pikchr.y"
2460 {yylhsminor.yy60.rAbs = yymsp[0].minor.yy73; yylhsminor.yy60.rRel = 0;}
2461 #line 2486 "pikchr.c"
2462 yymsp[0].minor.yy60 = yylhsminor.yy60;
2463 break;
2464 case 25: /* relexpr ::= expr PERCENT */
2465 #line 577 "pikchr.y"
2466 {yylhsminor.yy60.rAbs = 0; yylhsminor.yy60.rRel = yymsp[-1].minor.yy73/100;}
2467 #line 2492 "pikchr.c"
2468 yymsp[-1].minor.yy60 = yylhsminor.yy60;
2469 break;
2470 case 26: /* optrelexpr ::= */
2471 #line 579 "pikchr.y"
2472 {yymsp[1].minor.yy60.rAbs = 0; yymsp[1].minor.yy60.rRel = 1.0;}
2473 #line 2498 "pikchr.c"
2474 break;
2475 case 27: /* attribute_list ::= relexpr alist */
2476 #line 581 "pikchr.y"
2477 {pik_add_direction(p,0,&yymsp[-1].minor.yy60);}
2478 #line 2503 "pikchr.c"
2479 break;
2480 case 28: /* attribute ::= numproperty relexpr */
2481 #line 585 "pikchr.y"
2482 { pik_set_numprop(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy60); }
2483 #line 2508 "pikchr.c"
2484 break;
2485 case 29: /* attribute ::= dashproperty expr */
2486 #line 586 "pikchr.y"
2487 { pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy73); }
2488 #line 2513 "pikchr.c"
2489 break;
2490 case 30: /* attribute ::= dashproperty */
2491 #line 587 "pikchr.y"
2492 { pik_set_dashed(p,&yymsp[0].minor.yy0,0); }
2493 #line 2518 "pikchr.c"
2494 break;
2495 case 31: /* attribute ::= colorproperty rvalue */
2496 #line 588 "pikchr.y"
2497 { pik_set_clrprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy73); }
2498 #line 2523 "pikchr.c"
2499 break;
2500 case 32: /* attribute ::= go direction optrelexpr */
2501 #line 589 "pikchr.y"
2502 { pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy60);}
2503 #line 2528 "pikchr.c"
2504 break;
2505 case 33: /* attribute ::= go direction even position */
2506 #line 590 "pikchr.y"
2507 {pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy139);}
2508 #line 2533 "pikchr.c"
2509 break;
2510 case 34: /* attribute ::= CLOSE */
2511 #line 591 "pikchr.y"
2512 { pik_close_path(p,&yymsp[0].minor.yy0); }
2513 #line 2538 "pikchr.c"
2514 break;
2515 case 35: /* attribute ::= CHOP */
2516 #line 592 "pikchr.y"
2517 { p->cur->bChop = 1; }
2518 #line 2543 "pikchr.c"
2519 break;
2520 case 36: /* attribute ::= FROM position */
2521 #line 593 "pikchr.y"
2522 { pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy139); }
2523 #line 2548 "pikchr.c"
2524 break;
2525 case 37: /* attribute ::= TO position */
2526 #line 594 "pikchr.y"
2527 { pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy139); }
2528 #line 2553 "pikchr.c"
2529 break;
2530 case 38: /* attribute ::= THEN */
2531 #line 595 "pikchr.y"
2532 { pik_then(p, &yymsp[0].minor.yy0, p->cur); }
2533 #line 2558 "pikchr.c"
2534 break;
2535 case 39: /* attribute ::= THEN optrelexpr HEADING expr */
2536 case 41: /* attribute ::= GO optrelexpr HEADING expr */ yytestcase(yyruleno==41);
2537 #line 597 "pikchr.y"
2538 {pik_move_hdg(p,&yymsp[-2].minor.yy60,&yymsp[-1].minor.yy0,yymsp[0].minor.yy73,0,&yymsp[-3].minor.yy0);}
2539 #line 2564 "pikchr.c"
2540 break;
2541 case 40: /* attribute ::= THEN optrelexpr EDGEPT */
2542 case 42: /* attribute ::= GO optrelexpr EDGEPT */ yytestcase(yyruleno==42);
2543 #line 598 "pikchr.y"
2544 {pik_move_hdg(p,&yymsp[-1].minor.yy60,0,0,&yymsp[0].minor.yy0,&yymsp[-2].minor.yy0);}
2545 #line 2570 "pikchr.c"
2546 break;
2547 case 43: /* attribute ::= AT position */
2548 #line 603 "pikchr.y"
2549 { pik_set_at(p,0,&yymsp[0].minor.yy139,&yymsp[-1].minor.yy0); }
2550 #line 2575 "pikchr.c"
2551 break;
2552 case 44: /* attribute ::= SAME */
2553 #line 605 "pikchr.y"
2554 {pik_same(p,0,&yymsp[0].minor.yy0);}
2555 #line 2580 "pikchr.c"
2556 break;
2557 case 45: /* attribute ::= SAME AS object */
2558 #line 606 "pikchr.y"
2559 {pik_same(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0);}
2560 #line 2585 "pikchr.c"
2561 break;
2562 case 46: /* attribute ::= STRING textposition */
2563 #line 607 "pikchr.y"
2564 {pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy74);}
2565 #line 2590 "pikchr.c"
2566 break;
2567 case 47: /* attribute ::= FIT */
2568 #line 608 "pikchr.y"
2569 {pik_size_to_fit(p,&yymsp[0].minor.yy0); }
2570 #line 2595 "pikchr.c"
2571 break;
2572 case 48: /* attribute ::= BEHIND object */
2573 #line 609 "pikchr.y"
2574 {pik_behind(p,yymsp[0].minor.yy254);}
2575 #line 2600 "pikchr.c"
2576 break;
2577 case 49: /* withclause ::= DOT_E edge AT position */
2578 case 50: /* withclause ::= edge AT position */ yytestcase(yyruleno==50);
2579 #line 617 "pikchr.y"
2580 { pik_set_at(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy139,&yymsp[-1].minor.yy0); }
2581 #line 2606 "pikchr.c"
2582 break;
2583 case 51: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2584 #line 621 "pikchr.y"
2585 {yylhsminor.yy0 = yymsp[0].minor.yy0;}
2586 #line 2611 "pikchr.c"
2587 yymsp[0].minor.yy0 = yylhsminor.yy0;
2588 break;
2589 case 52: /* boolproperty ::= CW */
2590 #line 632 "pikchr.y"
2591 {p->cur->cw = 1;}
2592 #line 2617 "pikchr.c"
2593 break;
2594 case 53: /* boolproperty ::= CCW */
2595 #line 633 "pikchr.y"
2596 {p->cur->cw = 0;}
2597 #line 2622 "pikchr.c"
2598 break;
2599 case 54: /* boolproperty ::= LARROW */
2600 #line 634 "pikchr.y"
2601 {p->cur->larrow=1; p->cur->rarrow=0; }
2602 #line 2627 "pikchr.c"
2603 break;
2604 case 55: /* boolproperty ::= RARROW */
2605 #line 635 "pikchr.y"
2606 {p->cur->larrow=0; p->cur->rarrow=1; }
2607 #line 2632 "pikchr.c"
2608 break;
2609 case 56: /* boolproperty ::= LRARROW */
2610 #line 636 "pikchr.y"
2611 {p->cur->larrow=1; p->cur->rarrow=1; }
2612 #line 2637 "pikchr.c"
2613 break;
2614 case 57: /* boolproperty ::= INVIS */
2615 #line 637 "pikchr.y"
2616 {p->cur->sw = 0.0;}
2617 #line 2642 "pikchr.c"
2618 break;
2619 case 58: /* boolproperty ::= THICK */
2620 #line 638 "pikchr.y"
2621 {p->cur->sw *= 1.5;}
2622 #line 2647 "pikchr.c"
2623 break;
2624 case 59: /* boolproperty ::= THIN */
2625 #line 639 "pikchr.y"
2626 {p->cur->sw *= 0.67;}
2627 #line 2652 "pikchr.c"
2628 break;
2629 case 60: /* textposition ::= */
2630 #line 641 "pikchr.y"
2631 {yymsp[1].minor.yy74 = 0;}
2632 #line 2657 "pikchr.c"
2633 break;
2634 case 61: /* textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL */
2635 #line 644 "pikchr.y"
2636 {yylhsminor.yy74 = pik_text_position(p,yymsp[-1].minor.yy74,&yymsp[0].minor.yy0);}
2637 #line 2662 "pikchr.c"
2638 yymsp[-1].minor.yy74 = yylhsminor.yy74;
2639 break;
2640 case 62: /* position ::= expr COMMA expr */
2641 #line 647 "pikchr.y"
2642 {yylhsminor.yy139.x=yymsp[-2].minor.yy73; yylhsminor.yy139.y=yymsp[0].minor.yy73;}
2643 #line 2668 "pikchr.c"
2644 yymsp[-2].minor.yy139 = yylhsminor.yy139;
2645 break;
2646 case 63: /* position ::= place PLUS expr COMMA expr */
2647 #line 649 "pikchr.y"
2648 {yylhsminor.yy139.x=yymsp[-4].minor.yy139.x+yymsp[-2].minor.yy73; yylhsminor.yy139.y=yymsp[-4].minor.yy139.y+yymsp[0].minor.yy73;}
2649 #line 2674 "pikchr.c"
2650 yymsp[-4].minor.yy139 = yylhsminor.yy139;
2651 break;
2652 case 64: /* position ::= place MINUS expr COMMA expr */
2653 #line 650 "pikchr.y"
2654 {yylhsminor.yy139.x=yymsp[-4].minor.yy139.x-yymsp[-2].minor.yy73; yylhsminor.yy139.y=yymsp[-4].minor.yy139.y-yymsp[0].minor.yy73;}
2655 #line 2680 "pikchr.c"
2656 yymsp[-4].minor.yy139 = yylhsminor.yy139;
2657 break;
2658 case 65: /* position ::= place PLUS LP expr COMMA expr RP */
2659 #line 652 "pikchr.y"
2660 {yylhsminor.yy139.x=yymsp[-6].minor.yy139.x+yymsp[-3].minor.yy73; yylhsminor.yy139.y=yymsp[-6].minor.yy139.y+yymsp[-1].minor.yy73;}
2661 #line 2686 "pikchr.c"
2662 yymsp[-6].minor.yy139 = yylhsminor.yy139;
2663 break;
2664 case 66: /* position ::= place MINUS LP expr COMMA expr RP */
2665 #line 654 "pikchr.y"
2666 {yylhsminor.yy139.x=yymsp[-6].minor.yy139.x-yymsp[-3].minor.yy73; yylhsminor.yy139.y=yymsp[-6].minor.yy139.y-yymsp[-1].minor.yy73;}
2667 #line 2692 "pikchr.c"
2668 yymsp[-6].minor.yy139 = yylhsminor.yy139;
2669 break;
2670 case 67: /* position ::= LP position COMMA position RP */
2671 #line 655 "pikchr.y"
2672 {yymsp[-4].minor.yy139.x=yymsp[-3].minor.yy139.x; yymsp[-4].minor.yy139.y=yymsp[-1].minor.yy139.y;}
2673 #line 2698 "pikchr.c"
2674 break;
2675 case 68: /* position ::= LP position RP */
2676 #line 656 "pikchr.y"
2677 {yymsp[-2].minor.yy139=yymsp[-1].minor.yy139;}
2678 #line 2703 "pikchr.c"
2679 break;
2680 case 69: /* position ::= expr between position AND position */
2681 #line 658 "pikchr.y"
2682 {yylhsminor.yy139 = pik_position_between(p,yymsp[-4].minor.yy73,yymsp[-2].minor.yy139,yymsp[0].minor.yy139);}
2683 #line 2708 "pikchr.c"
2684 yymsp[-4].minor.yy139 = yylhsminor.yy139;
2685 break;
2686 case 70: /* position ::= expr LT position COMMA position GT */
2687 #line 660 "pikchr.y"
2688 {yylhsminor.yy139 = pik_position_between(p,yymsp[-5].minor.yy73,yymsp[-3].minor.yy139,yymsp[-1].minor.yy139);}
2689 #line 2714 "pikchr.c"
2690 yymsp[-5].minor.yy139 = yylhsminor.yy139;
2691 break;
2692 case 71: /* position ::= expr ABOVE position */
2693 #line 661 "pikchr.y"
2694 {yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.y += yymsp[-2].minor.yy73;}
2695 #line 2720 "pikchr.c"
2696 yymsp[-2].minor.yy139 = yylhsminor.yy139;
2697 break;
2698 case 72: /* position ::= expr BELOW position */
2699 #line 662 "pikchr.y"
2700 {yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.y -= yymsp[-2].minor.yy73;}
2701 #line 2726 "pikchr.c"
2702 yymsp[-2].minor.yy139 = yylhsminor.yy139;
2703 break;
2704 case 73: /* position ::= expr LEFT OF position */
2705 #line 663 "pikchr.y"
2706 {yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.x -= yymsp[-3].minor.yy73;}
2707 #line 2732 "pikchr.c"
2708 yymsp[-3].minor.yy139 = yylhsminor.yy139;
2709 break;
2710 case 74: /* position ::= expr RIGHT OF position */
2711 #line 664 "pikchr.y"
2712 {yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.x += yymsp[-3].minor.yy73;}
2713 #line 2738 "pikchr.c"
2714 yymsp[-3].minor.yy139 = yylhsminor.yy139;
2715 break;
2716 case 75: /* position ::= expr ON HEADING EDGEPT OF position */
2717 #line 666 "pikchr.y"
2718 {yylhsminor.yy139 = pik_position_at_hdg(p,yymsp[-5].minor.yy73,&yymsp[-2].minor.yy0,yymsp[0].minor.yy139);}
2719 #line 2744 "pikchr.c"
2720 yymsp[-5].minor.yy139 = yylhsminor.yy139;
2721 break;
2722 case 76: /* position ::= expr HEADING EDGEPT OF position */
2723 #line 668 "pikchr.y"
2724 {yylhsminor.yy139 = pik_position_at_hdg(p,yymsp[-4].minor.yy73,&yymsp[-2].minor.yy0,yymsp[0].minor.yy139);}
2725 #line 2750 "pikchr.c"
2726 yymsp[-4].minor.yy139 = yylhsminor.yy139;
2727 break;
2728 case 77: /* position ::= expr EDGEPT OF position */
2729 #line 670 "pikchr.y"
2730 {yylhsminor.yy139 = pik_position_at_hdg(p,yymsp[-3].minor.yy73,&yymsp[-2].minor.yy0,yymsp[0].minor.yy139);}
2731 #line 2756 "pikchr.c"
2732 yymsp[-3].minor.yy139 = yylhsminor.yy139;
2733 break;
2734 case 78: /* position ::= expr ON HEADING expr FROM position */
2735 #line 672 "pikchr.y"
2736 {yylhsminor.yy139 = pik_position_at_angle(p,yymsp[-5].minor.yy73,yymsp[-2].minor.yy73,yymsp[0].minor.yy139);}
2737 #line 2762 "pikchr.c"
2738 yymsp[-5].minor.yy139 = yylhsminor.yy139;
2739 break;
2740 case 79: /* position ::= expr HEADING expr FROM position */
2741 #line 674 "pikchr.y"
2742 {yylhsminor.yy139 = pik_position_at_angle(p,yymsp[-4].minor.yy73,yymsp[-2].minor.yy73,yymsp[0].minor.yy139);}
2743 #line 2768 "pikchr.c"
2744 yymsp[-4].minor.yy139 = yylhsminor.yy139;
2745 break;
2746 case 80: /* place ::= edge OF object */
2747 #line 686 "pikchr.y"
2748 {yylhsminor.yy139 = pik_place_of_elem(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0);}
2749 #line 2774 "pikchr.c"
2750 yymsp[-2].minor.yy139 = yylhsminor.yy139;
2751 break;
2752 case 81: /* place2 ::= object */
2753 #line 687 "pikchr.y"
2754 {yylhsminor.yy139 = pik_place_of_elem(p,yymsp[0].minor.yy254,0);}
2755 #line 2780 "pikchr.c"
2756 yymsp[0].minor.yy139 = yylhsminor.yy139;
2757 break;
2758 case 82: /* place2 ::= object DOT_E edge */
2759 #line 688 "pikchr.y"
2760 {yylhsminor.yy139 = pik_place_of_elem(p,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
2761 #line 2786 "pikchr.c"
2762 yymsp[-2].minor.yy139 = yylhsminor.yy139;
2763 break;
2764 case 83: /* place2 ::= NTH VERTEX OF object */
2765 #line 689 "pikchr.y"
2766 {yylhsminor.yy139 = pik_nth_vertex(p,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,yymsp[0].minor.yy254);}
2767 #line 2792 "pikchr.c"
2768 yymsp[-3].minor.yy139 = yylhsminor.yy139;
2769 break;
2770 case 84: /* object ::= nth */
2771 #line 701 "pikchr.y"
2772 {yylhsminor.yy254 = pik_find_nth(p,0,&yymsp[0].minor.yy0);}
2773 #line 2798 "pikchr.c"
2774 yymsp[0].minor.yy254 = yylhsminor.yy254;
2775 break;
2776 case 85: /* object ::= nth OF|IN object */
2777 #line 702 "pikchr.y"
2778 {yylhsminor.yy254 = pik_find_nth(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0);}
2779 #line 2804 "pikchr.c"
2780 yymsp[-2].minor.yy254 = yylhsminor.yy254;
2781 break;
2782 case 86: /* objectname ::= PLACENAME */
2783 #line 704 "pikchr.y"
2784 {yylhsminor.yy254 = pik_find_byname(p,0,&yymsp[0].minor.yy0);}
2785 #line 2810 "pikchr.c"
2786 yymsp[0].minor.yy254 = yylhsminor.yy254;
2787 break;
2788 case 87: /* objectname ::= objectname DOT_U PLACENAME */
2789 #line 706 "pikchr.y"
2790 {yylhsminor.yy254 = pik_find_byname(p,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
2791 #line 2816 "pikchr.c"
2792 yymsp[-2].minor.yy254 = yylhsminor.yy254;
2793 break;
2794 case 88: /* nth ::= NTH CLASSNAME */
2795 #line 708 "pikchr.y"
2796 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-1].minor.yy0); }
2797 #line 2822 "pikchr.c"
2798 yymsp[-1].minor.yy0 = yylhsminor.yy0;
2799 break;
2800 case 89: /* nth ::= NTH LAST CLASSNAME */
2801 #line 709 "pikchr.y"
2802 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-2].minor.yy0); }
2803 #line 2828 "pikchr.c"
2804 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2805 break;
2806 case 90: /* nth ::= LAST CLASSNAME */
2807 #line 710 "pikchr.y"
2808 {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.eCode = -1;}
2809 #line 2834 "pikchr.c"
2810 break;
2811 case 91: /* nth ::= LAST */
2812 #line 711 "pikchr.y"
2813 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -1;}
2814 #line 2839 "pikchr.c"
2815 yymsp[0].minor.yy0 = yylhsminor.yy0;
2816 break;
2817 case 92: /* nth ::= NTH LB RB */
2818 #line 712 "pikchr.y"
2819 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-2].minor.yy0);}
2820 #line 2845 "pikchr.c"
2821 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2822 break;
2823 case 93: /* nth ::= NTH LAST LB RB */
2824 #line 713 "pikchr.y"
2825 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-3].minor.yy0);}
2826 #line 2851 "pikchr.c"
2827 yymsp[-3].minor.yy0 = yylhsminor.yy0;
2828 break;
2829 case 94: /* nth ::= LAST LB RB */
2830 #line 714 "pikchr.y"
2831 {yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; }
2832 #line 2857 "pikchr.c"
2833 break;
2834 case 95: /* expr ::= expr PLUS expr */
2835 #line 716 "pikchr.y"
2836 {yylhsminor.yy73=yymsp[-2].minor.yy73+yymsp[0].minor.yy73;}
2837 #line 2862 "pikchr.c"
2838 yymsp[-2].minor.yy73 = yylhsminor.yy73;
2839 break;
2840 case 96: /* expr ::= expr MINUS expr */
2841 #line 717 "pikchr.y"
2842 {yylhsminor.yy73=yymsp[-2].minor.yy73-yymsp[0].minor.yy73;}
2843 #line 2868 "pikchr.c"
2844 yymsp[-2].minor.yy73 = yylhsminor.yy73;
2845 break;
2846 case 97: /* expr ::= expr STAR expr */
2847 #line 718 "pikchr.y"
2848 {yylhsminor.yy73=yymsp[-2].minor.yy73*yymsp[0].minor.yy73;}
2849 #line 2874 "pikchr.c"
2850 yymsp[-2].minor.yy73 = yylhsminor.yy73;
2851 break;
2852 case 98: /* expr ::= expr SLASH expr */
2853 #line 719 "pikchr.y"
2854 {
2855 if( yymsp[0].minor.yy73==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy73 = 0.0; }
2856 else{ yylhsminor.yy73 = yymsp[-2].minor.yy73/yymsp[0].minor.yy73; }
2857 }
2858 #line 2883 "pikchr.c"
2859 yymsp[-2].minor.yy73 = yylhsminor.yy73;
2860 break;
2861 case 99: /* expr ::= MINUS expr */
2862 #line 723 "pikchr.y"
2863 {yymsp[-1].minor.yy73=-yymsp[0].minor.yy73;}
2864 #line 2889 "pikchr.c"
2865 break;
2866 case 100: /* expr ::= PLUS expr */
2867 #line 724 "pikchr.y"
2868 {yymsp[-1].minor.yy73=yymsp[0].minor.yy73;}
2869 #line 2894 "pikchr.c"
2870 break;
2871 case 101: /* expr ::= LP expr RP */
2872 #line 725 "pikchr.y"
2873 {yymsp[-2].minor.yy73=yymsp[-1].minor.yy73;}
2874 #line 2899 "pikchr.c"
2875 break;
2876 case 102: /* expr ::= NUMBER */
2877 #line 726 "pikchr.y"
2878 {yylhsminor.yy73=pik_atof(p,&yymsp[0].minor.yy0);}
2879 #line 2904 "pikchr.c"
2880 yymsp[0].minor.yy73 = yylhsminor.yy73;
2881 break;
2882 case 103: /* expr ::= ID */
2883 #line 727 "pikchr.y"
2884 {yylhsminor.yy73=pik_get_var(p,&yymsp[0].minor.yy0);}
2885 #line 2910 "pikchr.c"
2886 yymsp[0].minor.yy73 = yylhsminor.yy73;
2887 break;
2888 case 104: /* expr ::= FUNC1 LP expr RP */
2889 #line 728 "pikchr.y"
2890 {yylhsminor.yy73 = pik_func(p,&yymsp[-3].minor.yy0,yymsp[-1].minor.yy73,0.0);}
2891 #line 2916 "pikchr.c"
2892 yymsp[-3].minor.yy73 = yylhsminor.yy73;
2893 break;
2894 case 105: /* expr ::= FUNC2 LP expr COMMA expr RP */
2895 #line 729 "pikchr.y"
2896 {yylhsminor.yy73 = pik_func(p,&yymsp[-5].minor.yy0,yymsp[-3].minor.yy73,yymsp[-1].minor.yy73);}
2897 #line 2922 "pikchr.c"
2898 yymsp[-5].minor.yy73 = yylhsminor.yy73;
2899 break;
2900 case 106: /* expr ::= place2 DOT_XY X */
2901 #line 730 "pikchr.y"
2902 {yylhsminor.yy73 = yymsp[-2].minor.yy139.x;}
2903 #line 2928 "pikchr.c"
2904 yymsp[-2].minor.yy73 = yylhsminor.yy73;
2905 break;
2906 case 107: /* expr ::= place2 DOT_XY Y */
2907 #line 731 "pikchr.y"
2908 {yylhsminor.yy73 = yymsp[-2].minor.yy139.y;}
2909 #line 2934 "pikchr.c"
2910 yymsp[-2].minor.yy73 = yylhsminor.yy73;
2911 break;
2912 case 108: /* expr ::= object DOT_L numproperty */
2913 case 109: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==109);
2914 case 110: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==110);
2915 #line 732 "pikchr.y"
2916 {yylhsminor.yy73=pik_property_of(p,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
2917 #line 2942 "pikchr.c"
2918 yymsp[-2].minor.yy73 = yylhsminor.yy73;
2919 break;
2920 default:
2921 /* (111) lvalue ::= ID */ yytestcase(yyruleno==111);
2922 /* (112) lvalue ::= FILL */ yytestcase(yyruleno==112);
@@ -3007,18 +3015,18 @@
3015 ){
3016 pik_parserARG_FETCH
3017 pik_parserCTX_FETCH
3018 #define TOKEN yyminor
3019 /************ Begin %syntax_error code ****************************************/
3020 #line 499 "pikchr.y"
3021
3022 if( TOKEN.z && TOKEN.z[0] ){
3023 pik_error(p, &TOKEN, "syntax error");
3024 }else{
3025 pik_error(p, 0, "syntax error");
3026 }
3027 #line 3052 "pikchr.c"
3028 /************ End %syntax_error code ******************************************/
3029 pik_parserARG_STORE /* Suppress warning about unused %extra_argument variable */
3030 pik_parserCTX_STORE
3031 }
3032
@@ -3247,11 +3255,11 @@
3255 #else
3256 (void)iToken;
3257 return 0;
3258 #endif
3259 }
3260 #line 737 "pikchr.y"
3261
3262
3263
3264 /* Chart of the 140 official HTML color names with their
3265 ** corresponding RGB value.
@@ -3855,11 +3863,11 @@
3863 static void fileInit(Pik *p, PElem *pElem){
3864 pElem->w = pik_value(p, "filewid",7,0);
3865 pElem->h = pik_value(p, "fileht",6,0);
3866 pElem->rad = pik_value(p, "filerad",7,0);
3867 }
3868 /* Return offset from the center of the file to the compass point
3869 ** given by parameter cp */
3870 static PPoint fileOffset(Pik *p, PElem *pElem, int cp){
3871 PPoint pt;
3872 PNum w2 = 0.5*pElem->w;
3873 PNum h2 = 0.5*pElem->h;
@@ -4004,11 +4012,11 @@
4012 pElem->h = pik_value(p, "lineht",6,0);
4013 pElem->rad = 1000;
4014 pElem->fill = -1.0; /* Disable fill by default */
4015 }
4016 /* Return a point along the path from "f" to "t" that is r units
4017 ** prior to reaching "t", except if the path is less than 2*r total,
4018 ** return the midpoint.
4019 */
4020 static PPoint radiusMidpoint(PPoint f, PPoint t, PNum r, int *pbMid){
4021 PNum dx = t.x - f.x;
4022 PNum dy = t.y - f.y;
@@ -4368,11 +4376,11 @@
4376 ** * The space character is changed into non-breaking space (U+0080)
4377 ** if mFlags has the 0x01 bit set. This is needed when outputting
4378 ** text to preserve leading and trailing whitespace. Turns out we
4379 ** cannot use &nbsp; as that is an HTML-ism and is not valid in XML.
4380 **
4381 ** * The "&" character is changed into "&amp;" if mFlags has the
4382 ** 0x02 bit set. This is needed when generating error message text.
4383 **
4384 ** * Except for the above, only "<" and ">" are escaped.
4385 */
4386 static void pik_append_text(Pik *p, const char *zText, int n, int mFlags){
@@ -4484,11 +4492,11 @@
4492
4493 /* Append a style="..." text. But, leave the quote unterminated, in case
4494 ** the caller wants to add some more.
4495 */
4496 static void pik_append_style(Pik *p, PElem *pElem){
4497 pik_append(p, " style=\"", -1);
4498 if( pElem->fill>=0 ){
4499 pik_append_clr(p, "fill:", pElem->fill, ";");
4500 }else{
4501 pik_append(p,"fill:none;",-1);
4502 }
@@ -4542,11 +4550,11 @@
4550 aTxt[i].eCode = (aTxt[i].eCode & ~TP_VMASK) | TP_ABOVE2;
4551 break;
4552 }
4553 }
4554 }
4555 /* If there is more than one TP_BELOW, change the last to TP_BELOW2 */
4556 for(j=mJust=0, i=0; i<n; i++){
4557 if( aTxt[i].eCode & TP_BELOW ){
4558 if( j==0 ){
4559 j++;
4560 mJust = aTxt[i].eCode & TP_JMASK;
@@ -4585,20 +4593,17 @@
4593 }
4594 }
4595 }
4596 }
4597
4598 /* Append multiple <text> SVG element for the text fields of the PElem.
4599 ** Parameters:
4600 **
4601 ** p The Pik object into which we are rendering
4602 **
4603 ** pElem Object containing the text to be rendered
4604 **
 
 
 
4605 ** pBox If not NULL, do no rendering at all. Instead
4606 ** expand the box object so that it will include all
4607 ** of the text.
4608 */
4609 static void pik_append_txt(Pik *p, PElem *pElem, PBox *pBox){
@@ -4771,11 +4776,11 @@
4776
4777 /*
4778 ** Process an "assert( place1 == place2 )" statement. Always return NULL.
4779 */
4780 static PElem *pik_place_assert(Pik *p, PPoint *e1, PToken *pEq, PPoint *e2){
4781 char zE1[100], zE2[100], zMsg[210];
4782
4783 /* Convert the numbers to strings using %g for comparison. This
4784 ** limits the precision of the comparison to account for rounding error. */
4785 snprintf(zE1, sizeof(zE1), "(%g,%g)", e1->x, e1->y); zE1[sizeof(zE1)-1] = 0;
4786 snprintf(zE2, sizeof(zE2), "(%g,%g)", e2->x, e2->y); zE1[sizeof(zE2)-1] = 0;
@@ -4874,11 +4879,11 @@
4879 if( pA->ne.x<pB->ne.x ) pA->ne.x = pB->ne.x;
4880 if( pA->ne.y<pB->ne.y ) pA->ne.y = pB->ne.y;
4881 }
4882
4883 /* Enlarge the PBox of the first argument, if necessary, so that
4884 ** it contains the point described by the 2nd and 3rd arguments.
4885 */
4886 static void pik_bbox_add_xy(PBox *pA, PNum x, PNum y){
4887 if( pik_bbox_isempty(pA) ){
4888 pA->ne.x = x;
4889 pA->ne.y = y;
@@ -5189,11 +5194,11 @@
5194 }
5195 return;
5196 }
5197
5198 /*
5199 ** Set a "dashed" property like "dash 0.05"
5200 **
5201 ** Use the value supplied by pVal if available. If pVal==0, use
5202 ** a default.
5203 */
5204 void pik_set_dashed(Pik *p, PToken *pId, PNum *pVal){
@@ -5351,11 +5356,11 @@
5356
5357 /* Process a movement attribute of the form "right until even with ..."
5358 **
5359 ** pDir is the first keyword, "right" or "left" or "up" or "down".
5360 ** The movement is in that direction until its closest approach to
5361 ** the point specified by pPoint.
5362 */
5363 static void pik_evenwith(Pik *p, PToken *pDir, PPoint *pPlace){
5364 PElem *pElem = p->cur;
5365 int n;
5366 if( !pElem->type->isLine ){
@@ -5521,15 +5526,16 @@
5526 else iRes = (iRes &~TP_SZMASK)|TP_SMALL; break;
5527 }
5528 return iRes;
5529 }
5530
5531 /* Return an estimate of the actual number of displayed characters
5532 ** in a character string.
5533 **
5534 ** Omit "\" used to escape characters. And count entities like
5535 ** "&lt;" as a single character. Multi-byte UTF8 characters count
5536 ** as a single character.
5537 */
5538 static int pik_text_length(const PToken *pToken){
5539 int n = pToken->n;
5540 const char *z = pToken->z;
5541 int cnt, j;
@@ -5545,11 +5551,11 @@
5551 }
5552 }
5553 return cnt;
5554 }
5555
5556 /* Adjust the width, height, and/or radius of the object so that
5557 ** it fits around the text that has been added so far.
5558 **
5559 ** (1) Only text specified prior to this attribute is considered.
5560 ** (2) The text size is estimated based on the charht and charwid
5561 ** variable settings.
@@ -5856,12 +5862,12 @@
5862 pik_error(p, pName, "no such object");
5863 return 0;
5864 }
5865
5866 /* Change most of the settings for the current object to be the
5867 ** same as the pOther object, or the most recent element of the same
5868 ** type if pOther is NULL.
5869 */
5870 static void pik_same(Pik *p, PElem *pOther, PToken *pErrTok){
5871 PElem *pElem = p->cur;
5872 if( p->nErr ) return;
5873 if( pOther==0 ){
@@ -5947,11 +5953,11 @@
5953 return out;
5954 }
5955
5956 /* Compute the position that is dist away from pt at an heading angle of r
5957 **
5958 ** The angle is a compass heading in degrees. North is 0 (or 360).
5959 ** East is 90. South is 180. West is 270. And so forth.
5960 */
5961 static PPoint pik_position_at_angle(Pik *p, PNum dist, PNum r, PPoint pt){
5962 r *= 0.017453292519943295769; /* degrees to radians */
5963 pt.x += dist*sin(r);
@@ -6366,10 +6372,23 @@
6372 h = p->bbox.ne.y - p->bbox.sw.y;
6373 p->wSVG = (int)(p->rScale*w);
6374 p->hSVG = (int)(p->rScale*h);
6375 pik_append_dis(p, " viewBox=\"0 0 ",w,"");
6376 pik_append_dis(p, " ",h,"\">\n");
6377 if( (p->mFlags & PIKCHR_INCLUDE_SOURCE)!=0 ){
6378 /* emit original pikchr source code as metadata */
6379 /* FIXME: emit this only if a certain p->mFlags is set. */
6380 pik_append(p, "<metadata>\n", 11);
6381 pik_append(p, "<pikchr:pikchr xmlns:pikchr="
6382 "\"https://pikchr.org/home/doc/trunk/doc/grammar.md\">\n",
6383 -1);
6384 pik_append(p, "<pikchr:src><![CDATA[", 21);
6385 pik_append(p, p->zIn, (int)p->nIn);
6386 pik_append(p, "]]></pikchr:src>\n", 17);
6387 pik_append(p, "</pikchr:pikchr>\n", 17);
6388 pik_append(p, "</metadata>\n", 12);
6389 }
6390 pik_elist_render(p, pEList);
6391 pik_append(p,"</svg>\n", -1);
6392 }else{
6393 p->wSVG = -1;
6394 p->hSVG = -1;
@@ -6482,11 +6501,11 @@
6501 { "x", 1, T_X, 0, 0 },
6502 { "y", 1, T_Y, 0, 0 },
6503 };
6504
6505 /*
6506 ** Search a PikWordlist for the given keyword. Return a pointer to the
6507 ** element found. Or return 0 if not found.
6508 */
6509 static const PikWord *pik_find_word(
6510 const char *zIn, /* Word to search for */
6511 int n, /* Length of zIn */
@@ -6809,11 +6828,11 @@
6828 ** Parse the PIKCHR script contained in zText[]. Return a rendering. Or
6829 ** if an error is encountered, return the error text. The error message
6830 ** is HTML formatted. So regardless of what happens, the return text
6831 ** is safe to be insertd into an HTML output stream.
6832 **
6833 ** If pnWidth and pnHeight are not NULL, then this routine writes the
6834 ** width and height of the <SVG> object into the integers that they
6835 ** point to. A value of -1 is written if an error is seen.
6836 **
6837 ** If zClass is not NULL, then it is a class name to be included in
6838 ** the <SVG> markup.
@@ -6837,10 +6856,11 @@
6856 memset(&s, 0, sizeof(s));
6857 s.zIn = zText;
6858 s.nIn = (unsigned int)strlen(zText);
6859 s.eDir = DIR_RIGHT;
6860 s.zClass = zClass;
6861 s.mFlags = mFlags;
6862 pik_parserInit(&sParse, &s);
6863 #if 0
6864 pik_parserTrace(stdout, "parser: ");
6865 #endif
6866 for(i=0; zText[i] && s.nErr==0; i+=sz){
@@ -6911,11 +6931,12 @@
6931 ** input text and the rendered SVG for all files named on the command
6932 ** line.
6933 */
6934 int main(int argc, char **argv){
6935 int i;
6936 int bNoEcho = 0; /* Do not the text of the script */
6937 int mPikchrFlags = 0; /* Flags passed into pikchr() */
6938 printf(
6939 "<!DOCTYPE html>\n"
6940 "<html lang=\"en-US\">\n"
6941 "<head>\n<title>PIKCHR Test</title>\n"
6942 "<meta charset=\"utf-8\">\n"
@@ -6936,10 +6957,13 @@
6957 z++;
6958 if( z[0]=='-' ) z++;
6959 if( strcmp(z,"no-echo")==0 ){
6960 bNoEcho = 1;
6961 }else
6962 if( strcmp(z,"include-source")==0 ){
6963 mPikchrFlags |= PIKCHR_INCLUDE_SOURCE;
6964 }else
6965 {
6966 fprintf(stderr,"unknown option: \"%s\"\n", argv[i]);
6967 exit(1);
6968 }
6969 continue;
@@ -6980,11 +7004,11 @@
7004 break;
7005 }
7006 }
7007 printf("</pre></blockquote>\n");
7008 }
7009 zOut = pikchr(zIn, "pikchr", mPikchrFlags, &w, &h);
7010 free(zIn);
7011 if( zOut ){
7012 if( w<0 ){
7013 printf("<p>ERROR:</p>\n");
7014 }else if( bNoEcho==0 ){
@@ -6999,6 +7023,6 @@
7023 printf("</body></html>\n");
7024 return 0;
7025 }
7026 #endif /* PIKCHR_SHELL */
7027
7028 #line 7053 "pikchr.c"
7029

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button