home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / snip9707.zip / W_WRAP.C < prev    next >
C/C++ Source or Header  |  1997-07-05  |  5KB  |  140 lines

  1. /* +++Date last modified: 05-Jul-1997 */
  2.  
  3. /* w_wrap.c */
  4.  
  5. /*
  6. **  This is an attempt at a useful word-wrap function.  It is given an array
  7. **  of characters ( a string ) and it modifies the string, replacing any
  8. **  new-lines found with spaces and placing new-lines where needed to make
  9. **  lines of the width specified, placing them only where there was previously
  10. **  white-space. ( ie. Words are not split across lines. )  At the present
  11. **  time it is rather stupid. 1) It doesn't know enough to split a line at an
  12. **  existing hyphen.  2) It has no clue about how to hyphenate words.  3) It
  13. **  makes no attempt at dealing intelligently with a singly word longer than
  14. **  the specified line length 4) It does not deal intelligently with multiple
  15. **  spaces new-lines, etc. ( eg. has no clue of paragraph separation, etc. )
  16. **  OTOH, it does deal well with unformatted, left justified text.
  17. **
  18. **  Tabs will be considered the size specified.  Note that word_wrap() does
  19. **  not actually expand tabs.  This is only to inform it of the number of
  20. **  spaces the output device will expand them to, so it will know how much
  21. **  they expand a line.  The only time word_wrap does anything with tabs, is
  22. **  if the tab size is set to zero, in which case each tab is replaced with a
  23. **  single space character.  This often provides the most useful output, since
  24. **  tabs will often be in the wrong places after re-formatting, and is
  25. **  therefor the default.
  26. **
  27. **
  28. **  Publicly available contents:
  29. **
  30. **      char *word_wrap(char *string,long line_len);
  31. **          Does the actual word-wrapping, as described above;
  32. **          Parameters:
  33. **            string:     actual string to work with
  34. **            line_len:   length of lines for output
  35. **          Returns:        pointer to justified string.
  36. **
  37. **          void set_tab_size(int size);
  38. **            Set the number of spaces that tabs will be expanded to on output
  39. **            default tab size is zero. (each tab replaced with a space char )
  40. **            word_wrap does not actually expand tabs.  This only lets it keep
  41. **            track of how many spaces they take up.  If this is set to
  42. **            zero, each tab will be replaced with a single space.
  43. **
  44. **  Other procedures:
  45. **      int get_word(char *string);
  46. **          returns the number of characters in the next word in string,
  47. **          including leading white-space characters.
  48. **
  49. **  This compiles without warnings and runs with the following compilers:
  50. **      MS Quick C 2.51:
  51. **      Borland C++ 2.0:            either as C or C++
  52. **      GNU C++ 1.39, DOS port:     either as C or C++
  53. **  As far as I know, it uses only portable, standard C constructs.  It should
  54. **  compile and run with little or no modification under nearly any C compiler
  55. **  and environment.
  56. **
  57. **
  58. **  This code was written Nov 16, 1991 by Jerry Coffin.
  59. **  It is hereby placed in the public domain, for free use by any and
  60. **  all who wish to do so, for any use, public, private, or commercial.
  61. */
  62.  
  63. #include <ctype.h>
  64. #include "w_wrap.h"
  65.  
  66. static int tab_size = 0;                  /* size to consider tabs as */
  67.  
  68. static size_t get_word(char *string);     /* returns size of next word*/
  69.  
  70. void set_tab_size(size_t size)
  71. {
  72.       tab_size = size;
  73. }
  74.  
  75. char *word_wrap(char *string, size_t line_len)
  76. {
  77.       size_t len,                         /* length of current word */
  78.              current_len = 0;             /* current length of line */
  79.       size_t start_line = 0;              /* index of beginning if line */
  80.  
  81.       while (0 != (len = get_word(&string[current_len + start_line])))
  82.       {
  83.             if (current_len + len < line_len)
  84.                   current_len += len;
  85.             else
  86.             {
  87.                   string[start_line+current_len] = '\n';
  88.                   start_line += current_len + 1;
  89.                   current_len = 0;
  90.             }
  91.       }
  92.       return string;
  93. }
  94.  
  95. static size_t get_word(char *string)
  96. {
  97.       register int i = 0, word_len = 0;
  98.  
  99.       if (!string[0])
  100.             return 0;
  101.       while (isspace(string[i]))
  102.       {
  103.             if ('\t' == string[i])
  104.             {
  105.                   if (0 == tab_size)
  106.                         string[i] = ' ';
  107.                   else  word_len += tab_size-1;
  108.             }
  109.             else if ('\n' == string[i])
  110.                   string[i]=' ';
  111.             word_len++;
  112.             i++;
  113.       }
  114.       while (string[i] && !isspace(string[i++]))
  115.             word_len++;
  116.       return word_len;
  117. }
  118.  
  119. #ifdef TEST
  120.  
  121. #include "w_wrap.h"
  122.  
  123. main()
  124. {
  125.       char *string =
  126.             "This is a long line\nto be wrapped by the w_wrap function. "
  127.             "Hopefully, things will work correctly and it will be wrapped "
  128.             "between words.  On the other hand, maybe I should hope that it "
  129.             "doesn't work well so I will have an opportunity\nto learn more "
  130.             "about what I'm doing";
  131.  
  132.       printf("Here's a string wrapped to 40 columns:\n\n%s\n\n",
  133.             word_wrap(string, 40));
  134.       printf("And here it's wrapped to 72:\n\n%s\n\n",
  135.             word_wrap(string,72));
  136.       return 0;
  137. }
  138.  
  139. #endif /* TEST */
  140.