1 #ifndef lint 2 static char sccsid[] = "@(#)tc.c 1.2 (CWI) 1.2 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 case 'q': 527 done(); 528 break; 529 case '\n': 530 if (stopped) 531 done(); 532 output = in_olist(n); 533 t_init(1); 534 return; 535 case '!': 536 callunix(&buf[1]); 537 fputs("!\n", stderr); 538 break; 539 case 'e': 540 erase = 1 - erase; 541 break; 542 case 'a': 543 aspect = atof(&buf[1]); 544 break; 545 case '-': 546 case 'p': 547 m = atoi(&buf[1]) + 1; 548 if (fp == stdin) { 549 fputs("you can't; it's not a file\n", stderr); 550 break; 551 } 552 if (np - m <= 0) { 553 fputs("too far back\n", stderr); 554 break; 555 } 556 np -= m; 557 fseek(fp, pgadr[np], 0); 558 output = 1; 559 t_init(1); 560 return; 561 case '0': case '1': case '2': case '3': case '4': 562 case '5': case '6': case '7': case '8': case '9': 563 m = atoi(&buf[0]); 564 for (i = 0; i < npmax; i++) 565 if (m == pgnum[i]) 566 break; 567 if (i >= npmax || fp == stdin) { 568 fputs("you can't\n", stderr); 569 break; 570 } 571 np = i + 1; 572 fseek(fp, pgadr[np], 0); 573 output = 1; 574 t_init(1); 575 return; 576 case 'o': 577 outlist(&buf[1]); 578 output = 0; 579 t_init(1); 580 return; 581 case '?': 582 fputs("!cmd unix cmd\n", stderr); 583 fputs("p print this page again\n", stderr); 584 fputs("-n go back n pages\n", stderr); 585 fputs("n print page n (previously printed)\n", stderr); 586 fputs("o... set the -o output list to ...\n", stderr); 587 fputs("q quit\n", stderr); 588 fputs("en n=0 -> don't erase; n=1 -> erase\n", stderr); 589 fputs("an sets aspect ratio to n\n", stderr); 590 break; 591 default: 592 fputs("?\n", stderr); 593 break; 594 } 595 goto next; 596 } 597 598 t_newline() /* do whatever for the end of a line */ 599 { 600 hpos = 0; 601 } 602 603 t_size(n) /* convert integer to internal size number*/ 604 int n; 605 { 606 int i; 607 608 if (n <= pstab[0]) 609 return(1); 610 else if (n >= pstab[nsizes-1]) 611 return(nsizes); 612 for (i = 0; n > pstab[i]; i++) 613 ; 614 return(i+1); 615 } 616 617 t_font(s) /* convert string to internal font number */ 618 char *s; 619 { 620 int n; 621 622 n = atoi(s); 623 if (n < 1 || n > nfonts) 624 n = 1; 625 return(n); 626 } 627 628 t_text(s) /* print string s as text */ 629 char *s; 630 { 631 int c, w; 632 char str[100]; 633 634 if (!output) 635 return; 636 w = res / 2 * pstab[size-1] / 72; 637 while ((c = *s++) != '\n') { 638 if (c == '\\') { 639 switch (c = *s++) { 640 case '\\': 641 case 'e': 642 put1('\\'); 643 break; 644 case '(': 645 str[0] = *s++; 646 str[1] = *s++; 647 str[2] = '\0'; 648 put1s(str); 649 break; 650 } 651 } else { 652 put1(c); 653 } 654 hmot(w); 655 } 656 } 657 658 t_reset(c) 659 { 660 int n; 661 662 output = 1; 663 fflush(stdout); 664 if (c == 's') { 665 stopped = 1; 666 t_page(9999); 667 } 668 } 669 670 t_trailer() 671 { 672 } 673 674 hgoto(n) 675 { 676 hpos = n; /* this is where we want to be */ 677 /* before printing a character, */ 678 /* have to make sure it's true */ 679 } 680 681 hmot(n) /* generate n units of horizontal motion */ 682 int n; 683 { 684 hgoto(hpos + n); 685 } 686 687 hflush() /* actual horizontal output occurs here */ 688 { 689 if (output) 690 sendpt(); 691 } 692 693 vgoto(n) 694 { 695 vpos = n; 696 } 697 698 vmot(n) /* generate n units of vertical motion */ 699 int n; 700 { 701 vgoto(vpos + n); /* ignores rounding */ 702 } 703 704 put1s(s) /* s is a funny char name */ 705 char *s; 706 { 707 int i; 708 char *p; 709 extern char *spectab[]; 710 static char prev[10] = ""; 711 static int previ; 712 713 if (!output) 714 return; 715 if (strcmp(s, prev) != 0) { 716 previ = -1; 717 for (i = 0; spectab[i] != 0; i += 2) 718 if (strcmp(spectab[i], s) == 0) { 719 strcpy(prev, s); 720 previ = i; 721 break; 722 } 723 } 724 if (previ >= 0) { 725 hflush(); 726 oput(US); 727 for (p = spectab[previ+1]; *p; p++) 728 oput(*p); 729 } else 730 prev[0] = 0; 731 } 732 733 put1(c) /* output char c */ 734 int c; 735 { 736 if (!output) 737 return; 738 hflush(); 739 oput(US); 740 oput(c); 741 } 742 743 setsize(n) /* set point size to n (internal) */ 744 int n; 745 { 746 747 if (!output) 748 return; 749 if (n == size) 750 return; /* already there */ 751 oput(ESC); 752 oput(pscode[n-1]); 753 size = n; 754 } 755 756 t_fp(n, s) /* font position n now contains font s */ 757 int n; 758 char *s; 759 { 760 } 761 762 setfont(n) /* set font to n */ 763 int n; 764 { 765 } 766 767 done() 768 { 769 output = 1; 770 hgoto(0); 771 vgoto(11 * res - 100); /* bottom of page */ 772 sendpt(); 773 oput(US); 774 oput(ESC); 775 oput(';'); 776 oput(US); 777 fflush(stdout); 778 exit(0); 779 } 780 781 callunix(line) 782 char line[]; 783 { 784 int rc, status, unixpid; 785 if( (unixpid=fork())==0 ) { 786 signal(SIGINT,sigint); signal(SIGQUIT,sigquit); 787 close(0); dup(2); 788 execl("/bin/sh", "-sh", "-c", line, 0); 789 exit(255); 790 } 791 else if(unixpid == -1) 792 return; 793 else{ signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); 794 while( (rc = wait(&status)) != unixpid && rc != -1 ) ; 795 signal(SIGINT, done); signal(SIGQUIT,sigquit); 796 } 797 } 798 readch(){ 799 char c; 800 if (read(2,&c,1)<1) c=0; 801 return(c); 802 } 803 sendpt(){ 804 int hy,xb,ly,hx,lx; 805 int xx, yy; 806 float fx, fy; 807 808 809 fx = hpos + horig; 810 fy = vpos + vorig; 811 xx = (fx * MAXY / 11) / res * aspect + 0.5; 812 yy = MAXY - (fy * MAXY / 11) / res + 0.5; 813 oput(GS); 814 hy = ((yy>>7) & 037); 815 xb = ((xx & 03) + ((yy<<2) & 014) & 017); 816 ly = ((yy>>2) & 037); 817 hx = ((xx>>7) & 037); 818 lx = ((xx>>2) & 037); 819 if(hy != ohy)oput(hy | 040); 820 if(xb != oxb)oput(xb | 0140); 821 if((ly != oly) || (hx != ohx) || (xb != oxb)) 822 oput(ly | 0140); 823 if(hx != ohx)oput(hx | 040); 824 oput(lx | 0100); 825 ohy = hy; 826 oxb = xb; 827 oly = ly; 828 ohx = hx; 829 olx = lx; 830 } 831 832 char *spectab[] ={ 833 "em", "--", 834 "en", "-", 835 "hy", "-", 836 "ff", "ff", 837 "fi", "fi", 838 "fl", "fl", 839 "Fi", "ffi", 840 "Fl", "ffl", 841 "ct", "\033\016Z\bM\033\017", /*cent sign*/ 842 "de", "\033\016J\033\017", /*degree*/ 843 "dg", "\033\016M\b_\033\017", /*dagger*/ 844 "rg", "\033\016O\b&\033\017", /*registered*/ 845 "bu", "\033\016O\b~\033\017", /*bullet*/ 846 "fm", "'", 847 "co", "\033\016O\b#\033\017", /*copyright*/ 848 "sq", "\033\016L\033\017", /*square*/ 849 "*q", "\033\016(\bM\033\017", /*psi*/ 850 "*h", "\033\016o\b_\033\017", /*theta*/ 851 "*n", "v\b)", /*nu*/ 852 "*m", "\033\016V\b,\033\017", /*mu*/ 853 "*l", "\033\016)\b?\033\017", /*lambda*/ 854 "*i", "\033\016I\033\017", /*iota*/ 855 "*z", "S\b\033\016Z\033\017", /*zeta*/ 856 "*s", "o\b\'", /*sigma*/ 857 "*d", "o\b\033\0165\033\017", /*delta*/ 858 "*b", "\033\016b\033\017", /*beta*/ 859 "*c", "\033\016e\bc\033\017", /*xi*/ 860 "*y", "j\b\033\016C\033\017", /*eta*/ 861 "*f", "\033\016O\bM\033\017", /*phi*/ 862 "*u", "\033\016(\033\017", /*upsilon*/ 863 "*k", "\033\016k\033\017", /*kappa*/ 864 "*p", "T\b\033\016S\033\017", /*pi*/ 865 "da", "\033\016U\033\017", /*down arrow*/ 866 "*a", "\033\016A\033\017", /*alpha*/ 867 "or", "|", 868 "*x", "l\b/", /*chi*/ 869 "*e", "\033\016E\033\017", /*epsilon*/ 870 "*o", "\033\016O\033\017", /*omicron*/ 871 "<-", "\033\016[\033\017", /*left arrow*/ 872 "*r", "\033\016R\033\017", /*rho*/ 873 "ua", "\033\016Y\033\017", /*up arrow*/ 874 "*t", "\033\016N\033\017", /*tau*/ 875 "ul", "_", 876 "ru", "_", 877 "\\_", "_", 878 "*Q", "I\b\033\016(\033\017", /*Psi*/ 879 "bs", "\033\016O\bJ\033\017", /*bell system sign*/ 880 "if", "\033\016W\bX\033\017", /*infinity*/ 881 "*g", "`\b/", /*gamma*/ 882 "ip", "\033\016X\bF\033\017", /*improper superset*/ 883 "pt", "\033\016A\033\017", /*proportional to*/ 884 "rh", "\033\016\\\b]\033\017", /*right hand*/ 885 "*w", "\033\016W\033\017", /*omega*/ 886 "gr", "\033\016G\033\017", /*gradient*/ 887 "*F", "I\033\016\bO\033\017", /*Phi*/ 888 "*H", "O\b=", /*Theta*/ 889 "*W", "O\b_", /*Omega*/ 890 "cu", "\033\016V\033\017", /*cup (union)*/ 891 "rn", "\033\016@\033\017", /*root en*/ 892 "ts", "s", /*terminal sigma*/ 893 "*L", "\033\016)\bK\033\017", /*Lambda*/ 894 "\\-", "-", 895 "*G", "\033\016S\bK\033\017", /*Gamma*/ 896 "is", "\033\016i\033\017", /*integral sign*/ 897 "Sl", "l", 898 "*P", "\033\016t\b'\033\017", /*Pi*/ 899 "sb", "\033\016Z\033\017", /*subset of*/ 900 "sp", "\033\016X\033\017", /*superset of*/ 901 "ap", "\033\016T\033\017", /*approximates*/ 902 "pd", "o\b`", /*partial derivative*/ 903 "*D", "\033\016H\033\017", /*Delta*/ 904 "sr", "\033\016I\b'\033\017", /*square root*/ 905 "*S", ">\b\033\016F\b@\033\017", /*Sigma*/ 906 "~~", "\033\016T\bF\033\017", /*approx =*/ 907 "*C", "\033\016_\bF\b@\033\017", /*Xi*/ 908 "sl", "/", 909 "ca", "\033\016C\033\017", /*cap (intersection)*/ 910 "U", "\033\016y\033\017", /*Upsilon*/ 911 "no", "\033\016|\033\017", /*not*/ 912 "rc", "|", /*right ceiling (rt of ")*/ 913 "lt", "|", /*left top (of big curly)*/ 914 "bv", "|", /*bold vertical*/ 915 "lk", "|", /*left center of big curly bracket*/ 916 "lb", "|", /*left bottom*/ 917 "rt", "|", /*right top*/ 918 "rk", "|", /*right center of big curly bracket*/ 919 "rb", "|", /*right bot*/ 920 "rf", "|", /*right floor (rb of ")*/ 921 "lf", "|", /*left floor (left bot of big sq bract)*/ 922 "lc", "|", /*left ceiling (lt of ")*/ 923 "mu", "\033\016=\033\017", /*multiply*/ 924 "di", "\033\016+\033\017", /*divide*/ 925 "+-", "+\b_", /*plus-minus*/ 926 "<=", "\033\016$\033\017", /*<=*/ 927 ">=", "\033\016^\033\017", /*>=*/ 928 "==", "=\b_", /*identically equal*/ 929 "!=", "\033\016*\033\017", /*not equal*/ 930 "aa", "'", 931 "ga", "`", 932 "lh", "\033\016|\b[\033\017", /*left hand*/ 933 "mo", "\033\016c\b_\033\017", /*member of*/ 934 "es", "\033\016O\b/\033\017", /*empty set*/ 935 "dd", "\033\016%\bM\033\017", /*dbl dagger*/ 936 "br", "|", /*box rule*/ 937 "vr", "|", /* vertical rule */ 938 "ib", "\033\016Z\bF\033\017", /*improper subset*/ 939 "ci", "\033\016O\033\017", /*circle*/ 940 "eq", "=", 941 "pl", "+", 942 "mi", "-", 943 "12", "1/2", 944 "14", "1/4", 945 "34", "3/4", 946 "->", "\033\016]\033\017", /*right arrow*/ 947 "sc", "g\b\033\016C\033\017", /*section mark*/ 948 "**", "*", 949 "l.", ".", 950 "L.", ".", 951 "bx", "[\b]", 952 "ob", "o", /* open bullet */ 953 "cd", ",", /* cedilla */ 954 "..", "\033\016!\033\017", /* umlaut */ 955 0, 0, 956 }; 957