/* * rtftxt - Crude NeXT Mail/RTF to ASCII text converter * Brian Katzung 11 March 1992 * * This software is provided on a strictly as-is basis. * Use it at your own risk. */ #include int width = 75; /* Output width */ #define RTF 256 /* RTF formatting (case code) */ #define STUFSIZ 256 /* Amount of input "stuffing" */ char attach[] = "attachment"; char stuff[STUFSIZ]; /* Input "stuffing" buffer */ char *stuffp; /* * Return the next character, or RTF to represent RTF wrappings. * Also handles the "[Attachment ]" hack. */ int rtfc (fp) FILE *fp; { int chr; char *ap; short sawat; /* Insert stuff buffer contents, if any */ if (stuffp != NULL) { if (*stuffp == '\0') { stuffp = NULL; return (RTF); } else { return (*stuffp++); } } /* Get more input from the file */ switch (chr = getc(fp)) { case '{': case '}': case '\n': return (RTF); case '\\': switch (chr = getc(fp)) { case '\\': case '{': case '}': case '\n': return (chr); default: /* Swallow RTF with hack for attachments */ sawat = 0; ap = attach; do { if (chr != *ap) ap = attach; else if (*++ap == '\0') sawat = 1; chr = getc(fp); } while (chr != EOF && chr != ' ' && chr != '\n' && chr != '\\'); /* Found an attachment reference */ if (sawat) { (void) strcpy(stuff, "[Attachment \""); for (stuffp = stuff; *stuffp; ++stuffp) ; while ((chr = getc(fp)) != EOF && chr != '\n') *stuffp++ = chr; (void) strcpy(stuffp, "\"]"); stuffp = stuff; } if (chr == '\\') ungetc('\\', fp); return (RTF); } /* NOTREACHED */ default: return (chr); } /* NOTREACHED */ } /* Convert RTF in file fp to plain ASCII with simple formatting */ void rtftxt (fp) FILE *fp; { int outcol; /* Actual output column */ int vrtcol; /* Virtual output column */ int chr; /* Input character */ char word[256]; /* Word buffer */ char *wp; outcol = 0; vrtcol = 0; wp = word; /* Punt on the first line (fonttbl and other junk) */ (void) fgets(word, sizeof word, fp); /* Just dump output literally if width is zero */ if (width == 0) { while ((chr = rtfc(fp)) != EOF) { if (chr != RTF) { putchar(chr); } } return; } do { switch (chr = rtfc(fp)) { case EOF: case RTF: case '\f': case '\n': case '\t': case ' ': /* Flush the current word on termination */ if (wp > word) { /* Won't fit without wrap */ if (vrtcol + wp - word > width) { putchar('\n'); outcol = 0; vrtcol = 0; } /* Update output to vrtcol */ else { if (vrtcol - outcol > 1) { while ((outcol | 7) + 1 <= vrtcol) { putchar('\t'); outcol = (outcol | 7) + 1; } } while (outcol++ < vrtcol) putchar(' '); --outcol; } printf("%.*s", wp - word, word); outcol += wp - word; vrtcol += wp - word; wp = word; } /* Process the terminating character */ switch (chr) { case ' ': ++vrtcol; break; case '\t': vrtcol = (vrtcol | 7) + 1; break; case '\n': putchar('\n'); outcol = 0; vrtcol = 0; break; case EOF: if (outcol) putchar('\n'); break; } break; default: if (chr > ' ') *wp++ = chr; break; } } while (chr != EOF); } /* Main argument and file processing loop */ int main (ac, av) char **av; { int i; FILE *fp; /* Quick & dirty width option */ if (ac > 1 && *av[1] == '-') { width = -atoi(av[1]); --ac; ++av; } /* Filter or process arguments */ if (ac == 1) rtftxt(stdin); else for (i = 1; i < ac; ++i) if ((fp = fopen(av[i], "r")) != NULL) { rtftxt(fp); fclose(fp); } else perror(av[i]); return (0); }