Commit | Line | Data |
---|---|---|
9c79dca0 BJ |
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*/ |