home *** CD-ROM | disk | FTP | other *** search
- /* nobs.c - Simple backspace filter - 3.0 */
-
- /*
- * This program will take lines containing overstrike pragmas of the form
- * <char><bs><char> and convert them to individual lines of output with a
- * return but no line feed between them. It is designed for filtering nroff
- * output to line printers that cannot back space (or on which back spaces
- * are expensive).
- *
- * Only the following control characters are expected: \b, \t, \n, \r, \f, ESC,
- * SO, and SI. \t is expanded. \b is processed (obviously). SO and SI delimit
- * an alternate character set. A single printer control character must follow
- * ESC; it is assumed that in the nroff output this character was a 7, 8, or
- * 9, for forward or reverse carriage motion, and that "col" processing has
- * made each ESC passed part of a line terminator sequence (\n-ESC-9 or
- * ESC-9-\r). Other ESC sequences are very likely to corrupt the output.
- * Other control characters may be passed, but with undefined results if
- * there is overstriking.
- *
- * Output from "col -f" is processed properly. Indeed, if there are reverse or
- * half-line forward carriage motions (ESC-[789]), then the raw nroff output
- * _must_ be filtered through "col" before "nobs". As noted, "Nobs" assumes
- * that escape sequences terminate a line, as in the output from "col".
- *
- * "Nobs", like "col", passes strings in an alternate character set, delimited
- * by SO (\016) and SI (\017). Characters of the alternate set are translated
- * subsequently by a printer-specific filter into printer control strings and
- * serve, e.g., to generate Greek characters and math symbols. "Nobs"
- * understands that characters of the alternate set have unit width for char
- * < 'r' and zero width for char >= 'r' (there is a non-portable assumption
- * of ascii order).
- *
- * Usage: cat file|pic|tbl|neqn|nroff -m? -TX|col -fx|nobs|X-filter >/dev/lp
- */
-
- /*-
- * Author:
- * Chad R. Larson This program is placed in the
- * DCF, Inc. Public Domain. You may do with
- * 14623 North 49th Place it as you please.
- * Scottsdale, AZ 85254
- *
- * Modified 3/3/89:
- * Kevin O'Gorman Changes also in the public domain.
- * Vital Computer Systems
- * 5115 Beachcomber
- * Oxnard, CA 93035
- *
- * Rewritten 6/27/89:
- * J.A. Rupley rupley!local@megaron.arizona.edu
- */
-
- #include <stdio.h>
-
- #define LINESIZE 1024 /* maximum line length */
- #define MAXOVER 8 /* maximum number of overstrikes */
- #define TABSIZE 8 /* tab length */
- #define ALT 0200 /* set MSB for alternate character set */
- #define SO '\016' /* input flag for start of alternate char set */
- #define SI '\017' /* input flag for end of above */
-
- /* forward references */
- void exit();
- char *memset();
-
- static char output[MAXOVER][LINESIZE + 3]; /* output line buffers with
- * room for end of line
- * delimters */
-
- int
- main()
- {
- int out_dex;/* offset into output buffer */
- int max_dex;/* high water for above */
- int line; /* output buffer array index */
- int line_count; /* number of output lines */
- int strip; /* trailing space strip index */
- int alt; /* flag for alternate character set on input */
- int chr; /* single character storage */
- char c; /* temp storage */
- char *s; /* pointer into an output buffer */
-
- /*
- * file is processed by parts, delimited by \n, \r, \f or \033
- * strings; splitting at \033 and \r handles \b in lines with printer
- * control characters, specifically fwrd-half-line in output of
- * the "col -f" filter.
- */
- do {
- memset((char *) output, ' ', sizeof(output));
- out_dex = -1;
- max_dex = 0;
- line = 0;
- line_count = 0;
-
- /* slide through input line, dropping bs chars */
- while ((chr = getchar())
- && chr != EOF
- && chr != '\033'
- && chr != '\f'
- && chr != '\n'
- && chr != '\r') {
- switch (chr) {
- case '\b':
- /* cannot backup thru half or full newline */
- out_dex = (out_dex >= 0) ? --out_dex : -1;
- break;
- case '\t':
- out_dex = ((out_dex + TABSIZE + 1) /
- TABSIZE) * TABSIZE - 1;
- break;
- case SO:
- alt = ALT;
- break;
- case SI:
- alt = 0;
- break;
- case ' ':
- max_dex = (++out_dex > max_dex) ? out_dex : max_dex;
- break;
- default:
- if ((max_dex = (++out_dex > max_dex) ? out_dex : max_dex) > LINESIZE) {
- fprintf(stderr, "nobs: line segment overflows buffer\n");
- exit(1);
- }
- for (line = 0; /* exit at break */ ; line++) {
- if (line == MAXOVER) {
- fprintf(stderr, "nobs: too many overstrikes\n");
- exit(1);
- }
- if (output[line][out_dex] == ' ') {
- /* flag alt char */
- output[line][out_dex] = chr | alt;
- if (line_count < line)
- line_count = line;
- /* for zero-width alt char */
- if (alt && chr >= 'r')
- out_dex = (out_dex >= 0) ? --out_dex : -1;
- break; /* exit loop */
- }
- }
- }
- } /* end (\n, \E, etc)-delimited processing */
-
- /* print the output buffers */
- for (line = 0; line <= line_count; line++) {
- strip = max_dex;
- while (output[line][strip] == ' ' && strip >= 0)
- --strip; /* strip trailing spaces */
- ++strip;/* point past string end */
- /*
- * append line terminator (\r for line to be
- * overwritten); only [789] for +-movt should follow
- * ESC, and col preprocessing is assumed to have made
- * each ESC part of a line terminator.
- */
- if (line < line_count) {
- output[line][strip++] = '\r';
- } else {
- if (chr == '\033') {
- output[line][strip++] = chr;
- chr = getchar();
- }
- output[line][strip++] = (chr == EOF) ? '\r' : chr;
- }
- output[line][strip] = '\0';
- for (s = output[line]; *s; s++) {
- c = *s & ~ALT; /* careful about sign
- * extension */
- if (*s & ALT && c > ' ') {
- putchar(SO); /* output printable
- * alt char with SO-SI
- * delimiters */
- putchar(c);
- putchar(SI);
- } else {
- putchar(c);
- }
- }
- }
-
- } while (chr != EOF); /* end of file */
- return (0);
- } /* end of main */
-