1 #ifndef lint 2 static char sccsid[] = "tc.c (CWI) 1.1 85/03/26"; 3 #endif lint 4 /* 5 * drive 4014 scope 6 */ 7 8 /* 9 output language from troff: 10 all numbers are character strings 11 12 sn size in points 13 fn font as number from 1-n 14 cx ascii character x 15 Cxyz funny char xyz. terminated by white space 16 Hn go to absolute horizontal position n 17 Vn go to absolute vertical position n (down is positive) 18 hn go n units horizontally (relative) 19 vn ditto vertically 20 nnc move right nn, then print c (exactly 2 digits!) 21 (this wart is an optimization that shrinks output file size 22 about 35% and run-time about 15% while preserving ascii-ness) 23 Dt ...\n draw operation 't': 24 Dl x y line from here by x,y 25 Dc d circle of diameter d with left side here 26 De x y ellipse of axes x,y with left side here 27 Da x y r arc counter-clockwise by x,y of radius r 28 D~ x y x y ... wiggly line by x,y then x,y ... 29 nb a end of line (information only -- no action needed) 30 b = space before line, a = after 31 p new page begins -- set v to 0 32 #...\n comment 33 x ...\n device control functions: 34 x i init 35 x T s name of device is s 36 x r n h v resolution is n/inch 37 h = min horizontal motion, v = min vert 38 x p pause (can restart) 39 x s stop -- done for ever 40 x t generate trailer 41 x f n s font position n contains font s 42 x H n set character height to n 43 x S n set slant to N 44 45 Subcommands like "i" are often spelled out like "init". 46 */ 47 48 #include <stdio.h> 49 #include <signal.h> 50 #include <ctype.h> 51 52 #include "../dev.h" 53 #define NFONT 10 54 55 int output = 0; /* do we do output at all? */ 56 int nolist = 0; /* output page list if > 0 */ 57 int olist[20]; /* pairs of page numbers */ 58 59 int erase = 1; 60 float aspect = 1.5; /* default aspect ratio */ 61 int (*sigint)(); 62 int (*sigquit)(); 63 64 struct dev dev; 65 struct font *fontbase[NFONT]; 66 short psizes[] ={ 11, 16, 22, 36, 0}; /* approx sizes available */ 67 short *pstab = psizes; 68 int nsizes = 4; 69 int pscode[] ={ ';', ':', '9', '8'}; 70 int nfonts; 71 int smnt; /* index of first special font */ 72 int nchtab; 73 char *chname; 74 short *chtab; 75 char *fitab[NFONT]; 76 char *widthtab[NFONT]; /* widtab would be a better name */ 77 char *codetab[NFONT]; /* device codes */ 78 79 #define FATAL 1 80 #define BMASK 0377 81 int keepon = 0; 82 int dbg = 0; 83 long lineno = 0; 84 int res = 972; /* input assumed computed according to this resolution */ 85 /* initial value to avoid 0 divide */ 86 FILE *tf = stdout; /* output file */ 87 char *fontdir = "/usr/lib/font"; 88 extern char devname[]; 89 90 FILE *fp = stdin; /* input file pointer */ 91 92 main(argc, argv) 93 char *argv[]; 94 { 95 char buf[BUFSIZ]; 96 float atof(); 97 int done(); 98 99 setbuf(stdout, buf); 100 while (argc > 1 && argv[1][0] == '-') { 101 switch (argv[1][1]) { 102 case 'T': 103 if (strcmp(&argv[1][2], "cat") == 0) { /* use the old one */ 104 if (fork() == 0) { 105 execv("/usr/bin/oldtc", argv); 106 fprintf(stderr, "tc: can't find oldtc\n"); 107 } 108 wait(); 109 exit(1); 110 } 111 break; 112 case 'a': 113 aspect = atof(&argv[1][2]); 114 break; 115 case 'e': 116 erase = 0; 117 break; 118 case 'o': 119 outlist(&argv[1][2]); 120 break; 121 case 'd': 122 dbg = atoi(&argv[1][2]); 123 if (dbg == 0) dbg = 1; 124 break; 125 case 'c': 126 keepon = 1; 127 break; 128 } 129 argc--; 130 argv++; 131 } 132 133 sigint = signal(SIGINT, done); 134 sigquit = signal(SIGQUIT, SIG_IGN); 135 if (argc <= 1) 136 conv(stdin); 137 else 138 while (--argc > 0) { 139 if (strcmp(*++argv, "-") == 0) 140 fp = stdin; 141 else if ((fp = fopen(*argv, "r")) == NULL) 142 error(FATAL, "can't open %s", *argv); 143 conv(fp); 144 fclose(fp); 145 } 146 done(); 147 } 148 149 outlist(s) /* process list of page numbers to be printed */ 150 char *s; 151 { 152 int n1, n2, i; 153 154 nolist = 0; 155 while (*s) { 156 n1 = 0; 157 if (isdigit(*s)) 158 do 159 n1 = 10 * n1 + *s++ - '0'; 160 while (isdigit(*s)); 161 else 162 n1 = -9999; 163 n2 = n1; 164 if (*s == '-') { 165 s++; 166 n2 = 0; 167 if (isdigit(*s)) 168 do 169 n2 = 10 * n2 + *s++ - '0'; 170 while (isdigit(*s)); 171 else 172 n2 = 9999; 173 } 174 olist[nolist++] = n1; 175 olist[nolist++] = n2; 176 if (*s != '\0') 177 s++; 178 } 179 olist[nolist] = 0; 180 if (dbg) 181 for (i=0; i<nolist; i += 2) 182 printf("%3d %3d\n", olist[i], olist[i+1]); 183 } 184 185 in_olist(n) /* is n in olist? */ 186 int n; 187 { 188 int i; 189 190 if (nolist == 0) 191 return(1); /* everything is included */ 192 for (i = 0; i < nolist; i += 2) 193 if (n >= olist[i] && n <= olist[i+1]) 194 return(1); 195 return(0); 196 } 197 198 conv(fp) 199 register FILE *fp; 200 { 201 register int c, k; 202 int m, n, i, n1, m1; 203 char str[100], buf[300]; 204 205 while ((c = getc(fp)) != EOF) { 206 switch (c) { 207 case '\n': /* when input is text */ 208 lineno++; 209 case ' ': 210 case 0: /* occasional noise creeps in */ 211 break; 212 case '{': /* push down current environment */ 213 t_push(); 214 break; 215 case '}': 216 t_pop(); 217 break; 218 case '0': case '1': case '2': case '3': case '4': 219 case '5': case '6': case '7': case '8': case '9': 220 /* two motion digits plus a character */ 221 hmot((c-'0')*10 + getc(fp)-'0'); 222 put1(getc(fp)); 223 break; 224 case 'c': /* single ascii character */ 225 put1(getc(fp)); 226 break; 227 case 'C': 228 fscanf(fp, "%s", str); 229 put1s(str); 230 break; 231 case 't': /* straight text */ 232 fgets(buf, sizeof(buf), fp); 233 lineno++; 234 t_text(buf); 235 break; 236 case 'D': /* draw function */ 237 fgets(buf, sizeof(buf), fp); 238 lineno++; 239 switch (buf[0]) { 240 case 'l': /* draw a line */ 241 sscanf(buf+1, "%d %d", &n, &m); 242 drawline(n, m, "."); 243 break; 244 case 'c': /* circle */ 245 sscanf(buf+1, "%d", &n); 246 drawcirc(n); 247 break; 248 case 'e': /* ellipse */ 249 sscanf(buf+1, "%d %d", &m, &n); 250 drawellip(m, n); 251 break; 252 case 'a': /* arc */ 253 sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1); 254 drawarc(n, m, n1, m1); 255 break; 256 case '~': /* wiggly line */ 257 drawwig(buf+1); 258 break; 259 default: 260 error(FATAL, "unknown drawing function %s\n", buf); 261 break; 262 } 263 break; 264 case 's': 265 fscanf(fp, "%d", &n); /* ignore fractional sizes */ 266 setsize(t_size(n)); 267 break; 268 case 'f': 269 fscanf(fp, "%s", str); 270 setfont(t_font(str)); 271 break; 272 case 'H': /* absolute horizontal motion */ 273 /* fscanf(fp, "%d", &n); */ 274 while ((c = getc(fp)) == ' ') 275 ; 276 k = 0; 277 do { 278 k = 10 * k + c - '0'; 279 } while (isdigit(c = getc(fp))); 280 ungetc(c, fp); 281 hgoto(k); 282 break; 283 case 'h': /* relative horizontal motion */ 284 /* fscanf(fp, "%d", &n); */ 285 while ((c = getc(fp)) == ' ') 286 ; 287 k = 0; 288 do { 289 k = 10 * k + c - '0'; 290 } while (isdigit(c = getc(fp))); 291 ungetc(c, fp); 292 hmot(k); 293 break; 294 case 'w': /* word space */ 295 break; 296 case 'V': 297 fscanf(fp, "%d", &n); 298 vgoto(n); 299 break; 300 case 'v': 301 fscanf(fp, "%d", &n); 302 vmot(n); 303 break; 304 case 'p': /* new page */ 305 fscanf(fp, "%d", &n); 306 t_page(n); 307 break; 308 case 'n': /* end of line */ 309 while (getc(fp) != '\n') 310 ; 311 t_newline(); 312 break; 313 case '#': /* comment */ 314 while (getc(fp) != '\n') 315 ; 316 lineno++; 317 break; 318 case 'x': /* device control */ 319 devcntrl(fp); 320 lineno++; 321 break; 322 default: 323 error(!FATAL, "unknown input character %o %c\n", c, c); 324 while (getc(fp) != '\n') 325 ; 326 } 327 } 328 } 329 330 devcntrl(fp) /* interpret device control functions */ 331 FILE *fp; 332 { 333 char str[20]; 334 int c, n; 335 336 fscanf(fp, "%s", str); 337 switch (str[0]) { /* crude for now */ 338 case 'i': /* initialize */ 339 fileinit(); 340 t_init(0); 341 break; 342 case 'T': /* device name */ 343 fscanf(fp, "%s", devname); 344 break; 345 case 't': /* trailer */ 346 t_trailer(); 347 break; 348 case 'p': /* pause -- can restart */ 349 t_reset('p'); 350 break; 351 case 's': /* stop */ 352 t_reset('s'); 353 break; 354 case 'r': /* resolution assumed when prepared */ 355 fscanf(fp, "%d", &res); 356 break; 357 case 'f': /* font used */ 358 fscanf(fp, "%d %s", &n, str); 359 loadfont(n, str); 360 break; 361 } 362 while (getc(fp) != '\n') /* skip rest of input line */ 363 ; 364 } 365 366 fileinit() /* read in font and code files, etc. */ 367 { 368 } 369 370 fontprint(i) /* debugging print of font i (0,...) */ 371 { 372 } 373 374 loadcode(n, nw) /* load codetab on position n (0...); #chars is nw */ 375 int n, nw; 376 { 377 } 378 379 loadfont(n, s) /* load font info for font s on position n (1...) */ 380 int n; 381 char *s; 382 { 383 } 384 385 #define ESC 033 386 #define MAXY (3071-100) 387 #define US 037 /* text mode */ 388 #define GS 035 /* graphics mode */ 389 #define FF 014 390 391 error(f, s, a1, a2, a3, a4, a5, a6, a7) { 392 fprintf(stderr, "%c%c%c", US, ESC, ';'); /* reset terminal sensibly */ 393 fprintf(stderr, "tc: "); 394 fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7); 395 fprintf(stderr, " near line %ld\n", lineno); 396 if (f) 397 done(2); 398 } 399 400 401 /* 402 Here beginneth all the stuff that really depends 403 on the 202 (we hope). 404 */ 405 406 407 char devname[20] = "4014"; 408 409 #define oput(c) if (output) putchar(c); else; 410 411 int stopped = 0; 412 int ohx = -1; 413 int ohy = -1; 414 int oxb = -1; 415 int oly = -1; 416 int olx = -1; 417 int skip; 418 int size = 1; 419 int font = 1; /* current font */ 420 int hpos; /* horizontal position where we are supposed to be next (left = 0) */ 421 int vpos; /* current vertical position (down positive) */ 422 423 int horig; /* h origin of current block; hpos rel to this */ 424 int vorig; /* v origin of current block; vpos rel to this */ 425 426 int DX = 10; /* step size in x for drawing */ 427 int DY = 10; /* step size in y for drawing */ 428 int drawdot = '.'; /* draw with this character */ 429 int drawsize = 1; /* shrink by this factor when drawing */ 430 431 t_init(reinit) /* initialize device */ 432 int reinit; 433 { 434 fflush(stdout); 435 stopped = 0; 436 if (erase) { 437 oput(ESC); 438 oput(FF); 439 oput(US); 440 } 441 hpos = vpos = 0; 442 setsize(t_size(10)); /* start somewhere */ 443 sendpt(); 444 } 445 446 #define MAXSTATE 5 447 448 struct state { 449 int ssize; 450 int sfont; 451 int shpos; 452 int svpos; 453 int shorig; 454 int svorig; 455 }; 456 struct state state[MAXSTATE]; 457 struct state *statep = state; 458 459 t_push() /* begin a new block */ 460 { 461 hflush(); 462 statep->ssize = size; 463 statep->sfont = font; 464 statep->shorig = horig; 465 statep->svorig = vorig; 466 statep->shpos = hpos; 467 statep->svpos = vpos; 468 horig = hpos; 469 vorig = vpos; 470 hpos = vpos = 0; 471 if (statep++ >= state+MAXSTATE) 472 error(FATAL, "{ nested too deep"); 473 hpos = vpos = 0; 474 } 475 476 t_pop() /* pop to previous state */ 477 { 478 if (--statep < state) 479 error(FATAL, "extra }"); 480 size = statep->ssize; 481 font = statep->sfont; 482 hpos = statep->shpos; 483 vpos = statep->svpos; 484 horig = statep->shorig; 485 vorig = statep->svorig; 486 } 487 488 int np; /* number of pages seen */ 489 int npmax; /* high-water mark of np */ 490 int pgnum[100]; /* their actual numbers */ 491 long pgadr[100]; /* their seek addresses */ 492 493 t_page(n) /* do whatever new page functions */ 494 { 495 long ftell(); 496 int c, m, i; 497 char buf[100], *bp; 498 499 pgnum[np++] = n; 500 pgadr[np] = ftell(fp); 501 if (np > npmax) 502 npmax = np; 503 if (output == 0) { 504 output = in_olist(n); 505 t_init(1); 506 return; 507 } 508 /* have just printed something, and seen p<n> for next one */ 509 vgoto(11 * res - 100); 510 sendpt(); 511 oput(US); 512 fflush(stdout); 513 514 515 if (keepon) { 516 t_init(1); 517 return; 518 } 519 next: 520 for (bp = buf; (*bp = readch()); ) 521 if (*bp++ == '\n') 522 break; 523 *bp = 0; 524 switch (buf[0]) { 525 case 0: 526 done(); 527 break; 528 case '\n': 529 if (stopped) 530 done(); 531 output = in_olist(n); 532 t_init(1); 533 return; 534 case '!': 535 callunix(&buf[1]); 536 fputs("!\n", stderr); 537 break; 538 case 'e': 539 erase = 1 - erase; 540 break; 541 case 'a': 542 aspect = atof(&buf[1]); 543 break; 544 case '-': 545 case 'p': 546 m = atoi(&buf[1]) + 1; 547 if (fp == stdin) { 548 fputs("you can't; it's not a file\n", stderr); 549 break; 550 } 551 if (np - m <= 0) { 552 fputs("too far back\n", stderr); 553 break; 554 } 555 np -= m; 556 fseek(fp, pgadr[np], 0); 557 output = 1; 558 t_init(1); 559 return; 560 case '0': case '1': case '2': case '3': case '4': 561 case '5': case '6': case '7': case '8': case '9': 562 m = atoi(&buf[0]); 563 for (i = 0; i < npmax; i++) 564 if (m == pgnum[i]) 565 break; 566 if (i >= npmax || fp == stdin) { 567 fputs("you can't\n", stderr); 568 break; 569 } 570 np = i + 1; 571 fseek(fp, pgadr[np], 0); 572 output = 1; 573 t_init(1); 574 return; 575 case 'o': 576 outlist(&buf[1]); 577 output = 0; 578 t_init(1); 579 return; 580 case '?': 581 fputs("!cmd unix cmd\n", stderr); 582 fputs("p print this page again\n", stderr); 583 fputs("-n go back n pages\n", stderr); 584 fputs("n print page n (previously printed)\n", stderr); 585 fputs("o... set the -o output list to ...\n", stderr); 586 fputs("en n=0 -> don't erase; n=1 -> erase\n", stderr); 587 fputs("an sets aspect ratio to n\n", stderr); 588 break; 589 default: 590 fputs("?\n", stderr); 591 break; 592 } 593 goto next; 594 } 595 596 t_newline() /* do whatever for the end of a line */ 597 { 598 hpos = 0; 599 } 600 601 t_size(n) /* convert integer to internal size number*/ 602 int n; 603 { 604 int i; 605 606 if (n <= pstab[0]) 607 return(1); 608 else if (n >= pstab[nsizes-1]) 609 return(nsizes); 610 for (i = 0; n > pstab[i]; i++) 611 ; 612 return(i+1); 613 } 614 615 t_font(s) /* convert string to internal font number */ 616 char *s; 617 { 618 int n; 619 620 n = atoi(s); 621 if (n < 1 || n > nfonts) 622 n = 1; 623 return(n); 624 } 625 626 t_text(s) /* print string s as text */ 627 char *s; 628 { 629 int c, w; 630 char str[100]; 631 632 if (!output) 633 return; 634 w = res / 2 * pstab[size-1] / 72; 635 while ((c = *s++) != '\n') { 636 if (c == '\\') { 637 switch (c = *s++) { 638 case '\\': 639 case 'e': 640 put1('\\'); 641 break; 642 case '(': 643 str[0] = *s++; 644 str[1] = *s++; 645 str[2] = '\0'; 646 put1s(str); 647 break; 648 } 649 } else { 650 put1(c); 651 } 652 hmot(w); 653 } 654 } 655 656 t_reset(c) 657 { 658 int n; 659 660 output = 1; 661 fflush(stdout); 662 if (c == 's') { 663 stopped = 1; 664 t_page(9999); 665 } 666 } 667 668 t_trailer() 669 { 670 } 671 672 hgoto(n) 673 { 674 hpos = n; /* this is where we want to be */ 675 /* before printing a character, */ 676 /* have to make sure it's true */ 677 } 678 679 hmot(n) /* generate n units of horizontal motion */ 680 int n; 681 { 682 hgoto(hpos + n); 683 } 684 685 hflush() /* actual horizontal output occurs here */ 686 { 687 if (output) 688 sendpt(); 689 } 690 691 vgoto(n) 692 { 693 vpos = n; 694 } 695 696 vmot(n) /* generate n units of vertical motion */ 697 int n; 698 { 699 vgoto(vpos + n); /* ignores rounding */ 700 } 701 702 put1s(s) /* s is a funny char name */ 703 char *s; 704 { 705 int i; 706 char *p; 707 extern char *spectab[]; 708 static char prev[10] = ""; 709 static int previ; 710 711 if (!output) 712 return; 713 if (strcmp(s, prev) != 0) { 714 previ = -1; 715 for (i = 0; spectab[i] != 0; i += 2) 716 if (strcmp(spectab[i], s) == 0) { 717 strcpy(prev, s); 718 previ = i; 719 break; 720 } 721 } 722 if (previ >= 0) { 723 hflush(); 724 oput(US); 725 for (p = spectab[previ+1]; *p; p++) 726 oput(*p); 727 } else 728 prev[0] = 0; 729 } 730 731 put1(c) /* output char c */ 732 int c; 733 { 734 if (!output) 735 return; 736 hflush(); 737 oput(US); 738 oput(c); 739 } 740 741 setsize(n) /* set point size to n (internal) */ 742 int n; 743 { 744 745 if (!output) 746 return; 747 if (n == size) 748 return; /* already there */ 749 oput(ESC); 750 oput(pscode[n-1]); 751 size = n; 752 } 753 754 t_fp(n, s) /* font position n now contains font s */ 755 int n; 756 char *s; 757 { 758 } 759 760 setfont(n) /* set font to n */ 761 int n; 762 { 763 } 764 765 done() 766 { 767 output = 1; 768 hgoto(0); 769 vgoto(11 * res - 100); /* bottom of page */ 770 sendpt(); 771 oput(US); 772 oput(ESC); 773 oput(';'); 774 oput(US); 775 fflush(stdout); 776 exit(0); 777 } 778 779 callunix(line) 780 char line[]; 781 { 782 int rc, status, unixpid; 783 if( (unixpid=fork())==0 ) { 784 signal(SIGINT,sigint); signal(SIGQUIT,sigquit); 785 close(0); dup(2); 786 execl("/bin/sh", "-sh", "-c", line, 0); 787 exit(255); 788 } 789 else if(unixpid == -1) 790 return; 791 else{ signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); 792 while( (rc = wait(&status)) != unixpid && rc != -1 ) ; 793 signal(SIGINT, done); signal(SIGQUIT,sigquit); 794 } 795 } 796 readch(){ 797 char c; 798 if (read(2,&c,1)<1) c=0; 799 return(c); 800 } 801 sendpt(){ 802 int hy,xb,ly,hx,lx; 803 int xx, yy; 804 float fx, fy; 805 806 807 fx = hpos + horig; 808 fy = vpos + vorig; 809 xx = (fx * MAXY / 11) / res * aspect + 0.5; 810 yy = MAXY - (fy * MAXY / 11) / res + 0.5; 811 oput(GS); 812 hy = ((yy>>7) & 037); 813 xb = ((xx & 03) + ((yy<<2) & 014) & 017); 814 ly = ((yy>>2) & 037); 815 hx = ((xx>>7) & 037); 816 lx = ((xx>>2) & 037); 817 if(hy != ohy)oput(hy | 040); 818 if(xb != oxb)oput(xb | 0140); 819 if((ly != oly) || (hx != ohx) || (xb != oxb)) 820 oput(ly | 0140); 821 if(hx != ohx)oput(hx | 040); 822 oput(lx | 0100); 823 ohy = hy; 824 oxb = xb; 825 oly = ly; 826 ohx = hx; 827 olx = lx; 828 } 829 830 char *spectab[] ={ 831 "em", "--", 832 "en", "-", 833 "hy", "-", 834 "ff", "ff", 835 "fi", "fi", 836 "fl", "fl", 837 "Fi", "ffi", 838 "Fl", "ffl", 839 "ct", "\033\016Z\bM\033\017", /*cent sign*/ 840 "de", "\033\016J\033\017", /*degree*/ 841 "dg", "\033\016M\b_\033\017", /*dagger*/ 842 "rg", "\033\016O\b&\033\017", /*registered*/ 843 "bu", "\033\016O\b~\033\017", /*bullet*/ 844 "fm", "'", 845 "co", "\033\016O\b#\033\017", /*copyright*/ 846 "sq", "\033\016L\033\017", /*square*/ 847 "*q", "\033\016(\bM\033\017", /*psi*/ 848 "*h", "\033\016o\b_\033\017", /*theta*/ 849 "*n", "v\b)", /*nu*/ 850 "*m", "\033\016V\b,\033\017", /*mu*/ 851 "*l", "\033\016)\b?\033\017", /*lambda*/ 852 "*i", "\033\016I\033\017", /*iota*/ 853 "*z", "S\b\033\016Z\033\017", /*zeta*/ 854 "*s", "o\b\'", /*sigma*/ 855 "*d", "o\b\033\0165\033\017", /*delta*/ 856 "*b", "\033\016b\033\017", /*beta*/ 857 "*c", "\033\016e\bc\033\017", /*xi*/ 858 "*y", "j\b\033\016C\033\017", /*eta*/ 859 "*f", "\033\016O\bM\033\017", /*phi*/ 860 "*u", "\033\016(\033\017", /*upsilon*/ 861 "*k", "\033\016k\033\017", /*kappa*/ 862 "*p", "T\b\033\016S\033\017", /*pi*/ 863 "da", "\033\016U\033\017", /*down arrow*/ 864 "*a", "\033\016A\033\017", /*alpha*/ 865 "or", "|", 866 "*x", "l\b/", /*chi*/ 867 "*e", "\033\016E\033\017", /*epsilon*/ 868 "*o", "\033\016O\033\017", /*omicron*/ 869 "<-", "\033\016[\033\017", /*left arrow*/ 870 "*r", "\033\016R\033\017", /*rho*/ 871 "ua", "\033\016Y\033\017", /*up arrow*/ 872 "*t", "\033\016N\033\017", /*tau*/ 873 "ul", "_", 874 "ru", "_", 875 "\\_", "_", 876 "*Q", "I\b\033\016(\033\017", /*Psi*/ 877 "bs", "\033\016O\bJ\033\017", /*bell system sign*/ 878 "if", "\033\016W\bX\033\017", /*infinity*/ 879 "*g", "`\b/", /*gamma*/ 880 "ip", "\033\016X\bF\033\017", /*improper superset*/ 881 "pt", "\033\016A\033\017", /*proportional to*/ 882 "rh", "\033\016\\\b]\033\017", /*right hand*/ 883 "*w", "\033\016W\033\017", /*omega*/ 884 "gr", "\033\016G\033\017", /*gradient*/ 885 "*F", "I\033\016\bO\033\017", /*Phi*/ 886 "*H", "O\b=", /*Theta*/ 887 "*W", "O\b_", /*Omega*/ 888 "cu", "\033\016V\033\017", /*cup (union)*/ 889 "rn", "\033\016@\033\017", /*root en*/ 890 "ts", "s", /*terminal sigma*/ 891 "*L", "\033\016)\bK\033\017", /*Lambda*/ 892 "\\-", "-", 893 "*G", "\033\016S\bK\033\017", /*Gamma*/ 894 "is", "\033\016i\033\017", /*integral sign*/ 895 "Sl", "l", 896 "*P", "\033\016t\b'\033\017", /*Pi*/ 897 "sb", "\033\016Z\033\017", /*subset of*/ 898 "sp", "\033\016X\033\017", /*superset of*/ 899 "ap", "\033\016T\033\017", /*approximates*/ 900 "pd", "o\b`", /*partial derivative*/ 901 "*D", "\033\016H\033\017", /*Delta*/ 902 "sr", "\033\016I\b'\033\017", /*square root*/ 903 "*S", ">\b\033\016F\b@\033\017", /*Sigma*/ 904 "~~", "\033\016T\bF\033\017", /*approx =*/ 905 "*C", "\033\016_\bF\b@\033\017", /*Xi*/ 906 "sl", "/", 907 "ca", "\033\016C\033\017", /*cap (intersection)*/ 908 "U", "\033\016y\033\017", /*Upsilon*/ 909 "no", "\033\016|\033\017", /*not*/ 910 "rc", "|", /*right ceiling (rt of ")*/ 911 "lt", "|", /*left top (of big curly)*/ 912 "bv", "|", /*bold vertical*/ 913 "lk", "|", /*left center of big curly bracket*/ 914 "lb", "|", /*left bottom*/ 915 "rt", "|", /*right top*/ 916 "rk", "|", /*right center of big curly bracket*/ 917 "rb", "|", /*right bot*/ 918 "rf", "|", /*right floor (rb of ")*/ 919 "lf", "|", /*left floor (left bot of big sq bract)*/ 920 "lc", "|", /*left ceiling (lt of ")*/ 921 "mu", "\033\016=\033\017", /*multiply*/ 922 "di", "\033\016+\033\017", /*divide*/ 923 "+-", "+\b_", /*plus-minus*/ 924 "<=", "\033\016$\033\017", /*<=*/ 925 ">=", "\033\016^\033\017", /*>=*/ 926 "==", "=\b_", /*identically equal*/ 927 "!=", "\033\016*\033\017", /*not equal*/ 928 "aa", "'", 929 "ga", "`", 930 "lh", "\033\016|\b[\033\017", /*left hand*/ 931 "mo", "\033\016c\b_\033\017", /*member of*/ 932 "es", "\033\016O\b/\033\017", /*empty set*/ 933 "dd", "\033\016%\bM\033\017", /*dbl dagger*/ 934 "br", "|", /*box rule*/ 935 "vr", "|", /* vertical rule */ 936 "ib", "\033\016Z\bF\033\017", /*improper subset*/ 937 "ci", "\033\016O\033\017", /*circle*/ 938 "eq", "=", 939 "pl", "+", 940 "mi", "-", 941 "12", "1/2", 942 "14", "1/4", 943 "34", "3/4", 944 "->", "\033\016]\033\017", /*right arrow*/ 945 "sc", "g\b\033\016C\033\017", /*section mark*/ 946 "**", "*", 947 "l.", ".", 948 "L.", ".", 949 "bx", "[\b]", 950 "ob", "o", /* open bullet */ 951 "cd", ",", /* cedilla */ 952 "..", "\033\016!\033\017", /* umlaut */ 953 0, 0, 954 }; 955