|
|
1.1 root 1: /* refont.c */
2:
3: /* Author:
4: * Steve Kirkendall
5: * 16820 SW Tallac Way
6: * Beaverton, OR 97006
7: * [email protected], or ...uunet!tektronix!psueea!jove!kirkenda
8: */
9:
10:
11: /* This file contains the complete source code for the refont program */
12:
13: /* The refont program converts font designations to the format of your choice.
14: * Known font formats are:
15: * -b overtype notation, using backspaces
16: * -c overtype notation, using carriage returns
17: * -d the "dot" command notation used by nroff (doesn't work well)
18: * -e Epson-compatible line printer codes
19: * -f the "\f" notation
20: * -x none (strip out the font codes)
21: *
22: * Other flags are:
23: * -I recognize \f and dot notations in input
24: * -F output a formfeed character between files
25: */
26:
27: #include <stdio.h>
28: #include "config.h"
29:
30: /* the program name, for diagnostics */
31: char *progname;
32:
33: /* remembers which output format to use */
34: int outfmt = 'f';
35:
36: /* do we allow "dot" and "backslash-f" on input? */
37: int infmt = 0;
38:
39: /* do we insert formfeeds between input files? */
40: int add_form_feed = 0;
41:
42: main(argc, argv)
43: int argc; /* number of command-line args */
44: char **argv; /* values of the command line args */
45: {
46: FILE *fp;
47: int i, j;
48: int retcode;
49:
50: progname = argv[0];
51:
52: /* parse the flags */
53: i = 1;
54: if (i < argc && argv[i][0] == '-' && argv[i][1])
55: {
56: for (j = 1; argv[i][j]; j++)
57: {
58: switch (argv[i][j])
59: {
60: case 'b':
61: #if !OSK
62: case 'c':
63: #endif
64: case 'd':
65: case 'e':
66: case 'f':
67: case 'x':
68: outfmt = argv[i][j];
69: break;
70:
71: case 'I':
72: infmt = 'I';
73: break;
74:
75: case 'F':
76: add_form_feed = 1;
77: break;
78:
79: default:
80: usage();
81: }
82: }
83: i++;
84: }
85:
86: retcode = 0;
87: if (i == argc)
88: {
89: /* probably shouldn't read from keyboard */
90: if (isatty(fileno(stdin)))
91: {
92: usage();
93: }
94:
95: /* no files named, so use stdin */
96: refont(stdin);
97: }
98: else
99: {
100: for (; i < argc; i++)
101: {
102: fp = fopen(argv[i], "r");
103: if (!fp)
104: {
105: perror(argv[i]);
106: retcode = 1;
107: }
108: else
109: {
110: refont(fp);
111: if (i < argc - 1 && add_form_feed)
112: {
113: putchar('\f');
114: }
115: fclose(fp);
116: }
117: }
118: }
119:
120: exit(retcode);
121: }
122:
123: usage()
124: {
125: fputs("usage: ", stderr);
126: fputs(progname, stderr);
127: fputs(" [-bcdefxFI] [filename]...\n", stderr);
128: exit(2);
129: }
130:
131: /* This function does the refont thing to a single file */
132: /* I apologize for the length of this function. It is gross. */
133: refont(fp)
134: FILE *fp;
135: {
136: char textbuf[1025]; /* chars of a line of text */
137: char fontbuf[1025]; /* fonts of chars in fontbuf */
138: int col; /* where we are in the line */
139: int font; /* remembered font */
140: int more; /* more characters to be output? */
141: int ch;
142:
143: /* reset some stuff */
144: for (col = sizeof fontbuf; --col >= 0; )
145: {
146: fontbuf[col] = 'R';
147: textbuf[col] = '\0';
148: }
149: col = 0;
150: font = 'R';
151:
152: /* get the first char - quit if eof */
153: while ((ch = getc(fp)) != EOF)
154: {
155: /* if "dot" command, read the rest of the command */
156: if (infmt == 'I' && ch == '.' && col == 0)
157: {
158:
159: textbuf[col++] = '.';
160: textbuf[col++] = getc(fp);
161: textbuf[col++] = getc(fp);
162: textbuf[col++] = ch = getc(fp);
163:
164: /* is it a font line? */
165: font = 0;
166: if (textbuf[1] == 'u' && textbuf[2] == 'l')
167: {
168: font = 'U';
169: }
170: else if (textbuf[1] == 'b' && textbuf[2] == 'o')
171: {
172: font = 'B';
173: }
174: else if (textbuf[1] == 'i' && textbuf[2] == 't')
175: {
176: font = 'I';
177: }
178:
179: /* if it is, discard the stuff so far but remember font */
180: if (font)
181: {
182: while (col > 0)
183: {
184: textbuf[--col] = '\0';
185: }
186: }
187: else /* some other format line - write it literally */
188: {
189: while (ch != '\n')
190: {
191: textbuf[col++] = ch = getc(fp);
192: }
193: fputs(textbuf, fp);
194: while (col > 0)
195: {
196: textbuf[--col] = '\0';
197: }
198: }
199: continue;
200: }
201:
202: /* is it a "\f" formatted font? */
203: if (infmt == 'I' && ch == '\\')
204: {
205: ch = getc(fp);
206: if (ch == 'f')
207: {
208: font = getc(fp);
209: }
210: else
211: {
212: textbuf[col++] = '\\';
213: textbuf[col++] = ch;
214: }
215: continue;
216: }
217:
218: /* is it an Epson font? */
219: if (ch == '\033')
220: {
221: ch = getc(fp);
222: switch (ch)
223: {
224: case '4':
225: font = 'I';
226: break;
227:
228: case 'E':
229: case 'G':
230: font = 'B';
231: break;
232:
233: case '5':
234: case 'F':
235: case 'H':
236: font = 'R';
237: break;
238:
239: case '-':
240: font = (getc(fp) & 1) ? 'U' : 'R';
241: break;
242: }
243: continue;
244: }
245:
246: /* control characters? */
247: if (ch == '\b')
248: {
249: if (col > 0)
250: col--;
251: continue;
252: }
253: else if (ch == '\t')
254: {
255: do
256: {
257: if (textbuf[col] == '\0')
258: {
259: textbuf[col] = ' ';
260: }
261: col++;
262: } while (col & 7);
263: continue;
264: }
265: #if !OSK
266: else if (ch == '\r')
267: {
268: col = 0;
269: continue;
270: }
271: #endif
272: else if (ch == ' ')
273: {
274: if (textbuf[col] == '\0')
275: {
276: textbuf[col] = ' ';
277: fontbuf[col] = font;
278: col++;
279: }
280: continue;
281: }
282:
283: /* newline? */
284: if (ch == '\n')
285: {
286: more = 0;
287: for (col = 0, font = 'R'; textbuf[col]; col++)
288: {
289: if (fontbuf[col] != font)
290: {
291: switch (outfmt)
292: {
293: case 'd':
294: putchar('\n');
295: switch (fontbuf[col])
296: {
297: case 'B':
298: fputs(".bo\n", stdout);
299: break;
300:
301: case 'I':
302: fputs(".it\n", stdout);
303: break;
304:
305: case 'U':
306: fputs(".ul\n", stdout);
307: break;
308: }
309: while (textbuf[col] == ' ')
310: {
311: col++;
312: }
313: break;
314:
315: case 'e':
316: switch (fontbuf[col])
317: {
318: case 'B':
319: fputs("\033E", stdout);
320: break;
321:
322: case 'I':
323: fputs("\0334", stdout);
324: break;
325:
326: case 'U':
327: fputs("\033-1", stdout);
328: break;
329:
330: default:
331: switch (font)
332: {
333: case 'B':
334: fputs("\033F", stdout);
335: break;
336:
337: case 'I':
338: fputs("\0335", stdout);
339: break;
340:
341: case 'U':
342: fputs("\033-0", stdout);
343: break;
344: }
345: }
346: break;
347:
348: case 'f':
349: putchar('\\');
350: putchar('f');
351: putchar(fontbuf[col]);
352: break;
353: }
354:
355: font = fontbuf[col];
356: }
357:
358: if (fontbuf[col] != 'R' && textbuf[col] != ' ')
359: {
360: switch (outfmt)
361: {
362: case 'b':
363: if (fontbuf[col] == 'B')
364: {
365: putchar(textbuf[col]);
366: }
367: else
368: {
369: putchar('_');
370: }
371: putchar('\b');
372: break;
373: #if !OSK
374: case 'c':
375: more = col + 1;
376: break;
377: #endif
378: }
379: }
380:
381: putchar(textbuf[col]);
382: }
383:
384: #if !OSK
385: /* another pass? */
386: if (more > 0)
387: {
388: putchar('\r');
389: for (col = 0; col < more; col++)
390: {
391: switch (fontbuf[col])
392: {
393: case 'I':
394: case 'U':
395: putchar('_');
396: break;
397:
398: case 'B':
399: putchar(textbuf[col]);
400: break;
401:
402: default:
403: putchar(' ');
404: }
405: }
406: }
407: #endif /* not OSK */
408:
409: /* newline */
410: if (font != 'R')
411: {
412: switch (outfmt)
413: {
414: case 'f':
415: putchar('\\');
416: putchar('f');
417: putchar('R');
418: break;
419:
420: case 'e':
421: switch (font)
422: {
423: case 'B':
424: fputs("\033F", stdout);
425: break;
426:
427: case 'I':
428: fputs("\0335", stdout);
429: break;
430:
431: case 'U':
432: fputs("\033-0", stdout);
433: break;
434: }
435: }
436: }
437: putchar('\n');
438:
439: /* reset some stuff */
440: for (col = sizeof fontbuf; --col >= 0; )
441: {
442: fontbuf[col] = 'R';
443: textbuf[col] = '\0';
444: }
445: col = 0;
446: font = 'R';
447: continue;
448: }
449:
450: /* normal character */
451: if (font != 'R')
452: {
453: textbuf[col] = ch;
454: fontbuf[col] = font;
455: }
456: else if (textbuf[col] == '_')
457: {
458: textbuf[col] = ch;
459: fontbuf[col] = 'U';
460: }
461: else if (textbuf[col] && textbuf[col] != ' ' && ch == '_')
462: {
463: fontbuf[col] = 'U';
464: }
465: else if (textbuf[col] == ch)
466: {
467: fontbuf[col] = 'B';
468: }
469: else
470: {
471: textbuf[col] = ch;
472: }
473: col++;
474: }
475: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.