|
|
1.1 root 1: static char *sccsid = "@(#)tc.c 4.4 (Berkeley) 1/2/90";
2: /*
3: * Simulate typesetter on 4014
4: */
5:
6: #include <sys/signal.h>
7: #include <paths.h>
8: #include <stdio.h>
9:
10: #define oput(c) if (pgskip==0) putchar(c); else (c);
11: #define MAXY 3071
12: #define US 037
13: #define GS 035
14: #define ESC 033
15: #define FF 014
16: #define DBL 0200
17:
18: int pl = 11*144;
19: int mpy = 1;
20: int div = 1;
21: char *ap;
22: int ch;
23: int nonumb;
24: int psize = 10;
25: int dfact = 1;
26: int esc;
27: int escd;
28: int verd;
29: int esct;
30: int osize = 02;
31: int size = 02;
32: int rx;
33: int xx;
34: int yy = MAXY+62+48;
35: int leadtot = -31;
36: int ohy = -1;
37: int ohx = -1;
38: int oxb = -1;
39: int oly = -1;
40: int olx = -1;
41: int tflag;
42: int railmag;
43: int lead;
44: int skip;
45: int pgskip;
46: int ksize = ';';
47: int mcase;
48: int stab[] = {010,0,01,07,02,03,04,05,0211,06,0212,0213,0214,0215,0216,0217};
49: int rtab[] = {6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 28, 36, 18};
50: int ktab[] = {';',';',';',';',';',';',':',':','9','9','9','9','8','8','8','9'};
51: int first = 1;
52: int alpha;
53: extern char *asctab[128];
54: extern char *spectab[128];
55: int erase = 1;
56: sig_t sigint, sigquit;
57:
58: main(argc,argv)
59: int argc;
60: char **argv;
61: {
62: register i, j;
63: register char *k;
64: extern void 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:
265: void
266: ex(){
267: yy = MAXY;
268: xx = 0;
269: sendpt();
270: oput(ESC);
271: oput(';');
272: oput(US);
273: fflush(stdout);
274: exit(0);
275: }
276: kwait(){
277: char buf[128]; char *bptr; char c;
278: if(pgskip) return;
279: next:
280: bptr=buf;
281: while((c=readch())&&(c!='\n')) *bptr++=c;
282: *bptr=0;
283: if(bptr!=buf){
284: bptr = buf;
285: if(*bptr == '!'){callunix(&buf[1]); fputs("!\n", stderr); goto next;}
286: else switch(*bptr++){
287: case 'e':
288: erase = 0;
289: goto next;
290: case 's':
291: ap = &buf[1];
292: dfact = 1;
293: pgskip = atoi() + 1;
294: goto next;
295: default:
296: fputs("?\n", stderr);
297: goto next;
298: }
299: }
300: else if (c==0) ex();
301: else return;
302: }
303: callunix(line)
304: char line[];
305: {
306: int rc, status, unixpid;
307: if( (unixpid=fork())==0 ) {
308: signal(SIGINT,sigint); signal(SIGQUIT,sigquit);
309: close(0); dup(2);
310: execl(_PATH_BSHELL, "-sh", "-c", line, 0);
311: exit(255);
312: }
313: else if(unixpid == -1)
314: return;
315: else{ signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN);
316: while( (rc = wait(&status)) != unixpid && rc != -1 ) ;
317: signal(SIGINT,ex); signal(SIGQUIT,sigquit);
318: }
319: }
320: readch(){
321: char c;
322: if (read(2,&c,1)<1) c=0;
323: return(c);
324: }
325: sendpt(){
326: int hy,xb,ly,hx,lx;
327:
328: oput(GS);
329: hy = ((yy>>7) & 037);
330: xb = ((xx & 03) + ((yy<<2) & 014) & 017);
331: ly = ((yy>>2) & 037);
332: hx = ((xx>>7) & 037);
333: lx = ((xx>>2) & 037);
334: if(hy != ohy)oput(hy | 040);
335: if(xb != oxb)oput(xb | 0140);
336: if((ly != oly) || (hx != ohx) || (xb != oxb))
337: oput(ly | 0140);
338: if(hx != ohx)oput(hx | 040);
339: oput(lx | 0100);
340: ohy = hy;
341: oxb = xb;
342: oly = ly;
343: ohx = hx;
344: olx = lx;
345: alpha = 0;
346: return;
347: }
348: atoi()
349: {
350: register i, j, acc;
351: int field, digits;
352: long dd;
353: long tscale();
354:
355: field = digits = acc = 0;
356: a1:
357: while(((j = (i = getch()) - '0') >= 0) && (j <= 9)){
358: field++;
359: digits++;
360: acc = 10*acc + j;
361: }
362: if(i == '.'){
363: field++;
364: digits = 0;
365: goto a1;
366: }
367: if(!(ch = i))ch = 'x';
368: dd = tscale(acc);
369: acc = dd;
370: if((field != digits) && (digits > 0)){
371: j = 1;
372: while(digits--)j *= 10;
373: acc = dd/j;
374: }
375: nonumb = !field;
376: ch = 0;
377: return(acc);
378: }
379: long tscale(n)
380: int n;
381: {
382: register i, j;
383:
384: switch(i = getch()){
385: case 'u':
386: j = 1;
387: break;
388: case 'p': /*Points*/
389: j = 6;
390: break;
391: case 'i': /*Inches*/
392: j = 432;
393: break;
394: case 'c': /*Centimeters; should be 170.0787*/
395: j = 170;
396: break;
397: case 'P': /*Picas*/
398: j = 72;
399: break;
400: default:
401: j = dfact;
402: ch = i;
403: }
404: return((long)n*j);
405: }
406: getch(){
407: register i;
408:
409: if(ch){
410: i = ch;
411: ch = 0;
412: return(i);
413: }
414: return(*ap++);
415: }
416:
417: char *asctab[128] = {
418: "\0", /*blank*/
419: "h", /*h*/
420: "t", /*t*/
421: "n", /*n*/
422: "m", /*m*/
423: "l", /*l*/
424: "i", /*i*/
425: "z", /*z*/
426: "s", /*s*/
427: "d", /*d*/
428: "b", /*b*/
429: "x", /*x*/
430: "f", /*f*/
431: "j", /*j*/
432: "u", /*u*/
433: "k", /*k*/
434: "\0", /*blank*/
435: "p", /*p*/
436: "-", /*_ 3/4 em dash*/
437: ";", /*;*/
438: "\0", /*blank*/
439: "a", /*a*/
440: "_", /*rule*/
441: "c", /*c*/
442: "`", /*` open*/
443: "e", /*e*/
444: "\'", /*' close*/
445: "o", /*o*/
446: "\0", /*1/4*/
447: "r", /*r*/
448: "\0", /*1/2*/
449: "v", /*v*/
450: "-", /*- hyphen*/
451: "w", /*w*/
452: "q", /*q*/
453: "/", /*/*/
454: ".", /*.*/
455: "g", /*g*/
456: "\0", /*3/4*/
457: ",", /*,*/
458: "&", /*&*/
459: "y", /*y*/
460: "\0", /*blank*/
461: "%", /*%*/
462: "\0", /*blank*/
463: "Q", /*Q*/
464: "T", /*T*/
465: "O", /*O*/
466: "H", /*H*/
467: "N", /*N*/
468: "M", /*M*/
469: "L", /*L*/
470: "R", /*R*/
471: "G", /*G*/
472: "I", /*I*/
473: "P", /*P*/
474: "C", /*C*/
475: "V", /*V*/
476: "E", /*E*/
477: "Z", /*Z*/
478: "D", /*D*/
479: "B", /*B*/
480: "S", /*S*/
481: "Y", /*Y*/
482: "\0", /*blank*/
483: "F", /*F*/
484: "X", /*X*/
485: "A", /*A*/
486: "W", /*W*/
487: "J", /*J*/
488: "U", /*U*/
489: "K", /*K*/
490: "0", /*0*/
491: "1", /*1*/
492: "2", /*2*/
493: "3", /*3*/
494: "4", /*4*/
495: "5", /*5*/
496: "6", /*6*/
497: "7", /*7*/
498: "8", /*8*/
499: "9", /*9*/
500: "*", /***/
501: "-", /*minus*/
502: "", /*fi*/
503: "", /*fl*/
504: "", /*ff*/
505: "\033\016Z\bM\033\017", /*cent sign*/
506: "", /*ffl*/
507: "", /*ffi*/
508: "(", /*(*/
509: ")", /*)*/
510: "[", /*[*/
511: "]", /*]*/
512: "\033\016J\033\017", /*degree*/
513: "\033\016M\b_\033\017", /*dagger*/
514: "=", /*=*/
515: "\033\016O\b&\033\017", /*registered*/
516: ":", /*:*/
517: "+", /*+*/
518: "\0", /*blank*/
519: "!", /*!*/
520: "\033\016O\b~\033\017", /*bullet*/
521: "?", /*?*/
522: "\'", /*foot mark*/
523: "|", /*|*/
524: "\0", /*blank*/
525: "\033\016O\b#\033\017", /*copyright*/
526: "\033\016L\033\017", /*square*/
527: "$" }; /*$*/
528:
529: char *spectab[128] = {
530: "\0", /*blank*/
531: "\033\016(\bM\033\017", /*psi*/
532: "\033\016o\b_\033\017", /*theta*/
533: "v\b)", /*nu*/
534: "\033\016V\b,\033\017", /*mu*/
535: "\033\016)\b?\033\017", /*lambda*/
536: "\033\016I\033\017", /*iota*/
537: "S\b\033\016Z\033\017", /*zeta*/
538: "o\b\'", /*sigma*/
539: "o\b\033\0165\033\017", /*delta*/
540: "\033\016b\033\017", /*beta*/
541: "\033\016e\bc\033\017", /*xi*/
542: "j\b\033\016C\033\017", /*eta*/
543: "\033\016O\bM\033\017", /*phi*/
544: "\033\016(\033\017", /*upsilon*/
545: "\033\016k\033\017", /*kappa*/
546: "\0", /*blank*/
547: "T\b\033\016S\033\017", /*pi*/
548: "@", /*at-sign*/
549: "\033\016U\033\017", /*down arrow*/
550: "\0", /*blank*/
551: "\033\016A\033\017", /*alpha*/
552: "|", /*or*/
553: "l\b/", /*chi*/
554: "\"", /*"*/
555: "\033\016E\033\017", /*epsilon*/
556: "=", /*=*/
557: "\033\016O\033\017", /*omicron*/
558: "\033\016[\033\017", /*left arrow*/
559: "\033\016R\033\017", /*rho*/
560: "\033\016Y\033\017", /*up arrow*/
561: "\033\016N\033\017", /*tau*/
562: "_", /*underrule*/
563: "\\", /*\*/
564: "I\b\033\016(\033\017", /*Psi*/
565: "\033\016O\bJ\033\017", /*bell system sign*/
566: "\033\016W\bX\033\017", /*infinity*/
567: "`\b/", /*gamma*/
568: "\033\016X\bF\033\017", /*improper superset*/
569: "\033\016A\033\017", /*proportional to*/
570: "\033\016\\\b]\033\017", /*right hand*/
571: "\033\016W\033\017", /*omega*/
572: "\0", /*blank*/
573: "\033\016G\033\017", /*gradient*/
574: "\0", /*blank*/
575: "I\033\016\bO\033\017", /*Phi*/
576: "O\b=", /*Theta*/
577: "O\b_", /*Omega*/
578: "\033\016V\033\017", /*cup (union)*/
579: "\033\016@\033\017", /*root en*/
580: "s", /*terminal sigma*/
581: "\033\016)\bK\033\017", /*Lambda*/
582: "-", /*minus*/
583: "\033\016S\bK\033\017", /*Gamma*/
584: "\033\016i\033\017", /*integral sign*/
585: "\033\016t\b'\033\017", /*Pi*/
586: "\033\016Z\033\017", /*subset of*/
587: "\033\016X\033\017", /*superset of*/
588: "\033\016T\033\017", /*approximates*/
589: "o\b`", /*partial derivative*/
590: "\033\016H\033\017", /*Delta*/
591: "\033\016I\b'\033\017", /*square root*/
592: ">\b\033\016F\b@\033\017", /*Sigma*/
593: "\033\016T\bF\033\017", /*approx =*/
594: "\0", /*blank*/
595: ">", /*>*/
596: "\033\016_\bF\b@\033\017", /*Xi*/
597: "<", /*<*/
598: "/", /*slash (longer)*/
599: "\033\016C\033\017", /*cap (intersection)*/
600: "\033\016y\033\017", /*Upsilon*/
601: "\033\016|\033\017", /*not*/
602: "|", /*right ceiling (rt of ")*/
603: "|", /*left top (of big curly)*/
604: "|", /*bold vertical*/
605: "|", /*left center of big curly bracket*/
606: "|", /*left bottom*/
607: "|", /*right top*/
608: "|", /*right center of big curly bracket*/
609: "|", /*right bot*/
610: "|", /*right floor (rb of ")*/
611: "|", /*left floor (left bot of big sq bract)*/
612: "|", /*left ceiling (lt of ")*/
613: "\033\016=\033\017", /*multiply*/
614: "\033\016+\033\017", /*divide*/
615: "+\b_", /*plus-minus*/
616: "\033\016$\033\017", /*<=*/
617: "\033\016^\033\017", /*>=*/
618: "=\b_", /*identically equal*/
619: "\033\016*\033\017", /*not equal*/
620: "{", /*{*/
621: "}", /*}*/
622: "\'", /*' acute accent*/
623: "`", /*` grave accent*/
624: "^", /*^*/
625: "#", /*sharp*/
626: "\033\016|\b[\033\017", /*left hand*/
627: "\033\016c\b_\033\017", /*member of*/
628: "~", /*~*/
629: "\033\016O\b/\033\017", /*empty set*/
630: "\0", /*blank*/
631: "\033\016%\bM\033\017", /*dbl dagger*/
632: "|", /*box rule*/
633: "*", /*asterisk*/
634: "\033\016Z\bF\033\017", /*improper subset*/
635: "\033\016O\033\017", /*circle*/
636: "\0", /*blank*/
637: "+", /*eqn plus*/
638: "\033\016]\033\017", /*right arrow*/
639: "g\b\033\016C\033\017" }; /*section mark*/
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.