static char *sccsid = "@(#)tc.c 4.2 (Berkeley) 7/6/81"; /* * Simulate typesetter on 4014 */ #include <signal.h> #include <stdio.h> #define oput(c) if (pgskip==0) putchar(c); else (c); #define MAXY 3071 #define US 037 #define GS 035 #define ESC 033 #define FF 014 #define DBL 0200 int pl = 11*144; int mpy = 1; int div = 1; char *ap; int ch; int nonumb; int psize = 10; int dfact = 1; int esc; int escd; int verd; int esct; int osize = 02; int size = 02; int rx; int xx; int yy = MAXY+62+48; int leadtot = -31; int ohy = -1; int ohx = -1; int oxb = -1; int oly = -1; int olx = -1; int tflag; int railmag; int lead; int skip; int pgskip; int ksize = ';'; int mcase; int stab[] = {010,0,01,07,02,03,04,05,0211,06,0212,0213,0214,0215,0216,0217}; int rtab[] = {6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 28, 36, 18}; int ktab[] = {';',';',';',';',';',';',':',':','9','9','9','9','8','8','8','9'}; int first = 1; int alpha; extern char *asctab[128]; extern char *spectab[128]; int erase = 1; int (*sigint)(); int (*sigquit)(); main(argc,argv) int argc; char **argv; { register i, j; register char *k; extern ex(); while((--argc > 0) && ((++argv)[0][0]=='-')){ switch(argv[0][1]){ case 'p': ap = &argv[0][2]; dfact = 72; if(i = atoi())pl = i/3; continue; case 't': tflag++; continue; case 's': ap = &argv[0][2]; dfact = 1; pgskip = atoi(); continue; default: dfact = 1; ap = &argv[0][1]; if(i = atoi())mpy = i; if(i = atoi())div = i; continue; } } if(argc){ if (freopen(argv[0], "r", stdin) == NULL) { fprintf(stderr, "tc: cannot open %s\n", argv[0]); exit(1); } } sigint = signal(SIGINT, ex); sigquit = signal(SIGQUIT, SIG_IGN); while((i = getchar()) != EOF){ if(!i)continue; if(i & 0200){ esc += (~i) & 0177; continue; } if(esc){ if(escd)esc = -esc; esct += esc; xx += (esc*mpy + rx)/div; rx = (esc*mpy + rx)%div; sendpt(); esc = 0; } switch(i){ case 0100: /*init*/ escd = verd = mcase = railmag = xx = 0; yy = MAXY + 48; leadtot = -31; ohy = oxb = oly = ohx = olx = -1; oput(US); fflush(stdout); if(!first && !tflag)kwait(); if(first){ first = 0; yy += 62; } init(); continue; case 0101: /*lower rail*/ railmag &= ~01; continue; case 0102: /*upper rail*/ railmag |= 01; continue; case 0103: /*upper mag*/ railmag |= 02; continue; case 0104: /*lower mag*/ railmag &= ~02; continue; case 0105: /*lower case*/ mcase = 0; continue; case 0106: /*upper case*/ mcase = 0100; continue; case 0107: /*escape forward*/ escd = 0; continue; case 0110: /*escape backward*/ escd = 1; continue; case 0111: /*stop*/ continue; case 0112: /*lead forward*/ verd = 0; continue; case 0113: /*undefined*/ continue; case 0114: /*lead backward*/ verd = 1; continue; case 0115: /*undefined*/ case 0116: case 0117: continue; } if((i & 0340) == 0140){ /*leading*/ lead = (~i) & 037; if(verd)lead = -lead; if((leadtot += lead) > pl){ leadtot = lead; oput(US); fflush(stdout); if(!tflag)kwait(); yy = MAXY; if(pgskip)--pgskip; init(); continue; } if(skip)continue; if((yy -= (lead<<1)) < 0){ skip++; yy = 0; }else sendpt(); continue; } if((i & 0360) == 0120){ /*size change*/ i &= 017; for(j = 0; i != (stab[j] & 017); j++); osize = size; size = stab[j]; psize = rtab[j]; ksize = ktab[j]; oput(ESC); oput(ksize); i = 0; if(!(osize & DBL) && (size & DBL))i = -55; else if((osize & DBL) && !(size & DBL))i = 55; if(escd)i = -i; esc += i; continue; } if(i & 0300)continue; i = (i & 077) | mcase; if(railmag != 03)k = asctab[i]; else k = spectab[i]; if(alpha)sendpt(); if(*k!='\0'){ oput(US); while(*k & 0377)oput(*k++); alpha++; continue; }else{ if(railmag != 03){ switch(i){ case 0124: lig("fi"); break; case 0125: lig("fl"); break; case 0126: lig("ff"); break; case 0130: lig("ffl"); break; case 0131: lig("ffi"); break; default: continue; } } continue; } } ex(); } lig(x) char *x; { register i, j; register char *k; j = 0; k = x; oput(US); oput(*k++); i = psize * 8 * mpy / (div * 6); /* 8/36 em */ while(*k){ xx += i; j += i; sendpt(); oput(US); oput(*k++); } xx -= j; sendpt(); } init(){ fflush(stdout); if(erase){ oput(ESC); oput(FF); }else erase = 1; oput(ESC); oput(ksize); /*delay about a second*/ /* let the system do it... for(i = 960; i > 0; i--)oput(GS); */ skip = 0; sendpt(); } ex(){ yy = MAXY; xx = 0; sendpt(); oput(ESC); oput(';'); oput(US); fflush(stdout); exit(0); } kwait(){ char buf[128]; char *bptr; char c; if(pgskip) return; next: bptr=buf; while((c=readch())&&(c!='\n')) *bptr++=c; *bptr=0; if(bptr!=buf){ bptr = buf; if(*bptr == '!'){callunix(&buf[1]); fputs("!\n", stderr); goto next;} else switch(*bptr++){ case 'e': erase = 0; goto next; case 's': ap = &buf[1]; dfact = 1; pgskip = atoi() + 1; goto next; default: fputs("?\n", stderr); goto next; } } else if (c==0) ex(); else return; } callunix(line) char line[]; { int rc, status, unixpid; if( (unixpid=fork())==0 ) { signal(SIGINT,sigint); signal(SIGQUIT,sigquit); close(0); dup(2); execl("/bin/sh", "-sh", "-c", line, 0); exit(255); } else if(unixpid == -1) return; else{ signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); while( (rc = wait(&status)) != unixpid && rc != -1 ) ; signal(SIGINT,ex); signal(SIGQUIT,sigquit); } } readch(){ char c; if (read(2,&c,1)<1) c=0; return(c); } sendpt(){ int hy,xb,ly,hx,lx; oput(GS); hy = ((yy>>7) & 037); xb = ((xx & 03) + ((yy<<2) & 014) & 017); ly = ((yy>>2) & 037); hx = ((xx>>7) & 037); lx = ((xx>>2) & 037); if(hy != ohy)oput(hy | 040); if(xb != oxb)oput(xb | 0140); if((ly != oly) || (hx != ohx) || (xb != oxb)) oput(ly | 0140); if(hx != ohx)oput(hx | 040); oput(lx | 0100); ohy = hy; oxb = xb; oly = ly; ohx = hx; olx = lx; alpha = 0; return; } atoi() { register i, j, acc; int field, digits; long dd; long tscale(); field = digits = acc = 0; a1: while(((j = (i = getch()) - '0') >= 0) && (j <= 9)){ field++; digits++; acc = 10*acc + j; } if(i == '.'){ field++; digits = 0; goto a1; } if(!(ch = i))ch = 'x'; dd = tscale(acc); acc = dd; if((field != digits) && (digits > 0)){ j = 1; while(digits--)j *= 10; acc = dd/j; } nonumb = !field; ch = 0; return(acc); } long tscale(n) int n; { register i, j; switch(i = getch()){ case 'u': j = 1; break; case 'p': /*Points*/ j = 6; break; case 'i': /*Inches*/ j = 432; break; case 'c': /*Centimeters; should be 170.0787*/ j = 170; break; case 'P': /*Picas*/ j = 72; break; default: j = dfact; ch = i; } return((long)n*j); } getch(){ register i; if(ch){ i = ch; ch = 0; return(i); } return(*ap++); } char *asctab[128] = { "\0", /*blank*/ "h", /*h*/ "t", /*t*/ "n", /*n*/ "m", /*m*/ "l", /*l*/ "i", /*i*/ "z", /*z*/ "s", /*s*/ "d", /*d*/ "b", /*b*/ "x", /*x*/ "f", /*f*/ "j", /*j*/ "u", /*u*/ "k", /*k*/ "\0", /*blank*/ "p", /*p*/ "-", /*_ 3/4 em dash*/ ";", /*;*/ "\0", /*blank*/ "a", /*a*/ "_", /*rule*/ "c", /*c*/ "`", /*` open*/ "e", /*e*/ "\'", /*' close*/ "o", /*o*/ "\0", /*1/4*/ "r", /*r*/ "\0", /*1/2*/ "v", /*v*/ "-", /*- hyphen*/ "w", /*w*/ "q", /*q*/ "/", /*/*/ ".", /*.*/ "g", /*g*/ "\0", /*3/4*/ ",", /*,*/ "&", /*&*/ "y", /*y*/ "\0", /*blank*/ "%", /*%*/ "\0", /*blank*/ "Q", /*Q*/ "T", /*T*/ "O", /*O*/ "H", /*H*/ "N", /*N*/ "M", /*M*/ "L", /*L*/ "R", /*R*/ "G", /*G*/ "I", /*I*/ "P", /*P*/ "C", /*C*/ "V", /*V*/ "E", /*E*/ "Z", /*Z*/ "D", /*D*/ "B", /*B*/ "S", /*S*/ "Y", /*Y*/ "\0", /*blank*/ "F", /*F*/ "X", /*X*/ "A", /*A*/ "W", /*W*/ "J", /*J*/ "U", /*U*/ "K", /*K*/ "0", /*0*/ "1", /*1*/ "2", /*2*/ "3", /*3*/ "4", /*4*/ "5", /*5*/ "6", /*6*/ "7", /*7*/ "8", /*8*/ "9", /*9*/ "*", /***/ "-", /*minus*/ "", /*fi*/ "", /*fl*/ "", /*ff*/ "\033\016Z\bM\033\017", /*cent sign*/ "", /*ffl*/ "", /*ffi*/ "(", /*(*/ ")", /*)*/ "[", /*[*/ "]", /*]*/ "\033\016J\033\017", /*degree*/ "\033\016M\b_\033\017", /*dagger*/ "=", /*=*/ "\033\016O\b&\033\017", /*registered*/ ":", /*:*/ "+", /*+*/ "\0", /*blank*/ "!", /*!*/ "\033\016O\b~\033\017", /*bullet*/ "?", /*?*/ "\'", /*foot mark*/ "|", /*|*/ "\0", /*blank*/ "\033\016O\b#\033\017", /*copyright*/ "\033\016L\033\017", /*square*/ "$" }; /*$*/ char *spectab[128] = { "\0", /*blank*/ "\033\016(\bM\033\017", /*psi*/ "\033\016o\b_\033\017", /*theta*/ "v\b)", /*nu*/ "\033\016V\b,\033\017", /*mu*/ "\033\016)\b?\033\017", /*lambda*/ "\033\016I\033\017", /*iota*/ "S\b\033\016Z\033\017", /*zeta*/ "o\b\'", /*sigma*/ "o\b\033\0165\033\017", /*delta*/ "\033\016b\033\017", /*beta*/ "\033\016e\bc\033\017", /*xi*/ "j\b\033\016C\033\017", /*eta*/ "\033\016O\bM\033\017", /*phi*/ "\033\016(\033\017", /*upsilon*/ "\033\016k\033\017", /*kappa*/ "\0", /*blank*/ "T\b\033\016S\033\017", /*pi*/ "@", /*at-sign*/ "\033\016U\033\017", /*down arrow*/ "\0", /*blank*/ "\033\016A\033\017", /*alpha*/ "|", /*or*/ "l\b/", /*chi*/ "\"", /*"*/ "\033\016E\033\017", /*epsilon*/ "=", /*=*/ "\033\016O\033\017", /*omicron*/ "\033\016[\033\017", /*left arrow*/ "\033\016R\033\017", /*rho*/ "\033\016Y\033\017", /*up arrow*/ "\033\016N\033\017", /*tau*/ "_", /*underrule*/ "\\", /*\*/ "I\b\033\016(\033\017", /*Psi*/ "\033\016O\bJ\033\017", /*bell system sign*/ "\033\016W\bX\033\017", /*infinity*/ "`\b/", /*gamma*/ "\033\016X\bF\033\017", /*improper superset*/ "\033\016A\033\017", /*proportional to*/ "\033\016\\\b]\033\017", /*right hand*/ "\033\016W\033\017", /*omega*/ "\0", /*blank*/ "\033\016G\033\017", /*gradient*/ "\0", /*blank*/ "I\033\016\bO\033\017", /*Phi*/ "O\b=", /*Theta*/ "O\b_", /*Omega*/ "\033\016V\033\017", /*cup (union)*/ "\033\016@\033\017", /*root en*/ "s", /*terminal sigma*/ "\033\016)\bK\033\017", /*Lambda*/ "-", /*minus*/ "\033\016S\bK\033\017", /*Gamma*/ "\033\016i\033\017", /*integral sign*/ "\033\016t\b'\033\017", /*Pi*/ "\033\016Z\033\017", /*subset of*/ "\033\016X\033\017", /*superset of*/ "\033\016T\033\017", /*approximates*/ "o\b`", /*partial derivative*/ "\033\016H\033\017", /*Delta*/ "\033\016I\b'\033\017", /*square root*/ ">\b\033\016F\b@\033\017", /*Sigma*/ "\033\016T\bF\033\017", /*approx =*/ "\0", /*blank*/ ">", /*>*/ "\033\016_\bF\b@\033\017", /*Xi*/ "<", /*<*/ "/", /*slash (longer)*/ "\033\016C\033\017", /*cap (intersection)*/ "\033\016y\033\017", /*Upsilon*/ "\033\016|\033\017", /*not*/ "|", /*right ceiling (rt of ")*/ "|", /*left top (of big curly)*/ "|", /*bold vertical*/ "|", /*left center of big curly bracket*/ "|", /*left bottom*/ "|", /*right top*/ "|", /*right center of big curly bracket*/ "|", /*right bot*/ "|", /*right floor (rb of ")*/ "|", /*left floor (left bot of big sq bract)*/ "|", /*left ceiling (lt of ")*/ "\033\016=\033\017", /*multiply*/ "\033\016+\033\017", /*divide*/ "+\b_", /*plus-minus*/ "\033\016$\033\017", /*<=*/ "\033\016^\033\017", /*>=*/ "=\b_", /*identically equal*/ "\033\016*\033\017", /*not equal*/ "{", /*{*/ "}", /*}*/ "\'", /*' acute accent*/ "`", /*` grave accent*/ "^", /*^*/ "#", /*sharp*/ "\033\016|\b[\033\017", /*left hand*/ "\033\016c\b_\033\017", /*member of*/ "~", /*~*/ "\033\016O\b/\033\017", /*empty set*/ "\0", /*blank*/ "\033\016%\bM\033\017", /*dbl dagger*/ "|", /*box rule*/ "*", /*asterisk*/ "\033\016Z\bF\033\017", /*improper subset*/ "\033\016O\033\017", /*circle*/ "\0", /*blank*/ "+", /*eqn plus*/ "\033\016]\033\017", /*right arrow*/ "g\b\033\016C\033\017" }; /*section mark*/