|
|
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.