home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume2 / uroff / uroff.c
C/C++ Source or Header  |  1986-11-30  |  5KB  |  201 lines

  1. /*T uroff - produce nroff underlining for not-so-smart printers */
  2. /*S introduction */
  3. /*H uroff ----------------------------------------------------------- **
  4. **
  5. ** uroff - produce underlining for nroff documents for printers that
  6. **            do not do backspacing.
  7. **
  8. ** This program was written to reduce frustration with the use of the
  9. ** Printronix P-series printers and nroff.  It was enough that we
  10. ** couldn't have bold, italics, or anything resembling correspondence
  11. ** or word-processing quality print.  But NO UNDERLINING either was too
  12. ** much.  This program works with any printer that can handle text
  13. ** followed by carriage return followed by some spaces and underscores.
  14. ** Like the P-series with an IGP!
  15. **
  16. ** This program is simple-minded, but quick.  It uses buffered I/O and
  17. ** classes characters into very simple categories.
  18. **
  19. ** usage: uroff [ file... ]
  20. **
  21. ** If no file names are specified, it will filter standard input.
  22. ** If a file name is dash (-), standard input will be read at that
  23. ** point.
  24. **
  25. ** Permission is granted for use and distribution, as long as you 
  26. ** include the following notice:
  27. **
  28. ** (c) 1985    Steven M. List
  29. **             Benetics Corporation, Mt. View, CA
  30. **             {cdp,greipa,idi,oliveb,sun,tolerant}!bene!luke!itkin
  31. **
  32. ** ------------------------------------------------------------------ */
  33. /*E*/
  34. #include    <stdio.h>
  35.  
  36. char    *pgm;
  37.  
  38. #ifdef BSD
  39. #define strrchr rindex
  40. #endif
  41. extern char *strrchr ();
  42. /*S main - control loop */
  43. /*Page Eject*/
  44. main (ac, av)
  45. int        ac;
  46. char    **av;
  47. {
  48.     register FILE    *in;            /* input stream                */
  49.  
  50.     /* ------------------------------------------------------------ */
  51.     /* set the basename of the program name for logging             */
  52.     /* ------------------------------------------------------------ */
  53.  
  54.     if (pgm = strrchr (av[0], '/')) pgm++;
  55.     else pgm = av[0];
  56.  
  57.     ac--; av++;
  58.  
  59.     /* ------------------------------------------------------------ */
  60.     /* arguments are file names - if none, use standard input       */
  61.     /* ------------------------------------------------------------ */
  62.  
  63.     if (ac == 0)
  64.     {
  65.         dofile (stdin);
  66.     }
  67.     else while (ac--)
  68.     {
  69.         if (!strcmp (*av, "-"))
  70.         {
  71.             in = stdin;
  72.         }
  73.         else if (!(in = fopen (*av, "r")))
  74.         {
  75.             fprintf (stderr,
  76.                 "%s: cannot open %s for read\n", pgm, *(av-1));
  77.         }
  78.  
  79.         av++;
  80.  
  81.         if (in)
  82.         {
  83.             dofile (in);
  84.             if (in != stdin) fclose (in);
  85.         }
  86.     }
  87.  
  88.     exit (0);
  89. }
  90. /*S dofile - process an input file */
  91. /*H dofile ***********************************************************
  92. *
  93. *                                   dofile
  94. *
  95. * Read each character from the input file.  Put it into the buffer
  96. * appropriate for the type.  Flush the buffers on newline or eof.
  97. *
  98. *********************************************************************/
  99. /*E*/
  100. dofile (stream)
  101. register FILE *stream;
  102. {
  103.     /* ------------------------------------------------------------ */
  104.     /* some convenient defines                                      */
  105.     /* ------------------------------------------------------------ */
  106.  
  107. #    define BUFSIZE 256
  108. #    define BACKSPACE '\b'
  109. #    define NEWLINE '\n'
  110. #    define FORMFEED '\f'
  111. #    define RETURN '\r'
  112. #    define UNDERSCORE '_'
  113. #    define TAB '\t'
  114. #    define SPACE ' '
  115. #    define NUL '\0'
  116.  
  117.     register unsigned char anyund = 0;
  118.     register unsigned char backup = 0;
  119.     register char    c;
  120.     register int    i;
  121.     register char    *tp;
  122.     register char    *up;
  123.  
  124.     char    tbuf[BUFSIZE];
  125.     char    ubuf[BUFSIZE];
  126.  
  127.     /* ------------------------------------------------------------ */
  128.     /* initialize BOTH buffers to all spaces                        */
  129.     /* ------------------------------------------------------------ */
  130.  
  131.     for (i = 0, tp = tbuf, up = ubuf; i < BUFSIZE; i++)
  132.         *(tp++) = *(up++) = SPACE;
  133.     tp = tbuf; up = ubuf;
  134.     
  135.     /* ------------------------------------------------------------ */
  136.     /* process each character in the input file                     */
  137.     /* ------------------------------------------------------------ */
  138.  
  139.     while ((c = getc (stream)) != EOF)
  140.     {
  141.         switch (c)
  142.         {
  143.             case    BACKSPACE:
  144.                 backup = 1;
  145.                 break;
  146.             case    UNDERSCORE:
  147.                 if (backup) *(up-1) = c;
  148.                 else
  149.                 {
  150.                     *up = c;
  151.                     up++; tp++;
  152.                 }
  153.                 anyund = 1;
  154.                 backup = 0;
  155.                 break;
  156.             case    NEWLINE:
  157.                 *tp = *up = NUL;
  158.                 fputs (tbuf, stdout);
  159.                 if (anyund)
  160.                 {
  161.                     putchar (RETURN);
  162.                     fputs (ubuf, stdout);
  163.                 }
  164.                 putchar (NEWLINE);
  165.                 anyund = 0;
  166.                 for (i = 0, tp = tbuf, up = ubuf; i < BUFSIZE; i++)
  167.                     *(tp++) = *(up++) = SPACE;
  168.                 tp = tbuf; up = ubuf;
  169.                 break;
  170.             case    SPACE:
  171.             case    TAB:
  172.             case    FORMFEED:
  173.                 *(up++) = *(tp++) = c;
  174.                 break;
  175.             default:
  176.                 if (backup) *(tp-1) = c;
  177.                 else
  178.                 {
  179.                     *tp = c;
  180.                     up++; tp++;
  181.                 }
  182.                 backup = 0;
  183.                 break;
  184.         }
  185.     }
  186.  
  187.     if (tp != tbuf)
  188.     {
  189.         *tp = *up = NUL;
  190.         fputs (tbuf, stdout);
  191.         if (anyund)
  192.         {
  193.             putchar (RETURN);
  194.             fputs (ubuf, stdout);
  195.         }
  196.         putchar (NEWLINE);
  197.     }
  198.  
  199.     return;
  200. }
  201.