home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume27 / psf3 / part05 / psfbs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-20  |  6.0 KB  |  251 lines

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