home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume20 / epf / part03 / nobs.c next >
Encoding:
C/C++ Source or Header  |  1989-10-24  |  6.0 KB  |  185 lines

  1. /* nobs.c - Simple backspace filter - 3.0 */
  2.  
  3. /*
  4.  * This program will take lines containing overstrike pragmas of the form
  5.  * <char><bs><char> and convert them to individual lines of output with a
  6.  * return but no line feed between them. It is designed for filtering nroff
  7.  * output to line printers that cannot back space (or on which back spaces
  8.  * are expensive). 
  9.  *
  10.  * Only the following control characters are expected: \b, \t, \n, \r, \f, ESC,
  11.  * SO, and SI. \t is expanded. \b is processed (obviously). SO and SI delimit
  12.  * an alternate character set. A single printer control character must follow
  13.  * ESC; it is assumed that in the nroff output this character was a 7, 8, or
  14.  * 9, for forward or reverse carriage motion, and that "col" processing has
  15.  * made each ESC passed part of a line terminator sequence (\n-ESC-9 or
  16.  * ESC-9-\r). Other ESC sequences are very likely to corrupt the output.
  17.  * Other control characters may be passed, but with undefined results if
  18.  * there is overstriking. 
  19.  *
  20.  * Output from "col -f" is processed properly.  Indeed, if there are reverse or
  21.  * half-line forward carriage motions (ESC-[789]), then the raw nroff output
  22.  * _must_ be filtered through "col" before "nobs". As noted, "Nobs" assumes
  23.  * that escape sequences terminate a line, as in the output from "col". 
  24.  *
  25.  * "Nobs", like "col", passes strings in an alternate character set, delimited
  26.  * by SO (\016) and SI (\017). Characters of the alternate set are translated
  27.  * subsequently by a printer-specific filter into printer control strings and
  28.  * serve, e.g., to generate Greek characters and math symbols. "Nobs"
  29.  * understands that characters of the alternate set have unit width for char
  30.  * < 'r' and zero width for char >= 'r' (there is a non-portable assumption
  31.  * of ascii order). 
  32.  *
  33.  * Usage: cat file|pic|tbl|neqn|nroff -m? -TX|col -fx|nobs|X-filter >/dev/lp 
  34.  */
  35.  
  36. /*-
  37.  * Author:
  38.  *   Chad R. Larson            This program is placed in the
  39.  *   DCF, Inc.                Public Domain.  You may do with
  40.  *   14623 North 49th Place        it as you please.
  41.  *   Scottsdale, AZ 85254
  42.  *
  43.  * Modified 3/3/89:
  44.  *   Kevin O'Gorman            Changes also in the public domain.
  45.  *   Vital Computer Systems
  46.  *   5115 Beachcomber
  47.  *   Oxnard, CA  93035
  48.  *
  49.  * Rewritten 6/27/89:
  50.  *   J.A. Rupley            rupley!local@megaron.arizona.edu
  51.  */
  52.  
  53. #include <stdio.h>
  54.  
  55. #define    LINESIZE    1024    /* maximum line length */
  56. #define MAXOVER        8    /* maximum number of overstrikes */
  57. #define TABSIZE        8    /* tab length */
  58. #define ALT        0200    /* set MSB for alternate character set */
  59. #define SO        '\016'    /* input flag for start of alternate char set */
  60. #define SI        '\017'    /* input flag for end of above */
  61.  
  62. /* forward references */
  63. void            exit();
  64. char           *memset();
  65.  
  66. static char     output[MAXOVER][LINESIZE + 3];    /* output line buffers with
  67.                          * room for end of line
  68.                          * delimters */
  69.  
  70. int
  71. main()
  72. {
  73.     int             out_dex;/* offset into output buffer */
  74.     int             max_dex;/* high water for above */
  75.     int             line;    /* output buffer array index */
  76.     int             line_count;    /* number of output lines */
  77.     int             strip;    /* trailing space strip index */
  78.     int             alt;    /* flag for alternate character set on input */
  79.     int             chr;    /* single character storage */
  80.     char            c;    /* temp storage */
  81.     char           *s;    /* pointer into an output buffer */
  82.  
  83.     /*
  84.      * file is processed by parts, delimited by \n, \r, \f or \033
  85.      * strings; splitting at \033 and \r handles \b in lines with printer
  86.      * control characters, specifically fwrd-half-line in output of 
  87.      * the "col -f" filter. 
  88.      */
  89.     do {
  90.         memset((char *) output, ' ', sizeof(output));
  91.         out_dex = -1;
  92.         max_dex = 0;
  93.         line = 0;
  94.         line_count = 0;
  95.  
  96.         /* slide through input line, dropping bs chars */
  97.         while ((chr = getchar())
  98.                && chr != EOF
  99.                && chr != '\033'
  100.                && chr != '\f'
  101.                && chr != '\n'
  102.                && chr != '\r') {
  103.             switch (chr) {
  104.             case '\b':
  105.                 /* cannot backup thru half or full newline */
  106.                 out_dex = (out_dex >= 0) ? --out_dex : -1;
  107.                 break;
  108.             case '\t':
  109.                 out_dex = ((out_dex + TABSIZE + 1) /
  110.                        TABSIZE) * TABSIZE - 1;
  111.                 break;
  112.             case SO:
  113.                 alt = ALT;
  114.                 break;
  115.             case SI:
  116.                 alt = 0;
  117.                 break;
  118.             case ' ':
  119.                 max_dex = (++out_dex > max_dex) ? out_dex : max_dex;
  120.                 break;
  121.             default:
  122.                 if ((max_dex = (++out_dex > max_dex) ? out_dex : max_dex) > LINESIZE) {
  123.                     fprintf(stderr, "nobs: line segment overflows buffer\n");
  124.                     exit(1);
  125.                 }
  126.                 for (line = 0; /* exit at break */ ; line++) {
  127.                     if (line == MAXOVER) {
  128.                         fprintf(stderr, "nobs: too many overstrikes\n");
  129.                         exit(1);
  130.                     }
  131.                     if (output[line][out_dex] == ' ') {
  132.                         /* flag alt char */
  133.                         output[line][out_dex] = chr | alt;
  134.                         if (line_count < line)
  135.                             line_count = line;
  136.                         /* for zero-width alt char */
  137.                         if (alt && chr >= 'r')
  138.                             out_dex = (out_dex >= 0) ? --out_dex : -1;
  139.                         break;    /* exit loop */
  140.                     }
  141.                 }
  142.             }
  143.         }        /* end (\n, \E, etc)-delimited processing */
  144.  
  145.         /* print the output buffers */
  146.         for (line = 0; line <= line_count; line++) {
  147.             strip = max_dex;
  148.             while (output[line][strip] == ' ' && strip >= 0)
  149.                 --strip;    /* strip trailing spaces */
  150.             ++strip;/* point past string end */
  151.             /*
  152.              * append line terminator (\r for line to be
  153.              * overwritten); only [789] for +-movt should follow
  154.              * ESC, and col preprocessing is assumed to have made
  155.              * each ESC part of a line terminator. 
  156.              */
  157.             if (line < line_count) {
  158.                 output[line][strip++] = '\r';
  159.             } else {
  160.                 if (chr == '\033') {
  161.                     output[line][strip++] = chr;
  162.                     chr = getchar();
  163.                 }
  164.                 output[line][strip++] = (chr == EOF) ? '\r' : chr;
  165.             }
  166.             output[line][strip] = '\0';
  167.             for (s = output[line]; *s; s++) {
  168.                 c = *s & ~ALT;    /* careful about sign
  169.                          * extension */
  170.                 if (*s & ALT && c > ' ') {
  171.                     putchar(SO);    /* output printable
  172.                              * alt char with SO-SI 
  173.                              * delimiters */
  174.                     putchar(c);
  175.                     putchar(SI);
  176.                 } else {
  177.                     putchar(c);
  178.                 }
  179.             }
  180.         }
  181.  
  182.     } while (chr != EOF);    /* end of file */
  183.     return (0);
  184. }                /* end of main */
  185.