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