Fossil SCM

Update to the very latest pikchr.c file for testing.

drh 2020-09-16 04:14 trunk
Commit a9c54aad9c5f6e44675cf277b20d031403f1cfde71e1fe365f6bb51cd1a85e08
1 file changed +382 -376
+382 -376
--- src/pikchr.c
+++ src/pikchr.c
@@ -146,10 +146,12 @@
146146
#define CP_S 5
147147
#define CP_SW 6
148148
#define CP_W 7
149149
#define CP_NW 8
150150
#define CP_C 9 /* .center or .c */
151
+#define CP_END 10 /* .end */
152
+#define CP_START 11 /* .start */
151153
152154
/* Heading angles corresponding to compass points */
153155
static const PNum pik_hdg_angle[] = {
154156
/* none */ 0.0,
155157
/* N */ 0.0,
@@ -262,26 +264,21 @@
262264
#define IsLeftRight(X) (((X)&1)==0)
263265
264266
/* Bitmask for the various attributes for PElem. These bits are
265267
** collected in PElem.mProp and PElem.mCalc to check for constraint
266268
** errors. */
267
-#define A_WIDTH 0x000001
268
-#define A_HEIGHT 0x000002
269
-#define A_RADIUS 0x000004
270
-#define A_THICKNESS 0x000008
271
-#define A_DASHED 0x000010 /* Includes "dotted" */
272
-#define A_FILL 0x000020
273
-#define A_COLOR 0x000040
274
-#define A_ARROW 0x000080
275
-#define A_TOP 0x000100
276
-#define A_BOTTOM 0x000200
277
-#define A_LEFT 0x000400
278
-#define A_RIGHT 0x000800
279
-#define A_CORNER 0x001000
280
-#define A_FROM 0x002000
281
-#define A_CW 0x004000
282
-#define A_AT 0x008000
269
+#define A_WIDTH 0x0001
270
+#define A_HEIGHT 0x0002
271
+#define A_RADIUS 0x0004
272
+#define A_THICKNESS 0x0008
273
+#define A_DASHED 0x0010 /* Includes "dotted" */
274
+#define A_FILL 0x0020
275
+#define A_COLOR 0x0040
276
+#define A_ARROW 0x0080
277
+#define A_FROM 0x0100
278
+#define A_CW 0x0200
279
+#define A_AT 0x0400
283280
284281
285282
/* A single element */
286283
struct PElem {
287284
const PClass *type; /* Element type */
@@ -453,11 +450,11 @@
453450
static void pik_behind(Pik*,PElem*);
454451
static PElem *pik_assert(Pik*,PNum,PToken*,PNum);
455452
static PElem *pik_place_assert(Pik*,PPoint*,PToken*,PPoint*);
456453
457454
458
-#line 484 "pikchr.c"
455
+#line 481 "pikchr.c"
459456
/**************** End of %include directives **********************************/
460457
/* These constants specify the various numeric values for terminal symbols.
461458
***************** Begin token definitions *************************************/
462459
#ifndef T_ID
463460
#define T_ID 1
@@ -1629,22 +1626,22 @@
16291626
** inside the C code.
16301627
*/
16311628
/********* Begin destructor definitions ***************************************/
16321629
case 94: /* element_list */
16331630
{
1634
-#line 473 "pikchr.y"
1631
+#line 470 "pikchr.y"
16351632
pik_elist_free(p,(yypminor->yy72));
1636
-#line 1661 "pikchr.c"
1633
+#line 1658 "pikchr.c"
16371634
}
16381635
break;
16391636
case 95: /* element */
16401637
case 96: /* unnamed_element */
16411638
case 97: /* basetype */
16421639
{
1643
-#line 475 "pikchr.y"
1640
+#line 472 "pikchr.y"
16441641
pik_elem_free(p,(yypminor->yy254));
1645
-#line 1670 "pikchr.c"
1642
+#line 1667 "pikchr.c"
16461643
}
16471644
break;
16481645
/********* End destructor definitions *****************************************/
16491646
default: break; /* If no destructor action specified: do nothing */
16501647
}
@@ -1858,14 +1855,14 @@
18581855
#endif
18591856
while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
18601857
/* Here code is inserted which will execute if the parser
18611858
** stack every overflows */
18621859
/******** Begin %stack_overflow code ******************************************/
1863
-#line 506 "pikchr.y"
1860
+#line 503 "pikchr.y"
18641861
18651862
pik_error(p, 0, "parser stack overflow");
1866
-#line 1891 "pikchr.c"
1863
+#line 1888 "pikchr.c"
18671864
/******** End %stack_overflow code ********************************************/
18681865
pik_parserARG_STORE /* Suppress warning about unused %extra_argument var */
18691866
pik_parserCTX_STORE
18701867
}
18711868
@@ -2330,593 +2327,593 @@
23302327
** break;
23312328
*/
23322329
/********** Begin reduce actions **********************************************/
23332330
YYMINORTYPE yylhsminor;
23342331
case 0: /* document ::= element_list */
2335
-#line 510 "pikchr.y"
2332
+#line 507 "pikchr.y"
23362333
{pik_render(p,yymsp[0].minor.yy72);}
2337
-#line 2362 "pikchr.c"
2334
+#line 2359 "pikchr.c"
23382335
break;
23392336
case 1: /* element_list ::= element */
2340
-#line 513 "pikchr.y"
2337
+#line 510 "pikchr.y"
23412338
{ yylhsminor.yy72 = pik_elist_append(p,0,yymsp[0].minor.yy254); }
2342
-#line 2367 "pikchr.c"
2339
+#line 2364 "pikchr.c"
23432340
yymsp[0].minor.yy72 = yylhsminor.yy72;
23442341
break;
23452342
case 2: /* element_list ::= element_list EOL element */
2346
-#line 515 "pikchr.y"
2343
+#line 512 "pikchr.y"
23472344
{ yylhsminor.yy72 = pik_elist_append(p,yymsp[-2].minor.yy72,yymsp[0].minor.yy254); }
2348
-#line 2373 "pikchr.c"
2345
+#line 2370 "pikchr.c"
23492346
yymsp[-2].minor.yy72 = yylhsminor.yy72;
23502347
break;
23512348
case 3: /* element ::= */
2352
-#line 518 "pikchr.y"
2349
+#line 515 "pikchr.y"
23532350
{ yymsp[1].minor.yy254 = 0; }
2354
-#line 2379 "pikchr.c"
2351
+#line 2376 "pikchr.c"
23552352
break;
23562353
case 4: /* element ::= direction */
2357
-#line 519 "pikchr.y"
2354
+#line 516 "pikchr.y"
23582355
{ pik_set_direction(p,yymsp[0].minor.yy0.eCode); yylhsminor.yy254=0; }
2359
-#line 2384 "pikchr.c"
2356
+#line 2381 "pikchr.c"
23602357
yymsp[0].minor.yy254 = yylhsminor.yy254;
23612358
break;
23622359
case 5: /* element ::= lvalue ASSIGN rvalue */
2363
-#line 520 "pikchr.y"
2360
+#line 517 "pikchr.y"
23642361
{pik_set_var(p,&yymsp[-2].minor.yy0,yymsp[0].minor.yy73,&yymsp[-1].minor.yy0); yylhsminor.yy254=0;}
2365
-#line 2390 "pikchr.c"
2362
+#line 2387 "pikchr.c"
23662363
yymsp[-2].minor.yy254 = yylhsminor.yy254;
23672364
break;
23682365
case 6: /* element ::= PLACENAME COLON unnamed_element */
2369
-#line 522 "pikchr.y"
2366
+#line 519 "pikchr.y"
23702367
{ yylhsminor.yy254 = yymsp[0].minor.yy254; pik_elem_setname(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0); }
2371
-#line 2396 "pikchr.c"
2368
+#line 2393 "pikchr.c"
23722369
yymsp[-2].minor.yy254 = yylhsminor.yy254;
23732370
break;
23742371
case 7: /* element ::= PLACENAME COLON position */
2375
-#line 524 "pikchr.y"
2372
+#line 521 "pikchr.y"
23762373
{ yylhsminor.yy254 = pik_elem_new(p,0,0,0);
23772374
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"
2375
+#line 2400 "pikchr.c"
23792376
yymsp[-2].minor.yy254 = yylhsminor.yy254;
23802377
break;
23812378
case 8: /* element ::= unnamed_element */
2382
-#line 526 "pikchr.y"
2379
+#line 523 "pikchr.y"
23832380
{yylhsminor.yy254 = yymsp[0].minor.yy254;}
2384
-#line 2409 "pikchr.c"
2381
+#line 2406 "pikchr.c"
23852382
yymsp[0].minor.yy254 = yylhsminor.yy254;
23862383
break;
23872384
case 9: /* element ::= print prlist */
2388
-#line 527 "pikchr.y"
2385
+#line 524 "pikchr.y"
23892386
{pik_append(p,"<br>\n",5); yymsp[-1].minor.yy254=0;}
2390
-#line 2415 "pikchr.c"
2387
+#line 2412 "pikchr.c"
23912388
break;
23922389
case 10: /* element ::= ASSERT LP expr EQ expr RP */
2393
-#line 532 "pikchr.y"
2390
+#line 529 "pikchr.y"
23942391
{yymsp[-5].minor.yy254=pik_assert(p,yymsp[-3].minor.yy73,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy73);}
2395
-#line 2420 "pikchr.c"
2392
+#line 2417 "pikchr.c"
23962393
break;
23972394
case 11: /* element ::= ASSERT LP place EQ place RP */
2398
-#line 534 "pikchr.y"
2395
+#line 531 "pikchr.y"
23992396
{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"
2397
+#line 2422 "pikchr.c"
24012398
break;
24022399
case 12: /* rvalue ::= PLACENAME */
2403
-#line 545 "pikchr.y"
2400
+#line 542 "pikchr.y"
24042401
{yylhsminor.yy73 = pik_lookup_color(p,&yymsp[0].minor.yy0);}
2405
-#line 2430 "pikchr.c"
2402
+#line 2427 "pikchr.c"
24062403
yymsp[0].minor.yy73 = yylhsminor.yy73;
24072404
break;
24082405
case 13: /* pritem ::= FILL */
24092406
case 14: /* pritem ::= COLOR */ yytestcase(yyruleno==14);
24102407
case 15: /* pritem ::= THICKNESS */ yytestcase(yyruleno==15);
2411
-#line 550 "pikchr.y"
2408
+#line 547 "pikchr.y"
24122409
{pik_append_num(p,"",pik_value(p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.n,0));}
2413
-#line 2438 "pikchr.c"
2410
+#line 2435 "pikchr.c"
24142411
break;
24152412
case 16: /* pritem ::= rvalue */
2416
-#line 553 "pikchr.y"
2413
+#line 550 "pikchr.y"
24172414
{pik_append_num(p,"",yymsp[0].minor.yy73);}
2418
-#line 2443 "pikchr.c"
2415
+#line 2440 "pikchr.c"
24192416
break;
24202417
case 17: /* pritem ::= STRING */
2421
-#line 554 "pikchr.y"
2418
+#line 551 "pikchr.y"
24222419
{pik_append_text(p,yymsp[0].minor.yy0.z+1,yymsp[0].minor.yy0.n-2,0);}
2423
-#line 2448 "pikchr.c"
2420
+#line 2445 "pikchr.c"
24242421
break;
24252422
case 18: /* prsep ::= COMMA */
2426
-#line 555 "pikchr.y"
2423
+#line 552 "pikchr.y"
24272424
{pik_append(p, " ", 1);}
2428
-#line 2453 "pikchr.c"
2425
+#line 2450 "pikchr.c"
24292426
break;
24302427
case 19: /* unnamed_element ::= basetype attribute_list */
2431
-#line 558 "pikchr.y"
2428
+#line 555 "pikchr.y"
24322429
{yylhsminor.yy254 = yymsp[-1].minor.yy254; pik_after_adding_attributes(p,yylhsminor.yy254);}
2433
-#line 2458 "pikchr.c"
2430
+#line 2455 "pikchr.c"
24342431
yymsp[-1].minor.yy254 = yylhsminor.yy254;
24352432
break;
24362433
case 20: /* basetype ::= CLASSNAME */
2437
-#line 560 "pikchr.y"
2434
+#line 557 "pikchr.y"
24382435
{yylhsminor.yy254 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); }
2439
-#line 2464 "pikchr.c"
2436
+#line 2461 "pikchr.c"
24402437
yymsp[0].minor.yy254 = yylhsminor.yy254;
24412438
break;
24422439
case 21: /* basetype ::= STRING textposition */
2443
-#line 562 "pikchr.y"
2440
+#line 559 "pikchr.y"
24442441
{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"
2442
+#line 2467 "pikchr.c"
24462443
yymsp[-1].minor.yy254 = yylhsminor.yy254;
24472444
break;
24482445
case 22: /* basetype ::= LB savelist element_list RB */
2449
-#line 564 "pikchr.y"
2446
+#line 561 "pikchr.y"
24502447
{ 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"
2448
+#line 2473 "pikchr.c"
24522449
break;
24532450
case 23: /* savelist ::= */
2454
-#line 569 "pikchr.y"
2451
+#line 566 "pikchr.y"
24552452
{yymsp[1].minor.yy72 = p->list; p->list = 0;}
2456
-#line 2481 "pikchr.c"
2453
+#line 2478 "pikchr.c"
24572454
break;
24582455
case 24: /* relexpr ::= expr */
2459
-#line 576 "pikchr.y"
2456
+#line 573 "pikchr.y"
24602457
{yylhsminor.yy60.rAbs = yymsp[0].minor.yy73; yylhsminor.yy60.rRel = 0;}
2461
-#line 2486 "pikchr.c"
2458
+#line 2483 "pikchr.c"
24622459
yymsp[0].minor.yy60 = yylhsminor.yy60;
24632460
break;
24642461
case 25: /* relexpr ::= expr PERCENT */
2465
-#line 577 "pikchr.y"
2462
+#line 574 "pikchr.y"
24662463
{yylhsminor.yy60.rAbs = 0; yylhsminor.yy60.rRel = yymsp[-1].minor.yy73/100;}
2467
-#line 2492 "pikchr.c"
2464
+#line 2489 "pikchr.c"
24682465
yymsp[-1].minor.yy60 = yylhsminor.yy60;
24692466
break;
24702467
case 26: /* optrelexpr ::= */
2471
-#line 579 "pikchr.y"
2468
+#line 576 "pikchr.y"
24722469
{yymsp[1].minor.yy60.rAbs = 0; yymsp[1].minor.yy60.rRel = 1.0;}
2473
-#line 2498 "pikchr.c"
2470
+#line 2495 "pikchr.c"
24742471
break;
24752472
case 27: /* attribute_list ::= relexpr alist */
2476
-#line 581 "pikchr.y"
2473
+#line 578 "pikchr.y"
24772474
{pik_add_direction(p,0,&yymsp[-1].minor.yy60);}
2478
-#line 2503 "pikchr.c"
2475
+#line 2500 "pikchr.c"
24792476
break;
24802477
case 28: /* attribute ::= numproperty relexpr */
2481
-#line 585 "pikchr.y"
2478
+#line 582 "pikchr.y"
24822479
{ pik_set_numprop(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy60); }
2483
-#line 2508 "pikchr.c"
2480
+#line 2505 "pikchr.c"
24842481
break;
24852482
case 29: /* attribute ::= dashproperty expr */
2486
-#line 586 "pikchr.y"
2483
+#line 583 "pikchr.y"
24872484
{ pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy73); }
2488
-#line 2513 "pikchr.c"
2485
+#line 2510 "pikchr.c"
24892486
break;
24902487
case 30: /* attribute ::= dashproperty */
2491
-#line 587 "pikchr.y"
2488
+#line 584 "pikchr.y"
24922489
{ pik_set_dashed(p,&yymsp[0].minor.yy0,0); }
2493
-#line 2518 "pikchr.c"
2490
+#line 2515 "pikchr.c"
24942491
break;
24952492
case 31: /* attribute ::= colorproperty rvalue */
2496
-#line 588 "pikchr.y"
2493
+#line 585 "pikchr.y"
24972494
{ pik_set_clrprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy73); }
2498
-#line 2523 "pikchr.c"
2495
+#line 2520 "pikchr.c"
24992496
break;
25002497
case 32: /* attribute ::= go direction optrelexpr */
2501
-#line 589 "pikchr.y"
2498
+#line 586 "pikchr.y"
25022499
{ pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy60);}
2503
-#line 2528 "pikchr.c"
2500
+#line 2525 "pikchr.c"
25042501
break;
25052502
case 33: /* attribute ::= go direction even position */
2506
-#line 590 "pikchr.y"
2503
+#line 587 "pikchr.y"
25072504
{pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy139);}
2508
-#line 2533 "pikchr.c"
2505
+#line 2530 "pikchr.c"
25092506
break;
25102507
case 34: /* attribute ::= CLOSE */
2511
-#line 591 "pikchr.y"
2508
+#line 588 "pikchr.y"
25122509
{ pik_close_path(p,&yymsp[0].minor.yy0); }
2513
-#line 2538 "pikchr.c"
2510
+#line 2535 "pikchr.c"
25142511
break;
25152512
case 35: /* attribute ::= CHOP */
2516
-#line 592 "pikchr.y"
2513
+#line 589 "pikchr.y"
25172514
{ p->cur->bChop = 1; }
2518
-#line 2543 "pikchr.c"
2515
+#line 2540 "pikchr.c"
25192516
break;
25202517
case 36: /* attribute ::= FROM position */
2521
-#line 593 "pikchr.y"
2518
+#line 590 "pikchr.y"
25222519
{ pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy139); }
2523
-#line 2548 "pikchr.c"
2520
+#line 2545 "pikchr.c"
25242521
break;
25252522
case 37: /* attribute ::= TO position */
2526
-#line 594 "pikchr.y"
2523
+#line 591 "pikchr.y"
25272524
{ pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy139); }
2528
-#line 2553 "pikchr.c"
2525
+#line 2550 "pikchr.c"
25292526
break;
25302527
case 38: /* attribute ::= THEN */
2531
-#line 595 "pikchr.y"
2528
+#line 592 "pikchr.y"
25322529
{ pik_then(p, &yymsp[0].minor.yy0, p->cur); }
2533
-#line 2558 "pikchr.c"
2530
+#line 2555 "pikchr.c"
25342531
break;
25352532
case 39: /* attribute ::= THEN optrelexpr HEADING expr */
25362533
case 41: /* attribute ::= GO optrelexpr HEADING expr */ yytestcase(yyruleno==41);
2537
-#line 597 "pikchr.y"
2534
+#line 594 "pikchr.y"
25382535
{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"
2536
+#line 2561 "pikchr.c"
25402537
break;
25412538
case 40: /* attribute ::= THEN optrelexpr EDGEPT */
25422539
case 42: /* attribute ::= GO optrelexpr EDGEPT */ yytestcase(yyruleno==42);
2543
-#line 598 "pikchr.y"
2540
+#line 595 "pikchr.y"
25442541
{pik_move_hdg(p,&yymsp[-1].minor.yy60,0,0,&yymsp[0].minor.yy0,&yymsp[-2].minor.yy0);}
2545
-#line 2570 "pikchr.c"
2542
+#line 2567 "pikchr.c"
25462543
break;
25472544
case 43: /* attribute ::= AT position */
2548
-#line 603 "pikchr.y"
2545
+#line 600 "pikchr.y"
25492546
{ pik_set_at(p,0,&yymsp[0].minor.yy139,&yymsp[-1].minor.yy0); }
2550
-#line 2575 "pikchr.c"
2547
+#line 2572 "pikchr.c"
25512548
break;
25522549
case 44: /* attribute ::= SAME */
2553
-#line 605 "pikchr.y"
2550
+#line 602 "pikchr.y"
25542551
{pik_same(p,0,&yymsp[0].minor.yy0);}
2555
-#line 2580 "pikchr.c"
2552
+#line 2577 "pikchr.c"
25562553
break;
25572554
case 45: /* attribute ::= SAME AS object */
2558
-#line 606 "pikchr.y"
2555
+#line 603 "pikchr.y"
25592556
{pik_same(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0);}
2560
-#line 2585 "pikchr.c"
2557
+#line 2582 "pikchr.c"
25612558
break;
25622559
case 46: /* attribute ::= STRING textposition */
2563
-#line 607 "pikchr.y"
2560
+#line 604 "pikchr.y"
25642561
{pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy74);}
2565
-#line 2590 "pikchr.c"
2562
+#line 2587 "pikchr.c"
25662563
break;
25672564
case 47: /* attribute ::= FIT */
2568
-#line 608 "pikchr.y"
2565
+#line 605 "pikchr.y"
25692566
{pik_size_to_fit(p,&yymsp[0].minor.yy0); }
2570
-#line 2595 "pikchr.c"
2567
+#line 2592 "pikchr.c"
25712568
break;
25722569
case 48: /* attribute ::= BEHIND object */
2573
-#line 609 "pikchr.y"
2570
+#line 606 "pikchr.y"
25742571
{pik_behind(p,yymsp[0].minor.yy254);}
2575
-#line 2600 "pikchr.c"
2572
+#line 2597 "pikchr.c"
25762573
break;
25772574
case 49: /* withclause ::= DOT_E edge AT position */
25782575
case 50: /* withclause ::= edge AT position */ yytestcase(yyruleno==50);
2579
-#line 617 "pikchr.y"
2576
+#line 614 "pikchr.y"
25802577
{ pik_set_at(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy139,&yymsp[-1].minor.yy0); }
2581
-#line 2606 "pikchr.c"
2578
+#line 2603 "pikchr.c"
25822579
break;
25832580
case 51: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2584
-#line 621 "pikchr.y"
2581
+#line 618 "pikchr.y"
25852582
{yylhsminor.yy0 = yymsp[0].minor.yy0;}
2586
-#line 2611 "pikchr.c"
2583
+#line 2608 "pikchr.c"
25872584
yymsp[0].minor.yy0 = yylhsminor.yy0;
25882585
break;
25892586
case 52: /* boolproperty ::= CW */
2590
-#line 632 "pikchr.y"
2587
+#line 629 "pikchr.y"
25912588
{p->cur->cw = 1;}
2592
-#line 2617 "pikchr.c"
2589
+#line 2614 "pikchr.c"
25932590
break;
25942591
case 53: /* boolproperty ::= CCW */
2595
-#line 633 "pikchr.y"
2592
+#line 630 "pikchr.y"
25962593
{p->cur->cw = 0;}
2597
-#line 2622 "pikchr.c"
2594
+#line 2619 "pikchr.c"
25982595
break;
25992596
case 54: /* boolproperty ::= LARROW */
2600
-#line 634 "pikchr.y"
2597
+#line 631 "pikchr.y"
26012598
{p->cur->larrow=1; p->cur->rarrow=0; }
2602
-#line 2627 "pikchr.c"
2599
+#line 2624 "pikchr.c"
26032600
break;
26042601
case 55: /* boolproperty ::= RARROW */
2605
-#line 635 "pikchr.y"
2602
+#line 632 "pikchr.y"
26062603
{p->cur->larrow=0; p->cur->rarrow=1; }
2607
-#line 2632 "pikchr.c"
2604
+#line 2629 "pikchr.c"
26082605
break;
26092606
case 56: /* boolproperty ::= LRARROW */
2610
-#line 636 "pikchr.y"
2607
+#line 633 "pikchr.y"
26112608
{p->cur->larrow=1; p->cur->rarrow=1; }
2612
-#line 2637 "pikchr.c"
2609
+#line 2634 "pikchr.c"
26132610
break;
26142611
case 57: /* boolproperty ::= INVIS */
2615
-#line 637 "pikchr.y"
2612
+#line 634 "pikchr.y"
26162613
{p->cur->sw = 0.0;}
2617
-#line 2642 "pikchr.c"
2614
+#line 2639 "pikchr.c"
26182615
break;
26192616
case 58: /* boolproperty ::= THICK */
2620
-#line 638 "pikchr.y"
2617
+#line 635 "pikchr.y"
26212618
{p->cur->sw *= 1.5;}
2622
-#line 2647 "pikchr.c"
2619
+#line 2644 "pikchr.c"
26232620
break;
26242621
case 59: /* boolproperty ::= THIN */
2625
-#line 639 "pikchr.y"
2622
+#line 636 "pikchr.y"
26262623
{p->cur->sw *= 0.67;}
2627
-#line 2652 "pikchr.c"
2624
+#line 2649 "pikchr.c"
26282625
break;
26292626
case 60: /* textposition ::= */
2630
-#line 641 "pikchr.y"
2627
+#line 638 "pikchr.y"
26312628
{yymsp[1].minor.yy74 = 0;}
2632
-#line 2657 "pikchr.c"
2629
+#line 2654 "pikchr.c"
26332630
break;
26342631
case 61: /* textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL */
2635
-#line 644 "pikchr.y"
2632
+#line 641 "pikchr.y"
26362633
{yylhsminor.yy74 = pik_text_position(p,yymsp[-1].minor.yy74,&yymsp[0].minor.yy0);}
2637
-#line 2662 "pikchr.c"
2634
+#line 2659 "pikchr.c"
26382635
yymsp[-1].minor.yy74 = yylhsminor.yy74;
26392636
break;
26402637
case 62: /* position ::= expr COMMA expr */
2641
-#line 647 "pikchr.y"
2638
+#line 644 "pikchr.y"
26422639
{yylhsminor.yy139.x=yymsp[-2].minor.yy73; yylhsminor.yy139.y=yymsp[0].minor.yy73;}
2643
-#line 2668 "pikchr.c"
2640
+#line 2665 "pikchr.c"
26442641
yymsp[-2].minor.yy139 = yylhsminor.yy139;
26452642
break;
26462643
case 63: /* position ::= place PLUS expr COMMA expr */
2647
-#line 649 "pikchr.y"
2644
+#line 646 "pikchr.y"
26482645
{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"
2646
+#line 2671 "pikchr.c"
26502647
yymsp[-4].minor.yy139 = yylhsminor.yy139;
26512648
break;
26522649
case 64: /* position ::= place MINUS expr COMMA expr */
2653
-#line 650 "pikchr.y"
2650
+#line 647 "pikchr.y"
26542651
{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"
2652
+#line 2677 "pikchr.c"
26562653
yymsp[-4].minor.yy139 = yylhsminor.yy139;
26572654
break;
26582655
case 65: /* position ::= place PLUS LP expr COMMA expr RP */
2659
-#line 652 "pikchr.y"
2656
+#line 649 "pikchr.y"
26602657
{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"
2658
+#line 2683 "pikchr.c"
26622659
yymsp[-6].minor.yy139 = yylhsminor.yy139;
26632660
break;
26642661
case 66: /* position ::= place MINUS LP expr COMMA expr RP */
2665
-#line 654 "pikchr.y"
2662
+#line 651 "pikchr.y"
26662663
{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"
2664
+#line 2689 "pikchr.c"
26682665
yymsp[-6].minor.yy139 = yylhsminor.yy139;
26692666
break;
26702667
case 67: /* position ::= LP position COMMA position RP */
2671
-#line 655 "pikchr.y"
2668
+#line 652 "pikchr.y"
26722669
{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"
2670
+#line 2695 "pikchr.c"
26742671
break;
26752672
case 68: /* position ::= LP position RP */
2676
-#line 656 "pikchr.y"
2673
+#line 653 "pikchr.y"
26772674
{yymsp[-2].minor.yy139=yymsp[-1].minor.yy139;}
2678
-#line 2703 "pikchr.c"
2675
+#line 2700 "pikchr.c"
26792676
break;
26802677
case 69: /* position ::= expr between position AND position */
2681
-#line 658 "pikchr.y"
2678
+#line 655 "pikchr.y"
26822679
{yylhsminor.yy139 = pik_position_between(p,yymsp[-4].minor.yy73,yymsp[-2].minor.yy139,yymsp[0].minor.yy139);}
2683
-#line 2708 "pikchr.c"
2680
+#line 2705 "pikchr.c"
26842681
yymsp[-4].minor.yy139 = yylhsminor.yy139;
26852682
break;
26862683
case 70: /* position ::= expr LT position COMMA position GT */
2687
-#line 660 "pikchr.y"
2684
+#line 657 "pikchr.y"
26882685
{yylhsminor.yy139 = pik_position_between(p,yymsp[-5].minor.yy73,yymsp[-3].minor.yy139,yymsp[-1].minor.yy139);}
2689
-#line 2714 "pikchr.c"
2686
+#line 2711 "pikchr.c"
26902687
yymsp[-5].minor.yy139 = yylhsminor.yy139;
26912688
break;
26922689
case 71: /* position ::= expr ABOVE position */
2693
-#line 661 "pikchr.y"
2690
+#line 658 "pikchr.y"
26942691
{yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.y += yymsp[-2].minor.yy73;}
2695
-#line 2720 "pikchr.c"
2692
+#line 2717 "pikchr.c"
26962693
yymsp[-2].minor.yy139 = yylhsminor.yy139;
26972694
break;
26982695
case 72: /* position ::= expr BELOW position */
2699
-#line 662 "pikchr.y"
2696
+#line 659 "pikchr.y"
27002697
{yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.y -= yymsp[-2].minor.yy73;}
2701
-#line 2726 "pikchr.c"
2698
+#line 2723 "pikchr.c"
27022699
yymsp[-2].minor.yy139 = yylhsminor.yy139;
27032700
break;
27042701
case 73: /* position ::= expr LEFT OF position */
2705
-#line 663 "pikchr.y"
2702
+#line 660 "pikchr.y"
27062703
{yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.x -= yymsp[-3].minor.yy73;}
2707
-#line 2732 "pikchr.c"
2704
+#line 2729 "pikchr.c"
27082705
yymsp[-3].minor.yy139 = yylhsminor.yy139;
27092706
break;
27102707
case 74: /* position ::= expr RIGHT OF position */
2711
-#line 664 "pikchr.y"
2708
+#line 661 "pikchr.y"
27122709
{yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.x += yymsp[-3].minor.yy73;}
2713
-#line 2738 "pikchr.c"
2710
+#line 2735 "pikchr.c"
27142711
yymsp[-3].minor.yy139 = yylhsminor.yy139;
27152712
break;
27162713
case 75: /* position ::= expr ON HEADING EDGEPT OF position */
2717
-#line 666 "pikchr.y"
2714
+#line 663 "pikchr.y"
27182715
{yylhsminor.yy139 = pik_position_at_hdg(p,yymsp[-5].minor.yy73,&yymsp[-2].minor.yy0,yymsp[0].minor.yy139);}
2719
-#line 2744 "pikchr.c"
2716
+#line 2741 "pikchr.c"
27202717
yymsp[-5].minor.yy139 = yylhsminor.yy139;
27212718
break;
27222719
case 76: /* position ::= expr HEADING EDGEPT OF position */
2723
-#line 668 "pikchr.y"
2720
+#line 665 "pikchr.y"
27242721
{yylhsminor.yy139 = pik_position_at_hdg(p,yymsp[-4].minor.yy73,&yymsp[-2].minor.yy0,yymsp[0].minor.yy139);}
2725
-#line 2750 "pikchr.c"
2722
+#line 2747 "pikchr.c"
27262723
yymsp[-4].minor.yy139 = yylhsminor.yy139;
27272724
break;
27282725
case 77: /* position ::= expr EDGEPT OF position */
2729
-#line 670 "pikchr.y"
2726
+#line 667 "pikchr.y"
27302727
{yylhsminor.yy139 = pik_position_at_hdg(p,yymsp[-3].minor.yy73,&yymsp[-2].minor.yy0,yymsp[0].minor.yy139);}
2731
-#line 2756 "pikchr.c"
2728
+#line 2753 "pikchr.c"
27322729
yymsp[-3].minor.yy139 = yylhsminor.yy139;
27332730
break;
27342731
case 78: /* position ::= expr ON HEADING expr FROM position */
2735
-#line 672 "pikchr.y"
2732
+#line 669 "pikchr.y"
27362733
{yylhsminor.yy139 = pik_position_at_angle(p,yymsp[-5].minor.yy73,yymsp[-2].minor.yy73,yymsp[0].minor.yy139);}
2737
-#line 2762 "pikchr.c"
2734
+#line 2759 "pikchr.c"
27382735
yymsp[-5].minor.yy139 = yylhsminor.yy139;
27392736
break;
27402737
case 79: /* position ::= expr HEADING expr FROM position */
2741
-#line 674 "pikchr.y"
2738
+#line 671 "pikchr.y"
27422739
{yylhsminor.yy139 = pik_position_at_angle(p,yymsp[-4].minor.yy73,yymsp[-2].minor.yy73,yymsp[0].minor.yy139);}
2743
-#line 2768 "pikchr.c"
2740
+#line 2765 "pikchr.c"
27442741
yymsp[-4].minor.yy139 = yylhsminor.yy139;
27452742
break;
27462743
case 80: /* place ::= edge OF object */
2747
-#line 686 "pikchr.y"
2744
+#line 683 "pikchr.y"
27482745
{yylhsminor.yy139 = pik_place_of_elem(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0);}
2749
-#line 2774 "pikchr.c"
2746
+#line 2771 "pikchr.c"
27502747
yymsp[-2].minor.yy139 = yylhsminor.yy139;
27512748
break;
27522749
case 81: /* place2 ::= object */
2753
-#line 687 "pikchr.y"
2750
+#line 684 "pikchr.y"
27542751
{yylhsminor.yy139 = pik_place_of_elem(p,yymsp[0].minor.yy254,0);}
2755
-#line 2780 "pikchr.c"
2752
+#line 2777 "pikchr.c"
27562753
yymsp[0].minor.yy139 = yylhsminor.yy139;
27572754
break;
27582755
case 82: /* place2 ::= object DOT_E edge */
2759
-#line 688 "pikchr.y"
2756
+#line 685 "pikchr.y"
27602757
{yylhsminor.yy139 = pik_place_of_elem(p,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
2761
-#line 2786 "pikchr.c"
2758
+#line 2783 "pikchr.c"
27622759
yymsp[-2].minor.yy139 = yylhsminor.yy139;
27632760
break;
27642761
case 83: /* place2 ::= NTH VERTEX OF object */
2765
-#line 689 "pikchr.y"
2762
+#line 686 "pikchr.y"
27662763
{yylhsminor.yy139 = pik_nth_vertex(p,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,yymsp[0].minor.yy254);}
2767
-#line 2792 "pikchr.c"
2764
+#line 2789 "pikchr.c"
27682765
yymsp[-3].minor.yy139 = yylhsminor.yy139;
27692766
break;
27702767
case 84: /* object ::= nth */
2771
-#line 701 "pikchr.y"
2768
+#line 698 "pikchr.y"
27722769
{yylhsminor.yy254 = pik_find_nth(p,0,&yymsp[0].minor.yy0);}
2773
-#line 2798 "pikchr.c"
2770
+#line 2795 "pikchr.c"
27742771
yymsp[0].minor.yy254 = yylhsminor.yy254;
27752772
break;
27762773
case 85: /* object ::= nth OF|IN object */
2777
-#line 702 "pikchr.y"
2774
+#line 699 "pikchr.y"
27782775
{yylhsminor.yy254 = pik_find_nth(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0);}
2779
-#line 2804 "pikchr.c"
2776
+#line 2801 "pikchr.c"
27802777
yymsp[-2].minor.yy254 = yylhsminor.yy254;
27812778
break;
27822779
case 86: /* objectname ::= PLACENAME */
2783
-#line 704 "pikchr.y"
2780
+#line 701 "pikchr.y"
27842781
{yylhsminor.yy254 = pik_find_byname(p,0,&yymsp[0].minor.yy0);}
2785
-#line 2810 "pikchr.c"
2782
+#line 2807 "pikchr.c"
27862783
yymsp[0].minor.yy254 = yylhsminor.yy254;
27872784
break;
27882785
case 87: /* objectname ::= objectname DOT_U PLACENAME */
2789
-#line 706 "pikchr.y"
2786
+#line 703 "pikchr.y"
27902787
{yylhsminor.yy254 = pik_find_byname(p,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
2791
-#line 2816 "pikchr.c"
2788
+#line 2813 "pikchr.c"
27922789
yymsp[-2].minor.yy254 = yylhsminor.yy254;
27932790
break;
27942791
case 88: /* nth ::= NTH CLASSNAME */
2795
-#line 708 "pikchr.y"
2792
+#line 705 "pikchr.y"
27962793
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-1].minor.yy0); }
2797
-#line 2822 "pikchr.c"
2794
+#line 2819 "pikchr.c"
27982795
yymsp[-1].minor.yy0 = yylhsminor.yy0;
27992796
break;
28002797
case 89: /* nth ::= NTH LAST CLASSNAME */
2801
-#line 709 "pikchr.y"
2798
+#line 706 "pikchr.y"
28022799
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-2].minor.yy0); }
2803
-#line 2828 "pikchr.c"
2800
+#line 2825 "pikchr.c"
28042801
yymsp[-2].minor.yy0 = yylhsminor.yy0;
28052802
break;
28062803
case 90: /* nth ::= LAST CLASSNAME */
2807
-#line 710 "pikchr.y"
2804
+#line 707 "pikchr.y"
28082805
{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.eCode = -1;}
2809
-#line 2834 "pikchr.c"
2806
+#line 2831 "pikchr.c"
28102807
break;
28112808
case 91: /* nth ::= LAST */
2812
-#line 711 "pikchr.y"
2809
+#line 708 "pikchr.y"
28132810
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -1;}
2814
-#line 2839 "pikchr.c"
2811
+#line 2836 "pikchr.c"
28152812
yymsp[0].minor.yy0 = yylhsminor.yy0;
28162813
break;
28172814
case 92: /* nth ::= NTH LB RB */
2818
-#line 712 "pikchr.y"
2815
+#line 709 "pikchr.y"
28192816
{yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-2].minor.yy0);}
2820
-#line 2845 "pikchr.c"
2817
+#line 2842 "pikchr.c"
28212818
yymsp[-2].minor.yy0 = yylhsminor.yy0;
28222819
break;
28232820
case 93: /* nth ::= NTH LAST LB RB */
2824
-#line 713 "pikchr.y"
2821
+#line 710 "pikchr.y"
28252822
{yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-3].minor.yy0);}
2826
-#line 2851 "pikchr.c"
2823
+#line 2848 "pikchr.c"
28272824
yymsp[-3].minor.yy0 = yylhsminor.yy0;
28282825
break;
28292826
case 94: /* nth ::= LAST LB RB */
2830
-#line 714 "pikchr.y"
2827
+#line 711 "pikchr.y"
28312828
{yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; }
2832
-#line 2857 "pikchr.c"
2829
+#line 2854 "pikchr.c"
28332830
break;
28342831
case 95: /* expr ::= expr PLUS expr */
2835
-#line 716 "pikchr.y"
2832
+#line 713 "pikchr.y"
28362833
{yylhsminor.yy73=yymsp[-2].minor.yy73+yymsp[0].minor.yy73;}
2837
-#line 2862 "pikchr.c"
2834
+#line 2859 "pikchr.c"
28382835
yymsp[-2].minor.yy73 = yylhsminor.yy73;
28392836
break;
28402837
case 96: /* expr ::= expr MINUS expr */
2841
-#line 717 "pikchr.y"
2838
+#line 714 "pikchr.y"
28422839
{yylhsminor.yy73=yymsp[-2].minor.yy73-yymsp[0].minor.yy73;}
2843
-#line 2868 "pikchr.c"
2840
+#line 2865 "pikchr.c"
28442841
yymsp[-2].minor.yy73 = yylhsminor.yy73;
28452842
break;
28462843
case 97: /* expr ::= expr STAR expr */
2847
-#line 718 "pikchr.y"
2844
+#line 715 "pikchr.y"
28482845
{yylhsminor.yy73=yymsp[-2].minor.yy73*yymsp[0].minor.yy73;}
2849
-#line 2874 "pikchr.c"
2846
+#line 2871 "pikchr.c"
28502847
yymsp[-2].minor.yy73 = yylhsminor.yy73;
28512848
break;
28522849
case 98: /* expr ::= expr SLASH expr */
2853
-#line 719 "pikchr.y"
2850
+#line 716 "pikchr.y"
28542851
{
28552852
if( yymsp[0].minor.yy73==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy73 = 0.0; }
28562853
else{ yylhsminor.yy73 = yymsp[-2].minor.yy73/yymsp[0].minor.yy73; }
28572854
}
2858
-#line 2883 "pikchr.c"
2855
+#line 2880 "pikchr.c"
28592856
yymsp[-2].minor.yy73 = yylhsminor.yy73;
28602857
break;
28612858
case 99: /* expr ::= MINUS expr */
2862
-#line 723 "pikchr.y"
2859
+#line 720 "pikchr.y"
28632860
{yymsp[-1].minor.yy73=-yymsp[0].minor.yy73;}
2864
-#line 2889 "pikchr.c"
2861
+#line 2886 "pikchr.c"
28652862
break;
28662863
case 100: /* expr ::= PLUS expr */
2867
-#line 724 "pikchr.y"
2864
+#line 721 "pikchr.y"
28682865
{yymsp[-1].minor.yy73=yymsp[0].minor.yy73;}
2869
-#line 2894 "pikchr.c"
2866
+#line 2891 "pikchr.c"
28702867
break;
28712868
case 101: /* expr ::= LP expr RP */
2872
-#line 725 "pikchr.y"
2869
+#line 722 "pikchr.y"
28732870
{yymsp[-2].minor.yy73=yymsp[-1].minor.yy73;}
2874
-#line 2899 "pikchr.c"
2871
+#line 2896 "pikchr.c"
28752872
break;
28762873
case 102: /* expr ::= NUMBER */
2877
-#line 726 "pikchr.y"
2874
+#line 723 "pikchr.y"
28782875
{yylhsminor.yy73=pik_atof(p,&yymsp[0].minor.yy0);}
2879
-#line 2904 "pikchr.c"
2876
+#line 2901 "pikchr.c"
28802877
yymsp[0].minor.yy73 = yylhsminor.yy73;
28812878
break;
28822879
case 103: /* expr ::= ID */
2883
-#line 727 "pikchr.y"
2880
+#line 724 "pikchr.y"
28842881
{yylhsminor.yy73=pik_get_var(p,&yymsp[0].minor.yy0);}
2885
-#line 2910 "pikchr.c"
2882
+#line 2907 "pikchr.c"
28862883
yymsp[0].minor.yy73 = yylhsminor.yy73;
28872884
break;
28882885
case 104: /* expr ::= FUNC1 LP expr RP */
2889
-#line 728 "pikchr.y"
2886
+#line 725 "pikchr.y"
28902887
{yylhsminor.yy73 = pik_func(p,&yymsp[-3].minor.yy0,yymsp[-1].minor.yy73,0.0);}
2891
-#line 2916 "pikchr.c"
2888
+#line 2913 "pikchr.c"
28922889
yymsp[-3].minor.yy73 = yylhsminor.yy73;
28932890
break;
28942891
case 105: /* expr ::= FUNC2 LP expr COMMA expr RP */
2895
-#line 729 "pikchr.y"
2892
+#line 726 "pikchr.y"
28962893
{yylhsminor.yy73 = pik_func(p,&yymsp[-5].minor.yy0,yymsp[-3].minor.yy73,yymsp[-1].minor.yy73);}
2897
-#line 2922 "pikchr.c"
2894
+#line 2919 "pikchr.c"
28982895
yymsp[-5].minor.yy73 = yylhsminor.yy73;
28992896
break;
29002897
case 106: /* expr ::= place2 DOT_XY X */
2901
-#line 730 "pikchr.y"
2898
+#line 727 "pikchr.y"
29022899
{yylhsminor.yy73 = yymsp[-2].minor.yy139.x;}
2903
-#line 2928 "pikchr.c"
2900
+#line 2925 "pikchr.c"
29042901
yymsp[-2].minor.yy73 = yylhsminor.yy73;
29052902
break;
29062903
case 107: /* expr ::= place2 DOT_XY Y */
2907
-#line 731 "pikchr.y"
2904
+#line 728 "pikchr.y"
29082905
{yylhsminor.yy73 = yymsp[-2].minor.yy139.y;}
2909
-#line 2934 "pikchr.c"
2906
+#line 2931 "pikchr.c"
29102907
yymsp[-2].minor.yy73 = yylhsminor.yy73;
29112908
break;
29122909
case 108: /* expr ::= object DOT_L numproperty */
29132910
case 109: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==109);
29142911
case 110: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==110);
2915
-#line 732 "pikchr.y"
2912
+#line 729 "pikchr.y"
29162913
{yylhsminor.yy73=pik_property_of(p,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
2917
-#line 2942 "pikchr.c"
2914
+#line 2939 "pikchr.c"
29182915
yymsp[-2].minor.yy73 = yylhsminor.yy73;
29192916
break;
29202917
default:
29212918
/* (111) lvalue ::= ID */ yytestcase(yyruleno==111);
29222919
/* (112) lvalue ::= FILL */ yytestcase(yyruleno==112);
@@ -3015,18 +3012,18 @@
30153012
){
30163013
pik_parserARG_FETCH
30173014
pik_parserCTX_FETCH
30183015
#define TOKEN yyminor
30193016
/************ Begin %syntax_error code ****************************************/
3020
-#line 499 "pikchr.y"
3017
+#line 496 "pikchr.y"
30213018
30223019
if( TOKEN.z && TOKEN.z[0] ){
30233020
pik_error(p, &TOKEN, "syntax error");
30243021
}else{
30253022
pik_error(p, 0, "syntax error");
30263023
}
3027
-#line 3052 "pikchr.c"
3024
+#line 3049 "pikchr.c"
30283025
/************ End %syntax_error code ******************************************/
30293026
pik_parserARG_STORE /* Suppress warning about unused %extra_argument variable */
30303027
pik_parserCTX_STORE
30313028
}
30323029
@@ -3255,11 +3252,11 @@
32553252
#else
32563253
(void)iToken;
32573254
return 0;
32583255
#endif
32593256
}
3260
-#line 737 "pikchr.y"
3257
+#line 734 "pikchr.y"
32613258
32623259
32633260
32643261
/* Chart of the 140 official HTML color names with their
32653262
** corresponding RGB value.
@@ -3534,10 +3531,33 @@
35343531
/* Methods for the "box" class */
35353532
static void boxInit(Pik *p, PElem *pElem){
35363533
pElem->w = pik_value(p, "boxwid",6,0);
35373534
pElem->h = pik_value(p, "boxht",5,0);
35383535
pElem->rad = pik_value(p, "boxrad",6,0);
3536
+}
3537
+/* Translate the CP_START and CP_END reference points into the
3538
+** corresponding compass point based on the direction.
3539
+*/
3540
+static int boxTranslateEndPoint(PElem *pElem, int cp){
3541
+#if 0
3542
+ if( cp==CP_START ){
3543
+ switch( pElem->inDir ){
3544
+ case DIR_RIGHT: cp = CP_W; break;
3545
+ case DIR_DOWN: cp = CP_N; break;
3546
+ case DIR_LEFT: cp = CP_E; break;
3547
+ case DIR_UP: cp = CP_S; break;
3548
+ }
3549
+ }else if( cp==CP_END ){
3550
+ switch( pElem->outDir ){
3551
+ case DIR_RIGHT: cp = CP_E; break;
3552
+ case DIR_DOWN: cp = CP_S; break;
3553
+ case DIR_LEFT: cp = CP_W; break;
3554
+ case DIR_UP: cp = CP_N; break;
3555
+ }
3556
+ }
3557
+#endif
3558
+ return cp;
35393559
}
35403560
/* Return offset from the center of the box to the compass point
35413561
** given by parameter cp */
35423562
static PPoint boxOffset(Pik *p, PElem *pElem, int cp){
35433563
PPoint pt;
@@ -3551,11 +3571,11 @@
35513571
if( rad>w2 ) rad = w2;
35523572
if( rad>h2 ) rad = h2;
35533573
rx = 0.29289321881345252392*rad;
35543574
}
35553575
pt.x = pt.y = 0.0;
3556
- switch( cp ){
3576
+ switch( boxTranslateEndPoint(pElem,cp) ){
35573577
case CP_C: pt.x = 0.0; pt.y = 0.0; break;
35583578
case CP_N: pt.x = 0.0; pt.y = h2; break;
35593579
case CP_NE: pt.x = w2-rx; pt.y = h2-rx; break;
35603580
case CP_E: pt.x = w2; pt.y = 0.0; break;
35613581
case CP_SE: pt.x = w2-rx; pt.y = rx-h2; break;
@@ -3748,11 +3768,11 @@
37483768
static PPoint cylinderOffset(Pik *p, PElem *pElem, int cp){
37493769
PPoint pt;
37503770
PNum w2 = pElem->w*0.5;
37513771
PNum h1 = pElem->h*0.5;
37523772
PNum h2 = h1 - pElem->rad;
3753
- switch( cp ){
3773
+ switch( boxTranslateEndPoint(pElem,cp) ){
37543774
case CP_C: pt.x = 0.0; pt.y = 0.0; break;
37553775
case CP_N: pt.x = 0.0; pt.y = h1; break;
37563776
case CP_NE: pt.x = w2; pt.y = h2; break;
37573777
case CP_E: pt.x = w2; pt.y = 0.0; break;
37583778
case CP_SE: pt.x = w2; pt.y = -h2; break;
@@ -3829,11 +3849,11 @@
38293849
PPoint pt;
38303850
PNum w = pElem->w*0.5;
38313851
PNum w2 = w*0.70710678118654747608;
38323852
PNum h = pElem->h*0.5;
38333853
PNum h2 = h*0.70710678118654747608;
3834
- switch( cp ){
3854
+ switch( boxTranslateEndPoint(pElem,cp) ){
38353855
case CP_C: pt.x = 0.0; pt.y = 0.0; break;
38363856
case CP_N: pt.x = 0.0; pt.y = h; break;
38373857
case CP_NE: pt.x = w2; pt.y = h2; break;
38383858
case CP_E: pt.x = w; pt.y = 0.0; break;
38393859
case CP_SE: pt.x = w2; pt.y = -h2; break;
@@ -3875,11 +3895,11 @@
38753895
PNum mn = w2<h2 ? w2 : h2;
38763896
if( rx>mn ) rx = mn;
38773897
if( rx<mn*0.25 ) rx = mn*0.25;
38783898
pt.x = pt.y = 0.0;
38793899
rx *= 0.5;
3880
- switch( cp ){
3900
+ switch( boxTranslateEndPoint(pElem,cp) ){
38813901
case CP_C: pt.x = 0.0; pt.y = 0.0; break;
38823902
case CP_N: pt.x = 0.0; pt.y = h2; break;
38833903
case CP_NE: pt.x = w2-rx; pt.y = h2-rx; break;
38843904
case CP_E: pt.x = w2; pt.y = 0.0; break;
38853905
case CP_SE: pt.x = w2; pt.y = -h2; break;
@@ -3929,17 +3949,13 @@
39293949
pElem->rad = pik_value(p, "linerad",7,0);
39303950
pElem->fill = -1.0;
39313951
}
39323952
static PPoint lineOffset(Pik *p, PElem *pElem, int cp){
39333953
3934
-#if 0 /* No. Just make .center the geometic center of the line.
3935
- ** This is different from legacy-PIC and Gnu-PIC, but it seems
3936
- ** to work better. And the two points are the same in most
3937
- ** cases anyhow. */
3938
- /* The .center of an unclosed line is half way between
3939
- ** its .start and .end. For everything else, the offset
3940
- ** is the same as for box */
3954
+#if 0
3955
+ /* In legacy PIC, the .center of an unclosed line is half way between
3956
+ ** its .start and .end. */
39413957
if( cp==CP_C && !pElem->bClose ){
39423958
PPoint out;
39433959
out.x = 0.5*(pElem->ptEnter.x + pElem->ptExit.x) - pElem->ptAt.x;
39443960
out.y = 0.5*(pElem->ptEnter.x + pElem->ptExit.y) - pElem->ptAt.y;
39453961
return out;
@@ -4104,11 +4120,11 @@
41044120
}
41054121
pElem->w = pElem->bbox.ne.x - pElem->bbox.sw.x;
41064122
pElem->h = pElem->bbox.ne.y - pElem->bbox.sw.y;
41074123
pElem->ptAt.x = 0.5*(pElem->bbox.ne.x + pElem->bbox.sw.x);
41084124
pElem->ptAt.y = 0.5*(pElem->bbox.ne.y + pElem->bbox.sw.y);
4109
- pElem->mCalc |= A_WIDTH|A_HEIGHT;
4125
+ pElem->mCalc |= A_WIDTH|A_HEIGHT|A_RADIUS;
41104126
}
41114127
41124128
41134129
/*
41144130
** The following array holds all the different kinds of named
@@ -4120,11 +4136,11 @@
41204136
/* eJust */ 0,
41214137
/* xInit */ arcInit,
41224138
/* xNumProp */ 0,
41234139
/* xCheck */ arcCheck,
41244140
/* xChop */ 0,
4125
- /* xOffset */ 0,
4141
+ /* xOffset */ boxOffset,
41264142
/* xFit */ 0,
41274143
/* xRender */ arcRender
41284144
},
41294145
{ /* name */ "arrow",
41304146
/* isline */ 1,
@@ -4219,11 +4235,11 @@
42194235
/* eJust */ 0,
42204236
/* xInit */ moveInit,
42214237
/* xNumProp */ 0,
42224238
/* xCheck */ 0,
42234239
/* xChop */ 0,
4224
- /* xOffset */ 0,
4240
+ /* xOffset */ boxOffset,
42254241
/* xFit */ 0,
42264242
/* xRender */ moveRender
42274243
},
42284244
{ /* name */ "oval",
42294245
/* isline */ 0,
@@ -4265,11 +4281,11 @@
42654281
/* eJust */ 0,
42664282
/* xInit */ sublistInit,
42674283
/* xNumProp */ 0,
42684284
/* xCheck */ 0,
42694285
/* xChop */ 0,
4270
- /* xOffset */ 0,
4286
+ /* xOffset */ boxOffset,
42714287
/* xFit */ 0,
42724288
/* xRender */ 0
42734289
};
42744290
static const PClass noopClass =
42754291
{ /* name */ "noop",
@@ -4277,11 +4293,11 @@
42774293
/* eJust */ 0,
42784294
/* xInit */ 0,
42794295
/* xNumProp */ 0,
42804296
/* xCheck */ 0,
42814297
/* xChop */ 0,
4282
- /* xOffset */ 0,
4298
+ /* xOffset */ boxOffset,
42834299
/* xFit */ 0,
42844300
/* xRender */ 0
42854301
};
42864302
42874303
@@ -4340,15 +4356,11 @@
43404356
/*
43414357
** Compute the relative offset to an edge location from the reference for a
43424358
** an element.
43434359
*/
43444360
static PPoint pik_elem_offset(Pik *p, PElem *pElem, int cp){
4345
- if( pElem->type->xOffset==0 ){
4346
- return boxOffset(p, pElem, cp);
4347
- }else{
4348
- return pElem->type->xOffset(p, pElem, cp);
4349
- }
4361
+ return pElem->type->xOffset(p, pElem, cp);
43504362
}
43514363
43524364
43534365
/*
43544366
** Append raw text to zOut
@@ -5060,15 +5072,29 @@
50605072
case DIR_DOWN: pElem->ptExit.y -= pElem->h*0.5; break;
50615073
}
50625074
}
50635075
}
50645076
5065
-/* Change the direction of travel
5077
+/* Change the layout direction.
50665078
*/
50675079
static void pik_set_direction(Pik *p, int eDir){
50685080
assert( ValidDir(eDir) );
50695081
p->eDir = eDir;
5082
+
5083
+ /* It seems to make sense to reach back into the last object and
5084
+ ** change its exit point (its ".end") to correspond to the new
5085
+ ** direction. Things just seem to work better this way. However,
5086
+ ** legacy PIC does *not* do this.
5087
+ **
5088
+ ** The difference can be seen in a script like this:
5089
+ **
5090
+ ** arrow; circle; down; arrow
5091
+ **
5092
+ ** You can make pikchr render the above exactly like PIC
5093
+ ** by deleting the following three lines. But I (drh) think
5094
+ ** it works better with those lines in place.
5095
+ */
50705096
if( p->list && p->list->n ){
50715097
pik_elem_set_exit(p, p->list->a[p->list->n-1], eDir);
50725098
}
50735099
}
50745100
@@ -5115,26 +5141,20 @@
51155141
*/
51165142
static int pik_param_ok(
51175143
Pik *p, /* For storing the error message (if any) */
51185144
PElem *pElem, /* The element under construction */
51195145
PToken *pId, /* Make the error point to this token */
5120
- int mThis, /* Value we are trying to set */
5121
- int mBlockers /* Other value that might block this one */
5146
+ int mThis /* Value we are trying to set */
51225147
){
5123
- int m;
51245148
if( pElem->mProp & mThis ){
51255149
pik_error(p, pId, "value is already set");
51265150
return 1;
51275151
}
51285152
if( pElem->mCalc & mThis ){
51295153
pik_error(p, pId, "value already fixed by prior constraints");
51305154
return 1;
51315155
}
5132
- m = pElem->mProp & mBlockers;
5133
- if( m ){
5134
- pElem->mCalc |= mThis|mBlockers;
5135
- }
51365156
pElem->mProp |= mThis;
51375157
return 0;
51385158
}
51395159
51405160
@@ -5146,27 +5166,27 @@
51465166
*/
51475167
void pik_set_numprop(Pik *p, PToken *pId, PRel *pVal){
51485168
PElem *pElem = p->cur;
51495169
switch( pId->eType ){
51505170
case T_HEIGHT:
5151
- if( pik_param_ok(p, pElem, pId, A_HEIGHT, A_BOTTOM|A_TOP|A_AT) ) return;
5171
+ if( pik_param_ok(p, pElem, pId, A_HEIGHT) ) return;
51525172
pElem->h = pElem->h*pVal->rRel + pVal->rAbs;
51535173
break;
51545174
case T_WIDTH:
5155
- if( pik_param_ok(p, pElem, pId, A_WIDTH, A_RIGHT|A_LEFT|A_AT) ) return;
5175
+ if( pik_param_ok(p, pElem, pId, A_WIDTH) ) return;
51565176
pElem->w = pElem->w*pVal->rRel + pVal->rAbs;
51575177
break;
51585178
case T_RADIUS:
5159
- if( pik_param_ok(p, pElem, pId, A_RADIUS, 0) ) return;
5179
+ if( pik_param_ok(p, pElem, pId, A_RADIUS) ) return;
51605180
pElem->rad = pElem->rad*pVal->rRel + pVal->rAbs;
51615181
break;
51625182
case T_DIAMETER:
5163
- if( pik_param_ok(p, pElem, pId, A_RADIUS, 0) ) return;
5183
+ if( pik_param_ok(p, pElem, pId, A_RADIUS) ) return;
51645184
pElem->rad = pElem->rad*pVal->rRel + 0.5*pVal->rAbs; /* diam it 2x rad */
51655185
break;
51665186
case T_THICKNESS:
5167
- if( pik_param_ok(p, pElem, pId, A_THICKNESS, 0) ) return;
5187
+ if( pik_param_ok(p, pElem, pId, A_THICKNESS) ) return;
51685188
pElem->sw = pElem->sw*pVal->rRel + pVal->rAbs;
51695189
break;
51705190
}
51715191
if( pElem->type->xNumProp ){
51725192
pElem->type->xNumProp(p, pElem, pId);
@@ -5179,15 +5199,15 @@
51795199
*/
51805200
void pik_set_clrprop(Pik *p, PToken *pId, PNum rClr){
51815201
PElem *pElem = p->cur;
51825202
switch( pId->eType ){
51835203
case T_FILL:
5184
- if( pik_param_ok(p, pElem, pId, A_FILL, 0) ) return;
5204
+ if( pik_param_ok(p, pElem, pId, A_FILL) ) return;
51855205
pElem->fill = rClr;
51865206
break;
51875207
case T_COLOR:
5188
- if( pik_param_ok(p, pElem, pId, A_COLOR, 0) ) return;
5208
+ if( pik_param_ok(p, pElem, pId, A_COLOR) ) return;
51895209
pElem->color = rClr;
51905210
break;
51915211
}
51925212
if( pElem->type->xNumProp ){
51935213
pElem->type->xNumProp(p, pElem, pId);
@@ -5475,22 +5495,12 @@
54755495
}
54765496
if( pElem->mProp & A_AT ){
54775497
pik_error(p, pErrTok, "location fixed by prior \"at\"");
54785498
return;
54795499
}
5480
- if( pElem->mCalc & A_AT ){
5481
- pik_error(p, pErrTok, "location fixed by prior constraints");
5482
- return;
5483
- }
5484
- if( pElem->mProp & (A_WIDTH|A_LEFT|A_RIGHT) ){
5485
- pElem->mCalc |= (A_WIDTH|A_LEFT|A_RIGHT|A_AT);
5486
- }
5487
- if( pElem->mProp & (A_HEIGHT|A_TOP|A_BOTTOM) ){
5488
- pElem->mCalc |= (A_HEIGHT|A_TOP|A_BOTTOM|A_AT);
5489
- }
54905500
pElem->mProp |= A_AT;
5491
- pElem->eWith = pEdge ? pEdge->eEdge : CP_C;
5501
+ pElem->eWith = pEdge ? boxTranslateEndPoint(pElem,pEdge->eEdge) : CP_C;
54925502
pElem->with = *pAt;
54935503
}
54945504
54955505
/*
54965506
** Try to add a text attribute to an element
@@ -5923,16 +5933,12 @@
59235933
if( pElem==0 ) return pt;
59245934
if( pEdge==0 ){
59255935
return pElem->ptAt;
59265936
}
59275937
pClass = pElem->type;
5928
- if( pEdge->eType==T_EDGEPT || pEdge->eEdge>0 ){
5929
- if( pClass->xOffset==0 ){
5930
- pt = boxOffset(p, pElem, pEdge->eEdge);
5931
- }else{
5932
- pt = pClass->xOffset(p, pElem, pEdge->eEdge);
5933
- }
5938
+ if( pEdge->eType==T_EDGEPT || (pEdge->eEdge>0 && pEdge->eEdge<CP_END) ){
5939
+ pt = pClass->xOffset(p, pElem, pEdge->eEdge);
59345940
pt.x += pElem->ptAt.x;
59355941
pt.y += pElem->ptAt.y;
59365942
return pt;
59375943
}
59385944
if( pEdge->eType==T_START ){
@@ -6411,97 +6417,97 @@
64116417
64126418
/*
64136419
** Keywords
64146420
*/
64156421
static const PikWord pik_keywords[] = {
6416
- { "above", 5, T_ABOVE, 0, 0 },
6417
- { "abs", 3, T_FUNC1, FN_ABS, 0 },
6418
- { "aligned", 7, T_ALIGNED, 0, 0 },
6419
- { "and", 3, T_AND, 0, 0 },
6420
- { "as", 2, T_AS, 0, 0 },
6421
- { "assert", 6, T_ASSERT, 0, 0 },
6422
- { "at", 2, T_AT, 0, 0 },
6423
- { "behind", 6, T_BEHIND, 0, 0 },
6424
- { "below", 5, T_BELOW, 0, 0 },
6425
- { "between", 7, T_BETWEEN, 0, 0 },
6426
- { "big", 3, T_BIG, 0, 0 },
6427
- { "bold", 4, T_BOLD, 0, 0 },
6428
- { "bot", 3, T_EDGEPT, 0, CP_S },
6429
- { "bottom", 6, T_BOTTOM, 0, CP_S },
6430
- { "c", 1, T_EDGEPT, 0, CP_C },
6431
- { "ccw", 3, T_CCW, 0, 0 },
6432
- { "center", 6, T_CENTER, 0, CP_C },
6433
- { "chop", 4, T_CHOP, 0, 0 },
6434
- { "close", 5, T_CLOSE, 0, 0 },
6435
- { "color", 5, T_COLOR, 0, 0 },
6436
- { "cos", 3, T_FUNC1, FN_COS, 0 },
6437
- { "cw", 2, T_CW, 0, 0 },
6438
- { "dashed", 6, T_DASHED, 0, 0 },
6439
- { "diameter", 8, T_DIAMETER, 0, 0 },
6440
- { "dotted", 6, T_DOTTED, 0, 0 },
6441
- { "down", 4, T_DOWN, DIR_DOWN, 0 },
6442
- { "e", 1, T_EDGEPT, 0, CP_E },
6443
- { "east", 4, T_EDGEPT, 0, CP_E },
6444
- { "end", 3, T_END, 0, 0 },
6445
- { "even", 4, T_EVEN, 0, 0 },
6446
- { "fill", 4, T_FILL, 0, 0 },
6447
- { "first", 5, T_NTH, 0, 0 },
6448
- { "fit", 3, T_FIT, 0, 0 },
6449
- { "from", 4, T_FROM, 0, 0 },
6450
- { "go", 2, T_GO, 0, 0 },
6451
- { "heading", 7, T_HEADING, 0, 0 },
6452
- { "height", 6, T_HEIGHT, 0, 0 },
6453
- { "ht", 2, T_HEIGHT, 0, 0 },
6454
- { "in", 2, T_IN, 0, 0 },
6455
- { "int", 3, T_FUNC1, FN_INT, 0 },
6456
- { "invis", 5, T_INVIS, 0, 0 },
6457
- { "invisible", 9, T_INVIS, 0, 0 },
6458
- { "italic", 6, T_ITALIC, 0, 0 },
6459
- { "last", 4, T_LAST, 0, 0 },
6460
- { "left", 4, T_LEFT, DIR_LEFT, CP_W },
6461
- { "ljust", 5, T_LJUST, 0, 0 },
6462
- { "max", 3, T_FUNC2, FN_MAX, 0 },
6463
- { "min", 3, T_FUNC2, FN_MIN, 0 },
6464
- { "n", 1, T_EDGEPT, 0, CP_N },
6465
- { "ne", 2, T_EDGEPT, 0, CP_NE },
6466
- { "north", 5, T_EDGEPT, 0, CP_N },
6467
- { "nw", 2, T_EDGEPT, 0, CP_NW },
6468
- { "of", 2, T_OF, 0, 0 },
6469
- { "previous", 8, T_LAST, 0, 0, },
6470
- { "print", 5, T_PRINT, 0, 0 },
6471
- { "rad", 3, T_RADIUS, 0, 0 },
6472
- { "radius", 6, T_RADIUS, 0, 0 },
6473
- { "right", 5, T_RIGHT, DIR_RIGHT, CP_E },
6474
- { "rjust", 5, T_RJUST, 0, 0 },
6475
- { "s", 1, T_EDGEPT, 0, CP_S },
6476
- { "same", 4, T_SAME, 0, 0 },
6477
- { "se", 2, T_EDGEPT, 0, CP_SE },
6478
- { "sin", 3, T_FUNC1, FN_SIN, 0 },
6479
- { "small", 5, T_SMALL, 0, 0 },
6480
- { "south", 5, T_EDGEPT, 0, CP_S },
6481
- { "sqrt", 4, T_FUNC1, FN_SQRT, 0 },
6482
- { "start", 5, T_START, 0, 0 },
6483
- { "sw", 2, T_EDGEPT, 0, CP_SW },
6484
- { "t", 1, T_TOP, 0, CP_N },
6485
- { "the", 3, T_THE, 0, 0 },
6486
- { "then", 4, T_THEN, 0, 0 },
6487
- { "thick", 5, T_THICK, 0, 0 },
6488
- { "thickness", 9, T_THICKNESS, 0, 0 },
6489
- { "thin", 4, T_THIN, 0, 0 },
6490
- { "to", 2, T_TO, 0, 0 },
6491
- { "top", 3, T_TOP, 0, CP_N },
6492
- { "until", 5, T_UNTIL, 0, 0 },
6493
- { "up", 2, T_UP, DIR_UP, 0 },
6494
- { "vertex", 6, T_VERTEX, 0, 0 },
6495
- { "w", 1, T_EDGEPT, 0, CP_W },
6496
- { "way", 3, T_WAY, 0, 0 },
6497
- { "west", 4, T_EDGEPT, 0, CP_W },
6498
- { "wid", 3, T_WIDTH, 0, 0 },
6499
- { "width", 5, T_WIDTH, 0, 0 },
6500
- { "with", 4, T_WITH, 0, 0 },
6501
- { "x", 1, T_X, 0, 0 },
6502
- { "y", 1, T_Y, 0, 0 },
6422
+ { "above", 5, T_ABOVE, 0, 0 },
6423
+ { "abs", 3, T_FUNC1, FN_ABS, 0 },
6424
+ { "aligned", 7, T_ALIGNED, 0, 0 },
6425
+ { "and", 3, T_AND, 0, 0 },
6426
+ { "as", 2, T_AS, 0, 0 },
6427
+ { "assert", 6, T_ASSERT, 0, 0 },
6428
+ { "at", 2, T_AT, 0, 0 },
6429
+ { "behind", 6, T_BEHIND, 0, 0 },
6430
+ { "below", 5, T_BELOW, 0, 0 },
6431
+ { "between", 7, T_BETWEEN, 0, 0 },
6432
+ { "big", 3, T_BIG, 0, 0 },
6433
+ { "bold", 4, T_BOLD, 0, 0 },
6434
+ { "bot", 3, T_EDGEPT, 0, CP_S },
6435
+ { "bottom", 6, T_BOTTOM, 0, CP_S },
6436
+ { "c", 1, T_EDGEPT, 0, CP_C },
6437
+ { "ccw", 3, T_CCW, 0, 0 },
6438
+ { "center", 6, T_CENTER, 0, CP_C },
6439
+ { "chop", 4, T_CHOP, 0, 0 },
6440
+ { "close", 5, T_CLOSE, 0, 0 },
6441
+ { "color", 5, T_COLOR, 0, 0 },
6442
+ { "cos", 3, T_FUNC1, FN_COS, 0 },
6443
+ { "cw", 2, T_CW, 0, 0 },
6444
+ { "dashed", 6, T_DASHED, 0, 0 },
6445
+ { "diameter", 8, T_DIAMETER, 0, 0 },
6446
+ { "dotted", 6, T_DOTTED, 0, 0 },
6447
+ { "down", 4, T_DOWN, DIR_DOWN, 0 },
6448
+ { "e", 1, T_EDGEPT, 0, CP_E },
6449
+ { "east", 4, T_EDGEPT, 0, CP_E },
6450
+ { "end", 3, T_END, 0, CP_END },
6451
+ { "even", 4, T_EVEN, 0, 0 },
6452
+ { "fill", 4, T_FILL, 0, 0 },
6453
+ { "first", 5, T_NTH, 0, 0 },
6454
+ { "fit", 3, T_FIT, 0, 0 },
6455
+ { "from", 4, T_FROM, 0, 0 },
6456
+ { "go", 2, T_GO, 0, 0 },
6457
+ { "heading", 7, T_HEADING, 0, 0 },
6458
+ { "height", 6, T_HEIGHT, 0, 0 },
6459
+ { "ht", 2, T_HEIGHT, 0, 0 },
6460
+ { "in", 2, T_IN, 0, 0 },
6461
+ { "int", 3, T_FUNC1, FN_INT, 0 },
6462
+ { "invis", 5, T_INVIS, 0, 0 },
6463
+ { "invisible", 9, T_INVIS, 0, 0 },
6464
+ { "italic", 6, T_ITALIC, 0, 0 },
6465
+ { "last", 4, T_LAST, 0, 0 },
6466
+ { "left", 4, T_LEFT, DIR_LEFT, CP_W },
6467
+ { "ljust", 5, T_LJUST, 0, 0 },
6468
+ { "max", 3, T_FUNC2, FN_MAX, 0 },
6469
+ { "min", 3, T_FUNC2, FN_MIN, 0 },
6470
+ { "n", 1, T_EDGEPT, 0, CP_N },
6471
+ { "ne", 2, T_EDGEPT, 0, CP_NE },
6472
+ { "north", 5, T_EDGEPT, 0, CP_N },
6473
+ { "nw", 2, T_EDGEPT, 0, CP_NW },
6474
+ { "of", 2, T_OF, 0, 0 },
6475
+ { "previous", 8, T_LAST, 0, 0, },
6476
+ { "print", 5, T_PRINT, 0, 0 },
6477
+ { "rad", 3, T_RADIUS, 0, 0 },
6478
+ { "radius", 6, T_RADIUS, 0, 0 },
6479
+ { "right", 5, T_RIGHT, DIR_RIGHT, CP_E },
6480
+ { "rjust", 5, T_RJUST, 0, 0 },
6481
+ { "s", 1, T_EDGEPT, 0, CP_S },
6482
+ { "same", 4, T_SAME, 0, 0 },
6483
+ { "se", 2, T_EDGEPT, 0, CP_SE },
6484
+ { "sin", 3, T_FUNC1, FN_SIN, 0 },
6485
+ { "small", 5, T_SMALL, 0, 0 },
6486
+ { "south", 5, T_EDGEPT, 0, CP_S },
6487
+ { "sqrt", 4, T_FUNC1, FN_SQRT, 0 },
6488
+ { "start", 5, T_START, 0, CP_START },
6489
+ { "sw", 2, T_EDGEPT, 0, CP_SW },
6490
+ { "t", 1, T_TOP, 0, CP_N },
6491
+ { "the", 3, T_THE, 0, 0 },
6492
+ { "then", 4, T_THEN, 0, 0 },
6493
+ { "thick", 5, T_THICK, 0, 0 },
6494
+ { "thickness", 9, T_THICKNESS, 0, 0 },
6495
+ { "thin", 4, T_THIN, 0, 0 },
6496
+ { "to", 2, T_TO, 0, 0 },
6497
+ { "top", 3, T_TOP, 0, CP_N },
6498
+ { "until", 5, T_UNTIL, 0, 0 },
6499
+ { "up", 2, T_UP, DIR_UP, 0 },
6500
+ { "vertex", 6, T_VERTEX, 0, 0 },
6501
+ { "w", 1, T_EDGEPT, 0, CP_W },
6502
+ { "way", 3, T_WAY, 0, 0 },
6503
+ { "west", 4, T_EDGEPT, 0, CP_W },
6504
+ { "wid", 3, T_WIDTH, 0, 0 },
6505
+ { "width", 5, T_WIDTH, 0, 0 },
6506
+ { "with", 4, T_WITH, 0, 0 },
6507
+ { "x", 1, T_X, 0, 0 },
6508
+ { "y", 1, T_Y, 0, 0 },
65036509
};
65046510
65056511
/*
65066512
** Search a PikWordlist for the given keyword. Return a pointer to the
65076513
** element found. Or return 0 if not found.
@@ -6931,11 +6937,11 @@
69316937
** input text and the rendered SVG for all files named on the command
69326938
** line.
69336939
*/
69346940
int main(int argc, char **argv){
69356941
int i;
6936
- int bNoEcho = 0; /* Do not the text of the script */
6942
+ int bNoEcho = 0; /* Do not show the text of the script */
69376943
int mPikchrFlags = 0; /* Flags passed into pikchr() */
69386944
printf(
69396945
"<!DOCTYPE html>\n"
69406946
"<html lang=\"en-US\">\n"
69416947
"<head>\n<title>PIKCHR Test</title>\n"
@@ -7023,6 +7029,6 @@
70237029
printf("</body></html>\n");
70247030
return 0;
70257031
}
70267032
#endif /* PIKCHR_SHELL */
70277033
7028
-#line 7053 "pikchr.c"
7034
+#line 7059 "pikchr.c"
70297035
--- src/pikchr.c
+++ src/pikchr.c
@@ -146,10 +146,12 @@
146 #define CP_S 5
147 #define CP_SW 6
148 #define CP_W 7
149 #define CP_NW 8
150 #define CP_C 9 /* .center or .c */
 
 
151
152 /* Heading angles corresponding to compass points */
153 static const PNum pik_hdg_angle[] = {
154 /* none */ 0.0,
155 /* N */ 0.0,
@@ -262,26 +264,21 @@
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
271 #define A_DASHED 0x000010 /* Includes "dotted" */
272 #define A_FILL 0x000020
273 #define A_COLOR 0x000040
274 #define A_ARROW 0x000080
275 #define A_TOP 0x000100
276 #define A_BOTTOM 0x000200
277 #define A_LEFT 0x000400
278 #define A_RIGHT 0x000800
279 #define A_CORNER 0x001000
280 #define A_FROM 0x002000
281 #define A_CW 0x004000
282 #define A_AT 0x008000
283
284
285 /* A single element */
286 struct PElem {
287 const PClass *type; /* Element type */
@@ -453,11 +450,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
@@ -1629,22 +1626,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 }
@@ -1858,14 +1855,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
@@ -2330,593 +2327,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);
@@ -3015,18 +3012,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
@@ -3255,11 +3252,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.
@@ -3534,10 +3531,33 @@
3534 /* Methods for the "box" class */
3535 static void boxInit(Pik *p, PElem *pElem){
3536 pElem->w = pik_value(p, "boxwid",6,0);
3537 pElem->h = pik_value(p, "boxht",5,0);
3538 pElem->rad = pik_value(p, "boxrad",6,0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3539 }
3540 /* Return offset from the center of the box to the compass point
3541 ** given by parameter cp */
3542 static PPoint boxOffset(Pik *p, PElem *pElem, int cp){
3543 PPoint pt;
@@ -3551,11 +3571,11 @@
3551 if( rad>w2 ) rad = w2;
3552 if( rad>h2 ) rad = h2;
3553 rx = 0.29289321881345252392*rad;
3554 }
3555 pt.x = pt.y = 0.0;
3556 switch( cp ){
3557 case CP_C: pt.x = 0.0; pt.y = 0.0; break;
3558 case CP_N: pt.x = 0.0; pt.y = h2; break;
3559 case CP_NE: pt.x = w2-rx; pt.y = h2-rx; break;
3560 case CP_E: pt.x = w2; pt.y = 0.0; break;
3561 case CP_SE: pt.x = w2-rx; pt.y = rx-h2; break;
@@ -3748,11 +3768,11 @@
3748 static PPoint cylinderOffset(Pik *p, PElem *pElem, int cp){
3749 PPoint pt;
3750 PNum w2 = pElem->w*0.5;
3751 PNum h1 = pElem->h*0.5;
3752 PNum h2 = h1 - pElem->rad;
3753 switch( cp ){
3754 case CP_C: pt.x = 0.0; pt.y = 0.0; break;
3755 case CP_N: pt.x = 0.0; pt.y = h1; break;
3756 case CP_NE: pt.x = w2; pt.y = h2; break;
3757 case CP_E: pt.x = w2; pt.y = 0.0; break;
3758 case CP_SE: pt.x = w2; pt.y = -h2; break;
@@ -3829,11 +3849,11 @@
3829 PPoint pt;
3830 PNum w = pElem->w*0.5;
3831 PNum w2 = w*0.70710678118654747608;
3832 PNum h = pElem->h*0.5;
3833 PNum h2 = h*0.70710678118654747608;
3834 switch( cp ){
3835 case CP_C: pt.x = 0.0; pt.y = 0.0; break;
3836 case CP_N: pt.x = 0.0; pt.y = h; break;
3837 case CP_NE: pt.x = w2; pt.y = h2; break;
3838 case CP_E: pt.x = w; pt.y = 0.0; break;
3839 case CP_SE: pt.x = w2; pt.y = -h2; break;
@@ -3875,11 +3895,11 @@
3875 PNum mn = w2<h2 ? w2 : h2;
3876 if( rx>mn ) rx = mn;
3877 if( rx<mn*0.25 ) rx = mn*0.25;
3878 pt.x = pt.y = 0.0;
3879 rx *= 0.5;
3880 switch( cp ){
3881 case CP_C: pt.x = 0.0; pt.y = 0.0; break;
3882 case CP_N: pt.x = 0.0; pt.y = h2; break;
3883 case CP_NE: pt.x = w2-rx; pt.y = h2-rx; break;
3884 case CP_E: pt.x = w2; pt.y = 0.0; break;
3885 case CP_SE: pt.x = w2; pt.y = -h2; break;
@@ -3929,17 +3949,13 @@
3929 pElem->rad = pik_value(p, "linerad",7,0);
3930 pElem->fill = -1.0;
3931 }
3932 static PPoint lineOffset(Pik *p, PElem *pElem, int cp){
3933
3934 #if 0 /* No. Just make .center the geometic center of the line.
3935 ** This is different from legacy-PIC and Gnu-PIC, but it seems
3936 ** to work better. And the two points are the same in most
3937 ** cases anyhow. */
3938 /* The .center of an unclosed line is half way between
3939 ** its .start and .end. For everything else, the offset
3940 ** is the same as for box */
3941 if( cp==CP_C && !pElem->bClose ){
3942 PPoint out;
3943 out.x = 0.5*(pElem->ptEnter.x + pElem->ptExit.x) - pElem->ptAt.x;
3944 out.y = 0.5*(pElem->ptEnter.x + pElem->ptExit.y) - pElem->ptAt.y;
3945 return out;
@@ -4104,11 +4120,11 @@
4104 }
4105 pElem->w = pElem->bbox.ne.x - pElem->bbox.sw.x;
4106 pElem->h = pElem->bbox.ne.y - pElem->bbox.sw.y;
4107 pElem->ptAt.x = 0.5*(pElem->bbox.ne.x + pElem->bbox.sw.x);
4108 pElem->ptAt.y = 0.5*(pElem->bbox.ne.y + pElem->bbox.sw.y);
4109 pElem->mCalc |= A_WIDTH|A_HEIGHT;
4110 }
4111
4112
4113 /*
4114 ** The following array holds all the different kinds of named
@@ -4120,11 +4136,11 @@
4120 /* eJust */ 0,
4121 /* xInit */ arcInit,
4122 /* xNumProp */ 0,
4123 /* xCheck */ arcCheck,
4124 /* xChop */ 0,
4125 /* xOffset */ 0,
4126 /* xFit */ 0,
4127 /* xRender */ arcRender
4128 },
4129 { /* name */ "arrow",
4130 /* isline */ 1,
@@ -4219,11 +4235,11 @@
4219 /* eJust */ 0,
4220 /* xInit */ moveInit,
4221 /* xNumProp */ 0,
4222 /* xCheck */ 0,
4223 /* xChop */ 0,
4224 /* xOffset */ 0,
4225 /* xFit */ 0,
4226 /* xRender */ moveRender
4227 },
4228 { /* name */ "oval",
4229 /* isline */ 0,
@@ -4265,11 +4281,11 @@
4265 /* eJust */ 0,
4266 /* xInit */ sublistInit,
4267 /* xNumProp */ 0,
4268 /* xCheck */ 0,
4269 /* xChop */ 0,
4270 /* xOffset */ 0,
4271 /* xFit */ 0,
4272 /* xRender */ 0
4273 };
4274 static const PClass noopClass =
4275 { /* name */ "noop",
@@ -4277,11 +4293,11 @@
4277 /* eJust */ 0,
4278 /* xInit */ 0,
4279 /* xNumProp */ 0,
4280 /* xCheck */ 0,
4281 /* xChop */ 0,
4282 /* xOffset */ 0,
4283 /* xFit */ 0,
4284 /* xRender */ 0
4285 };
4286
4287
@@ -4340,15 +4356,11 @@
4340 /*
4341 ** Compute the relative offset to an edge location from the reference for a
4342 ** an element.
4343 */
4344 static PPoint pik_elem_offset(Pik *p, PElem *pElem, int cp){
4345 if( pElem->type->xOffset==0 ){
4346 return boxOffset(p, pElem, cp);
4347 }else{
4348 return pElem->type->xOffset(p, pElem, cp);
4349 }
4350 }
4351
4352
4353 /*
4354 ** Append raw text to zOut
@@ -5060,15 +5072,29 @@
5060 case DIR_DOWN: pElem->ptExit.y -= pElem->h*0.5; break;
5061 }
5062 }
5063 }
5064
5065 /* Change the direction of travel
5066 */
5067 static void pik_set_direction(Pik *p, int eDir){
5068 assert( ValidDir(eDir) );
5069 p->eDir = eDir;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5070 if( p->list && p->list->n ){
5071 pik_elem_set_exit(p, p->list->a[p->list->n-1], eDir);
5072 }
5073 }
5074
@@ -5115,26 +5141,20 @@
5115 */
5116 static int pik_param_ok(
5117 Pik *p, /* For storing the error message (if any) */
5118 PElem *pElem, /* The element under construction */
5119 PToken *pId, /* Make the error point to this token */
5120 int mThis, /* Value we are trying to set */
5121 int mBlockers /* Other value that might block this one */
5122 ){
5123 int m;
5124 if( pElem->mProp & mThis ){
5125 pik_error(p, pId, "value is already set");
5126 return 1;
5127 }
5128 if( pElem->mCalc & mThis ){
5129 pik_error(p, pId, "value already fixed by prior constraints");
5130 return 1;
5131 }
5132 m = pElem->mProp & mBlockers;
5133 if( m ){
5134 pElem->mCalc |= mThis|mBlockers;
5135 }
5136 pElem->mProp |= mThis;
5137 return 0;
5138 }
5139
5140
@@ -5146,27 +5166,27 @@
5146 */
5147 void pik_set_numprop(Pik *p, PToken *pId, PRel *pVal){
5148 PElem *pElem = p->cur;
5149 switch( pId->eType ){
5150 case T_HEIGHT:
5151 if( pik_param_ok(p, pElem, pId, A_HEIGHT, A_BOTTOM|A_TOP|A_AT) ) return;
5152 pElem->h = pElem->h*pVal->rRel + pVal->rAbs;
5153 break;
5154 case T_WIDTH:
5155 if( pik_param_ok(p, pElem, pId, A_WIDTH, A_RIGHT|A_LEFT|A_AT) ) return;
5156 pElem->w = pElem->w*pVal->rRel + pVal->rAbs;
5157 break;
5158 case T_RADIUS:
5159 if( pik_param_ok(p, pElem, pId, A_RADIUS, 0) ) return;
5160 pElem->rad = pElem->rad*pVal->rRel + pVal->rAbs;
5161 break;
5162 case T_DIAMETER:
5163 if( pik_param_ok(p, pElem, pId, A_RADIUS, 0) ) return;
5164 pElem->rad = pElem->rad*pVal->rRel + 0.5*pVal->rAbs; /* diam it 2x rad */
5165 break;
5166 case T_THICKNESS:
5167 if( pik_param_ok(p, pElem, pId, A_THICKNESS, 0) ) return;
5168 pElem->sw = pElem->sw*pVal->rRel + pVal->rAbs;
5169 break;
5170 }
5171 if( pElem->type->xNumProp ){
5172 pElem->type->xNumProp(p, pElem, pId);
@@ -5179,15 +5199,15 @@
5179 */
5180 void pik_set_clrprop(Pik *p, PToken *pId, PNum rClr){
5181 PElem *pElem = p->cur;
5182 switch( pId->eType ){
5183 case T_FILL:
5184 if( pik_param_ok(p, pElem, pId, A_FILL, 0) ) return;
5185 pElem->fill = rClr;
5186 break;
5187 case T_COLOR:
5188 if( pik_param_ok(p, pElem, pId, A_COLOR, 0) ) return;
5189 pElem->color = rClr;
5190 break;
5191 }
5192 if( pElem->type->xNumProp ){
5193 pElem->type->xNumProp(p, pElem, pId);
@@ -5475,22 +5495,12 @@
5475 }
5476 if( pElem->mProp & A_AT ){
5477 pik_error(p, pErrTok, "location fixed by prior \"at\"");
5478 return;
5479 }
5480 if( pElem->mCalc & A_AT ){
5481 pik_error(p, pErrTok, "location fixed by prior constraints");
5482 return;
5483 }
5484 if( pElem->mProp & (A_WIDTH|A_LEFT|A_RIGHT) ){
5485 pElem->mCalc |= (A_WIDTH|A_LEFT|A_RIGHT|A_AT);
5486 }
5487 if( pElem->mProp & (A_HEIGHT|A_TOP|A_BOTTOM) ){
5488 pElem->mCalc |= (A_HEIGHT|A_TOP|A_BOTTOM|A_AT);
5489 }
5490 pElem->mProp |= A_AT;
5491 pElem->eWith = pEdge ? pEdge->eEdge : CP_C;
5492 pElem->with = *pAt;
5493 }
5494
5495 /*
5496 ** Try to add a text attribute to an element
@@ -5923,16 +5933,12 @@
5923 if( pElem==0 ) return pt;
5924 if( pEdge==0 ){
5925 return pElem->ptAt;
5926 }
5927 pClass = pElem->type;
5928 if( pEdge->eType==T_EDGEPT || pEdge->eEdge>0 ){
5929 if( pClass->xOffset==0 ){
5930 pt = boxOffset(p, pElem, pEdge->eEdge);
5931 }else{
5932 pt = pClass->xOffset(p, pElem, pEdge->eEdge);
5933 }
5934 pt.x += pElem->ptAt.x;
5935 pt.y += pElem->ptAt.y;
5936 return pt;
5937 }
5938 if( pEdge->eType==T_START ){
@@ -6411,97 +6417,97 @@
6411
6412 /*
6413 ** Keywords
6414 */
6415 static const PikWord pik_keywords[] = {
6416 { "above", 5, T_ABOVE, 0, 0 },
6417 { "abs", 3, T_FUNC1, FN_ABS, 0 },
6418 { "aligned", 7, T_ALIGNED, 0, 0 },
6419 { "and", 3, T_AND, 0, 0 },
6420 { "as", 2, T_AS, 0, 0 },
6421 { "assert", 6, T_ASSERT, 0, 0 },
6422 { "at", 2, T_AT, 0, 0 },
6423 { "behind", 6, T_BEHIND, 0, 0 },
6424 { "below", 5, T_BELOW, 0, 0 },
6425 { "between", 7, T_BETWEEN, 0, 0 },
6426 { "big", 3, T_BIG, 0, 0 },
6427 { "bold", 4, T_BOLD, 0, 0 },
6428 { "bot", 3, T_EDGEPT, 0, CP_S },
6429 { "bottom", 6, T_BOTTOM, 0, CP_S },
6430 { "c", 1, T_EDGEPT, 0, CP_C },
6431 { "ccw", 3, T_CCW, 0, 0 },
6432 { "center", 6, T_CENTER, 0, CP_C },
6433 { "chop", 4, T_CHOP, 0, 0 },
6434 { "close", 5, T_CLOSE, 0, 0 },
6435 { "color", 5, T_COLOR, 0, 0 },
6436 { "cos", 3, T_FUNC1, FN_COS, 0 },
6437 { "cw", 2, T_CW, 0, 0 },
6438 { "dashed", 6, T_DASHED, 0, 0 },
6439 { "diameter", 8, T_DIAMETER, 0, 0 },
6440 { "dotted", 6, T_DOTTED, 0, 0 },
6441 { "down", 4, T_DOWN, DIR_DOWN, 0 },
6442 { "e", 1, T_EDGEPT, 0, CP_E },
6443 { "east", 4, T_EDGEPT, 0, CP_E },
6444 { "end", 3, T_END, 0, 0 },
6445 { "even", 4, T_EVEN, 0, 0 },
6446 { "fill", 4, T_FILL, 0, 0 },
6447 { "first", 5, T_NTH, 0, 0 },
6448 { "fit", 3, T_FIT, 0, 0 },
6449 { "from", 4, T_FROM, 0, 0 },
6450 { "go", 2, T_GO, 0, 0 },
6451 { "heading", 7, T_HEADING, 0, 0 },
6452 { "height", 6, T_HEIGHT, 0, 0 },
6453 { "ht", 2, T_HEIGHT, 0, 0 },
6454 { "in", 2, T_IN, 0, 0 },
6455 { "int", 3, T_FUNC1, FN_INT, 0 },
6456 { "invis", 5, T_INVIS, 0, 0 },
6457 { "invisible", 9, T_INVIS, 0, 0 },
6458 { "italic", 6, T_ITALIC, 0, 0 },
6459 { "last", 4, T_LAST, 0, 0 },
6460 { "left", 4, T_LEFT, DIR_LEFT, CP_W },
6461 { "ljust", 5, T_LJUST, 0, 0 },
6462 { "max", 3, T_FUNC2, FN_MAX, 0 },
6463 { "min", 3, T_FUNC2, FN_MIN, 0 },
6464 { "n", 1, T_EDGEPT, 0, CP_N },
6465 { "ne", 2, T_EDGEPT, 0, CP_NE },
6466 { "north", 5, T_EDGEPT, 0, CP_N },
6467 { "nw", 2, T_EDGEPT, 0, CP_NW },
6468 { "of", 2, T_OF, 0, 0 },
6469 { "previous", 8, T_LAST, 0, 0, },
6470 { "print", 5, T_PRINT, 0, 0 },
6471 { "rad", 3, T_RADIUS, 0, 0 },
6472 { "radius", 6, T_RADIUS, 0, 0 },
6473 { "right", 5, T_RIGHT, DIR_RIGHT, CP_E },
6474 { "rjust", 5, T_RJUST, 0, 0 },
6475 { "s", 1, T_EDGEPT, 0, CP_S },
6476 { "same", 4, T_SAME, 0, 0 },
6477 { "se", 2, T_EDGEPT, 0, CP_SE },
6478 { "sin", 3, T_FUNC1, FN_SIN, 0 },
6479 { "small", 5, T_SMALL, 0, 0 },
6480 { "south", 5, T_EDGEPT, 0, CP_S },
6481 { "sqrt", 4, T_FUNC1, FN_SQRT, 0 },
6482 { "start", 5, T_START, 0, 0 },
6483 { "sw", 2, T_EDGEPT, 0, CP_SW },
6484 { "t", 1, T_TOP, 0, CP_N },
6485 { "the", 3, T_THE, 0, 0 },
6486 { "then", 4, T_THEN, 0, 0 },
6487 { "thick", 5, T_THICK, 0, 0 },
6488 { "thickness", 9, T_THICKNESS, 0, 0 },
6489 { "thin", 4, T_THIN, 0, 0 },
6490 { "to", 2, T_TO, 0, 0 },
6491 { "top", 3, T_TOP, 0, CP_N },
6492 { "until", 5, T_UNTIL, 0, 0 },
6493 { "up", 2, T_UP, DIR_UP, 0 },
6494 { "vertex", 6, T_VERTEX, 0, 0 },
6495 { "w", 1, T_EDGEPT, 0, CP_W },
6496 { "way", 3, T_WAY, 0, 0 },
6497 { "west", 4, T_EDGEPT, 0, CP_W },
6498 { "wid", 3, T_WIDTH, 0, 0 },
6499 { "width", 5, T_WIDTH, 0, 0 },
6500 { "with", 4, T_WITH, 0, 0 },
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.
@@ -6931,11 +6937,11 @@
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"
@@ -7023,6 +7029,6 @@
7023 printf("</body></html>\n");
7024 return 0;
7025 }
7026 #endif /* PIKCHR_SHELL */
7027
7028 #line 7053 "pikchr.c"
7029
--- src/pikchr.c
+++ src/pikchr.c
@@ -146,10 +146,12 @@
146 #define CP_S 5
147 #define CP_SW 6
148 #define CP_W 7
149 #define CP_NW 8
150 #define CP_C 9 /* .center or .c */
151 #define CP_END 10 /* .end */
152 #define CP_START 11 /* .start */
153
154 /* Heading angles corresponding to compass points */
155 static const PNum pik_hdg_angle[] = {
156 /* none */ 0.0,
157 /* N */ 0.0,
@@ -262,26 +264,21 @@
264 #define IsLeftRight(X) (((X)&1)==0)
265
266 /* Bitmask for the various attributes for PElem. These bits are
267 ** collected in PElem.mProp and PElem.mCalc to check for constraint
268 ** errors. */
269 #define A_WIDTH 0x0001
270 #define A_HEIGHT 0x0002
271 #define A_RADIUS 0x0004
272 #define A_THICKNESS 0x0008
273 #define A_DASHED 0x0010 /* Includes "dotted" */
274 #define A_FILL 0x0020
275 #define A_COLOR 0x0040
276 #define A_ARROW 0x0080
277 #define A_FROM 0x0100
278 #define A_CW 0x0200
279 #define A_AT 0x0400
 
 
 
 
 
280
281
282 /* A single element */
283 struct PElem {
284 const PClass *type; /* Element type */
@@ -453,11 +450,11 @@
450 static void pik_behind(Pik*,PElem*);
451 static PElem *pik_assert(Pik*,PNum,PToken*,PNum);
452 static PElem *pik_place_assert(Pik*,PPoint*,PToken*,PPoint*);
453
454
455 #line 481 "pikchr.c"
456 /**************** End of %include directives **********************************/
457 /* These constants specify the various numeric values for terminal symbols.
458 ***************** Begin token definitions *************************************/
459 #ifndef T_ID
460 #define T_ID 1
@@ -1629,22 +1626,22 @@
1626 ** inside the C code.
1627 */
1628 /********* Begin destructor definitions ***************************************/
1629 case 94: /* element_list */
1630 {
1631 #line 470 "pikchr.y"
1632 pik_elist_free(p,(yypminor->yy72));
1633 #line 1658 "pikchr.c"
1634 }
1635 break;
1636 case 95: /* element */
1637 case 96: /* unnamed_element */
1638 case 97: /* basetype */
1639 {
1640 #line 472 "pikchr.y"
1641 pik_elem_free(p,(yypminor->yy254));
1642 #line 1667 "pikchr.c"
1643 }
1644 break;
1645 /********* End destructor definitions *****************************************/
1646 default: break; /* If no destructor action specified: do nothing */
1647 }
@@ -1858,14 +1855,14 @@
1855 #endif
1856 while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
1857 /* Here code is inserted which will execute if the parser
1858 ** stack every overflows */
1859 /******** Begin %stack_overflow code ******************************************/
1860 #line 503 "pikchr.y"
1861
1862 pik_error(p, 0, "parser stack overflow");
1863 #line 1888 "pikchr.c"
1864 /******** End %stack_overflow code ********************************************/
1865 pik_parserARG_STORE /* Suppress warning about unused %extra_argument var */
1866 pik_parserCTX_STORE
1867 }
1868
@@ -2330,593 +2327,593 @@
2327 ** break;
2328 */
2329 /********** Begin reduce actions **********************************************/
2330 YYMINORTYPE yylhsminor;
2331 case 0: /* document ::= element_list */
2332 #line 507 "pikchr.y"
2333 {pik_render(p,yymsp[0].minor.yy72);}
2334 #line 2359 "pikchr.c"
2335 break;
2336 case 1: /* element_list ::= element */
2337 #line 510 "pikchr.y"
2338 { yylhsminor.yy72 = pik_elist_append(p,0,yymsp[0].minor.yy254); }
2339 #line 2364 "pikchr.c"
2340 yymsp[0].minor.yy72 = yylhsminor.yy72;
2341 break;
2342 case 2: /* element_list ::= element_list EOL element */
2343 #line 512 "pikchr.y"
2344 { yylhsminor.yy72 = pik_elist_append(p,yymsp[-2].minor.yy72,yymsp[0].minor.yy254); }
2345 #line 2370 "pikchr.c"
2346 yymsp[-2].minor.yy72 = yylhsminor.yy72;
2347 break;
2348 case 3: /* element ::= */
2349 #line 515 "pikchr.y"
2350 { yymsp[1].minor.yy254 = 0; }
2351 #line 2376 "pikchr.c"
2352 break;
2353 case 4: /* element ::= direction */
2354 #line 516 "pikchr.y"
2355 { pik_set_direction(p,yymsp[0].minor.yy0.eCode); yylhsminor.yy254=0; }
2356 #line 2381 "pikchr.c"
2357 yymsp[0].minor.yy254 = yylhsminor.yy254;
2358 break;
2359 case 5: /* element ::= lvalue ASSIGN rvalue */
2360 #line 517 "pikchr.y"
2361 {pik_set_var(p,&yymsp[-2].minor.yy0,yymsp[0].minor.yy73,&yymsp[-1].minor.yy0); yylhsminor.yy254=0;}
2362 #line 2387 "pikchr.c"
2363 yymsp[-2].minor.yy254 = yylhsminor.yy254;
2364 break;
2365 case 6: /* element ::= PLACENAME COLON unnamed_element */
2366 #line 519 "pikchr.y"
2367 { yylhsminor.yy254 = yymsp[0].minor.yy254; pik_elem_setname(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0); }
2368 #line 2393 "pikchr.c"
2369 yymsp[-2].minor.yy254 = yylhsminor.yy254;
2370 break;
2371 case 7: /* element ::= PLACENAME COLON position */
2372 #line 521 "pikchr.y"
2373 { yylhsminor.yy254 = pik_elem_new(p,0,0,0);
2374 if(yylhsminor.yy254){ yylhsminor.yy254->ptAt = yymsp[0].minor.yy139; pik_elem_setname(p,yylhsminor.yy254,&yymsp[-2].minor.yy0); }}
2375 #line 2400 "pikchr.c"
2376 yymsp[-2].minor.yy254 = yylhsminor.yy254;
2377 break;
2378 case 8: /* element ::= unnamed_element */
2379 #line 523 "pikchr.y"
2380 {yylhsminor.yy254 = yymsp[0].minor.yy254;}
2381 #line 2406 "pikchr.c"
2382 yymsp[0].minor.yy254 = yylhsminor.yy254;
2383 break;
2384 case 9: /* element ::= print prlist */
2385 #line 524 "pikchr.y"
2386 {pik_append(p,"<br>\n",5); yymsp[-1].minor.yy254=0;}
2387 #line 2412 "pikchr.c"
2388 break;
2389 case 10: /* element ::= ASSERT LP expr EQ expr RP */
2390 #line 529 "pikchr.y"
2391 {yymsp[-5].minor.yy254=pik_assert(p,yymsp[-3].minor.yy73,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy73);}
2392 #line 2417 "pikchr.c"
2393 break;
2394 case 11: /* element ::= ASSERT LP place EQ place RP */
2395 #line 531 "pikchr.y"
2396 {yymsp[-5].minor.yy254=pik_place_assert(p,&yymsp[-3].minor.yy139,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy139);}
2397 #line 2422 "pikchr.c"
2398 break;
2399 case 12: /* rvalue ::= PLACENAME */
2400 #line 542 "pikchr.y"
2401 {yylhsminor.yy73 = pik_lookup_color(p,&yymsp[0].minor.yy0);}
2402 #line 2427 "pikchr.c"
2403 yymsp[0].minor.yy73 = yylhsminor.yy73;
2404 break;
2405 case 13: /* pritem ::= FILL */
2406 case 14: /* pritem ::= COLOR */ yytestcase(yyruleno==14);
2407 case 15: /* pritem ::= THICKNESS */ yytestcase(yyruleno==15);
2408 #line 547 "pikchr.y"
2409 {pik_append_num(p,"",pik_value(p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.n,0));}
2410 #line 2435 "pikchr.c"
2411 break;
2412 case 16: /* pritem ::= rvalue */
2413 #line 550 "pikchr.y"
2414 {pik_append_num(p,"",yymsp[0].minor.yy73);}
2415 #line 2440 "pikchr.c"
2416 break;
2417 case 17: /* pritem ::= STRING */
2418 #line 551 "pikchr.y"
2419 {pik_append_text(p,yymsp[0].minor.yy0.z+1,yymsp[0].minor.yy0.n-2,0);}
2420 #line 2445 "pikchr.c"
2421 break;
2422 case 18: /* prsep ::= COMMA */
2423 #line 552 "pikchr.y"
2424 {pik_append(p, " ", 1);}
2425 #line 2450 "pikchr.c"
2426 break;
2427 case 19: /* unnamed_element ::= basetype attribute_list */
2428 #line 555 "pikchr.y"
2429 {yylhsminor.yy254 = yymsp[-1].minor.yy254; pik_after_adding_attributes(p,yylhsminor.yy254);}
2430 #line 2455 "pikchr.c"
2431 yymsp[-1].minor.yy254 = yylhsminor.yy254;
2432 break;
2433 case 20: /* basetype ::= CLASSNAME */
2434 #line 557 "pikchr.y"
2435 {yylhsminor.yy254 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); }
2436 #line 2461 "pikchr.c"
2437 yymsp[0].minor.yy254 = yylhsminor.yy254;
2438 break;
2439 case 21: /* basetype ::= STRING textposition */
2440 #line 559 "pikchr.y"
2441 {yymsp[-1].minor.yy0.eCode = yymsp[0].minor.yy74; yylhsminor.yy254 = pik_elem_new(p,0,&yymsp[-1].minor.yy0,0); }
2442 #line 2467 "pikchr.c"
2443 yymsp[-1].minor.yy254 = yylhsminor.yy254;
2444 break;
2445 case 22: /* basetype ::= LB savelist element_list RB */
2446 #line 561 "pikchr.y"
2447 { 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; }
2448 #line 2473 "pikchr.c"
2449 break;
2450 case 23: /* savelist ::= */
2451 #line 566 "pikchr.y"
2452 {yymsp[1].minor.yy72 = p->list; p->list = 0;}
2453 #line 2478 "pikchr.c"
2454 break;
2455 case 24: /* relexpr ::= expr */
2456 #line 573 "pikchr.y"
2457 {yylhsminor.yy60.rAbs = yymsp[0].minor.yy73; yylhsminor.yy60.rRel = 0;}
2458 #line 2483 "pikchr.c"
2459 yymsp[0].minor.yy60 = yylhsminor.yy60;
2460 break;
2461 case 25: /* relexpr ::= expr PERCENT */
2462 #line 574 "pikchr.y"
2463 {yylhsminor.yy60.rAbs = 0; yylhsminor.yy60.rRel = yymsp[-1].minor.yy73/100;}
2464 #line 2489 "pikchr.c"
2465 yymsp[-1].minor.yy60 = yylhsminor.yy60;
2466 break;
2467 case 26: /* optrelexpr ::= */
2468 #line 576 "pikchr.y"
2469 {yymsp[1].minor.yy60.rAbs = 0; yymsp[1].minor.yy60.rRel = 1.0;}
2470 #line 2495 "pikchr.c"
2471 break;
2472 case 27: /* attribute_list ::= relexpr alist */
2473 #line 578 "pikchr.y"
2474 {pik_add_direction(p,0,&yymsp[-1].minor.yy60);}
2475 #line 2500 "pikchr.c"
2476 break;
2477 case 28: /* attribute ::= numproperty relexpr */
2478 #line 582 "pikchr.y"
2479 { pik_set_numprop(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy60); }
2480 #line 2505 "pikchr.c"
2481 break;
2482 case 29: /* attribute ::= dashproperty expr */
2483 #line 583 "pikchr.y"
2484 { pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy73); }
2485 #line 2510 "pikchr.c"
2486 break;
2487 case 30: /* attribute ::= dashproperty */
2488 #line 584 "pikchr.y"
2489 { pik_set_dashed(p,&yymsp[0].minor.yy0,0); }
2490 #line 2515 "pikchr.c"
2491 break;
2492 case 31: /* attribute ::= colorproperty rvalue */
2493 #line 585 "pikchr.y"
2494 { pik_set_clrprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy73); }
2495 #line 2520 "pikchr.c"
2496 break;
2497 case 32: /* attribute ::= go direction optrelexpr */
2498 #line 586 "pikchr.y"
2499 { pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy60);}
2500 #line 2525 "pikchr.c"
2501 break;
2502 case 33: /* attribute ::= go direction even position */
2503 #line 587 "pikchr.y"
2504 {pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy139);}
2505 #line 2530 "pikchr.c"
2506 break;
2507 case 34: /* attribute ::= CLOSE */
2508 #line 588 "pikchr.y"
2509 { pik_close_path(p,&yymsp[0].minor.yy0); }
2510 #line 2535 "pikchr.c"
2511 break;
2512 case 35: /* attribute ::= CHOP */
2513 #line 589 "pikchr.y"
2514 { p->cur->bChop = 1; }
2515 #line 2540 "pikchr.c"
2516 break;
2517 case 36: /* attribute ::= FROM position */
2518 #line 590 "pikchr.y"
2519 { pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy139); }
2520 #line 2545 "pikchr.c"
2521 break;
2522 case 37: /* attribute ::= TO position */
2523 #line 591 "pikchr.y"
2524 { pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy139); }
2525 #line 2550 "pikchr.c"
2526 break;
2527 case 38: /* attribute ::= THEN */
2528 #line 592 "pikchr.y"
2529 { pik_then(p, &yymsp[0].minor.yy0, p->cur); }
2530 #line 2555 "pikchr.c"
2531 break;
2532 case 39: /* attribute ::= THEN optrelexpr HEADING expr */
2533 case 41: /* attribute ::= GO optrelexpr HEADING expr */ yytestcase(yyruleno==41);
2534 #line 594 "pikchr.y"
2535 {pik_move_hdg(p,&yymsp[-2].minor.yy60,&yymsp[-1].minor.yy0,yymsp[0].minor.yy73,0,&yymsp[-3].minor.yy0);}
2536 #line 2561 "pikchr.c"
2537 break;
2538 case 40: /* attribute ::= THEN optrelexpr EDGEPT */
2539 case 42: /* attribute ::= GO optrelexpr EDGEPT */ yytestcase(yyruleno==42);
2540 #line 595 "pikchr.y"
2541 {pik_move_hdg(p,&yymsp[-1].minor.yy60,0,0,&yymsp[0].minor.yy0,&yymsp[-2].minor.yy0);}
2542 #line 2567 "pikchr.c"
2543 break;
2544 case 43: /* attribute ::= AT position */
2545 #line 600 "pikchr.y"
2546 { pik_set_at(p,0,&yymsp[0].minor.yy139,&yymsp[-1].minor.yy0); }
2547 #line 2572 "pikchr.c"
2548 break;
2549 case 44: /* attribute ::= SAME */
2550 #line 602 "pikchr.y"
2551 {pik_same(p,0,&yymsp[0].minor.yy0);}
2552 #line 2577 "pikchr.c"
2553 break;
2554 case 45: /* attribute ::= SAME AS object */
2555 #line 603 "pikchr.y"
2556 {pik_same(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0);}
2557 #line 2582 "pikchr.c"
2558 break;
2559 case 46: /* attribute ::= STRING textposition */
2560 #line 604 "pikchr.y"
2561 {pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy74);}
2562 #line 2587 "pikchr.c"
2563 break;
2564 case 47: /* attribute ::= FIT */
2565 #line 605 "pikchr.y"
2566 {pik_size_to_fit(p,&yymsp[0].minor.yy0); }
2567 #line 2592 "pikchr.c"
2568 break;
2569 case 48: /* attribute ::= BEHIND object */
2570 #line 606 "pikchr.y"
2571 {pik_behind(p,yymsp[0].minor.yy254);}
2572 #line 2597 "pikchr.c"
2573 break;
2574 case 49: /* withclause ::= DOT_E edge AT position */
2575 case 50: /* withclause ::= edge AT position */ yytestcase(yyruleno==50);
2576 #line 614 "pikchr.y"
2577 { pik_set_at(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy139,&yymsp[-1].minor.yy0); }
2578 #line 2603 "pikchr.c"
2579 break;
2580 case 51: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2581 #line 618 "pikchr.y"
2582 {yylhsminor.yy0 = yymsp[0].minor.yy0;}
2583 #line 2608 "pikchr.c"
2584 yymsp[0].minor.yy0 = yylhsminor.yy0;
2585 break;
2586 case 52: /* boolproperty ::= CW */
2587 #line 629 "pikchr.y"
2588 {p->cur->cw = 1;}
2589 #line 2614 "pikchr.c"
2590 break;
2591 case 53: /* boolproperty ::= CCW */
2592 #line 630 "pikchr.y"
2593 {p->cur->cw = 0;}
2594 #line 2619 "pikchr.c"
2595 break;
2596 case 54: /* boolproperty ::= LARROW */
2597 #line 631 "pikchr.y"
2598 {p->cur->larrow=1; p->cur->rarrow=0; }
2599 #line 2624 "pikchr.c"
2600 break;
2601 case 55: /* boolproperty ::= RARROW */
2602 #line 632 "pikchr.y"
2603 {p->cur->larrow=0; p->cur->rarrow=1; }
2604 #line 2629 "pikchr.c"
2605 break;
2606 case 56: /* boolproperty ::= LRARROW */
2607 #line 633 "pikchr.y"
2608 {p->cur->larrow=1; p->cur->rarrow=1; }
2609 #line 2634 "pikchr.c"
2610 break;
2611 case 57: /* boolproperty ::= INVIS */
2612 #line 634 "pikchr.y"
2613 {p->cur->sw = 0.0;}
2614 #line 2639 "pikchr.c"
2615 break;
2616 case 58: /* boolproperty ::= THICK */
2617 #line 635 "pikchr.y"
2618 {p->cur->sw *= 1.5;}
2619 #line 2644 "pikchr.c"
2620 break;
2621 case 59: /* boolproperty ::= THIN */
2622 #line 636 "pikchr.y"
2623 {p->cur->sw *= 0.67;}
2624 #line 2649 "pikchr.c"
2625 break;
2626 case 60: /* textposition ::= */
2627 #line 638 "pikchr.y"
2628 {yymsp[1].minor.yy74 = 0;}
2629 #line 2654 "pikchr.c"
2630 break;
2631 case 61: /* textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL */
2632 #line 641 "pikchr.y"
2633 {yylhsminor.yy74 = pik_text_position(p,yymsp[-1].minor.yy74,&yymsp[0].minor.yy0);}
2634 #line 2659 "pikchr.c"
2635 yymsp[-1].minor.yy74 = yylhsminor.yy74;
2636 break;
2637 case 62: /* position ::= expr COMMA expr */
2638 #line 644 "pikchr.y"
2639 {yylhsminor.yy139.x=yymsp[-2].minor.yy73; yylhsminor.yy139.y=yymsp[0].minor.yy73;}
2640 #line 2665 "pikchr.c"
2641 yymsp[-2].minor.yy139 = yylhsminor.yy139;
2642 break;
2643 case 63: /* position ::= place PLUS expr COMMA expr */
2644 #line 646 "pikchr.y"
2645 {yylhsminor.yy139.x=yymsp[-4].minor.yy139.x+yymsp[-2].minor.yy73; yylhsminor.yy139.y=yymsp[-4].minor.yy139.y+yymsp[0].minor.yy73;}
2646 #line 2671 "pikchr.c"
2647 yymsp[-4].minor.yy139 = yylhsminor.yy139;
2648 break;
2649 case 64: /* position ::= place MINUS expr COMMA expr */
2650 #line 647 "pikchr.y"
2651 {yylhsminor.yy139.x=yymsp[-4].minor.yy139.x-yymsp[-2].minor.yy73; yylhsminor.yy139.y=yymsp[-4].minor.yy139.y-yymsp[0].minor.yy73;}
2652 #line 2677 "pikchr.c"
2653 yymsp[-4].minor.yy139 = yylhsminor.yy139;
2654 break;
2655 case 65: /* position ::= place PLUS LP expr COMMA expr RP */
2656 #line 649 "pikchr.y"
2657 {yylhsminor.yy139.x=yymsp[-6].minor.yy139.x+yymsp[-3].minor.yy73; yylhsminor.yy139.y=yymsp[-6].minor.yy139.y+yymsp[-1].minor.yy73;}
2658 #line 2683 "pikchr.c"
2659 yymsp[-6].minor.yy139 = yylhsminor.yy139;
2660 break;
2661 case 66: /* position ::= place MINUS LP expr COMMA expr RP */
2662 #line 651 "pikchr.y"
2663 {yylhsminor.yy139.x=yymsp[-6].minor.yy139.x-yymsp[-3].minor.yy73; yylhsminor.yy139.y=yymsp[-6].minor.yy139.y-yymsp[-1].minor.yy73;}
2664 #line 2689 "pikchr.c"
2665 yymsp[-6].minor.yy139 = yylhsminor.yy139;
2666 break;
2667 case 67: /* position ::= LP position COMMA position RP */
2668 #line 652 "pikchr.y"
2669 {yymsp[-4].minor.yy139.x=yymsp[-3].minor.yy139.x; yymsp[-4].minor.yy139.y=yymsp[-1].minor.yy139.y;}
2670 #line 2695 "pikchr.c"
2671 break;
2672 case 68: /* position ::= LP position RP */
2673 #line 653 "pikchr.y"
2674 {yymsp[-2].minor.yy139=yymsp[-1].minor.yy139;}
2675 #line 2700 "pikchr.c"
2676 break;
2677 case 69: /* position ::= expr between position AND position */
2678 #line 655 "pikchr.y"
2679 {yylhsminor.yy139 = pik_position_between(p,yymsp[-4].minor.yy73,yymsp[-2].minor.yy139,yymsp[0].minor.yy139);}
2680 #line 2705 "pikchr.c"
2681 yymsp[-4].minor.yy139 = yylhsminor.yy139;
2682 break;
2683 case 70: /* position ::= expr LT position COMMA position GT */
2684 #line 657 "pikchr.y"
2685 {yylhsminor.yy139 = pik_position_between(p,yymsp[-5].minor.yy73,yymsp[-3].minor.yy139,yymsp[-1].minor.yy139);}
2686 #line 2711 "pikchr.c"
2687 yymsp[-5].minor.yy139 = yylhsminor.yy139;
2688 break;
2689 case 71: /* position ::= expr ABOVE position */
2690 #line 658 "pikchr.y"
2691 {yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.y += yymsp[-2].minor.yy73;}
2692 #line 2717 "pikchr.c"
2693 yymsp[-2].minor.yy139 = yylhsminor.yy139;
2694 break;
2695 case 72: /* position ::= expr BELOW position */
2696 #line 659 "pikchr.y"
2697 {yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.y -= yymsp[-2].minor.yy73;}
2698 #line 2723 "pikchr.c"
2699 yymsp[-2].minor.yy139 = yylhsminor.yy139;
2700 break;
2701 case 73: /* position ::= expr LEFT OF position */
2702 #line 660 "pikchr.y"
2703 {yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.x -= yymsp[-3].minor.yy73;}
2704 #line 2729 "pikchr.c"
2705 yymsp[-3].minor.yy139 = yylhsminor.yy139;
2706 break;
2707 case 74: /* position ::= expr RIGHT OF position */
2708 #line 661 "pikchr.y"
2709 {yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.x += yymsp[-3].minor.yy73;}
2710 #line 2735 "pikchr.c"
2711 yymsp[-3].minor.yy139 = yylhsminor.yy139;
2712 break;
2713 case 75: /* position ::= expr ON HEADING EDGEPT OF position */
2714 #line 663 "pikchr.y"
2715 {yylhsminor.yy139 = pik_position_at_hdg(p,yymsp[-5].minor.yy73,&yymsp[-2].minor.yy0,yymsp[0].minor.yy139);}
2716 #line 2741 "pikchr.c"
2717 yymsp[-5].minor.yy139 = yylhsminor.yy139;
2718 break;
2719 case 76: /* position ::= expr HEADING EDGEPT OF position */
2720 #line 665 "pikchr.y"
2721 {yylhsminor.yy139 = pik_position_at_hdg(p,yymsp[-4].minor.yy73,&yymsp[-2].minor.yy0,yymsp[0].minor.yy139);}
2722 #line 2747 "pikchr.c"
2723 yymsp[-4].minor.yy139 = yylhsminor.yy139;
2724 break;
2725 case 77: /* position ::= expr EDGEPT OF position */
2726 #line 667 "pikchr.y"
2727 {yylhsminor.yy139 = pik_position_at_hdg(p,yymsp[-3].minor.yy73,&yymsp[-2].minor.yy0,yymsp[0].minor.yy139);}
2728 #line 2753 "pikchr.c"
2729 yymsp[-3].minor.yy139 = yylhsminor.yy139;
2730 break;
2731 case 78: /* position ::= expr ON HEADING expr FROM position */
2732 #line 669 "pikchr.y"
2733 {yylhsminor.yy139 = pik_position_at_angle(p,yymsp[-5].minor.yy73,yymsp[-2].minor.yy73,yymsp[0].minor.yy139);}
2734 #line 2759 "pikchr.c"
2735 yymsp[-5].minor.yy139 = yylhsminor.yy139;
2736 break;
2737 case 79: /* position ::= expr HEADING expr FROM position */
2738 #line 671 "pikchr.y"
2739 {yylhsminor.yy139 = pik_position_at_angle(p,yymsp[-4].minor.yy73,yymsp[-2].minor.yy73,yymsp[0].minor.yy139);}
2740 #line 2765 "pikchr.c"
2741 yymsp[-4].minor.yy139 = yylhsminor.yy139;
2742 break;
2743 case 80: /* place ::= edge OF object */
2744 #line 683 "pikchr.y"
2745 {yylhsminor.yy139 = pik_place_of_elem(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0);}
2746 #line 2771 "pikchr.c"
2747 yymsp[-2].minor.yy139 = yylhsminor.yy139;
2748 break;
2749 case 81: /* place2 ::= object */
2750 #line 684 "pikchr.y"
2751 {yylhsminor.yy139 = pik_place_of_elem(p,yymsp[0].minor.yy254,0);}
2752 #line 2777 "pikchr.c"
2753 yymsp[0].minor.yy139 = yylhsminor.yy139;
2754 break;
2755 case 82: /* place2 ::= object DOT_E edge */
2756 #line 685 "pikchr.y"
2757 {yylhsminor.yy139 = pik_place_of_elem(p,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
2758 #line 2783 "pikchr.c"
2759 yymsp[-2].minor.yy139 = yylhsminor.yy139;
2760 break;
2761 case 83: /* place2 ::= NTH VERTEX OF object */
2762 #line 686 "pikchr.y"
2763 {yylhsminor.yy139 = pik_nth_vertex(p,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,yymsp[0].minor.yy254);}
2764 #line 2789 "pikchr.c"
2765 yymsp[-3].minor.yy139 = yylhsminor.yy139;
2766 break;
2767 case 84: /* object ::= nth */
2768 #line 698 "pikchr.y"
2769 {yylhsminor.yy254 = pik_find_nth(p,0,&yymsp[0].minor.yy0);}
2770 #line 2795 "pikchr.c"
2771 yymsp[0].minor.yy254 = yylhsminor.yy254;
2772 break;
2773 case 85: /* object ::= nth OF|IN object */
2774 #line 699 "pikchr.y"
2775 {yylhsminor.yy254 = pik_find_nth(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0);}
2776 #line 2801 "pikchr.c"
2777 yymsp[-2].minor.yy254 = yylhsminor.yy254;
2778 break;
2779 case 86: /* objectname ::= PLACENAME */
2780 #line 701 "pikchr.y"
2781 {yylhsminor.yy254 = pik_find_byname(p,0,&yymsp[0].minor.yy0);}
2782 #line 2807 "pikchr.c"
2783 yymsp[0].minor.yy254 = yylhsminor.yy254;
2784 break;
2785 case 87: /* objectname ::= objectname DOT_U PLACENAME */
2786 #line 703 "pikchr.y"
2787 {yylhsminor.yy254 = pik_find_byname(p,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
2788 #line 2813 "pikchr.c"
2789 yymsp[-2].minor.yy254 = yylhsminor.yy254;
2790 break;
2791 case 88: /* nth ::= NTH CLASSNAME */
2792 #line 705 "pikchr.y"
2793 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-1].minor.yy0); }
2794 #line 2819 "pikchr.c"
2795 yymsp[-1].minor.yy0 = yylhsminor.yy0;
2796 break;
2797 case 89: /* nth ::= NTH LAST CLASSNAME */
2798 #line 706 "pikchr.y"
2799 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-2].minor.yy0); }
2800 #line 2825 "pikchr.c"
2801 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2802 break;
2803 case 90: /* nth ::= LAST CLASSNAME */
2804 #line 707 "pikchr.y"
2805 {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.eCode = -1;}
2806 #line 2831 "pikchr.c"
2807 break;
2808 case 91: /* nth ::= LAST */
2809 #line 708 "pikchr.y"
2810 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -1;}
2811 #line 2836 "pikchr.c"
2812 yymsp[0].minor.yy0 = yylhsminor.yy0;
2813 break;
2814 case 92: /* nth ::= NTH LB RB */
2815 #line 709 "pikchr.y"
2816 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-2].minor.yy0);}
2817 #line 2842 "pikchr.c"
2818 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2819 break;
2820 case 93: /* nth ::= NTH LAST LB RB */
2821 #line 710 "pikchr.y"
2822 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-3].minor.yy0);}
2823 #line 2848 "pikchr.c"
2824 yymsp[-3].minor.yy0 = yylhsminor.yy0;
2825 break;
2826 case 94: /* nth ::= LAST LB RB */
2827 #line 711 "pikchr.y"
2828 {yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; }
2829 #line 2854 "pikchr.c"
2830 break;
2831 case 95: /* expr ::= expr PLUS expr */
2832 #line 713 "pikchr.y"
2833 {yylhsminor.yy73=yymsp[-2].minor.yy73+yymsp[0].minor.yy73;}
2834 #line 2859 "pikchr.c"
2835 yymsp[-2].minor.yy73 = yylhsminor.yy73;
2836 break;
2837 case 96: /* expr ::= expr MINUS expr */
2838 #line 714 "pikchr.y"
2839 {yylhsminor.yy73=yymsp[-2].minor.yy73-yymsp[0].minor.yy73;}
2840 #line 2865 "pikchr.c"
2841 yymsp[-2].minor.yy73 = yylhsminor.yy73;
2842 break;
2843 case 97: /* expr ::= expr STAR expr */
2844 #line 715 "pikchr.y"
2845 {yylhsminor.yy73=yymsp[-2].minor.yy73*yymsp[0].minor.yy73;}
2846 #line 2871 "pikchr.c"
2847 yymsp[-2].minor.yy73 = yylhsminor.yy73;
2848 break;
2849 case 98: /* expr ::= expr SLASH expr */
2850 #line 716 "pikchr.y"
2851 {
2852 if( yymsp[0].minor.yy73==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy73 = 0.0; }
2853 else{ yylhsminor.yy73 = yymsp[-2].minor.yy73/yymsp[0].minor.yy73; }
2854 }
2855 #line 2880 "pikchr.c"
2856 yymsp[-2].minor.yy73 = yylhsminor.yy73;
2857 break;
2858 case 99: /* expr ::= MINUS expr */
2859 #line 720 "pikchr.y"
2860 {yymsp[-1].minor.yy73=-yymsp[0].minor.yy73;}
2861 #line 2886 "pikchr.c"
2862 break;
2863 case 100: /* expr ::= PLUS expr */
2864 #line 721 "pikchr.y"
2865 {yymsp[-1].minor.yy73=yymsp[0].minor.yy73;}
2866 #line 2891 "pikchr.c"
2867 break;
2868 case 101: /* expr ::= LP expr RP */
2869 #line 722 "pikchr.y"
2870 {yymsp[-2].minor.yy73=yymsp[-1].minor.yy73;}
2871 #line 2896 "pikchr.c"
2872 break;
2873 case 102: /* expr ::= NUMBER */
2874 #line 723 "pikchr.y"
2875 {yylhsminor.yy73=pik_atof(p,&yymsp[0].minor.yy0);}
2876 #line 2901 "pikchr.c"
2877 yymsp[0].minor.yy73 = yylhsminor.yy73;
2878 break;
2879 case 103: /* expr ::= ID */
2880 #line 724 "pikchr.y"
2881 {yylhsminor.yy73=pik_get_var(p,&yymsp[0].minor.yy0);}
2882 #line 2907 "pikchr.c"
2883 yymsp[0].minor.yy73 = yylhsminor.yy73;
2884 break;
2885 case 104: /* expr ::= FUNC1 LP expr RP */
2886 #line 725 "pikchr.y"
2887 {yylhsminor.yy73 = pik_func(p,&yymsp[-3].minor.yy0,yymsp[-1].minor.yy73,0.0);}
2888 #line 2913 "pikchr.c"
2889 yymsp[-3].minor.yy73 = yylhsminor.yy73;
2890 break;
2891 case 105: /* expr ::= FUNC2 LP expr COMMA expr RP */
2892 #line 726 "pikchr.y"
2893 {yylhsminor.yy73 = pik_func(p,&yymsp[-5].minor.yy0,yymsp[-3].minor.yy73,yymsp[-1].minor.yy73);}
2894 #line 2919 "pikchr.c"
2895 yymsp[-5].minor.yy73 = yylhsminor.yy73;
2896 break;
2897 case 106: /* expr ::= place2 DOT_XY X */
2898 #line 727 "pikchr.y"
2899 {yylhsminor.yy73 = yymsp[-2].minor.yy139.x;}
2900 #line 2925 "pikchr.c"
2901 yymsp[-2].minor.yy73 = yylhsminor.yy73;
2902 break;
2903 case 107: /* expr ::= place2 DOT_XY Y */
2904 #line 728 "pikchr.y"
2905 {yylhsminor.yy73 = yymsp[-2].minor.yy139.y;}
2906 #line 2931 "pikchr.c"
2907 yymsp[-2].minor.yy73 = yylhsminor.yy73;
2908 break;
2909 case 108: /* expr ::= object DOT_L numproperty */
2910 case 109: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==109);
2911 case 110: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==110);
2912 #line 729 "pikchr.y"
2913 {yylhsminor.yy73=pik_property_of(p,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
2914 #line 2939 "pikchr.c"
2915 yymsp[-2].minor.yy73 = yylhsminor.yy73;
2916 break;
2917 default:
2918 /* (111) lvalue ::= ID */ yytestcase(yyruleno==111);
2919 /* (112) lvalue ::= FILL */ yytestcase(yyruleno==112);
@@ -3015,18 +3012,18 @@
3012 ){
3013 pik_parserARG_FETCH
3014 pik_parserCTX_FETCH
3015 #define TOKEN yyminor
3016 /************ Begin %syntax_error code ****************************************/
3017 #line 496 "pikchr.y"
3018
3019 if( TOKEN.z && TOKEN.z[0] ){
3020 pik_error(p, &TOKEN, "syntax error");
3021 }else{
3022 pik_error(p, 0, "syntax error");
3023 }
3024 #line 3049 "pikchr.c"
3025 /************ End %syntax_error code ******************************************/
3026 pik_parserARG_STORE /* Suppress warning about unused %extra_argument variable */
3027 pik_parserCTX_STORE
3028 }
3029
@@ -3255,11 +3252,11 @@
3252 #else
3253 (void)iToken;
3254 return 0;
3255 #endif
3256 }
3257 #line 734 "pikchr.y"
3258
3259
3260
3261 /* Chart of the 140 official HTML color names with their
3262 ** corresponding RGB value.
@@ -3534,10 +3531,33 @@
3531 /* Methods for the "box" class */
3532 static void boxInit(Pik *p, PElem *pElem){
3533 pElem->w = pik_value(p, "boxwid",6,0);
3534 pElem->h = pik_value(p, "boxht",5,0);
3535 pElem->rad = pik_value(p, "boxrad",6,0);
3536 }
3537 /* Translate the CP_START and CP_END reference points into the
3538 ** corresponding compass point based on the direction.
3539 */
3540 static int boxTranslateEndPoint(PElem *pElem, int cp){
3541 #if 0
3542 if( cp==CP_START ){
3543 switch( pElem->inDir ){
3544 case DIR_RIGHT: cp = CP_W; break;
3545 case DIR_DOWN: cp = CP_N; break;
3546 case DIR_LEFT: cp = CP_E; break;
3547 case DIR_UP: cp = CP_S; break;
3548 }
3549 }else if( cp==CP_END ){
3550 switch( pElem->outDir ){
3551 case DIR_RIGHT: cp = CP_E; break;
3552 case DIR_DOWN: cp = CP_S; break;
3553 case DIR_LEFT: cp = CP_W; break;
3554 case DIR_UP: cp = CP_N; break;
3555 }
3556 }
3557 #endif
3558 return cp;
3559 }
3560 /* Return offset from the center of the box to the compass point
3561 ** given by parameter cp */
3562 static PPoint boxOffset(Pik *p, PElem *pElem, int cp){
3563 PPoint pt;
@@ -3551,11 +3571,11 @@
3571 if( rad>w2 ) rad = w2;
3572 if( rad>h2 ) rad = h2;
3573 rx = 0.29289321881345252392*rad;
3574 }
3575 pt.x = pt.y = 0.0;
3576 switch( boxTranslateEndPoint(pElem,cp) ){
3577 case CP_C: pt.x = 0.0; pt.y = 0.0; break;
3578 case CP_N: pt.x = 0.0; pt.y = h2; break;
3579 case CP_NE: pt.x = w2-rx; pt.y = h2-rx; break;
3580 case CP_E: pt.x = w2; pt.y = 0.0; break;
3581 case CP_SE: pt.x = w2-rx; pt.y = rx-h2; break;
@@ -3748,11 +3768,11 @@
3768 static PPoint cylinderOffset(Pik *p, PElem *pElem, int cp){
3769 PPoint pt;
3770 PNum w2 = pElem->w*0.5;
3771 PNum h1 = pElem->h*0.5;
3772 PNum h2 = h1 - pElem->rad;
3773 switch( boxTranslateEndPoint(pElem,cp) ){
3774 case CP_C: pt.x = 0.0; pt.y = 0.0; break;
3775 case CP_N: pt.x = 0.0; pt.y = h1; break;
3776 case CP_NE: pt.x = w2; pt.y = h2; break;
3777 case CP_E: pt.x = w2; pt.y = 0.0; break;
3778 case CP_SE: pt.x = w2; pt.y = -h2; break;
@@ -3829,11 +3849,11 @@
3849 PPoint pt;
3850 PNum w = pElem->w*0.5;
3851 PNum w2 = w*0.70710678118654747608;
3852 PNum h = pElem->h*0.5;
3853 PNum h2 = h*0.70710678118654747608;
3854 switch( boxTranslateEndPoint(pElem,cp) ){
3855 case CP_C: pt.x = 0.0; pt.y = 0.0; break;
3856 case CP_N: pt.x = 0.0; pt.y = h; break;
3857 case CP_NE: pt.x = w2; pt.y = h2; break;
3858 case CP_E: pt.x = w; pt.y = 0.0; break;
3859 case CP_SE: pt.x = w2; pt.y = -h2; break;
@@ -3875,11 +3895,11 @@
3895 PNum mn = w2<h2 ? w2 : h2;
3896 if( rx>mn ) rx = mn;
3897 if( rx<mn*0.25 ) rx = mn*0.25;
3898 pt.x = pt.y = 0.0;
3899 rx *= 0.5;
3900 switch( boxTranslateEndPoint(pElem,cp) ){
3901 case CP_C: pt.x = 0.0; pt.y = 0.0; break;
3902 case CP_N: pt.x = 0.0; pt.y = h2; break;
3903 case CP_NE: pt.x = w2-rx; pt.y = h2-rx; break;
3904 case CP_E: pt.x = w2; pt.y = 0.0; break;
3905 case CP_SE: pt.x = w2; pt.y = -h2; break;
@@ -3929,17 +3949,13 @@
3949 pElem->rad = pik_value(p, "linerad",7,0);
3950 pElem->fill = -1.0;
3951 }
3952 static PPoint lineOffset(Pik *p, PElem *pElem, int cp){
3953
3954 #if 0
3955 /* In legacy PIC, the .center of an unclosed line is half way between
3956 ** its .start and .end. */
 
 
 
 
3957 if( cp==CP_C && !pElem->bClose ){
3958 PPoint out;
3959 out.x = 0.5*(pElem->ptEnter.x + pElem->ptExit.x) - pElem->ptAt.x;
3960 out.y = 0.5*(pElem->ptEnter.x + pElem->ptExit.y) - pElem->ptAt.y;
3961 return out;
@@ -4104,11 +4120,11 @@
4120 }
4121 pElem->w = pElem->bbox.ne.x - pElem->bbox.sw.x;
4122 pElem->h = pElem->bbox.ne.y - pElem->bbox.sw.y;
4123 pElem->ptAt.x = 0.5*(pElem->bbox.ne.x + pElem->bbox.sw.x);
4124 pElem->ptAt.y = 0.5*(pElem->bbox.ne.y + pElem->bbox.sw.y);
4125 pElem->mCalc |= A_WIDTH|A_HEIGHT|A_RADIUS;
4126 }
4127
4128
4129 /*
4130 ** The following array holds all the different kinds of named
@@ -4120,11 +4136,11 @@
4136 /* eJust */ 0,
4137 /* xInit */ arcInit,
4138 /* xNumProp */ 0,
4139 /* xCheck */ arcCheck,
4140 /* xChop */ 0,
4141 /* xOffset */ boxOffset,
4142 /* xFit */ 0,
4143 /* xRender */ arcRender
4144 },
4145 { /* name */ "arrow",
4146 /* isline */ 1,
@@ -4219,11 +4235,11 @@
4235 /* eJust */ 0,
4236 /* xInit */ moveInit,
4237 /* xNumProp */ 0,
4238 /* xCheck */ 0,
4239 /* xChop */ 0,
4240 /* xOffset */ boxOffset,
4241 /* xFit */ 0,
4242 /* xRender */ moveRender
4243 },
4244 { /* name */ "oval",
4245 /* isline */ 0,
@@ -4265,11 +4281,11 @@
4281 /* eJust */ 0,
4282 /* xInit */ sublistInit,
4283 /* xNumProp */ 0,
4284 /* xCheck */ 0,
4285 /* xChop */ 0,
4286 /* xOffset */ boxOffset,
4287 /* xFit */ 0,
4288 /* xRender */ 0
4289 };
4290 static const PClass noopClass =
4291 { /* name */ "noop",
@@ -4277,11 +4293,11 @@
4293 /* eJust */ 0,
4294 /* xInit */ 0,
4295 /* xNumProp */ 0,
4296 /* xCheck */ 0,
4297 /* xChop */ 0,
4298 /* xOffset */ boxOffset,
4299 /* xFit */ 0,
4300 /* xRender */ 0
4301 };
4302
4303
@@ -4340,15 +4356,11 @@
4356 /*
4357 ** Compute the relative offset to an edge location from the reference for a
4358 ** an element.
4359 */
4360 static PPoint pik_elem_offset(Pik *p, PElem *pElem, int cp){
4361 return pElem->type->xOffset(p, pElem, cp);
 
 
 
 
4362 }
4363
4364
4365 /*
4366 ** Append raw text to zOut
@@ -5060,15 +5072,29 @@
5072 case DIR_DOWN: pElem->ptExit.y -= pElem->h*0.5; break;
5073 }
5074 }
5075 }
5076
5077 /* Change the layout direction.
5078 */
5079 static void pik_set_direction(Pik *p, int eDir){
5080 assert( ValidDir(eDir) );
5081 p->eDir = eDir;
5082
5083 /* It seems to make sense to reach back into the last object and
5084 ** change its exit point (its ".end") to correspond to the new
5085 ** direction. Things just seem to work better this way. However,
5086 ** legacy PIC does *not* do this.
5087 **
5088 ** The difference can be seen in a script like this:
5089 **
5090 ** arrow; circle; down; arrow
5091 **
5092 ** You can make pikchr render the above exactly like PIC
5093 ** by deleting the following three lines. But I (drh) think
5094 ** it works better with those lines in place.
5095 */
5096 if( p->list && p->list->n ){
5097 pik_elem_set_exit(p, p->list->a[p->list->n-1], eDir);
5098 }
5099 }
5100
@@ -5115,26 +5141,20 @@
5141 */
5142 static int pik_param_ok(
5143 Pik *p, /* For storing the error message (if any) */
5144 PElem *pElem, /* The element under construction */
5145 PToken *pId, /* Make the error point to this token */
5146 int mThis /* Value we are trying to set */
 
5147 ){
 
5148 if( pElem->mProp & mThis ){
5149 pik_error(p, pId, "value is already set");
5150 return 1;
5151 }
5152 if( pElem->mCalc & mThis ){
5153 pik_error(p, pId, "value already fixed by prior constraints");
5154 return 1;
5155 }
 
 
 
 
5156 pElem->mProp |= mThis;
5157 return 0;
5158 }
5159
5160
@@ -5146,27 +5166,27 @@
5166 */
5167 void pik_set_numprop(Pik *p, PToken *pId, PRel *pVal){
5168 PElem *pElem = p->cur;
5169 switch( pId->eType ){
5170 case T_HEIGHT:
5171 if( pik_param_ok(p, pElem, pId, A_HEIGHT) ) return;
5172 pElem->h = pElem->h*pVal->rRel + pVal->rAbs;
5173 break;
5174 case T_WIDTH:
5175 if( pik_param_ok(p, pElem, pId, A_WIDTH) ) return;
5176 pElem->w = pElem->w*pVal->rRel + pVal->rAbs;
5177 break;
5178 case T_RADIUS:
5179 if( pik_param_ok(p, pElem, pId, A_RADIUS) ) return;
5180 pElem->rad = pElem->rad*pVal->rRel + pVal->rAbs;
5181 break;
5182 case T_DIAMETER:
5183 if( pik_param_ok(p, pElem, pId, A_RADIUS) ) return;
5184 pElem->rad = pElem->rad*pVal->rRel + 0.5*pVal->rAbs; /* diam it 2x rad */
5185 break;
5186 case T_THICKNESS:
5187 if( pik_param_ok(p, pElem, pId, A_THICKNESS) ) return;
5188 pElem->sw = pElem->sw*pVal->rRel + pVal->rAbs;
5189 break;
5190 }
5191 if( pElem->type->xNumProp ){
5192 pElem->type->xNumProp(p, pElem, pId);
@@ -5179,15 +5199,15 @@
5199 */
5200 void pik_set_clrprop(Pik *p, PToken *pId, PNum rClr){
5201 PElem *pElem = p->cur;
5202 switch( pId->eType ){
5203 case T_FILL:
5204 if( pik_param_ok(p, pElem, pId, A_FILL) ) return;
5205 pElem->fill = rClr;
5206 break;
5207 case T_COLOR:
5208 if( pik_param_ok(p, pElem, pId, A_COLOR) ) return;
5209 pElem->color = rClr;
5210 break;
5211 }
5212 if( pElem->type->xNumProp ){
5213 pElem->type->xNumProp(p, pElem, pId);
@@ -5475,22 +5495,12 @@
5495 }
5496 if( pElem->mProp & A_AT ){
5497 pik_error(p, pErrTok, "location fixed by prior \"at\"");
5498 return;
5499 }
 
 
 
 
 
 
 
 
 
 
5500 pElem->mProp |= A_AT;
5501 pElem->eWith = pEdge ? boxTranslateEndPoint(pElem,pEdge->eEdge) : CP_C;
5502 pElem->with = *pAt;
5503 }
5504
5505 /*
5506 ** Try to add a text attribute to an element
@@ -5923,16 +5933,12 @@
5933 if( pElem==0 ) return pt;
5934 if( pEdge==0 ){
5935 return pElem->ptAt;
5936 }
5937 pClass = pElem->type;
5938 if( pEdge->eType==T_EDGEPT || (pEdge->eEdge>0 && pEdge->eEdge<CP_END) ){
5939 pt = pClass->xOffset(p, pElem, pEdge->eEdge);
 
 
 
 
5940 pt.x += pElem->ptAt.x;
5941 pt.y += pElem->ptAt.y;
5942 return pt;
5943 }
5944 if( pEdge->eType==T_START ){
@@ -6411,97 +6417,97 @@
6417
6418 /*
6419 ** Keywords
6420 */
6421 static const PikWord pik_keywords[] = {
6422 { "above", 5, T_ABOVE, 0, 0 },
6423 { "abs", 3, T_FUNC1, FN_ABS, 0 },
6424 { "aligned", 7, T_ALIGNED, 0, 0 },
6425 { "and", 3, T_AND, 0, 0 },
6426 { "as", 2, T_AS, 0, 0 },
6427 { "assert", 6, T_ASSERT, 0, 0 },
6428 { "at", 2, T_AT, 0, 0 },
6429 { "behind", 6, T_BEHIND, 0, 0 },
6430 { "below", 5, T_BELOW, 0, 0 },
6431 { "between", 7, T_BETWEEN, 0, 0 },
6432 { "big", 3, T_BIG, 0, 0 },
6433 { "bold", 4, T_BOLD, 0, 0 },
6434 { "bot", 3, T_EDGEPT, 0, CP_S },
6435 { "bottom", 6, T_BOTTOM, 0, CP_S },
6436 { "c", 1, T_EDGEPT, 0, CP_C },
6437 { "ccw", 3, T_CCW, 0, 0 },
6438 { "center", 6, T_CENTER, 0, CP_C },
6439 { "chop", 4, T_CHOP, 0, 0 },
6440 { "close", 5, T_CLOSE, 0, 0 },
6441 { "color", 5, T_COLOR, 0, 0 },
6442 { "cos", 3, T_FUNC1, FN_COS, 0 },
6443 { "cw", 2, T_CW, 0, 0 },
6444 { "dashed", 6, T_DASHED, 0, 0 },
6445 { "diameter", 8, T_DIAMETER, 0, 0 },
6446 { "dotted", 6, T_DOTTED, 0, 0 },
6447 { "down", 4, T_DOWN, DIR_DOWN, 0 },
6448 { "e", 1, T_EDGEPT, 0, CP_E },
6449 { "east", 4, T_EDGEPT, 0, CP_E },
6450 { "end", 3, T_END, 0, CP_END },
6451 { "even", 4, T_EVEN, 0, 0 },
6452 { "fill", 4, T_FILL, 0, 0 },
6453 { "first", 5, T_NTH, 0, 0 },
6454 { "fit", 3, T_FIT, 0, 0 },
6455 { "from", 4, T_FROM, 0, 0 },
6456 { "go", 2, T_GO, 0, 0 },
6457 { "heading", 7, T_HEADING, 0, 0 },
6458 { "height", 6, T_HEIGHT, 0, 0 },
6459 { "ht", 2, T_HEIGHT, 0, 0 },
6460 { "in", 2, T_IN, 0, 0 },
6461 { "int", 3, T_FUNC1, FN_INT, 0 },
6462 { "invis", 5, T_INVIS, 0, 0 },
6463 { "invisible", 9, T_INVIS, 0, 0 },
6464 { "italic", 6, T_ITALIC, 0, 0 },
6465 { "last", 4, T_LAST, 0, 0 },
6466 { "left", 4, T_LEFT, DIR_LEFT, CP_W },
6467 { "ljust", 5, T_LJUST, 0, 0 },
6468 { "max", 3, T_FUNC2, FN_MAX, 0 },
6469 { "min", 3, T_FUNC2, FN_MIN, 0 },
6470 { "n", 1, T_EDGEPT, 0, CP_N },
6471 { "ne", 2, T_EDGEPT, 0, CP_NE },
6472 { "north", 5, T_EDGEPT, 0, CP_N },
6473 { "nw", 2, T_EDGEPT, 0, CP_NW },
6474 { "of", 2, T_OF, 0, 0 },
6475 { "previous", 8, T_LAST, 0, 0, },
6476 { "print", 5, T_PRINT, 0, 0 },
6477 { "rad", 3, T_RADIUS, 0, 0 },
6478 { "radius", 6, T_RADIUS, 0, 0 },
6479 { "right", 5, T_RIGHT, DIR_RIGHT, CP_E },
6480 { "rjust", 5, T_RJUST, 0, 0 },
6481 { "s", 1, T_EDGEPT, 0, CP_S },
6482 { "same", 4, T_SAME, 0, 0 },
6483 { "se", 2, T_EDGEPT, 0, CP_SE },
6484 { "sin", 3, T_FUNC1, FN_SIN, 0 },
6485 { "small", 5, T_SMALL, 0, 0 },
6486 { "south", 5, T_EDGEPT, 0, CP_S },
6487 { "sqrt", 4, T_FUNC1, FN_SQRT, 0 },
6488 { "start", 5, T_START, 0, CP_START },
6489 { "sw", 2, T_EDGEPT, 0, CP_SW },
6490 { "t", 1, T_TOP, 0, CP_N },
6491 { "the", 3, T_THE, 0, 0 },
6492 { "then", 4, T_THEN, 0, 0 },
6493 { "thick", 5, T_THICK, 0, 0 },
6494 { "thickness", 9, T_THICKNESS, 0, 0 },
6495 { "thin", 4, T_THIN, 0, 0 },
6496 { "to", 2, T_TO, 0, 0 },
6497 { "top", 3, T_TOP, 0, CP_N },
6498 { "until", 5, T_UNTIL, 0, 0 },
6499 { "up", 2, T_UP, DIR_UP, 0 },
6500 { "vertex", 6, T_VERTEX, 0, 0 },
6501 { "w", 1, T_EDGEPT, 0, CP_W },
6502 { "way", 3, T_WAY, 0, 0 },
6503 { "west", 4, T_EDGEPT, 0, CP_W },
6504 { "wid", 3, T_WIDTH, 0, 0 },
6505 { "width", 5, T_WIDTH, 0, 0 },
6506 { "with", 4, T_WITH, 0, 0 },
6507 { "x", 1, T_X, 0, 0 },
6508 { "y", 1, T_Y, 0, 0 },
6509 };
6510
6511 /*
6512 ** Search a PikWordlist for the given keyword. Return a pointer to the
6513 ** element found. Or return 0 if not found.
@@ -6931,11 +6937,11 @@
6937 ** input text and the rendered SVG for all files named on the command
6938 ** line.
6939 */
6940 int main(int argc, char **argv){
6941 int i;
6942 int bNoEcho = 0; /* Do not show the text of the script */
6943 int mPikchrFlags = 0; /* Flags passed into pikchr() */
6944 printf(
6945 "<!DOCTYPE html>\n"
6946 "<html lang=\"en-US\">\n"
6947 "<head>\n<title>PIKCHR Test</title>\n"
@@ -7023,6 +7029,6 @@
7029 printf("</body></html>\n");
7030 return 0;
7031 }
7032 #endif /* PIKCHR_SHELL */
7033
7034 #line 7059 "pikchr.c"
7035

Keyboard Shortcuts

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