home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume12 / psf2 / part03 / pnf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-19  |  6.1 KB  |  258 lines

  1. /* ta=4 */
  2. /****************************************************************************
  3. *                            p n f . c      v2.0                                *
  4. *                                                                            *
  5. *    postscript filter for nroff'ed text                                        *
  6. *                                                                            *
  7. *    Translate backspaces in nroff documents to either BOLD or UNDERLINE        *
  8. *    for psf usage                                                            *
  9. *                                                                            *
  10. *    Copyright: 1989-Feb, Tony Field.       tony@ajfcal                        *
  11. ****************************************************************************/
  12. /* revision history:
  13.  
  14.     1989-Jun-15        Added -l linecount. For nroff, suppress 3 blank lines 
  15.                     between nroff'ed pages.    
  16.                     
  17.                     Corrected a very stupid programming mistake with how[i-1].
  18.  
  19.                     Correct problem if "bold" is adjacent to "underline"
  20.  
  21.                     Removed -x option.  user must "man -b".
  22.  
  23.     1989-May-20        Allow input from multiple file names as well as stdin
  24. */
  25.  
  26. /*    For each line in of input text, scan for backspaces.  Determine if
  27.     the operation is an underline (i.e. the preceeding character is
  28.     the "_") or if it is a bolding (the character after the underscore
  29.     is the same as the preceeding.
  30.     
  31.     Generate the sequence \005B..text..\005b   for bold
  32.                           \005U..text..\005u   for underline
  33.                           \005I..text..\005i   for italics
  34.  
  35.     Since the text from nroff does not have a decent way of identifying
  36.     italics, you may make the decision to generate the "italic" or 
  37.     "underline" escape sequence  whenever an underline is detected in
  38.     the output.  Italic fonts look nicer than the underlines 2-up.
  39.  
  40.     The logic cannot handle bold-underlined (nor italic-underlined).
  41.     This could be done with a bit of extra logic to manipulate bits
  42.     in the "how" vector.
  43.  
  44.     For nroff, remove three blank lines between pages (an nroff'ed
  45.         document, letter size, has 66 lines.  the postscript
  46.         printer must see 63 lines.)   Assume that nroff is consistent.
  47.         If "point size" adjustments are made (e.g. some documents
  48.         originally intended for troff), then lines per page may not
  49.         be consistent.
  50.         
  51. */
  52.  
  53. #include <stdio.h>
  54. #include "psf.h"
  55. #include "patchlevel.h"
  56.  
  57. char    *pgmname;
  58.  
  59. main (argc, argv)
  60. int        argc;
  61. char    *argv[];
  62. {    int        i, c;
  63.     int        nroff_lines = 66;
  64.     int        remove = 3;
  65.     int        count_lines = 1;
  66.     char    *underline_on, *underline_off;
  67.     extern char *optarg;
  68.     extern int    optind;
  69.     FILE    *input_fp;
  70.     
  71.     pgmname = argv[0];
  72.     underline_on  = BEGIN_UNDERLINE;
  73.     underline_off = END_UNDERLINE;
  74.  
  75.     if (strcmp (argv[1], "-") == 0)
  76.         usage();
  77.     while ((c = getopt(argc, argv, "ifr:l:-")) != -1)
  78.     {    switch (c)
  79.         {
  80.         case 'i':
  81.             underline_on  = BEGIN_ITALICS;
  82.             underline_off = END_ITALICS;
  83.             break;
  84.         
  85.         case 'l':
  86.             nroff_lines = atoi (optarg);
  87.             break;
  88.             
  89.         case 'r':
  90.             remove = atoi (optarg);
  91.             break;
  92.             
  93.         case 'f':
  94.             count_lines = 0;
  95.             break;
  96.             
  97.         default:
  98.             usage ();
  99.         }
  100.     }
  101.     
  102.     if (optind >= argc)
  103.     {    input_fp = stdin;
  104.         print_file (input_fp, nroff_lines, remove, underline_on, underline_off, count_lines);
  105.     }
  106.     else
  107.     {
  108.         for (i = 0 ;  optind < argc;  optind++)
  109.         {    if ((input_fp = fopen (argv[optind], "r")) == NULL)
  110.             {    fprintf (stderr, "%s: File %s not found\n", pgmname, argv[optind]);
  111.             }
  112.             else
  113.             {    if (i)
  114.                     send ("\f");
  115.                 print_file (input_fp, nroff_lines, remove, underline_on, underline_off, count_lines);
  116.                 fclose (input_fp);
  117.                 i++;
  118.             }
  119.         }
  120.     }
  121.     exit (0);
  122.         
  123. }
  124.  
  125. print_file (fp, nroff_lines, remove, underline_on, underline_off, count_lines)
  126. FILE    *fp;
  127. int        nroff_lines;
  128. int        remove;
  129. int        count_lines;
  130. char    *underline_on, *underline_off;
  131. {
  132.     int        c, n, i;
  133.     int        how[401];
  134.     char    line[401];
  135.     char    buf[401];
  136.     int        ii;
  137.     int        nroff_count;
  138.     int        insert_two = 0;
  139.  
  140.     nroff_count = n = 0;
  141.     
  142.     clear (line, how, 400);
  143.     while (( c = fgetc (fp)) != EOF)
  144.     {
  145.         if (c == '\033')            /* if ESCAPE character, then handle */
  146.         {    if ((c = fgetc (fp)) == EOF)
  147.                 break;
  148.             if (c == '9')        /*    1/2 line space fwd                */
  149.             {    putchar (ESCAPE);
  150.                 putchar ('+');
  151.                 nroff_count += 5;
  152.                 continue;
  153.             }
  154.             else if (c == '8')        /*    1/2 line space back            */
  155.             {    putchar (ESCAPE);
  156.                 putchar ('-');
  157.                 nroff_count -= 5;
  158.                 continue;
  159.             }
  160.             else
  161.             {
  162.                 continue;
  163.             }
  164.         }
  165.             
  166.         else if (c == '\b')
  167.             n--;
  168.         else if (c == '\n')
  169.         {    if (count_lines)
  170.             {    /*    remove 3 blank lines between pages
  171.                     1 from beginning of page,
  172.                     2 from end of page.
  173.                 */
  174.                 nroff_count = (nroff_count + 10) % (nroff_lines * 10);
  175.                 if (nroff_count < 20  ||  nroff_count > (nroff_lines - (remove-1)) * 10)
  176.                     continue;
  177.             }
  178.             how[n] = 0;
  179.             line[n] = 0;
  180.             for (i = 0;  i <= n;  i++)
  181.             {
  182.                 if (how[i])
  183.                 {    /*    either bold or underlined see if previous char
  184.                         is not escaped - indicates the beginning of 
  185.                         an escape sequence.  may need to terminate
  186.                         previous sequence first (e.g. bold followed
  187.                         by underlined).
  188.                     */
  189.                     if (i > 0  &&  how[i-1]  &&  (how[i] != how[i-1]))
  190.                     {    if (how[i-1] == 1)
  191.                             send (END_BOLD);
  192.                         else
  193.                             send (underline_off);
  194.                     }
  195.                     if (how[i] == 1  &&  (i == 0  ||  how[i-1] != 1))
  196.                         send (BEGIN_BOLD);
  197.                     else if (how[i] == 2  &&  (i == 0  ||  how[i-1] != 2))
  198.                         send (underline_on);
  199.                 }
  200.                 else    /* zero means just a character, unmodified */
  201.                 {    /* are we at the end of an escape sequence? */
  202.                     if (i > 0)
  203.                     {    if (how[i-1] == 1)
  204.                             send (END_BOLD);
  205.                         else if (how[i-1] == 2)
  206.                             send (underline_off);
  207.                     }
  208.                 }
  209.                 if (line[i])
  210.                     putchar (line[i]);
  211.             }
  212.             putchar ('\n');    
  213.             clear (line, how, n);
  214.             n = 0;
  215.         }
  216.         else
  217.         {    if (line[n])
  218.             {    if (line[n] == c)        /* same character?        */
  219.                     how[n] = 1;            /*    yes:    bold        */
  220.                 else
  221.                     how[n] = 2;            /*    no:        underline    */
  222.             }
  223.             line[n++] = c;
  224.         }
  225.     }
  226. }
  227.  
  228. clear (line, how, n)
  229. char    *line;
  230. int        *how;
  231. int        n;
  232. {
  233.     int        i;
  234.     
  235.     for (i  = 0;  i <= n;  i++)
  236.     {    line[i] = '\0';
  237.         how[i] = 0;
  238.     }
  239. }
  240.  
  241. send (s)
  242. char    *s;
  243. {
  244.     while (*s)
  245.         putchar (*s++);
  246. }
  247.  
  248. usage ()
  249. {
  250.     fprintf (stderr, "Usage:   pnf [-i] [ -f ] [ -l n ] [ -r n ] file ... >out.file\n");
  251.     fprintf (stderr, " where        -i   = use italics in lieu of underline\n");
  252.     fprintf (stderr, "              -f   = document has form feeds, ignore line count\n");
  253.     fprintf (stderr, "              -l n = make n line nroff'ed documents fit\n");
  254.     fprintf (stderr, "              -r n = number of blank lines to remove\n");
  255.     fprintf (stderr, "             file = input files (or stdin)\n");
  256.     exit (0);    
  257. }
  258.