home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 181_01 / libes.c < prev    next >
Encoding:
Text File  |  1986-01-07  |  6.8 KB  |  195 lines

  1.  
  2. Reprinted from: Micro/Systems Journal, Volume 1. No. 2. May/June 1985
  3. Article Title: "C Forum - Writing A Translation Program In C"
  4. Author: Alex Soya
  5. -----------------------------------------------------------------
  6. Copy of back issue may be obtained for $4.50 (foreign $6) from:
  7. Subscriptions: $20/yr & $35/2 yrs domestic; published bimonthly
  8. Micro/Systems Journal
  9. Box 1192
  10. Mountainside NJ 07092
  11. -----------------------------------------------------------------
  12. Copyright 1986
  13. Micro/Systems Journal, Box 1192, Mountainside NJ 07092
  14. This software is released into the public domain for
  15.  non-commercial use only.
  16. -----------------------------------------------------------------
  17.  
  18. ▒  #includσ <stdio.h>
  19. 2  #include <ctype.h>
  20.  
  21. 4  #define TRUE        1
  22. 5  #define FALSE        0
  23.  
  24. 7  #define NL        '\n'
  25. 8  #define CR        '\r'
  26. 9  #define SOFT_HYPHEN    0x1f    /* inserted to break words at eol */
  27.  
  28. 11  #define TABSIZE    8
  29.  
  30. 13  #define CONTROL(x)    ((x)-'a')
  31. 14  #define BOLD    (CONTROL('b'))
  32. 15  #define SUPERSCRIPT    (CONTROL('t'))
  33. 16  #define SUBSCRIPT    (CONTROL('v'))
  34. 17  #define UNDERSCORE    (CONTROL('s'))
  35.  
  36. 19  #define BOLD_BEGIN        "<<<"
  37. 20  #define BOLD_END        ">>>"
  38. 21  #define UNDERSCORE_BEGIN    "<_"
  39. 22  #define UNDERSCORE_END    "_>"
  40. 23  #define SUBSCRIPT_BEGIN    "<<"
  41. 24  #define SUBSCRIPT_END    ">>"
  42. 25  #define SUPERSCRIPT_BEGIN    "<^"
  43. 26  #define SUPERSCRIPT_END    "^>"
  44.  
  45. 28  typedef int boolean;
  46.  
  47. 30  int column;        /* column to output next character */
  48. 31  int c;              /* last character read */
  49.  
  50. 33  boolean superscript = FALSE;/* if superscripting */
  51. 34  boolean subscript = FALSE;    /* if subscripting */
  52. 35  boolean bold = FALSE;    /* if emboldening */
  53. 36  boolean underscore = FALSE;    /* if underscoring */
  54. 37  boolean msb_was_set;    /* if char most significant bit set */
  55. 38  boolean soft_space = FALSE;    /* if between words and have seen */
  56. 39                  /* soft space, but no other spaces */
  57. 40  boolean soft_hyphen = FALSE;/* if in the middle of a word that */
  58. 41                  /* was hyphenated by ws */
  59. 42  boolean dotcmd = FALSE;    /* if in the middle of a dot cmd */
  60. 43  boolean wrap_soon = FALSE;    /* if should wrap as soon as we get */
  61. 44                  /* to the end of the current word */
  62.  
  63. 46  int spacerun = 0;        /* number of spaces seen in a row */
  64.  
  65. 48  main() {
  66. 49      while (TRUE) {
  67. 50          /* look at single characters */
  68. 51          msb_was_set = FALSE;
  69. 52          if (EOF == (c = getchar())) break;
  70. 53          if (!isascii(c)) {    /* is most sig. bit set? */
  71. 54              c = toascii(c);    /* turn of most sig. bit */
  72. è55              msb_was_set = TRUE;
  73. 56          }
  74. 57          if (c == CR) continue; /* always followed by an NL */
  75. 58          if (c == NL) {
  76. 59              if (soft_hyphen) {
  77. 60                  wrap_soon = TRUE;
  78. 61              } else newline();
  79. 62          } else if (dotcmd) {
  80. 63              /* throw away chars if we are in a dot command */
  81. 64              continue;
  82. 65          } else if (c == ' ') {
  83. 66              /* ignore blanks with msb set - they are soft */
  84. 67              if (!msb_was_set) {    /* a real space */
  85. 68                  soft_space = FALSE;
  86. 69                  spacerun++;
  87. 70                  column++;
  88. 71                  if (wrap_soon) { /* wrap now! */
  89. 72                      newline();
  90. 73                      wrap_soon = FALSE;
  91. 74                  }
  92. 75              } else soft_space = TRUE;
  93. 76          } else if (c == SOFT_HYPHEN) {
  94. 77              /* ignore hyphens with msb set - they are soft */
  95. 78              soft_hyphen = TRUE;
  96. 79          } else if (c == '.' && column == 0) {
  97. 80              /* text processing directive */
  98. 81              dotcmd = TRUE;
  99. 82          } else if (iswscntrl(c)) {
  100. 83              /* ignore wordstar print control characters */
  101. 84              /* e.g. ^S (underscore), ^B (bold) */
  102. 85              wscntrl(c);
  103. 86          } else if (iscntrl(c)) {
  104. 87              /* unknown control character - ignore */
  105. 88              continue;
  106. 89          } else { /* normal character */
  107. 90              /* if we encountered a soft space, stick in at */
  108. 91              /* least one space */
  109. 92              if (soft_space) {
  110. 93                  spacerun = 1;
  111. 94                  column++;
  112. 95                  soft_space = FALSE;
  113. 96              }
  114. 97              if (spacerun) { /* beginning of word */
  115. 98                  /* calculate tabs and blanks to lay down */
  116. 99          space_out(column-spacerun,column);
  117. 100                  spacerun = 0;
  118. 101              }
  119. 102              putchar(c);
  120. 103              column++;
  121. 104          }
  122. 105      }
  123. 106  }
  124.  
  125. 108  /* print least number of spaces & tabs to move from "oldpos" */
  126.  
  127. 109  /* to "newpos" */
  128. è110  space_out(oldpos,curpos)
  129. 111  int oldpos;    /* old position */
  130. 112  int newpos;    /* new position */
  131. 113  {
  132. 114      int spaces, tabs;   /* number of spaces & tabs to print */
  133. 115      int i;
  134.  
  135. 117      if (oldpos >= newpos) return;    /* no space in between */
  136.  
  137. 119      /* first calculate tabs */
  138. 120      tabs = newpos/TABSIZE - oldpos/TABSIZE;
  139.  
  140. 122      /* now calulate spaces */
  141. 123      /* if old & new at same tab stop, its just difference */
  142. 124      if (tabs == 0) spaces = newpos - oldpos;
  143. 125      /* if not, then its remainder from nearest tab stop */
  144. 126      else spaces = newpos % TABSIZE;
  145.  
  146. 128      for (i=0;i<tabs;i++) putchar('\t');
  147. 129      for (i=0;i<spaces;i++) putchar(' ');
  148. 130  }
  149.  
  150. 132  /* true if wordstar control character */
  151. 133  boolean
  152. 134  iswscntrl(c)
  153. 135  int c;
  154. 136  {
  155. 137      if ((c == BOLD) ||
  156. 138         (c == UNDERSCORE) ||
  157. 139         (c == SUPERSCRIPT) ||
  158. 140         (c == SUBSCRIPT)) return(TRUE);
  159. 141      else return(FALSE);
  160. 142  }
  161.  
  162. 144  newline()
  163. 145  {
  164. 146      if (!dotcmd) putchar('\n');
  165. 147      column = 0;
  166. 148      spacerun = 0;
  167. 149      dotcmd = FALSE;
  168. 150  }
  169.  
  170. 152  wscntrl(c)
  171. 153  char c;
  172. 154  {
  173. 155      switch (c) {    /* print control character */
  174. 156      case BOLD:
  175. 157          if (bold) printf(BOLD_END);
  176. 158          else printf(BOLD_BEGIN);
  177. 159          bold = !bold;
  178. 160          break;
  179. 161      case UNDERSCORE:
  180. 162          if (underscore) printf(UNDERSCORE_END);
  181. 163          else printf(UNDERSCORE_BEGIN);
  182. 164          underscore = !underscore;
  183. è165          break;
  184. 166      case SUBSCRIPT:
  185. 167          if (subscript) printf(SUBSCRIPT_END);
  186. 168          else printf(SUBSCRIPT_BEGIN);
  187. 169          subscript = !subscript;
  188. 170          break;
  189. 171      case SUPERSCRIPT:
  190. 172          if (superscript) printf(SUPERSCRIPT_END);
  191. 173          else printf(SUPERSCRIPT_BEGIN);
  192. 174          superscript = !superscript;
  193. 175          break;
  194. 176      default:
  195. 177          /* unknown - ignore for now */
  196. 178          break;
  197. 179      }
  198. 180  }
  199.