home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / c_spec / execute / ptext.c < prev    next >
Text File  |  1986-02-20  |  4KB  |  163 lines

  1. #include <stdio.h>
  2.  
  3. /*
  4.  *          PTEXT.C: Multi-column print utility
  5.  *
  6.  *      Copyright (c) 1985 Allen I. Holub,  all rights reserved.
  7.  *    This program may be reproduced for personal, non-profit use only
  8.  *
  9.  *    Bugs and Features:
  10.  *
  11.  *    1) Pr_line assumes that the output device supports backspace
  12.  *       ('\b' == ^H ).   This is only a problem when  the  source
  13.  *       has underlined text implemented as:
  14.  *            texttexttext\r   _______
  15.  *       We can't just ouput a '\r' in this case because we may
  16.  *       not be in the leftmost column. A \r should get us to the
  17.  *       left edge of the current column.
  18.  *
  19.  *    2) When printing multi-column stuff. If a line is truncated it
  20.  *       will run into the column to its right. That is, there is no
  21.  *       seperator between columns other than the  whitespace needed
  22.  *       to pad the column out to a particular width. If no  padding
  23.  *       is necessary (ie. the lines have been truncated), then  the
  24.  *       columns will run together.
  25.  *
  26.  *    3) When an ESC is found, the escape and the next three characters
  27.  *       take up no space in the output. This lets us print out the
  28.  *       various SGR commands without messing up the column width.
  29.  *
  30.  *    4) Strange things happen to an IBM screen when the leftmost
  31.  *       character on a line is printed with underline. To compensate
  32.  *       for this, a single blank is printed as the left-most
  33.  *       character on every line if IBM is #defined.
  34.  */
  35.  
  36. #define ESC    0x1b
  37. #define IBM    1
  38.  
  39. /*----------------------------------------------------------------------*/
  40.  
  41. ptext(linec, linev, outfile, numcols, colwidth, numrows)
  42. int    linec, numcols, colwidth;
  43. char    **linev;
  44. FILE    *outfile;
  45. int    numrows;
  46. {
  47.     /*    Print out the array of strings "linev" which consists of
  48.      *    linec entrys. Output is sent to "outfile" formated as
  49.      *    follows:
  50.      *
  51.      *    "numcols"  : number of columns
  52.      *    "colwidth" : width of a column in characters. Any text
  53.      *            longer than colwidth is truncated off.
  54.      *    "numrows"  : columns are numrows long. The left-most
  55.      *            column is printed in its entirety
  56.      *            first then the next column in its
  57.      *            entirety, and so on.
  58.      */
  59.  
  60.     register int    j ;
  61.     register char    **lineend, **line, **nextline ;
  62.  
  63.     lineend = &linev[linec-1];    /* Last linev entry to print    */
  64.  
  65.     for( j = numrows ; --j >= 0 ; )
  66.     {
  67. #ifdef IBM
  68.         putc( ' ', outfile );
  69. #endif
  70.         for( line = linev++;  line <= lineend; line = nextline)
  71.         {
  72.             nextline = line + numrows;
  73.  
  74.             /*   Print the line. Don't pad the rightmost    */
  75.             /*   column.                    */
  76.                                     
  77.             pr_line( *line, outfile, colwidth,
  78.                         nextline <= lineend);
  79.         }
  80.  
  81.         fputs("\n" , outfile);
  82.     }
  83. }
  84.  
  85. /*----------------------------------------------------------------------*/
  86.  
  87. static pr_line( str, stream, width, padded )
  88. register char    *str;
  89. FILE        *stream;
  90. int        width, padded;
  91. {
  92.     /*     Print out "str" into "stream" padding it to "width"
  93.      * columns wide. Non-printing characters and 3 printing characters
  94.      * immediatly following an ESC are not counted as having printed.
  95.      * '\n' characters are treated as line teminators but are not
  96.      * printed. If "padded" is 0 then no padding is done, though the
  97.      * line will still be truncated if it's too long.
  98.      */
  99.  
  100.     int    col = 0 ;
  101.  
  102.     while( col < width  &&  *str )
  103.     {
  104.         if ( *str == '\n' )
  105.             break;
  106.  
  107.         else if( *str == '\r' )
  108.         {
  109.             /* Back up to the left edge of the current column
  110.              */
  111.  
  112.             while( col >  0 )
  113.             {
  114.                 --col;
  115.                 putc('\b' , stream);
  116.             }
  117.  
  118.             str++;
  119.         }
  120.         else if( *str == '\t' )        /* expand tabs */
  121.         {
  122.             str++ ;
  123.             col++ ;
  124.             putc( ' ' , stream );
  125.  
  126.             while( (col % 8)  &&  col < width)
  127.             {
  128.                 putc( ' ' , stream );
  129.                 col++;
  130.             }
  131.         }
  132.         else
  133.         {
  134.             if( *str == ESC )
  135.             {
  136.                 putc( *str++ , stream );
  137.                 if( !*str )
  138.                     break;
  139.  
  140.                 putc( *str++ , stream );
  141.                 if( !*str )
  142.                     break;
  143.  
  144.                 putc( *str++ , stream );
  145.                 if( !*str )
  146.                     break;
  147.             }
  148.             
  149.             else if (*str == '\b')
  150.                 --col ;
  151.  
  152.             else if( *str >= ' ' )
  153.                 ++col ;
  154.  
  155.             putc( *str++ , stream );
  156.         }
  157.     }
  158.  
  159.     if (padded)
  160.         while( col++  <  width )
  161.             putc( ' '  , stream );
  162. }
  163.