1: static char *sccsid = "@(#)tc.c 4.2 (Berkeley) 7/6/81"; 2: /* 3: * Simulate typesetter on 4014 4: */ 5: 6: #include <signal.h> 7: #include <stdio.h> 8: 9: #define oput(c) if (pgskip==0) putchar(c); else (c); 10: #define MAXY 3071 11: #define US 037 12: #define GS 035 13: #define ESC 033 14: #define FF 014 15: #define DBL 0200 16: 17: int pl = 11*144; 18: int mpy = 1; 19: int div = 1; 20: char *ap; 21: int ch; 22: int nonumb; 23: int psize = 10; 24: int dfact = 1; 25: int esc; 26: int escd; 27: int verd; 28: int esct; 29: int osize = 02; 30: int size = 02; 31: int rx; 32: int xx; 33: int yy = MAXY+62+48; 34: int leadtot = -31; 35: int ohy = -1; 36: int ohx = -1; 37: int oxb = -1; 38: int oly = -1; 39: int olx = -1; 40: int tflag; 41: int railmag; 42: int lead; 43: int skip; 44: int pgskip; 45: int ksize = ';'; 46: int mcase; 47: int stab[] = {010,0,01,07,02,03,04,05,0211,06,0212,0213,0214,0215,0216,0217}; 48: int rtab[] = {6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 28, 36, 18}; 49: int ktab[] = {';',';',';',';',';',';',':',':','9','9','9','9','8','8','8','9'}; 50: int first = 1; 51: int alpha; 52: extern char *asctab[128]; 53: extern char *spectab[128]; 54: int erase = 1; 55: int (*sigint)(); 56: int (*sigquit)(); 57: 58: main(argc,argv) 59: int argc; 60: char **argv; 61: { 62: register i, j; 63: register char *k; 64: extern ex(); 65: 66: while((--argc > 0) && ((++argv)[0][0]=='-')){ 67: switch(argv[0][1]){ 68: case 'p': 69: ap = &argv[0][2]; 70: dfact = 72; 71: if(i = atoi())pl = i/3; 72: continue; 73: case 't': 74: tflag++; 75: continue; 76: case 's': 77: ap = &argv[0][2]; 78: dfact = 1; 79: pgskip = atoi(); 80: continue; 81: default: 82: dfact = 1; 83: ap = &argv[0][1]; 84: if(i = atoi())mpy = i; 85: if(i = atoi())div = i; 86: continue; 87: } 88: } 89: if(argc){ 90: if (freopen(argv[0], "r", stdin) == NULL) { 91: fprintf(stderr, "tc: cannot open %s\n", argv[0]); 92: exit(1); 93: } 94: } 95: sigint = signal(SIGINT, ex); 96: sigquit = signal(SIGQUIT, SIG_IGN); 97: while((i = getchar()) != EOF){ 98: if(!i)continue; 99: if(i & 0200){ 100: esc += (~i) & 0177; 101: continue; 102: } 103: if(esc){ 104: if(escd)esc = -esc; 105: esct += esc; 106: xx += (esc*mpy + rx)/div; 107: rx = (esc*mpy + rx)%div; 108: sendpt(); 109: esc = 0; 110: } 111: switch(i){ 112: case 0100: /*init*/ 113: escd = verd = mcase = railmag = xx = 0; 114: yy = MAXY + 48; 115: leadtot = -31; 116: ohy = oxb = oly = ohx = olx = -1; 117: oput(US); 118: fflush(stdout); 119: if(!first && !tflag)kwait(); 120: if(first){ 121: first = 0; 122: yy += 62; 123: } 124: init(); 125: continue; 126: case 0101: /*lower rail*/ 127: railmag &= ~01; 128: continue; 129: case 0102: /*upper rail*/ 130: railmag |= 01; 131: continue; 132: case 0103: /*upper mag*/ 133: railmag |= 02; 134: continue; 135: case 0104: /*lower mag*/ 136: railmag &= ~02; 137: continue; 138: case 0105: /*lower case*/ 139: mcase = 0; 140: continue; 141: case 0106: /*upper case*/ 142: mcase = 0100; 143: continue; 144: case 0107: /*escape forward*/ 145: escd = 0; 146: continue; 147: case 0110: /*escape backward*/ 148: escd = 1; 149: continue; 150: case 0111: /*stop*/ 151: continue; 152: case 0112: /*lead forward*/ 153: verd = 0; 154: continue; 155: case 0113: /*undefined*/ 156: continue; 157: case 0114: /*lead backward*/ 158: verd = 1; 159: continue; 160: case 0115: /*undefined*/ 161: case 0116: 162: case 0117: 163: continue; 164: } 165: if((i & 0340) == 0140){ /*leading*/ 166: lead = (~i) & 037; 167: if(verd)lead = -lead; 168: if((leadtot += lead) > pl){ 169: leadtot = lead; 170: oput(US); 171: fflush(stdout); 172: if(!tflag)kwait(); 173: yy = MAXY; 174: if(pgskip)--pgskip; 175: init(); 176: continue; 177: } 178: if(skip)continue; 179: if((yy -= (lead<<1)) < 0){ 180: skip++; 181: yy = 0; 182: }else sendpt(); 183: continue; 184: } 185: if((i & 0360) == 0120){ /*size change*/ 186: i &= 017; 187: for(j = 0; i != (stab[j] & 017); j++); 188: osize = size; 189: size = stab[j]; 190: psize = rtab[j]; 191: ksize = ktab[j]; 192: oput(ESC); 193: oput(ksize); 194: i = 0; 195: if(!(osize & DBL) && (size & DBL))i = -55; 196: else if((osize & DBL) && !(size & DBL))i = 55; 197: if(escd)i = -i; 198: esc += i; 199: continue; 200: } 201: if(i & 0300)continue; 202: i = (i & 077) | mcase; 203: if(railmag != 03)k = asctab[i]; 204: else k = spectab[i]; 205: if(alpha)sendpt(); 206: if(*k!='\0'){ 207: oput(US); 208: while(*k & 0377)oput(*k++); 209: alpha++; 210: continue; 211: }else{ 212: if(railmag != 03){ 213: switch(i){ 214: case 0124: lig("fi"); break; 215: case 0125: lig("fl"); break; 216: case 0126: lig("ff"); break; 217: case 0130: lig("ffl"); break; 218: case 0131: lig("ffi"); break; 219: default: continue; 220: } 221: } 222: continue; 223: } 224: } 225: ex(); 226: } 227: lig(x) 228: char *x; 229: { 230: register i, j; 231: register char *k; 232: 233: j = 0; 234: k = x; 235: oput(US); 236: oput(*k++); 237: i = psize * 8 * mpy / (div * 6); /* 8/36 em */ 238: while(*k){ 239: xx += i; 240: j += i; 241: sendpt(); 242: oput(US); 243: oput(*k++); 244: } 245: xx -= j; 246: sendpt(); 247: } 248: init(){ 249: 250: fflush(stdout); 251: if(erase){ 252: oput(ESC); 253: oput(FF); 254: }else erase = 1; 255: oput(ESC); 256: oput(ksize); 257: /*delay about a second*/ 258: /* let the system do it... 259: for(i = 960; i > 0; i--)oput(GS); 260: */ 261: skip = 0; 262: sendpt(); 263: } 264: ex(){ 265: yy = MAXY; 266: xx = 0; 267: sendpt(); 268: oput(ESC); 269: oput(';'); 270: oput(US); 271: fflush(stdout); 272: exit(0); 273: } 274: kwait(){ 275: char buf[128]; char *bptr; char c; 276: if(pgskip) return; 277: next: 278: bptr=buf; 279: while((c=readch())&&(c!='\n')) *bptr++=c; 280: *bptr=0; 281: if(bptr!=buf){ 282: bptr = buf; 283: if(*bptr == '!'){callunix(&buf[1]); fputs("!\n", stderr); goto next;} 284: else switch(*bptr++){ 285: case 'e': 286: erase = 0; 287: goto next; 288: case 's': 289: ap = &buf[1]; 290: dfact = 1; 291: pgskip = atoi() + 1; 292: goto next; 293: default: 294: fputs("?\n", stderr); 295: goto next; 296: } 297: } 298: else if (c==0) ex(); 299: else return; 300: } 301: callunix(line) 302: char line[]; 303: { 304: int rc, status, unixpid; 305: if( (unixpid=fork())==0 ) { 306: signal(SIGINT,sigint); signal(SIGQUIT,sigquit); 307: close(0); dup(2); 308: execl("/bin/sh", "-sh", "-c", line, 0); 309: exit(255); 310: } 311: else if(unixpid == -1) 312: return; 313: else{ signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); 314: while( (rc = wait(&status)) != unixpid && rc != -1 ) ; 315: signal(SIGINT,ex); signal(SIGQUIT,sigquit); 316: } 317: } 318: readch(){ 319: char c; 320: if (read(2,&c,1)<1) c=0; 321: return(c); 322: } 323: sendpt(){ 324: int hy,xb,ly,hx,lx; 325: 326: oput(GS); 327: hy = ((yy>>7) & 037); 328: xb = ((xx & 03) + ((yy<<2) & 014) & 017); 329: ly = ((yy>>2) & 037); 330: hx = ((xx>>7) & 037); 331: lx = ((xx>>2) & 037); 332: if(hy != ohy)oput(hy | 040); 333: if(xb != oxb)oput(xb | 0140); 334: if((ly != oly) || (hx != ohx) || (xb != oxb)) 335: oput(ly | 0140); 336: if(hx != ohx)oput(hx | 040); 337: oput(lx | 0100); 338: ohy = hy; 339: oxb = xb; 340: oly = ly; 341: ohx = hx; 342: olx = lx; 343: alpha = 0; 344: return; 345: } 346: atoi() 347: { 348: register i, j, acc; 349: int field, digits; 350: long dd; 351: long tscale(); 352: 353: field = digits = acc = 0; 354: a1: 355: while(((j = (i = getch()) - '0') >= 0) && (j <= 9)){ 356: field++; 357: digits++; 358: acc = 10*acc + j; 359: } 360: if(i == '.'){ 361: field++; 362: digits = 0; 363: goto a1; 364: } 365: if(!(ch = i))ch = 'x'; 366: dd = tscale(acc); 367: acc = dd; 368: if((field != digits) && (digits > 0)){ 369: j = 1; 370: while(digits--)j *= 10; 371: acc = dd/j; 372: } 373: nonumb = !field; 374: ch = 0; 375: return(acc); 376: } 377: long tscale(n) 378: int n; 379: { 380: register i, j; 381: 382: switch(i = getch()){ 383: case 'u': 384: j = 1; 385: break; 386: case 'p': /*Points*/ 387: j = 6; 388: break; 389: case 'i': /*Inches*/ 390: j = 432; 391: break; 392: case 'c': /*Centimeters; should be 170.0787*/ 393: j = 170; 394: break; 395: case 'P': /*Picas*/ 396: j = 72; 397: break; 398: default: 399: j = dfact; 400: ch = i; 401: } 402: return((long)n*j); 403: } 404: getch(){ 405: register i; 406: 407: if(ch){ 408: i = ch; 409: ch = 0; 410: return(i); 411: } 412: return(*ap++); 413: } 414: 415: char *asctab[128] = { 416: "\0", /*blank*/ 417: "h", /*h*/ 418: "t", /*t*/ 419: "n", /*n*/ 420: "m", /*m*/ 421: "l", /*l*/ 422: "i", /*i*/ 423: "z", /*z*/ 424: "s", /*s*/ 425: "d", /*d*/ 426: "b", /*b*/ 427: "x", /*x*/ 428: "f", /*f*/ 429: "j", /*j*/ 430: "u", /*u*/ 431: "k", /*k*/ 432: "\0", /*blank*/ 433: "p", /*p*/ 434: "-", /*_ 3/4 em dash*/ 435: ";", /*;*/ 436: "\0", /*blank*/ 437: "a", /*a*/ 438: "_", /*rule*/ 439: "c", /*c*/ 440: "`", /*` open*/ 441: "e", /*e*/ 442: "\'", /*' close*/ 443: "o", /*o*/ 444: "\0", /*1/4*/ 445: "r", /*r*/ 446: "\0", /*1/2*/ 447: "v", /*v*/ 448: "-", /*- hyphen*/ 449: "w", /*w*/ 450: "q", /*q*/ 451: "/", /*/*/ 452: ".", /*.*/ 453: "g", /*g*/ 454: "\0", /*3/4*/ 455: ",", /*,*/ 456: "&", /*&*/ 457: "y", /*y*/ 458: "\0", /*blank*/ 459: "%", /*%*/ 460: "\0", /*blank*/ 461: "Q", /*Q*/ 462: "T", /*T*/ 463: "O", /*O*/ 464: "H", /*H*/ 465: "N", /*N*/ 466: "M", /*M*/ 467: "L", /*L*/ 468: "R", /*R*/ 469: "G", /*G*/ 470: "I", /*I*/ 471: "P", /*P*/ 472: "C", /*C*/ 473: "V", /*V*/ 474: "E", /*E*/ 475: "Z", /*Z*/ 476: "D", /*D*/ 477: "B", /*B*/ 478: "S", /*S*/ 479: "Y", /*Y*/ 480: "\0", /*blank*/ 481: "F", /*F*/ 482: "X", /*X*/ 483: "A", /*A*/ 484: "W", /*W*/ 485: "J", /*J*/ 486: "U", /*U*/ 487: "K", /*K*/ 488: "0", /*0*/ 489: "1", /*1*/ 490: "2", /*2*/ 491: "3", /*3*/ 492: "4", /*4*/ 493: "5", /*5*/ 494: "6", /*6*/ 495: "7", /*7*/ 496: "8", /*8*/ 497: "9", /*9*/ 498: "*", /***/ 499: "-", /*minus*/ 500: "", /*fi*/ 501: "", /*fl*/ 502: "", /*ff*/ 503: "\033\016Z\bM\033\017", /*cent sign*/ 504: "", /*ffl*/ 505: "", /*ffi*/ 506: "(", /*(*/ 507: ")", /*)*/ 508: "[", /*[*/ 509: "]", /*]*/ 510: "\033\016J\033\017", /*degree*/ 511: "\033\016M\b_\033\017", /*dagger*/ 512: "=", /*=*/ 513: "\033\016O\b&\033\017", /*registered*/ 514: ":", /*:*/ 515: "+", /*+*/ 516: "\0", /*blank*/ 517: "!", /*!*/ 518: "\033\016O\b~\033\017", /*bullet*/ 519: "?", /*?*/ 520: "\'", /*foot mark*/ 521: "|", /*|*/ 522: "\0", /*blank*/ 523: "\033\016O\b#\033\017", /*copyright*/ 524: "\033\016L\033\017", /*square*/ 525: "$" }; /*$*/ 526: 527: char *spectab[128] = { 528: "\0", /*blank*/ 529: "\033\016(\bM\033\017", /*psi*/ 530: "\033\016o\b_\033\017", /*theta*/ 531: "v\b)", /*nu*/ 532: "\033\016V\b,\033\017", /*mu*/ 533: "\033\016)\b?\033\017", /*lambda*/ 534: "\033\016I\033\017", /*iota*/ 535: "S\b\033\016Z\033\017", /*zeta*/ 536: "o\b\'", /*sigma*/ 537: "o\b\033\0165\033\017", /*delta*/ 538: "\033\016b\033\017", /*beta*/ 539: "\033\016e\bc\033\017", /*xi*/ 540: "j\b\033\016C\033\017", /*eta*/ 541: "\033\016O\bM\033\017", /*phi*/ 542: "\033\016(\033\017", /*upsilon*/ 543: "\033\016k\033\017", /*kappa*/ 544: "\0", /*blank*/ 545: "T\b\033\016S\033\017", /*pi*/ 546: "@", /*at-sign*/ 547: "\033\016U\033\017", /*down arrow*/ 548: "\0", /*blank*/ 549: "\033\016A\033\017", /*alpha*/ 550: "|", /*or*/ 551: "l\b/", /*chi*/ 552: "\"", /*"*/ 553: "\033\016E\033\017", /*epsilon*/ 554: "=", /*=*/ 555: "\033\016O\033\017", /*omicron*/ 556: "\033\016[\033\017", /*left arrow*/ 557: "\033\016R\033\017", /*rho*/ 558: "\033\016Y\033\017", /*up arrow*/ 559: "\033\016N\033\017", /*tau*/ 560: "_", /*underrule*/ 561: "\\", /*\*/ 562: "I\b\033\016(\033\017", /*Psi*/ 563: "\033\016O\bJ\033\017", /*bell system sign*/ 564: "\033\016W\bX\033\017", /*infinity*/ 565: "`\b/", /*gamma*/ 566: "\033\016X\bF\033\017", /*improper superset*/ 567: "\033\016A\033\017", /*proportional to*/ 568: "\033\016\\\b]\033\017", /*right hand*/ 569: "\033\016W\033\017", /*omega*/ 570: "\0", /*blank*/ 571: "\033\016G\033\017", /*gradient*/ 572: "\0", /*blank*/ 573: "I\033\016\bO\033\017", /*Phi*/ 574: "O\b=", /*Theta*/ 575: "O\b_", /*Omega*/ 576: "\033\016V\033\017", /*cup (union)*/ 577: "\033\016@\033\017", /*root en*/ 578: "s", /*terminal sigma*/ 579: "\033\016)\bK\033\017", /*Lambda*/ 580: "-", /*minus*/ 581: "\033\016S\bK\033\017", /*Gamma*/ 582: "\033\016i\033\017", /*integral sign*/ 583: "\033\016t\b'\033\017", /*Pi*/ 584: "\033\016Z\033\017", /*subset of*/ 585: "\033\016X\033\017", /*superset of*/ 586: "\033\016T\033\017", /*approximates*/ 587: "o\b`", /*partial derivative*/ 588: "\033\016H\033\017", /*Delta*/ 589: "\033\016I\b'\033\017", /*square root*/ 590: ">\b\033\016F\b@\033\017", /*Sigma*/ 591: "\033\016T\bF\033\017", /*approx =*/ 592: "\0", /*blank*/ 593: ">", /*>*/ 594: "\033\016_\bF\b@\033\017", /*Xi*/ 595: "<", /*<*/ 596: "/", /*slash (longer)*/ 597: "\033\016C\033\017", /*cap (intersection)*/ 598: "\033\016y\033\017", /*Upsilon*/ 599: "\033\016|\033\017", /*not*/ 600: "|", /*right ceiling (rt of ")*/ 601: "|", /*left top (of big curly)*/ 602: "|", /*bold vertical*/ 603: "|", /*left center of big curly bracket*/ 604: "|", /*left bottom*/ 605: "|", /*right top*/ 606: "|", /*right center of big curly bracket*/ 607: "|", /*right bot*/ 608: "|", /*right floor (rb of ")*/ 609: "|", /*left floor (left bot of big sq bract)*/ 610: "|", /*left ceiling (lt of ")*/ 611: "\033\016=\033\017", /*multiply*/ 612: "\033\016+\033\017", /*divide*/ 613: "+\b_", /*plus-minus*/ 614: "\033\016$\033\017", /*<=*/ 615: "\033\016^\033\017", /*>=*/ 616: "=\b_", /*identically equal*/ 617: "\033\016*\033\017", /*not equal*/ 618: "{", /*{*/ 619: "}", /*}*/ 620: "\'", /*' acute accent*/ 621: "`", /*` grave accent*/ 622: "^", /*^*/ 623: "#", /*sharp*/ 624: "\033\016|\b[\033\017", /*left hand*/ 625: "\033\016c\b_\033\017", /*member of*/ 626: "~", /*~*/ 627: "\033\016O\b/\033\017", /*empty set*/ 628: "\0", /*blank*/ 629: "\033\016%\bM\033\017", /*dbl dagger*/ 630: "|", /*box rule*/ 631: "*", /*asterisk*/ 632: "\033\016Z\bF\033\017", /*improper subset*/ 633: "\033\016O\033\017", /*circle*/ 634: "\0", /*blank*/ 635: "+", /*eqn plus*/ 636: "\033\016]\033\017", /*right arrow*/ 637: "g\b\033\016C\033\017" }; /*section mark*/