home *** CD-ROM | disk | FTP | other *** search
/ The Developer Connection…ice Driver Kit for OS/2 3 / DEV3-D1.ISO / source / util2src / text2bm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-17  |  20.3 KB  |  354 lines

  1. /*============================================================================*
  2.  * module: text2bm.c - Text file to BookMaster source conversion.
  3.  *
  4.  * (C)Copyright IBM Corporation, 1990, 1991.              Brian E. Yoder
  5.  *
  6.  * This module contains code to convert ASCII text files to BookMaster
  7.  * source files.  Many characters must be converted to BookMaster
  8.  * symbols (for example: a ':' is converted to "&colon.").  Since the output
  9.  * lines may have many multiple-character symbol names in them, they are
  10.  * broken up (using the BookMaster continuation symbol) if necessary.
  11.  *
  12.  * For a complete list of BookMaster symbols, see IBM's "Publishing Systems
  13.  * BookMaster: User's Guide", Publication number SC34-5009.
  14.  *
  15.  * 07/19/90 - Created.
  16.  * 07/20/90 - Initial version of the text2bm() subroutine.
  17.  * 08/07/90 - Changed " " to "&rbl." for character code 32 (space).
  18.  * 02/05/91 - Changed ";" to "&semi.", since BookMaster sometimes interprets
  19.  *            a semicolon as a line break.  Added the double-line box chars,
  20.  *            left/right arrowheads (16, 17) , the up/down arrowheads (30, 31),
  21.  *            and the arrows (24-27).
  22.  * 02/14/91 - Changed character code 32 back to " " (space), to cut down on
  23.  *            the number of &rbl. strings and make the output file readable.
  24.  *            However, this means that if the last character in a line is a
  25.  *            space, we need to change it into "&rbl.".  Then, if the next
  26.  *            line begins with .ct (continuation), we won't lose those
  27.  *            trailing spaces and misalign the output line.  (This is what
  28.  *            I should have done for the 08/07/90 fix!)
  29.  * 04/03/91 - Ported from AIX to DOS C/2.
  30.  * 08/13/91 - Use BookMaster's &cont. instead of SCRIPT's .ct to handle line
  31.  *            continuation.  Also, change OUT_MAX from 132 to 62, making it
  32.  *            much shorter (a short value supposedly works better with &cont.).
  33.  *            I tried it with OUT_MAX = 72 (not including continuation symbol),
  34.  *            but it doesn't work: 72 is "too long".
  35.  * 10/08/91 - Expand tab characters instead of ignoring them.
  36.  * 10/17/91 - Added more symbols to the TextBM[] translation table.
  37.  *============================================================================*/
  38.  
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <string.h>
  42. #include <memory.h>
  43. #include <sys/types.h>
  44.  
  45. #include "util.h"
  46.  
  47. #define EXP_MAX 1024                /* Max. length of tab-expanded input line */
  48.  
  49. /*============================================================================*
  50.  * Function prototypes for subroutines used only by this module
  51.  *============================================================================*/
  52.  
  53. static int AddStr(char *, FILE *);
  54.  
  55. /*============================================================================*
  56.  * The OUT_MAX label defines the maximum number of characters to put into
  57.  * the line buffer.  If adding a string to the output file's line would cause
  58.  * this length to be exceeded, then the line is written to the output file and
  59.  * the next line is initialized with the continuation symbol
  60.  *
  61.  * The cont[] array contains SCRIPT's line continuation control word.
  62.  *
  63.  * The output line(s) are built in the line[] buffer.
  64.  *============================================================================*/
  65.  
  66. #define OUT_MAX   62                /* Maximum output line length */
  67.  
  68. static  char cont[] = "&cont.";     /* Continuation control symbol */
  69.  
  70. #define CONT_LEN (sizeof(cont) - 1) /* Length not including null term. byte */
  71.  
  72. static  uint linelen;               /* Current output line length */
  73.  
  74. static  char line[OUT_MAX +         /* Line buffer: text + symbols + */
  75.                   CONT_LEN +        /*              line continuation + */
  76.                   32];              /*              safety buffer! */
  77.  
  78. /*============================================================================*
  79.  * TextBM[] : ASCII CHARACTER-TO-STRING TRANSLATION TABLE.
  80.  *
  81.  * A character's 8-bit ASCII value is used as an index into this array.  The
  82.  * pointer at an index points to a string that will cause BookMaster to
  83.  * print the symbol.
  84.  *
  85.  * Note: This conversion array would be extremely tedious to edit with vi.
  86.  *============================================================================*/
  87.  
  88. static char *TextBM[256] = {
  89.  
  90. /*                    |                           |                           |                           |*/
  91. NULL         /* 0     |*/ , NULL         /* 1     |*/ , NULL         /* 2     |*/ , NULL         /* 3     |*/ ,
  92. NULL         /* 4     |*/ , NULL         /* 5     |*/ , NULL         /* 6     |*/ , NULL         /* 7     |*/ ,
  93. NULL         /* 8     |*/ , " "          /* 9 TAB |*/ , NULL         /* 10 LF |*/ , NULL         /* 11    |*/ ,
  94. ".pa"        /* 12 FF |*/ , NULL         /* 13 CR |*/ , NULL         /* 14    |*/ , "&sun."      /* 15   |*/ ,
  95. "&rahead."   /* 16   |*/ , "&lahead."   /* 17   |*/ , NULL         /* 18    |*/ , NULL         /* 19    |*/ ,
  96. NULL         /* 20    |*/ , NULL         /* 21    |*/ , NULL         /* 22    |*/ , NULL         /* 23    |*/ ,
  97. "&uarrow."   /* 24   |*/ , "&darrow."   /* 25   |*/ , "&rarrow."   /* 26    |*/ , "&larrow."   /* 27   |*/ ,
  98. NULL         /* 28    |*/ , NULL         /* 29    |*/ , "&uahead."   /* 30   |*/ , "&dahead."   /* 31   |*/ ,
  99.  
  100. " "       /* 32 space |*/ , "!"          /* 33  ! |*/ , "\""         /* 34  " |*/ , "#"          /* 35  # |*/ ,
  101. "$"          /* 36  $ |*/ , "&percent."  /* 37  % |*/ , "&."      /* 38  & |*/ , "'"          /* 39  ' |*/ ,
  102. "("          /* 40  ( |*/ , ")"          /* 41  ) |*/ , "*"          /* 42  * |*/ , "+"          /* 43  + |*/ ,
  103. ","          /* 44  , |*/ , "-"          /* 45  - |*/ , "&period."   /* 46  . |*/ , "/"          /* 47  / |*/ ,
  104. "0"          /* 48  0 |*/ , "1"          /* 49  1 |*/ , "2"          /* 50  2 |*/ , "3"          /* 51  3 |*/ ,
  105. "4"          /* 52  4 |*/ , "5"          /* 53  5 |*/ , "6"          /* 54  6 |*/ , "7"          /* 55  7 |*/ ,
  106. "8"          /* 56  8 |*/ , "9"          /* 57  9 |*/ , "&colon."    /* 58  : |*/ , "&semi."     /* 59  ; |*/ ,
  107. "<"          /* 60  < |*/ , "="          /* 61  = |*/ , ">"          /* 62  > |*/ , "?"          /* 63  ? |*/ ,
  108.  
  109. "@"          /* 64  @ |*/ , "A"          /* 65  A |*/ , "B"          /* 66  B |*/ , "C"          /* 67  C |*/ ,
  110. "D"          /* 68  D |*/ , "E"          /* 69  E |*/ , "F"          /* 70  F |*/ , "G"          /* 71  G |*/ ,
  111. "H"          /* 72  H |*/ , "I"          /* 73  I |*/ , "J"          /* 74  J |*/ , "K"          /* 75  K |*/ ,
  112. "L"          /* 76  L |*/ , "M"          /* 77  M |*/ , "N"          /* 78  N |*/ , "O"          /* 79  O |*/ ,
  113. "P"          /* 80  P |*/ , "Q"          /* 81  Q |*/ , "R"          /* 83  R |*/ , "S"          /* 83  S |*/ ,
  114. "T"          /* 84  T |*/ , "U"          /* 85  U |*/ , "V"          /* 86  V |*/ , "W"          /* 87  W |*/ ,
  115. "X"          /* 88  X |*/ , "Y"          /* 89  Y |*/ , "Z"          /* 90  Z |*/ , "&lbrk."     /* 91  [ |*/ ,
  116. "&bsl."      /* 92  \ |*/ , "&rbrk."     /* 93  ] |*/ , "&caret."    /* 94  ^ |*/ , "_"          /* 95  _ |*/ ,
  117.  
  118. "&grave."    /* 96  ` |*/ , "a"          /* 97  a |*/ , "b"          /* 98  b |*/ , "c"          /* 99  c |*/ ,
  119. "d"          /* 100 d |*/ , "e"          /* 101 e |*/ , "f"          /* 102 f |*/ , "g"          /* 103 g |*/ ,
  120. "h"          /* 104 h |*/ , "i"          /* 105 i |*/ , "j"          /* 106 j |*/ , "k"          /* 107 k |*/ ,
  121. "l"          /* 108 l |*/ , "m"          /* 109 m |*/ , "n"          /* 110 n |*/ , "o"          /* 111 o |*/ ,
  122. "p"          /* 112 p |*/ , "q"          /* 111 q |*/ , "r"          /* 114 r |*/ , "s"          /* 115 s |*/ ,
  123. "t"          /* 116 t |*/ , "u"          /* 117 u |*/ , "v"          /* 118 v |*/ , "w"          /* 119 w |*/ ,
  124. "x"          /* 120 x |*/ , "y"          /* 121 y |*/ , "z"          /* 122 z |*/ , "&lbrc."     /* 123 { |*/ ,
  125. "&bxv."      /* 124 | |*/ , "&rbrc."     /* 125 } |*/ , "&tilde."    /* 126 ~ |*/ , "&similar."  /* 127   |*/ ,
  126.  
  127. "&Cc."       /* 128 Ç |*/ , "&ue."       /* 129 ü |*/ , "&ea."       /* 130 é |*/ , "&ac."       /* 131 â |*/ ,
  128. "&ae."       /* 132 ä |*/ , "&ag."       /* 133 à |*/ , "&ao."       /* 134 å |*/ , "&cc."       /* 135 ç |*/ ,
  129. "&ec."       /* 136 ê |*/ , "&ee."       /* 137 ë |*/ , "&eg."       /* 138 è |*/ , "&ie."       /* 139 ï |*/ ,
  130. "&ic."       /* 140 î |*/ , "&ig."       /* 141 ì |*/ , "&Ae."       /* 142 Ä |*/ , "&Ao."       /* 143 Å |*/ ,
  131. "&Ea."       /* 144 É |*/ , "æ."    /* 145 æ |*/ , "Æ."    /* 146 Æ |*/ , "&oc."       /* 147 ô |*/ ,
  132. "&oe."       /* 148 ö |*/ , "&og."       /* 149 ò |*/ , "&uc."       /* 150 û |*/ , "&ug."       /* 151 ù |*/ ,
  133. "&ye."       /* 152 ÿ |*/ , "&Oe."       /* 153 Ö |*/ , "&Ue."       /* 154 Ü |*/ , "¢."     /* 155 ¢ |*/ ,
  134. "&Lsterling."/* 156 £ |*/ , "¥."      /* 157 ¥ |*/ , "&peseta."   /* 158 ₧ |*/ , "&fnof."     /* 159 ƒ |*/ ,
  135.  
  136. "&aa."       /* 160 á |*/ , "&ia."       /* 161 í |*/ , "&oa."       /* 162 ó |*/ , "&ua."       /* 163 ú |*/ ,
  137. "&nt."       /* 164 ñ |*/ , "&Nt."       /* 165 Ñ |*/ , "&aus."      /* 166 ª |*/ , "&ous."      /* 167 º |*/ ,
  138. "&invq."     /* 168 ¿ |*/ , "&lnotrev."  /* 169 ⌐ |*/ , "&lnot."     /* 170 ¬ |*/ , "½."   /* 171 ½ |*/ ,
  139. "¼."   /* 172 ¼ |*/ , "&inve."     /* 173 ¡ |*/ , "&odqf."     /* 174 « |*/ , "&cdqf."     /* 175 » |*/ ,
  140. "&box14."    /* 176 ░ |*/ , "&box12."    /* 177 ▒ |*/ , "&box34."    /* 178 ▓ |*/ , "&bxv."      /* 179 │ |*/ ,
  141. "&bxri."     /* 180 ┤ |*/ , "&bx1012."   /* 181   |*/ , "&bx2021."   /* 182   |*/ , "&bx0021."   /* 183   |*/ ,
  142. "&bx0012."   /* 184   |*/ , "&bx2022."   /* 185   |*/ , "&bx2020."   /* 186   |*/ , "&bx0022."   /* 187   |*/ ,
  143. "&bx2002."   /* 188   |*/ , "&bx2001."   /* 189   |*/ , "&bx1002."   /* 190   |*/ , "&bxur."     /* 191 ┐ |*/ ,
  144.  
  145. "&bxll."     /* 192 └ |*/ , "&bxas."     /* 193 ┴ |*/ , "&bxde."     /* 194 ┬ |*/ , "&bxle."     /* 195 ├ |*/ ,
  146. "&bxh."      /* 196 ─ |*/ , "&bxcr."     /* 197 ┼ |*/ , "&bx1210."   /* 198   |*/ , "&bx2120."   /* 199   |*/ ,
  147. "&bx2200."   /* 200   |*/ , "&bx0220."   /* 201   |*/ , "&bx2202."   /* 202   |*/ , "&bx0222."   /* 203   |*/ ,
  148. "&bx2220."   /* 204   |*/ , "&bx0202."   /* 205   |*/ , "&bx2222."   /* 206   |*/ , "&bx1202."   /* 207   |*/ ,
  149. "&bx2101."   /* 208   |*/ , "&bx0212."   /* 209   |*/ , "&bx0121."   /* 210   |*/ , "&bx2100."   /* 211   |*/ ,
  150. "&bx1200."   /* 212   |*/ , "&bx0210."   /* 213   |*/ , "&bx0120."   /* 214   |*/ , "&bx2121."   /* 215   |*/ ,
  151. "&bx1212."   /* 216   |*/ , "&bxlr."     /* 217 ┘ |*/ , "&bxul."     /* 218 ┌ |*/ , "&BOX."      /* 219 █ |*/ ,
  152. "&BOXBOT."   /* 220 ▄ |*/ , "&BOXLEFT."  /* 221 ▌ |*/ , "&BOXRIGHT." /* 222 ▐ |*/ , "&BOXTOP."   /* 223 ▀ |*/ ,
  153.  
  154. "&alpha."    /* 224 α |*/ , "&beta."     /* 225 ß |*/ , "&Gamma."    /* 226 Γ |*/ , "&pi."       /* 227 π |*/ ,
  155. "&Sigma."    /* 228 Σ |*/ , "&sigma."    /* 229 σ |*/ , "&mu."       /* 230 µ |*/ , "&tau."      /* 231 τ |*/ ,
  156. "&Phi."      /* 232 Φ |*/ , "&Theta."    /* 233 Θ |*/ , "&Omega."    /* 234 Ω |*/ , "&delta."    /* 235 δ |*/ ,
  157. "&infinity." /* 236 ∞ |*/ , "&phi."      /* 237 φ |*/ , "&memberof." /* 238 ε |*/ , "&intersect."/* 239 ∩ |*/ ,
  158. "&identical."/* 240 ≡ |*/ , "&pm."       /* 241 ± |*/ , "&ge."       /* 242 ≥ |*/ , "&le."       /* 243 ≤ |*/ ,
  159. "&inttop."   /* 244 ⌠ |*/ , "&intbot."   /* 245 ⌡ |*/ , "&div."      /* 246 ÷ |*/ , "&nearly."   /* 247 ≈ |*/ ,
  160. "&sup0."     /* 248 ° |*/ , "&lmultdot." /* 249 ∙ |*/ , "&smultdot." /* 250 · |*/ , "&sqrt."     /* 251 √ |*/ ,
  161. "&supn."     /* 252 ⁿ |*/ , "²."     /* 253 ² |*/ , "&sqbul."    /* 254 ■ |*/ , "&rbl."      /* 255   |*/
  162.  
  163. };
  164.  
  165. /*============================================================================*
  166.  * text2bm() - Convert ASCII text to BookMaster source.
  167.  *
  168.  * PURPOSE:
  169.  *   This subroutine processes a text string that represents a single line,
  170.  *   converting each character (as needed) to its corresponding BookMaster
  171.  *   symbol and writing one or more lines to the ouput file 'bmfile'.
  172.  *
  173.  *   Of course, output file must be opened for writing (or appending).
  174.  *
  175.  * REMARKS:
  176.  *   This subroutine only works with 8-bit characters.  It uses the value of
  177.  *   a character as an index into the TextBM[] array to determine the string
  178.  *   that should be written to the output file.
  179.  *
  180.  *   If a NULL pointer is stored in the array, then nothing is written to the
  181.  *   output file for that character.  For normal characters (letters, numbers),
  182.  *   a one-character string is stored:  "a", "b", etc.  For other characters,
  183.  *   a BookMaster symbol string is stored: "&bxul.", "&colon.", etc.
  184.  *
  185.  *   Formfeed characters are replaced by the ".pa" SCRIPT control word.  For
  186.  *   this to work properly with SCRIPT, a formfeed character should exist in
  187.  *   the input text line all by itself.
  188.  *
  189.  *   The resulting output lines created by this subroutine should be bracketed
  190.  *   by the :xmp. and :exmp. BookMaster tags.
  191.  *
  192.  * RETURNS:
  193.  *   0, if successful.
  194.  *   1, if the output file is full.
  195.  *============================================================================*/
  196. int text2bm(textstr, bmfile)
  197.  
  198. char   *textstr;                    /* Input text string */
  199. FILE   *bmfile;                     /* Output BookMaster source file */
  200.  
  201. {
  202.   uint   idx;                       /* Counter used while expanding tabs */
  203.   char  *cpi;                       /* Character pointers to input, output, */
  204.   char  *cpo;                       /*    and end of output, used during tab */
  205.   char  *cpoend;                    /*    expansion */
  206.   uint   i;                         /* Index into conversion array */
  207.   uchar *text;                      /* Pointer to string of unsigned chars */
  208.   char  *str;                       /* Pointer to string */
  209.   char   intext[EXP_MAX+1];         /* Buffer to hold line w/tabs expanded */
  210.  
  211.   if (bmfile == NULL)               /* If output file is not open: */
  212.      return(1);                     /*    Return */
  213.  
  214.  /*------------------------------------------------------------------*
  215.   * Store 'textstr' in intext[], expanding any tabs that are found
  216.   *------------------------------------------------------------------*/
  217.  
  218.   idx = 0;                          /* Initialize tab expansion counter */
  219.   cpi = textstr;                    /* Point cpi to start of input text string */
  220.   cpo = intext;                     /* Point cpo to start of expanded text buffer */
  221.   cpoend = cpo + EXP_MAX;           /* Point just past end of output text */
  222.  
  223.   for (;;)                          /* Loop to copy, and expand tabs: */
  224.   {
  225.      if (cpo >= cpoend) break;           /* Quit if output intext[] is full */
  226.  
  227.      if (idx != 0)                       /* If idx != 0: We're expanding tabs: */
  228.      {
  229.         *cpo = ' ';                           /* Store space in output */
  230.         cpo++;                                /* Bump output pointer */
  231.         idx--;                                /* Decrement tab count */
  232.         continue;                             /* Repeat loop */
  233.      }
  234.  
  235.      if (*cpi == '\t')                   /* If input character is a tab: */
  236.      {
  237.         idx = 7-((cpo-intext)%8);             /* Modulo division for tab count */
  238.         *cpo = ' ';                           /* Store space in output */
  239.      }
  240.      else                                /* Else: Input character is NOT a tab: */
  241.      {
  242.         *cpo = *cpi;                          /* Simply copy character */
  243.         if (*cpo == '\0') break;              /* Stop if at end of input */
  244.      }
  245.  
  246.      cpi++;                              /* Step input char position */
  247.      cpo++;                              /* And step output character position */
  248.   } /* end of for loop to copy and expand tabs */
  249.  
  250.  /*------------------------------------------------------------------*
  251.   * Write the intext[] array's characters to the output file, and
  252.   * convert any special characters to BookMaster symbols, according
  253.   * to the TextBM[] conversion array.
  254.   *------------------------------------------------------------------*/
  255.  
  256.   line[0] = '\0';                   /* Store null string in line buffer */
  257.   linelen = 0;                      /* And set its length to zero */
  258.  
  259.   text = intext;                    /* Set of unsigned char pointer, then: */
  260.   for (;;)                          /* For each character in input text string: */
  261.   {
  262.      i = *text;                          /* Store character in index variable */
  263.      if (i == 0) break;                  /* If character is null: end-of-string */
  264.      text++;                             /* Point to next char in text string */
  265.  
  266.      str = TextBM[i];                    /* Point to text string for character */
  267.      if (str == NULL) continue;          /* If none: Continue with next char */
  268.  
  269.      i = AddStr(str, bmfile);            /* Add the string to output */
  270.      if (i != 0) return(1);              /* If error: return with error */
  271.   }                                 /* end of for loop */
  272.  
  273.   strcat(line, "\n");               /* Add newline to end of line buffer */
  274.   linelen += 1;                     /* and increment line length */
  275.   i = fwrite(line, 1, linelen,      /* Write line buffer to output file */
  276.              bmfile);
  277.  
  278.   if (i == 0)                       /* If error: */
  279.     return(1);                           /* Return with error */
  280.   else                              /* Otherwise: */
  281.     return(0);                           /* Return successfully */
  282. }
  283.  
  284. /*============================================================================*
  285.  * AddStr() - Add string to output.
  286.  *
  287.  * PURPOSE:
  288.  *   This subroutine adds the string 'str' to the output line buffer defined
  289.  *   by the static 'line[]' array.  If adding 'str' would make the length
  290.  *   of the 'line[]' string larger than OUT_MAX, the current 'line[]' array
  291.  *   is first written to the output file and nulled before adding 'str'.
  292.  *
  293.  * RETURNS:
  294.  *   0 if successful, 1 if error.
  295.  *
  296.  * NOTES:
  297.  *   This subroutine also takes care of adding the correct line continuation
  298.  *   commands.
  299.  *
  300.  *   If the .ct control word is used, then it must be added to the beginning
  301.  *   of the next line.  If the last character on the current line is a space,
  302.  *   it must be converted to &rbl. to keep it from becoming truncated when
  303.  *   the file is uploaded and processed.
  304.  *
  305.  *   If the &cont. symbol is used (recommended with BookMaster), then it must
  306.  *   be added to the end of the current line.  However, the output lines must
  307.  *   be kept "short", the exact definition of short being unknown and
  308.  *   experimentally determined.
  309.  *
  310.  *   It was recommended to me to use &cont. instead of .ct with BookMaster.
  311.  *   Every once in a while, I have found that .ct produces slightly incorrect
  312.  *   results.
  313.  *============================================================================*/
  314.  
  315. static int AddStr(str, file)
  316.  
  317. char   *str;                        /* Pointer to string */
  318. FILE   *file;                       /* Output file */
  319.  
  320. {
  321.   register int len;                 /* Length */
  322.   int   i;                          /* Generic integer */
  323.   char *lastch;                     /* Pointer to last character in line */
  324.  
  325.   len = strlen(str);                /* Find length of string */
  326.   if ((linelen + len) > OUT_MAX)    /* If str would make line too long: */
  327.   {
  328. //   lastch = line + linelen - 1;        /* Point to last character in line */
  329. //   if (*lastch == ' ')                 /* If the last character is a space: */
  330. //   {
  331. //      strcpy(lastch, "&rbl.");              /* Replace it with space symbol */
  332. //      linelen = strlen(line);               /* And update line length */
  333. //   }
  334.  
  335.      strcat(line, cont);                 /* Add line with continuation symbol word */
  336.      strcat(line, "\n");                 /* Add newline char to line */
  337.      linelen = strlen(line);             /* Update line length */
  338.  
  339.      i = fwrite(line, 1,                 /* Write line buffer to output file */
  340.                 linelen,
  341.                 file);
  342.      if (i == 0) return(1);              /* Be sure write was ok */
  343.  
  344.      line[0] = '\0';                     /* Reset line buffer/length to null */
  345. //   strcat(line, cont);                 /* Start line with continuation control word */
  346.      linelen = 0;                        /* And set its length */
  347.   }
  348.  
  349.   strcat(line, str);                /* Add str to end of line */
  350.   linelen += len;                   /* And update line length */
  351.  
  352.   return(0);                        /* Return */
  353. }
  354.