|
|
1.1 root 1: static char *sccsid = "@(#)tc.c 4.1 (Berkeley) 10/1/80";
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;
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*/
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.