| 1 | /* $Id: reader.c,v 1.2 2000-08-02 14:58:40 bird Exp $ */ | 
|---|
| 2 | /* | 
|---|
| 3 | * - Need to document error code meanings. | 
|---|
| 4 | * - Need to do something with \* on destinations. | 
|---|
| 5 | * - Make the parameter a long? | 
|---|
| 6 | * | 
|---|
| 7 | * reader.c - RTF file reader.  Release 1.10. | 
|---|
| 8 | * | 
|---|
| 9 | * ASCII 10 (\n) and 13 (\r) are ignored and silently discarded. | 
|---|
| 10 | * Nulls are also discarded. | 
|---|
| 11 | * (although the read hook will still get a look at them.) | 
|---|
| 12 | * | 
|---|
| 13 | * "\:" is not a ":", it's a control symbol.  But some versions of | 
|---|
| 14 | * Word seem to write "\:" for ":".  This reader treats "\:" as a | 
|---|
| 15 | * plain text ":" | 
|---|
| 16 | * | 
|---|
| 17 | * 19 Mar 93 | 
|---|
| 18 | * - Add hack to skip "{\*\keycode ... }" group in stylesheet. | 
|---|
| 19 | * This is probably the wrong thing to do, but it's simple. | 
|---|
| 20 | * 13 Jul 93 | 
|---|
| 21 | * - Add THINK C awareness to malloc() declaration.  Necessary so | 
|---|
| 22 | * compiler knows the malloc argument is 4 bytes.  Ugh. | 
|---|
| 23 | * 07 Sep 93 | 
|---|
| 24 | * - Text characters are mapped onto standard codes, which are placed | 
|---|
| 25 | * in rtfMinor. | 
|---|
| 26 | * - Eliminated use of index() function. | 
|---|
| 27 | * 05 Mar 94 | 
|---|
| 28 | * - Added zillions of new symbols (those defined in RTF spec 1.2). | 
|---|
| 29 | * 14 Mar 94 | 
|---|
| 30 | * - Public functions RTFMsg() and RTFPanic() now take variable arguments. | 
|---|
| 31 | * This means RTFPanic() now is used in place of what was formerly the | 
|---|
| 32 | * internal function Error(). | 
|---|
| 33 | * - 8-bit characters are now legal, so they're not converted to \'xx | 
|---|
| 34 | * hex char representation now. | 
|---|
| 35 | * 01 Apr 94 | 
|---|
| 36 | * - Added public variables rtfLineNum and rtfLinePos. | 
|---|
| 37 | * - #include string.h or strings.h, avoiding strncmp() problem where | 
|---|
| 38 | * last argument is treated as zero when prototype isn't available. | 
|---|
| 39 | * 04 Apr 94 | 
|---|
| 40 | * - Treat style numbers 222 and 0 properly as "no style" and "normal". | 
|---|
| 41 | * | 
|---|
| 42 | * Author: Paul DuBois  dubois@primate.wisc.edu | 
|---|
| 43 | * | 
|---|
| 44 | * This software may be redistributed without restriction and used for | 
|---|
| 45 | * any purpose whatsoever. | 
|---|
| 46 | */ | 
|---|
| 47 |  | 
|---|
| 48 | # ifndef STRING_H | 
|---|
| 49 | # define STRING_H <string.h> | 
|---|
| 50 | # endif | 
|---|
| 51 |  | 
|---|
| 52 | # include       <stdio.h> | 
|---|
| 53 | # include       <ctype.h> | 
|---|
| 54 | # include       STRING_H | 
|---|
| 55 | # ifdef STDARG | 
|---|
| 56 | # include       <stdarg.h> | 
|---|
| 57 | # else | 
|---|
| 58 | # ifdef VARARGS | 
|---|
| 59 | # include       <varargs.h> | 
|---|
| 60 | # endif /* VARARGS */ | 
|---|
| 61 | # endif /* STDARG */ | 
|---|
| 62 |  | 
|---|
| 63 | # define        rtfInternal | 
|---|
| 64 | # include       "rtf.h" | 
|---|
| 65 | # undef         rtfInternal | 
|---|
| 66 |  | 
|---|
| 67 | /* | 
|---|
| 68 | *  include hard coded charsets | 
|---|
| 69 | */ | 
|---|
| 70 |  | 
|---|
| 71 | #include "ansi_gen.h" | 
|---|
| 72 | #include "ansi_sym.h" | 
|---|
| 73 | #include "text_map.h" | 
|---|
| 74 |  | 
|---|
| 75 | #include <stdlib.h> | 
|---|
| 76 | #include "charlist.h" | 
|---|
| 77 | #include "windows.h" | 
|---|
| 78 |  | 
|---|
| 79 | extern HANDLE RICHED32_hHeap; | 
|---|
| 80 |  | 
|---|
| 81 | /* | 
|---|
| 82 | * Return pointer to new element of type t, or NULL | 
|---|
| 83 | * if no memory available. | 
|---|
| 84 | */ | 
|---|
| 85 |  | 
|---|
| 86 | # define        New(t)  ((t *) RTFAlloc ((int) sizeof (t))) | 
|---|
| 87 |  | 
|---|
| 88 | /* maximum number of character values representable in a byte */ | 
|---|
| 89 |  | 
|---|
| 90 | # define        charSetSize             256 | 
|---|
| 91 |  | 
|---|
| 92 | /* charset stack size */ | 
|---|
| 93 |  | 
|---|
| 94 | # define        maxCSStack              10 | 
|---|
| 95 |  | 
|---|
| 96 | #ifndef __WIN32OS2__ | 
|---|
| 97 | #ifndef THINK_C | 
|---|
| 98 | extern char     *malloc (); | 
|---|
| 99 | #else | 
|---|
| 100 | extern void     *malloc(size_t); | 
|---|
| 101 | #endif | 
|---|
| 102 | #endif | 
|---|
| 103 |  | 
|---|
| 104 | static int      _RTFGetChar(); | 
|---|
| 105 | static void     _RTFGetToken (); | 
|---|
| 106 | static void     _RTFGetToken2 (); | 
|---|
| 107 | static int      GetChar (); | 
|---|
| 108 | static void     ReadFontTbl (); | 
|---|
| 109 | static void     ReadColorTbl (); | 
|---|
| 110 | static void     ReadStyleSheet (); | 
|---|
| 111 | static void     ReadInfoGroup (); | 
|---|
| 112 | static void     ReadPictGroup (); | 
|---|
| 113 | static void     ReadObjGroup (); | 
|---|
| 114 | static void     LookupInit (); | 
|---|
| 115 | static void     Lookup (); | 
|---|
| 116 | static int      Hash (); | 
|---|
| 117 |  | 
|---|
| 118 | static void     CharSetInit (); | 
|---|
| 119 | static void     ReadCharSetMaps (); | 
|---|
| 120 |  | 
|---|
| 121 |  | 
|---|
| 122 | /* | 
|---|
| 123 | * Public variables (listed in rtf.h) | 
|---|
| 124 | */ | 
|---|
| 125 |  | 
|---|
| 126 | int     rtfClass; | 
|---|
| 127 | int     rtfMajor; | 
|---|
| 128 | int     rtfMinor; | 
|---|
| 129 | int     rtfParam; | 
|---|
| 130 | char    *rtfTextBuf = (char *) NULL; | 
|---|
| 131 | int     rtfTextLen; | 
|---|
| 132 |  | 
|---|
| 133 | long    rtfLineNum; | 
|---|
| 134 | int     rtfLinePos; | 
|---|
| 135 |  | 
|---|
| 136 |  | 
|---|
| 137 | /* | 
|---|
| 138 | * Private stuff | 
|---|
| 139 | */ | 
|---|
| 140 |  | 
|---|
| 141 | static int      pushedChar;     /* pushback char if read too far */ | 
|---|
| 142 |  | 
|---|
| 143 | static int      pushedClass;    /* pushed token info for RTFUngetToken() */ | 
|---|
| 144 | static int      pushedMajor; | 
|---|
| 145 | static int      pushedMinor; | 
|---|
| 146 | static int      pushedParam; | 
|---|
| 147 | static char     *pushedTextBuf = (char *) NULL; | 
|---|
| 148 |  | 
|---|
| 149 | static int      prevChar; | 
|---|
| 150 | static int      bumpLine; | 
|---|
| 151 |  | 
|---|
| 152 | static RTFFont  *fontList = (RTFFont *) NULL;   /* these lists MUST be */ | 
|---|
| 153 | static RTFColor *colorList = (RTFColor *) NULL; /* initialized to NULL */ | 
|---|
| 154 | static RTFStyle *styleList = (RTFStyle *) NULL; | 
|---|
| 155 |  | 
|---|
| 156 | static char     *inputName = (char *) NULL; | 
|---|
| 157 | static char     *outputName = (char *) NULL; | 
|---|
| 158 |  | 
|---|
| 159 | static EDITSTREAM editstream; | 
|---|
| 160 | static CHARLIST inputCharList = {0, NULL, NULL}; | 
|---|
| 161 |  | 
|---|
| 162 | /* | 
|---|
| 163 | * This array is used to map standard character names onto their numeric codes. | 
|---|
| 164 | * The position of the name within the array is the code. | 
|---|
| 165 | * stdcharnames.h is generated in the ../h directory. | 
|---|
| 166 | */ | 
|---|
| 167 |  | 
|---|
| 168 | static char     *stdCharName[] = | 
|---|
| 169 | { | 
|---|
| 170 | # include       "stdcharnames.h" | 
|---|
| 171 | (char *) NULL | 
|---|
| 172 | }; | 
|---|
| 173 |  | 
|---|
| 174 |  | 
|---|
| 175 | /* | 
|---|
| 176 | * These arrays are used to map RTF input character values onto the standard | 
|---|
| 177 | * character names represented by the values.  Input character values are | 
|---|
| 178 | * used as indices into the arrays to produce standard character codes. | 
|---|
| 179 | */ | 
|---|
| 180 |  | 
|---|
| 181 |  | 
|---|
| 182 | static char     *genCharSetFile = (char *) NULL; | 
|---|
| 183 | static int      genCharCode[charSetSize];       /* general */ | 
|---|
| 184 | static int      haveGenCharSet = 0; | 
|---|
| 185 |  | 
|---|
| 186 | static char     *symCharSetFile = (char *) NULL; | 
|---|
| 187 | static int      symCharCode[charSetSize];       /* symbol */ | 
|---|
| 188 | static int      haveSymCharSet = 0; | 
|---|
| 189 |  | 
|---|
| 190 | static int      curCharSet = rtfCSGeneral; | 
|---|
| 191 | static int      *curCharCode = genCharCode; | 
|---|
| 192 |  | 
|---|
| 193 | /* | 
|---|
| 194 | * By default, the reader is configured to handle charset mapping invisibly, | 
|---|
| 195 | * including reading the charset files and switching charset maps as necessary | 
|---|
| 196 | * for Symbol font. | 
|---|
| 197 | */ | 
|---|
| 198 |  | 
|---|
| 199 | static int      autoCharSetFlags; | 
|---|
| 200 |  | 
|---|
| 201 | /* | 
|---|
| 202 | * Stack for keeping track of charset map on group begin/end.  This is | 
|---|
| 203 | * necessary because group termination reverts the font to the previous | 
|---|
| 204 | * value, which may implicitly change it. | 
|---|
| 205 | */ | 
|---|
| 206 |  | 
|---|
| 207 | static int      csStack[maxCSStack]; | 
|---|
| 208 | static int      csTop = 0; | 
|---|
| 209 |  | 
|---|
| 210 | /* | 
|---|
| 211 | * Get a char from the charlist. The charlist is used to store characters | 
|---|
| 212 | * from the editstream. | 
|---|
| 213 | * | 
|---|
| 214 | */ | 
|---|
| 215 |  | 
|---|
| 216 | int | 
|---|
| 217 | _RTFGetChar() | 
|---|
| 218 | { | 
|---|
| 219 | char myChar; | 
|---|
| 220 | if(CHARLIST_GetNbItems(&inputCharList) == 0) | 
|---|
| 221 | { | 
|---|
| 222 | char buff[10]; | 
|---|
| 223 | long pcb; | 
|---|
| 224 | editstream.pfnCallback(editstream.dwCookie, buff, 1, &pcb); | 
|---|
| 225 | if(pcb == 0) | 
|---|
| 226 | return EOF; | 
|---|
| 227 | else | 
|---|
| 228 | CHARLIST_Enqueue(&inputCharList, buff[0]); | 
|---|
| 229 | } | 
|---|
| 230 | myChar = CHARLIST_Dequeue(&inputCharList); | 
|---|
| 231 | return (int) myChar; | 
|---|
| 232 | } | 
|---|
| 233 |  | 
|---|
| 234 | void | 
|---|
| 235 | RTFSetEditStream(EDITSTREAM *es) | 
|---|
| 236 | { | 
|---|
| 237 | editstream.dwCookie = es->dwCookie; | 
|---|
| 238 | editstream.dwError  = es->dwError; | 
|---|
| 239 | editstream.pfnCallback = es->pfnCallback; | 
|---|
| 240 | } | 
|---|
| 241 |  | 
|---|
| 242 | /* | 
|---|
| 243 | * Initialize the reader.  This may be called multiple times, | 
|---|
| 244 | * to read multiple files.  The only thing not reset is the input | 
|---|
| 245 | * stream; that must be done with RTFSetStream(). | 
|---|
| 246 | */ | 
|---|
| 247 |  | 
|---|
| 248 | void | 
|---|
| 249 | RTFInit () | 
|---|
| 250 | { | 
|---|
| 251 | int     i; | 
|---|
| 252 | RTFColor        *cp; | 
|---|
| 253 | RTFFont         *fp; | 
|---|
| 254 | RTFStyle        *sp; | 
|---|
| 255 | RTFStyleElt     *eltList, *ep; | 
|---|
| 256 |  | 
|---|
| 257 | if (rtfTextBuf == (char *) NULL)        /* initialize the text buffers */ | 
|---|
| 258 | { | 
|---|
| 259 | rtfTextBuf = RTFAlloc (rtfBufSiz); | 
|---|
| 260 | pushedTextBuf = RTFAlloc (rtfBufSiz); | 
|---|
| 261 | if (rtfTextBuf == (char *) NULL | 
|---|
| 262 | || pushedTextBuf == (char *) NULL) | 
|---|
| 263 | RTFPanic ("Cannot allocate text buffers."); | 
|---|
| 264 | rtfTextBuf[0] = pushedTextBuf[0] = '\0'; | 
|---|
| 265 | } | 
|---|
| 266 |  | 
|---|
| 267 | RTFFree (inputName); | 
|---|
| 268 | RTFFree (outputName); | 
|---|
| 269 | inputName = outputName = (char *) NULL; | 
|---|
| 270 |  | 
|---|
| 271 | /* initialize lookup table */ | 
|---|
| 272 | LookupInit (); | 
|---|
| 273 |  | 
|---|
| 274 | for (i = 0; i < rtfMaxClass; i++) | 
|---|
| 275 | RTFSetClassCallback (i, (RTFFuncPtr) NULL); | 
|---|
| 276 | for (i = 0; i < rtfMaxDestination; i++) | 
|---|
| 277 | RTFSetDestinationCallback (i, (RTFFuncPtr) NULL); | 
|---|
| 278 |  | 
|---|
| 279 | /* install built-in destination readers */ | 
|---|
| 280 | RTFSetDestinationCallback (rtfFontTbl, ReadFontTbl); | 
|---|
| 281 | RTFSetDestinationCallback (rtfColorTbl, ReadColorTbl); | 
|---|
| 282 | RTFSetDestinationCallback (rtfStyleSheet, ReadStyleSheet); | 
|---|
| 283 | RTFSetDestinationCallback (rtfInfo, ReadInfoGroup); | 
|---|
| 284 | RTFSetDestinationCallback (rtfPict, ReadPictGroup); | 
|---|
| 285 | RTFSetDestinationCallback (rtfObject, ReadObjGroup); | 
|---|
| 286 |  | 
|---|
| 287 |  | 
|---|
| 288 | RTFSetReadHook ((RTFFuncPtr) NULL); | 
|---|
| 289 |  | 
|---|
| 290 | /* dump old lists if necessary */ | 
|---|
| 291 |  | 
|---|
| 292 | while (fontList != (RTFFont *) NULL) | 
|---|
| 293 | { | 
|---|
| 294 | fp = fontList->rtfNextFont; | 
|---|
| 295 | RTFFree (fontList->rtfFName); | 
|---|
| 296 | RTFFree ((char *) fontList); | 
|---|
| 297 | fontList = fp; | 
|---|
| 298 | } | 
|---|
| 299 | while (colorList != (RTFColor *) NULL) | 
|---|
| 300 | { | 
|---|
| 301 | cp = colorList->rtfNextColor; | 
|---|
| 302 | RTFFree ((char *) colorList); | 
|---|
| 303 | colorList = cp; | 
|---|
| 304 | } | 
|---|
| 305 | while (styleList != (RTFStyle *) NULL) | 
|---|
| 306 | { | 
|---|
| 307 | sp = styleList->rtfNextStyle; | 
|---|
| 308 | eltList = styleList->rtfSSEList; | 
|---|
| 309 | while (eltList != (RTFStyleElt *) NULL) | 
|---|
| 310 | { | 
|---|
| 311 | ep = eltList->rtfNextSE; | 
|---|
| 312 | RTFFree (eltList->rtfSEText); | 
|---|
| 313 | RTFFree ((char *) eltList); | 
|---|
| 314 | eltList = ep; | 
|---|
| 315 | } | 
|---|
| 316 | RTFFree (styleList->rtfSName); | 
|---|
| 317 | RTFFree ((char *) styleList); | 
|---|
| 318 | styleList = sp; | 
|---|
| 319 | } | 
|---|
| 320 |  | 
|---|
| 321 | rtfClass = -1; | 
|---|
| 322 | pushedClass = -1; | 
|---|
| 323 | pushedChar = EOF; | 
|---|
| 324 |  | 
|---|
| 325 | rtfLineNum = 0; | 
|---|
| 326 | rtfLinePos = 0; | 
|---|
| 327 | prevChar = EOF; | 
|---|
| 328 | bumpLine = 0; | 
|---|
| 329 |  | 
|---|
| 330 | CharSetInit (); | 
|---|
| 331 | csTop = 0; | 
|---|
| 332 | } | 
|---|
| 333 |  | 
|---|
| 334 | /* | 
|---|
| 335 | * Set or get the input or output file name.  These are never guaranteed | 
|---|
| 336 | * to be accurate, only insofar as the calling program makes them so. | 
|---|
| 337 | */ | 
|---|
| 338 |  | 
|---|
| 339 | void | 
|---|
| 340 | RTFSetInputName (name) | 
|---|
| 341 | char    *name; | 
|---|
| 342 | { | 
|---|
| 343 | if ((inputName = RTFStrSave (name)) == (char *) NULL) | 
|---|
| 344 | RTFPanic ("RTFSetInputName: out of memory"); | 
|---|
| 345 | } | 
|---|
| 346 |  | 
|---|
| 347 |  | 
|---|
| 348 | char * | 
|---|
| 349 | RTFGetInputName () | 
|---|
| 350 | { | 
|---|
| 351 | return (inputName); | 
|---|
| 352 | } | 
|---|
| 353 |  | 
|---|
| 354 |  | 
|---|
| 355 | void | 
|---|
| 356 | RTFSetOutputName (name) | 
|---|
| 357 | char    *name; | 
|---|
| 358 | { | 
|---|
| 359 | if ((outputName = RTFStrSave (name)) == (char *) NULL) | 
|---|
| 360 | RTFPanic ("RTFSetOutputName: out of memory"); | 
|---|
| 361 | } | 
|---|
| 362 |  | 
|---|
| 363 |  | 
|---|
| 364 | char * | 
|---|
| 365 | RTFGetOutputName () | 
|---|
| 366 | { | 
|---|
| 367 | return (outputName); | 
|---|
| 368 | } | 
|---|
| 369 |  | 
|---|
| 370 |  | 
|---|
| 371 |  | 
|---|
| 372 | /* ---------------------------------------------------------------------- */ | 
|---|
| 373 |  | 
|---|
| 374 | /* | 
|---|
| 375 | * Callback table manipulation routines | 
|---|
| 376 | */ | 
|---|
| 377 |  | 
|---|
| 378 |  | 
|---|
| 379 | /* | 
|---|
| 380 | * Install or return a writer callback for a token class | 
|---|
| 381 | */ | 
|---|
| 382 |  | 
|---|
| 383 |  | 
|---|
| 384 | static RTFFuncPtr       ccb[rtfMaxClass];               /* class callbacks */ | 
|---|
| 385 |  | 
|---|
| 386 |  | 
|---|
| 387 | void | 
|---|
| 388 | RTFSetClassCallback (class, callback) | 
|---|
| 389 | int             class; | 
|---|
| 390 | RTFFuncPtr      callback; | 
|---|
| 391 | { | 
|---|
| 392 | if (class >= 0 && class < rtfMaxClass) | 
|---|
| 393 | ccb[class] = callback; | 
|---|
| 394 | } | 
|---|
| 395 |  | 
|---|
| 396 |  | 
|---|
| 397 | RTFFuncPtr | 
|---|
| 398 | RTFGetClassCallback (class) | 
|---|
| 399 | int     class; | 
|---|
| 400 | { | 
|---|
| 401 | if (class >= 0 && class < rtfMaxClass) | 
|---|
| 402 | return (ccb[class]); | 
|---|
| 403 | return ((RTFFuncPtr) NULL); | 
|---|
| 404 | } | 
|---|
| 405 |  | 
|---|
| 406 |  | 
|---|
| 407 | /* | 
|---|
| 408 | * Install or return a writer callback for a destination type | 
|---|
| 409 | */ | 
|---|
| 410 |  | 
|---|
| 411 | static RTFFuncPtr       dcb[rtfMaxDestination]; /* destination callbacks */ | 
|---|
| 412 |  | 
|---|
| 413 |  | 
|---|
| 414 | void | 
|---|
| 415 | RTFSetDestinationCallback (dest, callback) | 
|---|
| 416 | int             dest; | 
|---|
| 417 | RTFFuncPtr      callback; | 
|---|
| 418 | { | 
|---|
| 419 | if (dest >= 0 && dest < rtfMaxDestination) | 
|---|
| 420 | dcb[dest] = callback; | 
|---|
| 421 | } | 
|---|
| 422 |  | 
|---|
| 423 |  | 
|---|
| 424 | RTFFuncPtr | 
|---|
| 425 | RTFGetDestinationCallback (dest) | 
|---|
| 426 | int     dest; | 
|---|
| 427 | { | 
|---|
| 428 | if (dest >= 0 && dest < rtfMaxDestination) | 
|---|
| 429 | return (dcb[dest]); | 
|---|
| 430 | return ((RTFFuncPtr) NULL); | 
|---|
| 431 | } | 
|---|
| 432 |  | 
|---|
| 433 |  | 
|---|
| 434 | /* ---------------------------------------------------------------------- */ | 
|---|
| 435 |  | 
|---|
| 436 | /* | 
|---|
| 437 | * Token reading routines | 
|---|
| 438 | */ | 
|---|
| 439 |  | 
|---|
| 440 |  | 
|---|
| 441 | /* | 
|---|
| 442 | * Read the input stream, invoking the writer's callbacks | 
|---|
| 443 | * where appropriate. | 
|---|
| 444 | */ | 
|---|
| 445 |  | 
|---|
| 446 | void | 
|---|
| 447 | RTFRead () | 
|---|
| 448 | { | 
|---|
| 449 | while (RTFGetToken () != rtfEOF) | 
|---|
| 450 | RTFRouteToken (); | 
|---|
| 451 | } | 
|---|
| 452 |  | 
|---|
| 453 |  | 
|---|
| 454 | /* | 
|---|
| 455 | * Route a token.  If it's a destination for which a reader is | 
|---|
| 456 | * installed, process the destination internally, otherwise | 
|---|
| 457 | * pass the token to the writer's class callback. | 
|---|
| 458 | */ | 
|---|
| 459 |  | 
|---|
| 460 | void | 
|---|
| 461 | RTFRouteToken () | 
|---|
| 462 | { | 
|---|
| 463 | RTFFuncPtr      p; | 
|---|
| 464 |  | 
|---|
| 465 | if (rtfClass < 0 || rtfClass >= rtfMaxClass)    /* watchdog */ | 
|---|
| 466 | { | 
|---|
| 467 | RTFPanic ("Unknown class %d: %s (reader malfunction)", | 
|---|
| 468 | rtfClass, rtfTextBuf); | 
|---|
| 469 | } | 
|---|
| 470 | if (RTFCheckCM (rtfControl, rtfDestination)) | 
|---|
| 471 | { | 
|---|
| 472 | /* invoke destination-specific callback if there is one */ | 
|---|
| 473 | if ((p = RTFGetDestinationCallback (rtfMinor)) | 
|---|
| 474 | != (RTFFuncPtr) NULL) | 
|---|
| 475 | { | 
|---|
| 476 | (*p) (); | 
|---|
| 477 | return; | 
|---|
| 478 | } | 
|---|
| 479 | } | 
|---|
| 480 | /* invoke class callback if there is one */ | 
|---|
| 481 | if ((p = RTFGetClassCallback (rtfClass)) != (RTFFuncPtr) NULL) | 
|---|
| 482 | (*p) (); | 
|---|
| 483 | } | 
|---|
| 484 |  | 
|---|
| 485 |  | 
|---|
| 486 | /* | 
|---|
| 487 | * Skip to the end of the current group.  When this returns, | 
|---|
| 488 | * writers that maintain a state stack may want to call their | 
|---|
| 489 | * state unstacker; global vars will still be set to the group's | 
|---|
| 490 | * closing brace. | 
|---|
| 491 | */ | 
|---|
| 492 |  | 
|---|
| 493 | void | 
|---|
| 494 | RTFSkipGroup () | 
|---|
| 495 | { | 
|---|
| 496 | int     level = 1; | 
|---|
| 497 |  | 
|---|
| 498 | while (RTFGetToken () != rtfEOF) | 
|---|
| 499 | { | 
|---|
| 500 | if (rtfClass == rtfGroup) | 
|---|
| 501 | { | 
|---|
| 502 | if (rtfMajor == rtfBeginGroup) | 
|---|
| 503 | ++level; | 
|---|
| 504 | else if (rtfMajor == rtfEndGroup) | 
|---|
| 505 | { | 
|---|
| 506 | if (--level < 1) | 
|---|
| 507 | break;  /* end of initial group */ | 
|---|
| 508 | } | 
|---|
| 509 | } | 
|---|
| 510 | } | 
|---|
| 511 | } | 
|---|
| 512 |  | 
|---|
| 513 |  | 
|---|
| 514 | /* | 
|---|
| 515 | * Read one token.  Call the read hook if there is one.  The | 
|---|
| 516 | * token class is the return value.  Returns rtfEOF when there | 
|---|
| 517 | * are no more tokens. | 
|---|
| 518 | */ | 
|---|
| 519 |  | 
|---|
| 520 | int | 
|---|
| 521 | RTFGetToken () | 
|---|
| 522 | { | 
|---|
| 523 | RTFFuncPtr      p; | 
|---|
| 524 |  | 
|---|
| 525 | for (;;) | 
|---|
| 526 | { | 
|---|
| 527 | _RTFGetToken (); | 
|---|
| 528 | if ((p = RTFGetReadHook ()) != (RTFFuncPtr) NULL) | 
|---|
| 529 | (*p) ();        /* give read hook a look at token */ | 
|---|
| 530 |  | 
|---|
| 531 | /* Silently discard newlines, carriage returns, nulls.  */ | 
|---|
| 532 | if (!(rtfClass == rtfText | 
|---|
| 533 | && (rtfMajor == '\n' || rtfMajor == '\r' | 
|---|
| 534 | || rtfMajor == '\0'))) | 
|---|
| 535 | break; | 
|---|
| 536 | } | 
|---|
| 537 | return (rtfClass); | 
|---|
| 538 | } | 
|---|
| 539 |  | 
|---|
| 540 |  | 
|---|
| 541 | /* | 
|---|
| 542 | * Install or return a token reader hook. | 
|---|
| 543 | */ | 
|---|
| 544 |  | 
|---|
| 545 | static RTFFuncPtr       readHook; | 
|---|
| 546 |  | 
|---|
| 547 |  | 
|---|
| 548 | void | 
|---|
| 549 | RTFSetReadHook (f) | 
|---|
| 550 | RTFFuncPtr      f; | 
|---|
| 551 | { | 
|---|
| 552 | readHook = f; | 
|---|
| 553 | } | 
|---|
| 554 |  | 
|---|
| 555 |  | 
|---|
| 556 | RTFFuncPtr | 
|---|
| 557 | RTFGetReadHook () | 
|---|
| 558 | { | 
|---|
| 559 | return (readHook); | 
|---|
| 560 | } | 
|---|
| 561 |  | 
|---|
| 562 |  | 
|---|
| 563 | void | 
|---|
| 564 | RTFUngetToken () | 
|---|
| 565 | { | 
|---|
| 566 | if (pushedClass >= 0)   /* there's already an ungotten token */ | 
|---|
| 567 | RTFPanic ("cannot unget two tokens"); | 
|---|
| 568 | if (rtfClass < 0) | 
|---|
| 569 | RTFPanic ("no token to unget"); | 
|---|
| 570 | pushedClass = rtfClass; | 
|---|
| 571 | pushedMajor = rtfMajor; | 
|---|
| 572 | pushedMinor = rtfMinor; | 
|---|
| 573 | pushedParam = rtfParam; | 
|---|
| 574 | (void) strcpy (pushedTextBuf, rtfTextBuf); | 
|---|
| 575 | } | 
|---|
| 576 |  | 
|---|
| 577 |  | 
|---|
| 578 | int | 
|---|
| 579 | RTFPeekToken () | 
|---|
| 580 | { | 
|---|
| 581 | _RTFGetToken (); | 
|---|
| 582 | RTFUngetToken (); | 
|---|
| 583 | return (rtfClass); | 
|---|
| 584 | } | 
|---|
| 585 |  | 
|---|
| 586 |  | 
|---|
| 587 | static void | 
|---|
| 588 | _RTFGetToken () | 
|---|
| 589 | { | 
|---|
| 590 | RTFFont *fp; | 
|---|
| 591 |  | 
|---|
| 592 | /* first check for pushed token from RTFUngetToken() */ | 
|---|
| 593 |  | 
|---|
| 594 | if (pushedClass >= 0) | 
|---|
| 595 | { | 
|---|
| 596 | rtfClass = pushedClass; | 
|---|
| 597 | rtfMajor = pushedMajor; | 
|---|
| 598 | rtfMinor = pushedMinor; | 
|---|
| 599 | rtfParam = pushedParam; | 
|---|
| 600 | (void) strcpy (rtfTextBuf, pushedTextBuf); | 
|---|
| 601 | rtfTextLen = strlen (rtfTextBuf); | 
|---|
| 602 | pushedClass = -1; | 
|---|
| 603 | return; | 
|---|
| 604 | } | 
|---|
| 605 |  | 
|---|
| 606 | /* | 
|---|
| 607 | * Beyond this point, no token is ever seen twice, which is | 
|---|
| 608 | * important, e.g., for making sure no "}" pops the font stack twice. | 
|---|
| 609 | */ | 
|---|
| 610 |  | 
|---|
| 611 | _RTFGetToken2 (); | 
|---|
| 612 | if (rtfClass == rtfText)        /* map RTF char to standard code */ | 
|---|
| 613 | rtfMinor = RTFMapChar (rtfMajor); | 
|---|
| 614 |  | 
|---|
| 615 | /* | 
|---|
| 616 | * If auto-charset stuff is activated, see if anything needs doing, | 
|---|
| 617 | * like reading the charset maps or switching between them. | 
|---|
| 618 | */ | 
|---|
| 619 |  | 
|---|
| 620 | if (autoCharSetFlags == 0) | 
|---|
| 621 | return; | 
|---|
| 622 |  | 
|---|
| 623 | if ((autoCharSetFlags & rtfReadCharSet) | 
|---|
| 624 | && RTFCheckCM (rtfControl, rtfCharSet)) | 
|---|
| 625 | { | 
|---|
| 626 | ReadCharSetMaps (); | 
|---|
| 627 | } | 
|---|
| 628 | else if ((autoCharSetFlags & rtfSwitchCharSet) | 
|---|
| 629 | && RTFCheckCMM (rtfControl, rtfCharAttr, rtfFontNum)) | 
|---|
| 630 | { | 
|---|
| 631 | if ((fp = RTFGetFont (rtfParam)) != (RTFFont *) NULL) | 
|---|
| 632 | { | 
|---|
| 633 | if (strncmp (fp->rtfFName, "Symbol", 6) == 0) | 
|---|
| 634 | curCharSet = rtfCSSymbol; | 
|---|
| 635 | else | 
|---|
| 636 | curCharSet = rtfCSGeneral; | 
|---|
| 637 | RTFSetCharSet (curCharSet); | 
|---|
| 638 | } | 
|---|
| 639 | } | 
|---|
| 640 | else if ((autoCharSetFlags & rtfSwitchCharSet) && rtfClass == rtfGroup) | 
|---|
| 641 | { | 
|---|
| 642 | switch (rtfMajor) | 
|---|
| 643 | { | 
|---|
| 644 | case rtfBeginGroup: | 
|---|
| 645 | if (csTop >= maxCSStack) | 
|---|
| 646 | RTFPanic ("_RTFGetToken: stack overflow"); | 
|---|
| 647 | csStack[csTop++] = curCharSet; | 
|---|
| 648 | break; | 
|---|
| 649 | case rtfEndGroup: | 
|---|
| 650 | if (csTop <= 0) | 
|---|
| 651 | RTFPanic ("_RTFGetToken: stack underflow"); | 
|---|
| 652 | curCharSet = csStack[--csTop]; | 
|---|
| 653 | RTFSetCharSet (curCharSet); | 
|---|
| 654 | break; | 
|---|
| 655 | } | 
|---|
| 656 | } | 
|---|
| 657 | } | 
|---|
| 658 |  | 
|---|
| 659 |  | 
|---|
| 660 | /* this shouldn't be called anywhere but from _RTFGetToken() */ | 
|---|
| 661 |  | 
|---|
| 662 | static void | 
|---|
| 663 | _RTFGetToken2 () | 
|---|
| 664 | { | 
|---|
| 665 | int     sign; | 
|---|
| 666 | int     c; | 
|---|
| 667 |  | 
|---|
| 668 | /* initialize token vars */ | 
|---|
| 669 |  | 
|---|
| 670 | rtfClass = rtfUnknown; | 
|---|
| 671 | rtfParam = rtfNoParam; | 
|---|
| 672 | rtfTextBuf[rtfTextLen = 0] = '\0'; | 
|---|
| 673 |  | 
|---|
| 674 | /* get first character, which may be a pushback from previous token */ | 
|---|
| 675 |  | 
|---|
| 676 | if (pushedChar != EOF) | 
|---|
| 677 | { | 
|---|
| 678 | c = pushedChar; | 
|---|
| 679 | rtfTextBuf[rtfTextLen++] = c; | 
|---|
| 680 | rtfTextBuf[rtfTextLen] = '\0'; | 
|---|
| 681 | pushedChar = EOF; | 
|---|
| 682 | } | 
|---|
| 683 | else if ((c = GetChar ()) == EOF) | 
|---|
| 684 | { | 
|---|
| 685 | rtfClass = rtfEOF; | 
|---|
| 686 | return; | 
|---|
| 687 | } | 
|---|
| 688 |  | 
|---|
| 689 | if (c == '{') | 
|---|
| 690 | { | 
|---|
| 691 | rtfClass = rtfGroup; | 
|---|
| 692 | rtfMajor = rtfBeginGroup; | 
|---|
| 693 | return; | 
|---|
| 694 | } | 
|---|
| 695 | if (c == '}') | 
|---|
| 696 | { | 
|---|
| 697 | rtfClass = rtfGroup; | 
|---|
| 698 | rtfMajor = rtfEndGroup; | 
|---|
| 699 | return; | 
|---|
| 700 | } | 
|---|
| 701 | if (c != '\\') | 
|---|
| 702 | { | 
|---|
| 703 | /* | 
|---|
| 704 | * Two possibilities here: | 
|---|
| 705 | * 1) ASCII 9, effectively like \tab control symbol | 
|---|
| 706 | * 2) literal text char | 
|---|
| 707 | */ | 
|---|
| 708 | if (c == '\t')                  /* ASCII 9 */ | 
|---|
| 709 | { | 
|---|
| 710 | rtfClass = rtfControl; | 
|---|
| 711 | rtfMajor = rtfSpecialChar; | 
|---|
| 712 | rtfMinor = rtfTab; | 
|---|
| 713 | } | 
|---|
| 714 | else | 
|---|
| 715 | { | 
|---|
| 716 | rtfClass = rtfText; | 
|---|
| 717 | rtfMajor = c; | 
|---|
| 718 | } | 
|---|
| 719 | return; | 
|---|
| 720 | } | 
|---|
| 721 | if ((c = GetChar ()) == EOF) | 
|---|
| 722 | { | 
|---|
| 723 | /* early eof, whoops (class is rtfUnknown) */ | 
|---|
| 724 | return; | 
|---|
| 725 | } | 
|---|
| 726 | if (!isalpha (c)) | 
|---|
| 727 | { | 
|---|
| 728 | /* | 
|---|
| 729 | * Three possibilities here: | 
|---|
| 730 | * 1) hex encoded text char, e.g., \'d5, \'d3 | 
|---|
| 731 | * 2) special escaped text char, e.g., \{, \} | 
|---|
| 732 | * 3) control symbol, e.g., \_, \-, \|, \<10> | 
|---|
| 733 | */ | 
|---|
| 734 | if (c == '\'')                          /* hex char */ | 
|---|
| 735 | { | 
|---|
| 736 | int     c2; | 
|---|
| 737 |  | 
|---|
| 738 | if ((c = GetChar ()) != EOF && (c2 = GetChar ()) != EOF) | 
|---|
| 739 | { | 
|---|
| 740 | /* should do isxdigit check! */ | 
|---|
| 741 | rtfClass = rtfText; | 
|---|
| 742 | rtfMajor = RTFCharToHex (c) * 16 | 
|---|
| 743 | + RTFCharToHex (c2); | 
|---|
| 744 | return; | 
|---|
| 745 | } | 
|---|
| 746 | /* early eof, whoops (class is rtfUnknown) */ | 
|---|
| 747 | return; | 
|---|
| 748 | } | 
|---|
| 749 |  | 
|---|
| 750 | /* escaped char */ | 
|---|
| 751 | /*if (index (":{}\\", c) != (char *) NULL)*/ /* escaped char */ | 
|---|
| 752 | if (c == ':' || c == '{' || c == '}' || c == '\\') | 
|---|
| 753 | { | 
|---|
| 754 | rtfClass = rtfText; | 
|---|
| 755 | rtfMajor = c; | 
|---|
| 756 | return; | 
|---|
| 757 | } | 
|---|
| 758 |  | 
|---|
| 759 | /* control symbol */ | 
|---|
| 760 | Lookup (rtfTextBuf);    /* sets class, major, minor */ | 
|---|
| 761 | return; | 
|---|
| 762 | } | 
|---|
| 763 | /* control word */ | 
|---|
| 764 | while (isalpha (c)) | 
|---|
| 765 | { | 
|---|
| 766 | if ((c = GetChar ()) == EOF) | 
|---|
| 767 | break; | 
|---|
| 768 | } | 
|---|
| 769 |  | 
|---|
| 770 | /* | 
|---|
| 771 | * At this point, the control word is all collected, so the | 
|---|
| 772 | * major/minor numbers are determined before the parameter | 
|---|
| 773 | * (if any) is scanned.  There will be one too many characters | 
|---|
| 774 | * in the buffer, though, so fix up before and restore after | 
|---|
| 775 | * looking up. | 
|---|
| 776 | */ | 
|---|
| 777 |  | 
|---|
| 778 | if (c != EOF) | 
|---|
| 779 | rtfTextBuf[rtfTextLen-1] = '\0'; | 
|---|
| 780 | Lookup (rtfTextBuf);    /* sets class, major, minor */ | 
|---|
| 781 | if (c != EOF) | 
|---|
| 782 | rtfTextBuf[rtfTextLen-1] = c; | 
|---|
| 783 |  | 
|---|
| 784 | /* | 
|---|
| 785 | * Should be looking at first digit of parameter if there | 
|---|
| 786 | * is one, unless it's negative.  In that case, next char | 
|---|
| 787 | * is '-', so need to gobble next char, and remember sign. | 
|---|
| 788 | */ | 
|---|
| 789 |  | 
|---|
| 790 | sign = 1; | 
|---|
| 791 | if (c == '-') | 
|---|
| 792 | { | 
|---|
| 793 | sign = -1; | 
|---|
| 794 | c = GetChar (); | 
|---|
| 795 | } | 
|---|
| 796 | if (c != EOF && isdigit (c)) | 
|---|
| 797 | { | 
|---|
| 798 | rtfParam = 0; | 
|---|
| 799 | while (isdigit (c))     /* gobble parameter */ | 
|---|
| 800 | { | 
|---|
| 801 | rtfParam = rtfParam * 10 + c - '0'; | 
|---|
| 802 | if ((c = GetChar ()) == EOF) | 
|---|
| 803 | break; | 
|---|
| 804 | } | 
|---|
| 805 | rtfParam *= sign; | 
|---|
| 806 | } | 
|---|
| 807 | /* | 
|---|
| 808 | * If control symbol delimiter was a blank, gobble it. | 
|---|
| 809 | * Otherwise the character is first char of next token, so | 
|---|
| 810 | * push it back for next call.  In either case, delete the | 
|---|
| 811 | * delimiter from the token buffer. | 
|---|
| 812 | */ | 
|---|
| 813 | if (c != EOF) | 
|---|
| 814 | { | 
|---|
| 815 | if (c != ' ') | 
|---|
| 816 | pushedChar = c; | 
|---|
| 817 | rtfTextBuf[--rtfTextLen] = '\0'; | 
|---|
| 818 | } | 
|---|
| 819 | } | 
|---|
| 820 |  | 
|---|
| 821 |  | 
|---|
| 822 | /* | 
|---|
| 823 | * Read the next character from the input.  This handles setting the | 
|---|
| 824 | * current line and position-within-line variables.  Those variable are | 
|---|
| 825 | * set correctly whether lines end with CR, LF, or CRLF (the last being | 
|---|
| 826 | * the tricky case). | 
|---|
| 827 | * | 
|---|
| 828 | * bumpLine indicates whether the line number should be incremented on | 
|---|
| 829 | * the *next* input character. | 
|---|
| 830 | */ | 
|---|
| 831 |  | 
|---|
| 832 |  | 
|---|
| 833 | static int | 
|---|
| 834 | GetChar () | 
|---|
| 835 | { | 
|---|
| 836 | int     c; | 
|---|
| 837 | int     oldBumpLine; | 
|---|
| 838 |  | 
|---|
| 839 | if ((c = _RTFGetChar()) != EOF) | 
|---|
| 840 | { | 
|---|
| 841 | rtfTextBuf[rtfTextLen++] = c; | 
|---|
| 842 | rtfTextBuf[rtfTextLen] = '\0'; | 
|---|
| 843 | } | 
|---|
| 844 | if (prevChar == EOF) | 
|---|
| 845 | bumpLine = 1; | 
|---|
| 846 | oldBumpLine = bumpLine; /* non-zero if prev char was line ending */ | 
|---|
| 847 | bumpLine = 0; | 
|---|
| 848 | if (c == '\r') | 
|---|
| 849 | bumpLine = 1; | 
|---|
| 850 | else if (c == '\n') | 
|---|
| 851 | { | 
|---|
| 852 | bumpLine = 1; | 
|---|
| 853 | if (prevChar == '\r')           /* oops, previous \r wasn't */ | 
|---|
| 854 | oldBumpLine = 0;        /* really a line ending */ | 
|---|
| 855 | } | 
|---|
| 856 | ++rtfLinePos; | 
|---|
| 857 | if (oldBumpLine)        /* were we supposed to increment the */ | 
|---|
| 858 | {                       /* line count on this char? */ | 
|---|
| 859 | ++rtfLineNum; | 
|---|
| 860 | rtfLinePos = 1; | 
|---|
| 861 | } | 
|---|
| 862 | prevChar = c; | 
|---|
| 863 | return (c); | 
|---|
| 864 | } | 
|---|
| 865 |  | 
|---|
| 866 |  | 
|---|
| 867 | /* | 
|---|
| 868 | * Synthesize a token by setting the global variables to the | 
|---|
| 869 | * values supplied.  Typically this is followed with a call | 
|---|
| 870 | * to RTFRouteToken(). | 
|---|
| 871 | * | 
|---|
| 872 | * If a param value other than rtfNoParam is passed, it becomes | 
|---|
| 873 | * part of the token text. | 
|---|
| 874 | */ | 
|---|
| 875 |  | 
|---|
| 876 | void | 
|---|
| 877 | RTFSetToken (class, major, minor, param, text) | 
|---|
| 878 | int     class, major, minor, param; | 
|---|
| 879 | char    *text; | 
|---|
| 880 | { | 
|---|
| 881 | rtfClass = class; | 
|---|
| 882 | rtfMajor = major; | 
|---|
| 883 | rtfMinor = minor; | 
|---|
| 884 | rtfParam = param; | 
|---|
| 885 | if (param == rtfNoParam) | 
|---|
| 886 | (void) strcpy (rtfTextBuf, text); | 
|---|
| 887 | else | 
|---|
| 888 | sprintf (rtfTextBuf, "%s%d", text, param); | 
|---|
| 889 | rtfTextLen = strlen (rtfTextBuf); | 
|---|
| 890 | } | 
|---|
| 891 |  | 
|---|
| 892 |  | 
|---|
| 893 | /* ---------------------------------------------------------------------- */ | 
|---|
| 894 |  | 
|---|
| 895 | /* | 
|---|
| 896 | * Routines to handle mapping of RTF character sets | 
|---|
| 897 | * onto standard characters. | 
|---|
| 898 | * | 
|---|
| 899 | * RTFStdCharCode(name) given char name, produce numeric code | 
|---|
| 900 | * RTFStdCharName(code) given char code, return name | 
|---|
| 901 | * RTFMapChar(c)        map input (RTF) char code to std code | 
|---|
| 902 | * RTFSetCharSet(id)    select given charset map | 
|---|
| 903 | * RTFGetCharSet()      get current charset map | 
|---|
| 904 | * | 
|---|
| 905 | * See ../h/README for more information about charset names and codes. | 
|---|
| 906 | */ | 
|---|
| 907 |  | 
|---|
| 908 |  | 
|---|
| 909 | /* | 
|---|
| 910 | * Initialize charset stuff. | 
|---|
| 911 | */ | 
|---|
| 912 |  | 
|---|
| 913 | static void | 
|---|
| 914 | CharSetInit () | 
|---|
| 915 | { | 
|---|
| 916 | autoCharSetFlags = (rtfReadCharSet | rtfSwitchCharSet); | 
|---|
| 917 | RTFFree (genCharSetFile); | 
|---|
| 918 | genCharSetFile = (char *) NULL; | 
|---|
| 919 | haveGenCharSet = 0; | 
|---|
| 920 | RTFFree (symCharSetFile); | 
|---|
| 921 | symCharSetFile = (char *) NULL; | 
|---|
| 922 | haveSymCharSet = 0; | 
|---|
| 923 | curCharSet = rtfCSGeneral; | 
|---|
| 924 | curCharCode = genCharCode; | 
|---|
| 925 | } | 
|---|
| 926 |  | 
|---|
| 927 |  | 
|---|
| 928 | /* | 
|---|
| 929 | * Specify the name of a file to be read when auto-charset-file reading is | 
|---|
| 930 | * done. | 
|---|
| 931 | */ | 
|---|
| 932 |  | 
|---|
| 933 | void | 
|---|
| 934 | RTFSetCharSetMap (name, csId) | 
|---|
| 935 | char    *name; | 
|---|
| 936 | int     csId; | 
|---|
| 937 | { | 
|---|
| 938 | if ((name = RTFStrSave (name)) == (char *) NULL)        /* make copy */ | 
|---|
| 939 | RTFPanic ("RTFSetCharSetMap: out of memory"); | 
|---|
| 940 | switch (csId) | 
|---|
| 941 | { | 
|---|
| 942 | case rtfCSGeneral: | 
|---|
| 943 | RTFFree (genCharSetFile);       /* free any previous value */ | 
|---|
| 944 | genCharSetFile = name; | 
|---|
| 945 | break; | 
|---|
| 946 | case rtfCSSymbol: | 
|---|
| 947 | RTFFree (symCharSetFile);       /* free any previous value */ | 
|---|
| 948 | symCharSetFile = name; | 
|---|
| 949 | break; | 
|---|
| 950 | } | 
|---|
| 951 | } | 
|---|
| 952 |  | 
|---|
| 953 |  | 
|---|
| 954 | /* | 
|---|
| 955 | * Do auto-charset-file reading. | 
|---|
| 956 | * will always use the ansi charset no mater what the value | 
|---|
| 957 | * of the rtfTextBuf is. | 
|---|
| 958 | * | 
|---|
| 959 | * TODO: add support for other charset in the future. | 
|---|
| 960 | * | 
|---|
| 961 | */ | 
|---|
| 962 |  | 
|---|
| 963 | static void | 
|---|
| 964 | ReadCharSetMaps () | 
|---|
| 965 | { | 
|---|
| 966 | char    buf[rtfBufSiz]; | 
|---|
| 967 |  | 
|---|
| 968 | if (genCharSetFile != (char *) NULL) | 
|---|
| 969 | (void) strcpy (buf, genCharSetFile); | 
|---|
| 970 | else | 
|---|
| 971 | sprintf (buf, "%s-gen", &rtfTextBuf[1]); | 
|---|
| 972 | if (RTFReadCharSetMap (rtfCSGeneral) == 0) | 
|---|
| 973 | RTFPanic ("ReadCharSetMaps: Cannot read charset map %s", buf); | 
|---|
| 974 | if (symCharSetFile != (char *) NULL) | 
|---|
| 975 | (void) strcpy (buf, symCharSetFile); | 
|---|
| 976 | else | 
|---|
| 977 | sprintf (buf, "%s-sym", &rtfTextBuf[1]); | 
|---|
| 978 | if (RTFReadCharSetMap (rtfCSSymbol) == 0) | 
|---|
| 979 | RTFPanic ("ReadCharSetMaps: Cannot read charset map %s", buf); | 
|---|
| 980 | } | 
|---|
| 981 |  | 
|---|
| 982 |  | 
|---|
| 983 |  | 
|---|
| 984 | /* | 
|---|
| 985 | * Convert a CaracterSetMap (caracter_name, caracter) into | 
|---|
| 986 | * this form : array[caracter_ident] = caracter; | 
|---|
| 987 | */ | 
|---|
| 988 |  | 
|---|
| 989 | int | 
|---|
| 990 | RTFReadCharSetMap (csId) | 
|---|
| 991 | int     csId; | 
|---|
| 992 | { | 
|---|
| 993 | int     *stdCodeArray; | 
|---|
| 994 | int i; | 
|---|
| 995 | switch (csId) | 
|---|
| 996 | { | 
|---|
| 997 | default: | 
|---|
| 998 | return (0);     /* illegal charset id */ | 
|---|
| 999 | case rtfCSGeneral: | 
|---|
| 1000 |  | 
|---|
| 1001 | haveGenCharSet = 1; | 
|---|
| 1002 | stdCodeArray = genCharCode; | 
|---|
| 1003 | for (i = 0; i < charSetSize; i++) | 
|---|
| 1004 | { | 
|---|
| 1005 | stdCodeArray[i] = rtfSC_nothing; | 
|---|
| 1006 | } | 
|---|
| 1007 |  | 
|---|
| 1008 | for ( i = 0 ; i< sizeof(ansi_gen)/(sizeof(int));i+=2) | 
|---|
| 1009 | { | 
|---|
| 1010 | stdCodeArray[ ansi_gen[i+1] ] = ansi_gen[i]; | 
|---|
| 1011 | } | 
|---|
| 1012 | break; | 
|---|
| 1013 |  | 
|---|
| 1014 | case rtfCSSymbol: | 
|---|
| 1015 |  | 
|---|
| 1016 | haveSymCharSet = 1; | 
|---|
| 1017 | stdCodeArray = symCharCode; | 
|---|
| 1018 | for (i = 0; i < charSetSize; i++) | 
|---|
| 1019 | { | 
|---|
| 1020 | stdCodeArray[i] = rtfSC_nothing; | 
|---|
| 1021 | } | 
|---|
| 1022 |  | 
|---|
| 1023 | for ( i = 0 ; i< sizeof(ansi_sym)/(sizeof(int));i+=2) | 
|---|
| 1024 | { | 
|---|
| 1025 | stdCodeArray[ ansi_sym[i+1] ] = ansi_sym[i]; | 
|---|
| 1026 | } | 
|---|
| 1027 | break; | 
|---|
| 1028 | } | 
|---|
| 1029 |  | 
|---|
| 1030 | return (1); | 
|---|
| 1031 | } | 
|---|
| 1032 |  | 
|---|
| 1033 |  | 
|---|
| 1034 | /* | 
|---|
| 1035 | * Given a standard character name (a string), find its code (a number). | 
|---|
| 1036 | * Return -1 if name is unknown. | 
|---|
| 1037 | */ | 
|---|
| 1038 |  | 
|---|
| 1039 | int | 
|---|
| 1040 | RTFStdCharCode (name) | 
|---|
| 1041 | char    *name; | 
|---|
| 1042 | { | 
|---|
| 1043 | int     i; | 
|---|
| 1044 |  | 
|---|
| 1045 | for (i = 0; i < rtfSC_MaxChar; i++) | 
|---|
| 1046 | { | 
|---|
| 1047 | if (strcmp (name, stdCharName[i]) == 0) | 
|---|
| 1048 | return (i); | 
|---|
| 1049 | } | 
|---|
| 1050 | return (-1); | 
|---|
| 1051 | } | 
|---|
| 1052 |  | 
|---|
| 1053 |  | 
|---|
| 1054 | /* | 
|---|
| 1055 | * Given a standard character code (a number), find its name (a string). | 
|---|
| 1056 | * Return NULL if code is unknown. | 
|---|
| 1057 | */ | 
|---|
| 1058 |  | 
|---|
| 1059 | char * | 
|---|
| 1060 | RTFStdCharName (code) | 
|---|
| 1061 | int     code; | 
|---|
| 1062 | { | 
|---|
| 1063 | if (code < 0 || code >= rtfSC_MaxChar) | 
|---|
| 1064 | return ((char *) NULL); | 
|---|
| 1065 | return (stdCharName[code]); | 
|---|
| 1066 | } | 
|---|
| 1067 |  | 
|---|
| 1068 |  | 
|---|
| 1069 | /* | 
|---|
| 1070 | * Given an RTF input character code, find standard character code. | 
|---|
| 1071 | * The translator should read the appropriate charset maps when it finds a | 
|---|
| 1072 | * charset control.  However, the file might not contain one.  In this | 
|---|
| 1073 | * case, no map will be available.  When the first attempt is made to | 
|---|
| 1074 | * map a character under these circumstances, RTFMapChar() assumes ANSI | 
|---|
| 1075 | * and reads the map as necessary. | 
|---|
| 1076 | */ | 
|---|
| 1077 |  | 
|---|
| 1078 | int | 
|---|
| 1079 | RTFMapChar (c) | 
|---|
| 1080 | int     c; | 
|---|
| 1081 | { | 
|---|
| 1082 | switch (curCharSet) | 
|---|
| 1083 | { | 
|---|
| 1084 | case rtfCSGeneral: | 
|---|
| 1085 | if (!haveGenCharSet) | 
|---|
| 1086 | { | 
|---|
| 1087 | if (RTFReadCharSetMap (rtfCSGeneral) == 0) | 
|---|
| 1088 | RTFPanic ("RTFMapChar: cannot read ansi-gen"); | 
|---|
| 1089 | } | 
|---|
| 1090 | break; | 
|---|
| 1091 | case rtfCSSymbol: | 
|---|
| 1092 | if (!haveSymCharSet) | 
|---|
| 1093 | { | 
|---|
| 1094 | if (RTFReadCharSetMap (rtfCSSymbol) == 0) | 
|---|
| 1095 | RTFPanic ("RTFMapChar: cannot read ansi-sym"); | 
|---|
| 1096 | } | 
|---|
| 1097 | break; | 
|---|
| 1098 | } | 
|---|
| 1099 | if (c < 0 || c >= charSetSize) | 
|---|
| 1100 | return (rtfSC_nothing); | 
|---|
| 1101 | return (curCharCode[c]); | 
|---|
| 1102 | } | 
|---|
| 1103 |  | 
|---|
| 1104 |  | 
|---|
| 1105 | /* | 
|---|
| 1106 | * Set the current character set.  If csId is illegal, uses general charset. | 
|---|
| 1107 | */ | 
|---|
| 1108 |  | 
|---|
| 1109 | void | 
|---|
| 1110 | RTFSetCharSet (csId) | 
|---|
| 1111 | int     csId; | 
|---|
| 1112 | { | 
|---|
| 1113 | switch (csId) | 
|---|
| 1114 | { | 
|---|
| 1115 | default:                /* use general if csId unknown */ | 
|---|
| 1116 | case rtfCSGeneral: | 
|---|
| 1117 | curCharCode = genCharCode; | 
|---|
| 1118 | curCharSet = csId; | 
|---|
| 1119 | break; | 
|---|
| 1120 | case rtfCSSymbol: | 
|---|
| 1121 | curCharCode = symCharCode; | 
|---|
| 1122 | curCharSet = csId; | 
|---|
| 1123 | break; | 
|---|
| 1124 | } | 
|---|
| 1125 | } | 
|---|
| 1126 |  | 
|---|
| 1127 |  | 
|---|
| 1128 | int | 
|---|
| 1129 | RTFGetCharSet () | 
|---|
| 1130 | { | 
|---|
| 1131 | return (curCharSet); | 
|---|
| 1132 | } | 
|---|
| 1133 |  | 
|---|
| 1134 |  | 
|---|
| 1135 | /* ---------------------------------------------------------------------- */ | 
|---|
| 1136 |  | 
|---|
| 1137 | /* | 
|---|
| 1138 | * Special destination readers.  They gobble the destination so the | 
|---|
| 1139 | * writer doesn't have to deal with them.  That's wrong for any | 
|---|
| 1140 | * translator that wants to process any of these itself.  In that | 
|---|
| 1141 | * case, these readers should be overridden by installing a different | 
|---|
| 1142 | * destination callback. | 
|---|
| 1143 | * | 
|---|
| 1144 | * NOTE: The last token read by each of these reader will be the | 
|---|
| 1145 | * destination's terminating '}', which will then be the current token. | 
|---|
| 1146 | * That '}' token is passed to RTFRouteToken() - the writer has already | 
|---|
| 1147 | * seen the '{' that began the destination group, and may have pushed a | 
|---|
| 1148 | * state; it also needs to know at the end of the group that a state | 
|---|
| 1149 | * should be popped. | 
|---|
| 1150 | * | 
|---|
| 1151 | * It's important that rtf.h and the control token lookup table list | 
|---|
| 1152 | * as many symbols as possible, because these destination readers | 
|---|
| 1153 | * unfortunately make strict assumptions about the input they expect, | 
|---|
| 1154 | * and a token of class rtfUnknown will throw them off easily. | 
|---|
| 1155 | */ | 
|---|
| 1156 |  | 
|---|
| 1157 |  | 
|---|
| 1158 | /* | 
|---|
| 1159 | * Read { \fonttbl ... } destination.  Old font tables don't have | 
|---|
| 1160 | * braces around each table entry; try to adjust for that. | 
|---|
| 1161 | */ | 
|---|
| 1162 |  | 
|---|
| 1163 | static void | 
|---|
| 1164 | ReadFontTbl () | 
|---|
| 1165 | { | 
|---|
| 1166 | RTFFont *fp = NULL; | 
|---|
| 1167 | char    buf[rtfBufSiz], *bp; | 
|---|
| 1168 | int     old = -1; | 
|---|
| 1169 | char    *fn = "ReadFontTbl"; | 
|---|
| 1170 |  | 
|---|
| 1171 | for (;;) | 
|---|
| 1172 | { | 
|---|
| 1173 | (void) RTFGetToken (); | 
|---|
| 1174 | if (RTFCheckCM (rtfGroup, rtfEndGroup)) | 
|---|
| 1175 | break; | 
|---|
| 1176 | if (old < 0)            /* first entry - determine tbl type */ | 
|---|
| 1177 | { | 
|---|
| 1178 | if (RTFCheckCMM (rtfControl, rtfCharAttr, rtfFontNum)) | 
|---|
| 1179 | old = 1;        /* no brace */ | 
|---|
| 1180 | else if (RTFCheckCM (rtfGroup, rtfBeginGroup)) | 
|---|
| 1181 | old = 0;        /* brace */ | 
|---|
| 1182 | else                    /* can't tell! */ | 
|---|
| 1183 | RTFPanic ("%s: Cannot determine format", fn); | 
|---|
| 1184 | } | 
|---|
| 1185 | if (old == 0)           /* need to find "{" here */ | 
|---|
| 1186 | { | 
|---|
| 1187 | if (!RTFCheckCM (rtfGroup, rtfBeginGroup)) | 
|---|
| 1188 | RTFPanic ("%s: missing \"{\"", fn); | 
|---|
| 1189 | (void) RTFGetToken ();  /* yes, skip to next token */ | 
|---|
| 1190 | } | 
|---|
| 1191 | if ((fp = New (RTFFont)) == (RTFFont *) NULL) | 
|---|
| 1192 | RTFPanic ("%s: cannot allocate font entry", fn); | 
|---|
| 1193 |  | 
|---|
| 1194 | fp->rtfNextFont = fontList; | 
|---|
| 1195 | fontList = fp; | 
|---|
| 1196 |  | 
|---|
| 1197 | fp->rtfFName = (char *) NULL; | 
|---|
| 1198 | fp->rtfFAltName = (char *) NULL; | 
|---|
| 1199 | fp->rtfFNum = -1; | 
|---|
| 1200 | fp->rtfFFamily = 0; | 
|---|
| 1201 | fp->rtfFCharSet = 0; | 
|---|
| 1202 | fp->rtfFPitch = 0; | 
|---|
| 1203 | fp->rtfFType = 0; | 
|---|
| 1204 | fp->rtfFCodePage = 0; | 
|---|
| 1205 |  | 
|---|
| 1206 | while (rtfClass != rtfEOF | 
|---|
| 1207 | && !RTFCheckCM (rtfText, ';') | 
|---|
| 1208 | && !RTFCheckCM (rtfGroup, rtfEndGroup)) | 
|---|
| 1209 | { | 
|---|
| 1210 | if (rtfClass == rtfControl) | 
|---|
| 1211 | { | 
|---|
| 1212 | switch (rtfMajor) | 
|---|
| 1213 | { | 
|---|
| 1214 | default: | 
|---|
| 1215 | /* ignore token but announce it */ | 
|---|
| 1216 | RTFMsg ("%s: unknown token \"%s\"\n", | 
|---|
| 1217 | fn, rtfTextBuf); | 
|---|
| 1218 | case rtfFontFamily: | 
|---|
| 1219 | fp->rtfFFamily = rtfMinor; | 
|---|
| 1220 | break; | 
|---|
| 1221 | case rtfCharAttr: | 
|---|
| 1222 | switch (rtfMinor) | 
|---|
| 1223 | { | 
|---|
| 1224 | default: | 
|---|
| 1225 | break;  /* ignore unknown? */ | 
|---|
| 1226 | case rtfFontNum: | 
|---|
| 1227 | fp->rtfFNum = rtfParam; | 
|---|
| 1228 | break; | 
|---|
| 1229 | } | 
|---|
| 1230 | break; | 
|---|
| 1231 | case rtfFontAttr: | 
|---|
| 1232 | switch (rtfMinor) | 
|---|
| 1233 | { | 
|---|
| 1234 | default: | 
|---|
| 1235 | break;  /* ignore unknown? */ | 
|---|
| 1236 | case rtfFontCharSet: | 
|---|
| 1237 | fp->rtfFCharSet = rtfParam; | 
|---|
| 1238 | break; | 
|---|
| 1239 | case rtfFontPitch: | 
|---|
| 1240 | fp->rtfFPitch = rtfParam; | 
|---|
| 1241 | break; | 
|---|
| 1242 | case rtfFontCodePage: | 
|---|
| 1243 | fp->rtfFCodePage = rtfParam; | 
|---|
| 1244 | break; | 
|---|
| 1245 | case rtfFTypeNil: | 
|---|
| 1246 | case rtfFTypeTrueType: | 
|---|
| 1247 | fp->rtfFType = rtfParam; | 
|---|
| 1248 | break; | 
|---|
| 1249 | } | 
|---|
| 1250 | break; | 
|---|
| 1251 | } | 
|---|
| 1252 | } | 
|---|
| 1253 | else if (RTFCheckCM (rtfGroup, rtfBeginGroup))  /* dest */ | 
|---|
| 1254 | { | 
|---|
| 1255 | RTFSkipGroup ();        /* ignore for now */ | 
|---|
| 1256 | } | 
|---|
| 1257 | else if (rtfClass == rtfText)   /* font name */ | 
|---|
| 1258 | { | 
|---|
| 1259 | bp = buf; | 
|---|
| 1260 | while (rtfClass != rtfEOF | 
|---|
| 1261 | && !RTFCheckCM (rtfText, ';') | 
|---|
| 1262 | && !RTFCheckCM (rtfGroup, rtfEndGroup)) | 
|---|
| 1263 | { | 
|---|
| 1264 | *bp++ = rtfMajor; | 
|---|
| 1265 | (void) RTFGetToken (); | 
|---|
| 1266 | } | 
|---|
| 1267 |  | 
|---|
| 1268 | /* FIX: in some cases the <fontinfo> isn't finished with a semi-column */ | 
|---|
| 1269 | if(RTFCheckCM (rtfGroup, rtfEndGroup)) | 
|---|
| 1270 | { | 
|---|
| 1271 | RTFUngetToken (); | 
|---|
| 1272 | } | 
|---|
| 1273 | *bp = '\0'; | 
|---|
| 1274 | fp->rtfFName = RTFStrSave (buf); | 
|---|
| 1275 | if (fp->rtfFName == (char *) NULL) | 
|---|
| 1276 | RTFPanic ("%s: cannot allocate font name", fn); | 
|---|
| 1277 | /* already have next token; don't read one */ | 
|---|
| 1278 | /* at bottom of loop */ | 
|---|
| 1279 | continue; | 
|---|
| 1280 | } | 
|---|
| 1281 | else | 
|---|
| 1282 | { | 
|---|
| 1283 | /* ignore token but announce it */ | 
|---|
| 1284 | RTFMsg ("%s: unknown token \"%s\"\n", | 
|---|
| 1285 | fn, rtfTextBuf); | 
|---|
| 1286 | } | 
|---|
| 1287 | (void) RTFGetToken (); | 
|---|
| 1288 | } | 
|---|
| 1289 | if (old == 0)   /* need to see "}" here */ | 
|---|
| 1290 | { | 
|---|
| 1291 | (void) RTFGetToken (); | 
|---|
| 1292 | if (!RTFCheckCM (rtfGroup, rtfEndGroup)) | 
|---|
| 1293 | RTFPanic ("%s: missing \"}\"", fn); | 
|---|
| 1294 | } | 
|---|
| 1295 | } | 
|---|
| 1296 | if (fp->rtfFNum == -1) | 
|---|
| 1297 | RTFPanic ("%s: missing font number", fn); | 
|---|
| 1298 | /* | 
|---|
| 1299 | * Could check other pieces of structure here, too, I suppose. | 
|---|
| 1300 | */ | 
|---|
| 1301 | RTFRouteToken ();       /* feed "}" back to router */ | 
|---|
| 1302 | } | 
|---|
| 1303 |  | 
|---|
| 1304 |  | 
|---|
| 1305 | /* | 
|---|
| 1306 | * The color table entries have color values of -1 if | 
|---|
| 1307 | * the default color should be used for the entry (only | 
|---|
| 1308 | * a semi-colon is given in the definition, no color values). | 
|---|
| 1309 | * There will be a problem if a partial entry (1 or 2 but | 
|---|
| 1310 | * not 3 color values) is given.  The possibility is ignored | 
|---|
| 1311 | * here. | 
|---|
| 1312 | */ | 
|---|
| 1313 |  | 
|---|
| 1314 | static void | 
|---|
| 1315 | ReadColorTbl () | 
|---|
| 1316 | { | 
|---|
| 1317 | RTFColor        *cp; | 
|---|
| 1318 | int             cnum = 0; | 
|---|
| 1319 | char            *fn = "ReadColorTbl"; | 
|---|
| 1320 |  | 
|---|
| 1321 | for (;;) | 
|---|
| 1322 | { | 
|---|
| 1323 | (void) RTFGetToken (); | 
|---|
| 1324 | if (RTFCheckCM (rtfGroup, rtfEndGroup)) | 
|---|
| 1325 | break; | 
|---|
| 1326 | if ((cp = New (RTFColor)) == (RTFColor *) NULL) | 
|---|
| 1327 | RTFPanic ("%s: cannot allocate color entry", fn); | 
|---|
| 1328 | cp->rtfCNum = cnum++; | 
|---|
| 1329 | cp->rtfCRed = cp->rtfCGreen = cp->rtfCBlue = -1; | 
|---|
| 1330 | cp->rtfNextColor = colorList; | 
|---|
| 1331 | colorList = cp; | 
|---|
| 1332 | while (RTFCheckCM (rtfControl, rtfColorName)) | 
|---|
| 1333 | { | 
|---|
| 1334 | switch (rtfMinor) | 
|---|
| 1335 | { | 
|---|
| 1336 | case rtfRed:    cp->rtfCRed = rtfParam; break; | 
|---|
| 1337 | case rtfGreen:  cp->rtfCGreen = rtfParam; break; | 
|---|
| 1338 | case rtfBlue:   cp->rtfCBlue = rtfParam; break; | 
|---|
| 1339 | } | 
|---|
| 1340 | RTFGetToken (); | 
|---|
| 1341 | } | 
|---|
| 1342 | if (!RTFCheckCM (rtfText, (int) ';')) | 
|---|
| 1343 | RTFPanic ("%s: malformed entry", fn); | 
|---|
| 1344 | } | 
|---|
| 1345 | RTFRouteToken ();       /* feed "}" back to router */ | 
|---|
| 1346 | } | 
|---|
| 1347 |  | 
|---|
| 1348 |  | 
|---|
| 1349 | /* | 
|---|
| 1350 | * The "Normal" style definition doesn't contain any style number, | 
|---|
| 1351 | * all others do.  Normal style is given style rtfNormalStyleNum. | 
|---|
| 1352 | */ | 
|---|
| 1353 |  | 
|---|
| 1354 | static void | 
|---|
| 1355 | ReadStyleSheet () | 
|---|
| 1356 | { | 
|---|
| 1357 | RTFStyle        *sp; | 
|---|
| 1358 | RTFStyleElt     *sep, *sepLast; | 
|---|
| 1359 | char            buf[rtfBufSiz], *bp; | 
|---|
| 1360 | char            *fn = "ReadStyleSheet"; | 
|---|
| 1361 |  | 
|---|
| 1362 | for (;;) | 
|---|
| 1363 | { | 
|---|
| 1364 | (void) RTFGetToken (); | 
|---|
| 1365 | if (RTFCheckCM (rtfGroup, rtfEndGroup)) | 
|---|
| 1366 | break; | 
|---|
| 1367 | if ((sp = New (RTFStyle)) == (RTFStyle *) NULL) | 
|---|
| 1368 | RTFPanic ("%s: cannot allocate stylesheet entry", fn); | 
|---|
| 1369 | sp->rtfSName = (char *) NULL; | 
|---|
| 1370 | sp->rtfSNum = -1; | 
|---|
| 1371 | sp->rtfSType = rtfParStyle; | 
|---|
| 1372 | sp->rtfSAdditive = 0; | 
|---|
| 1373 | sp->rtfSBasedOn = rtfNoStyleNum; | 
|---|
| 1374 | sp->rtfSNextPar = -1; | 
|---|
| 1375 | sp->rtfSSEList = sepLast = (RTFStyleElt *) NULL; | 
|---|
| 1376 | sp->rtfNextStyle = styleList; | 
|---|
| 1377 | sp->rtfExpanding = 0; | 
|---|
| 1378 | styleList = sp; | 
|---|
| 1379 | if (!RTFCheckCM (rtfGroup, rtfBeginGroup)) | 
|---|
| 1380 | RTFPanic ("%s: missing \"{\"", fn); | 
|---|
| 1381 | for (;;) | 
|---|
| 1382 | { | 
|---|
| 1383 | (void) RTFGetToken (); | 
|---|
| 1384 | if (rtfClass == rtfEOF | 
|---|
| 1385 | || RTFCheckCM (rtfText, ';')) | 
|---|
| 1386 | break; | 
|---|
| 1387 | if (rtfClass == rtfControl) | 
|---|
| 1388 | { | 
|---|
| 1389 | if (RTFCheckMM (rtfSpecialChar, rtfOptDest)) | 
|---|
| 1390 | continue;       /* ignore "\*" */ | 
|---|
| 1391 | if (RTFCheckMM (rtfParAttr, rtfStyleNum)) | 
|---|
| 1392 | { | 
|---|
| 1393 | sp->rtfSNum = rtfParam; | 
|---|
| 1394 | sp->rtfSType = rtfParStyle; | 
|---|
| 1395 | continue; | 
|---|
| 1396 | } | 
|---|
| 1397 | if (RTFCheckMM (rtfCharAttr, rtfCharStyleNum)) | 
|---|
| 1398 | { | 
|---|
| 1399 | sp->rtfSNum = rtfParam; | 
|---|
| 1400 | sp->rtfSType = rtfCharStyle; | 
|---|
| 1401 | continue; | 
|---|
| 1402 | } | 
|---|
| 1403 | if (RTFCheckMM (rtfSectAttr, rtfSectStyleNum)) | 
|---|
| 1404 | { | 
|---|
| 1405 | sp->rtfSNum = rtfParam; | 
|---|
| 1406 | sp->rtfSType = rtfSectStyle; | 
|---|
| 1407 | continue; | 
|---|
| 1408 | } | 
|---|
| 1409 | if (RTFCheckMM (rtfStyleAttr, rtfBasedOn)) | 
|---|
| 1410 | { | 
|---|
| 1411 | sp->rtfSBasedOn = rtfParam; | 
|---|
| 1412 | continue; | 
|---|
| 1413 | } | 
|---|
| 1414 | if (RTFCheckMM (rtfStyleAttr, rtfAdditive)) | 
|---|
| 1415 | { | 
|---|
| 1416 | sp->rtfSAdditive = 1; | 
|---|
| 1417 | continue; | 
|---|
| 1418 | } | 
|---|
| 1419 | if (RTFCheckMM (rtfStyleAttr, rtfNext)) | 
|---|
| 1420 | { | 
|---|
| 1421 | sp->rtfSNextPar = rtfParam; | 
|---|
| 1422 | continue; | 
|---|
| 1423 | } | 
|---|
| 1424 | if ((sep = New (RTFStyleElt)) == (RTFStyleElt *) NULL) | 
|---|
| 1425 | RTFPanic ("%s: cannot allocate style element", fn); | 
|---|
| 1426 | sep->rtfSEClass = rtfClass; | 
|---|
| 1427 | sep->rtfSEMajor = rtfMajor; | 
|---|
| 1428 | sep->rtfSEMinor = rtfMinor; | 
|---|
| 1429 | sep->rtfSEParam = rtfParam; | 
|---|
| 1430 | if ((sep->rtfSEText = RTFStrSave (rtfTextBuf)) | 
|---|
| 1431 | == (char *) NULL) | 
|---|
| 1432 | RTFPanic ("%s: cannot allocate style element text", fn); | 
|---|
| 1433 | if (sepLast == (RTFStyleElt *) NULL) | 
|---|
| 1434 | sp->rtfSSEList = sep;   /* first element */ | 
|---|
| 1435 | else                            /* add to end */ | 
|---|
| 1436 | sepLast->rtfNextSE = sep; | 
|---|
| 1437 | sep->rtfNextSE = (RTFStyleElt *) NULL; | 
|---|
| 1438 | sepLast = sep; | 
|---|
| 1439 | } | 
|---|
| 1440 | else if (RTFCheckCM (rtfGroup, rtfBeginGroup)) | 
|---|
| 1441 | { | 
|---|
| 1442 | /* | 
|---|
| 1443 | * This passes over "{\*\keycode ... }, among | 
|---|
| 1444 | * other things. A temporary (perhaps) hack. | 
|---|
| 1445 | */ | 
|---|
| 1446 | RTFSkipGroup (); | 
|---|
| 1447 | continue; | 
|---|
| 1448 | } | 
|---|
| 1449 | else if (rtfClass == rtfText)   /* style name */ | 
|---|
| 1450 | { | 
|---|
| 1451 | bp = buf; | 
|---|
| 1452 | while (rtfClass == rtfText) | 
|---|
| 1453 | { | 
|---|
| 1454 | if (rtfMajor == ';') | 
|---|
| 1455 | { | 
|---|
| 1456 | /* put back for "for" loop */ | 
|---|
| 1457 | (void) RTFUngetToken (); | 
|---|
| 1458 | break; | 
|---|
| 1459 | } | 
|---|
| 1460 | *bp++ = rtfMajor; | 
|---|
| 1461 | (void) RTFGetToken (); | 
|---|
| 1462 | } | 
|---|
| 1463 | *bp = '\0'; | 
|---|
| 1464 | if ((sp->rtfSName = RTFStrSave (buf)) == (char *) NULL) | 
|---|
| 1465 | RTFPanic ("%s: cannot allocate style name", fn); | 
|---|
| 1466 | } | 
|---|
| 1467 | else            /* unrecognized */ | 
|---|
| 1468 | { | 
|---|
| 1469 | /* ignore token but announce it */ | 
|---|
| 1470 | RTFMsg ("%s: unknown token \"%s\"\n", | 
|---|
| 1471 | fn, rtfTextBuf); | 
|---|
| 1472 | } | 
|---|
| 1473 | } | 
|---|
| 1474 | (void) RTFGetToken (); | 
|---|
| 1475 | if (!RTFCheckCM (rtfGroup, rtfEndGroup)) | 
|---|
| 1476 | RTFPanic ("%s: missing \"}\"", fn); | 
|---|
| 1477 |  | 
|---|
| 1478 | /* | 
|---|
| 1479 | * Check over the style structure.  A name is a must. | 
|---|
| 1480 | * If no style number was specified, check whether it's the | 
|---|
| 1481 | * Normal style (in which case it's given style number | 
|---|
| 1482 | * rtfNormalStyleNum).  Note that some "normal" style names | 
|---|
| 1483 | * just begin with "Normal" and can have other stuff following, | 
|---|
| 1484 | * e.g., "Normal,Times 10 point".  Ugh. | 
|---|
| 1485 | * | 
|---|
| 1486 | * Some German RTF writers use "Standard" instead of "Normal". | 
|---|
| 1487 | */ | 
|---|
| 1488 | if (sp->rtfSName == (char *) NULL) | 
|---|
| 1489 | RTFPanic ("%s: missing style name", fn); | 
|---|
| 1490 | if (sp->rtfSNum < 0) | 
|---|
| 1491 | { | 
|---|
| 1492 | if (strncmp (buf, "Normal", 6) != 0 | 
|---|
| 1493 | && strncmp (buf, "Standard", 8) != 0) | 
|---|
| 1494 | RTFPanic ("%s: missing style number", fn); | 
|---|
| 1495 | sp->rtfSNum = rtfNormalStyleNum; | 
|---|
| 1496 | } | 
|---|
| 1497 | if (sp->rtfSNextPar == -1)      /* if \snext not given, */ | 
|---|
| 1498 | sp->rtfSNextPar = sp->rtfSNum;  /* next is itself */ | 
|---|
| 1499 | } | 
|---|
| 1500 | RTFRouteToken ();       /* feed "}" back to router */ | 
|---|
| 1501 | } | 
|---|
| 1502 |  | 
|---|
| 1503 |  | 
|---|
| 1504 | static void | 
|---|
| 1505 | ReadInfoGroup () | 
|---|
| 1506 | { | 
|---|
| 1507 | RTFSkipGroup (); | 
|---|
| 1508 | RTFRouteToken ();       /* feed "}" back to router */ | 
|---|
| 1509 | } | 
|---|
| 1510 |  | 
|---|
| 1511 |  | 
|---|
| 1512 | static void | 
|---|
| 1513 | ReadPictGroup () | 
|---|
| 1514 | { | 
|---|
| 1515 | RTFSkipGroup (); | 
|---|
| 1516 | RTFRouteToken ();       /* feed "}" back to router */ | 
|---|
| 1517 | } | 
|---|
| 1518 |  | 
|---|
| 1519 |  | 
|---|
| 1520 | static void | 
|---|
| 1521 | ReadObjGroup () | 
|---|
| 1522 | { | 
|---|
| 1523 | RTFSkipGroup (); | 
|---|
| 1524 | RTFRouteToken ();       /* feed "}" back to router */ | 
|---|
| 1525 | } | 
|---|
| 1526 |  | 
|---|
| 1527 |  | 
|---|
| 1528 | /* ---------------------------------------------------------------------- */ | 
|---|
| 1529 |  | 
|---|
| 1530 | /* | 
|---|
| 1531 | * Routines to return pieces of stylesheet, or font or color tables. | 
|---|
| 1532 | * References to style 0 are mapped onto the Normal style. | 
|---|
| 1533 | */ | 
|---|
| 1534 |  | 
|---|
| 1535 |  | 
|---|
| 1536 | RTFStyle * | 
|---|
| 1537 | RTFGetStyle (num) | 
|---|
| 1538 | int     num; | 
|---|
| 1539 | { | 
|---|
| 1540 | RTFStyle        *s; | 
|---|
| 1541 |  | 
|---|
| 1542 | if (num == -1) | 
|---|
| 1543 | return (styleList); | 
|---|
| 1544 | for (s = styleList; s != (RTFStyle *) NULL; s = s->rtfNextStyle) | 
|---|
| 1545 | { | 
|---|
| 1546 | if (s->rtfSNum == num) | 
|---|
| 1547 | break; | 
|---|
| 1548 | } | 
|---|
| 1549 | return (s);             /* NULL if not found */ | 
|---|
| 1550 | } | 
|---|
| 1551 |  | 
|---|
| 1552 |  | 
|---|
| 1553 | RTFFont * | 
|---|
| 1554 | RTFGetFont (num) | 
|---|
| 1555 | int     num; | 
|---|
| 1556 | { | 
|---|
| 1557 | RTFFont *f; | 
|---|
| 1558 |  | 
|---|
| 1559 | if (num == -1) | 
|---|
| 1560 | return (fontList); | 
|---|
| 1561 | for (f = fontList; f != (RTFFont *) NULL; f = f->rtfNextFont) | 
|---|
| 1562 | { | 
|---|
| 1563 | if (f->rtfFNum == num) | 
|---|
| 1564 | break; | 
|---|
| 1565 | } | 
|---|
| 1566 | return (f);             /* NULL if not found */ | 
|---|
| 1567 | } | 
|---|
| 1568 |  | 
|---|
| 1569 |  | 
|---|
| 1570 | RTFColor * | 
|---|
| 1571 | RTFGetColor (num) | 
|---|
| 1572 | int     num; | 
|---|
| 1573 | { | 
|---|
| 1574 | RTFColor        *c; | 
|---|
| 1575 |  | 
|---|
| 1576 | if (num == -1) | 
|---|
| 1577 | return (colorList); | 
|---|
| 1578 | for (c = colorList; c != (RTFColor *) NULL; c = c->rtfNextColor) | 
|---|
| 1579 | { | 
|---|
| 1580 | if (c->rtfCNum == num) | 
|---|
| 1581 | break; | 
|---|
| 1582 | } | 
|---|
| 1583 | return (c);             /* NULL if not found */ | 
|---|
| 1584 | } | 
|---|
| 1585 |  | 
|---|
| 1586 |  | 
|---|
| 1587 | /* ---------------------------------------------------------------------- */ | 
|---|
| 1588 |  | 
|---|
| 1589 |  | 
|---|
| 1590 | /* | 
|---|
| 1591 | * Expand style n, if there is such a style. | 
|---|
| 1592 | */ | 
|---|
| 1593 |  | 
|---|
| 1594 | void | 
|---|
| 1595 | RTFExpandStyle (n) | 
|---|
| 1596 | int     n; | 
|---|
| 1597 | { | 
|---|
| 1598 | RTFStyle        *s; | 
|---|
| 1599 | RTFStyleElt     *se; | 
|---|
| 1600 |  | 
|---|
| 1601 | if (n == -1 || (s = RTFGetStyle (n)) == (RTFStyle *) NULL) | 
|---|
| 1602 | return; | 
|---|
| 1603 | if (s->rtfExpanding != 0) | 
|---|
| 1604 | RTFPanic ("Style expansion loop, style %d", n); | 
|---|
| 1605 | s->rtfExpanding = 1;    /* set expansion flag for loop detection */ | 
|---|
| 1606 | /* | 
|---|
| 1607 | * Expand "based-on" style (unless it's the same as the current | 
|---|
| 1608 | * style -- Normal style usually gives itself as its own based-on | 
|---|
| 1609 | * style).  Based-on style expansion is done by synthesizing | 
|---|
| 1610 | * the token that the writer needs to see in order to trigger | 
|---|
| 1611 | * another style expansion, and feeding to token back through | 
|---|
| 1612 | * the router so the writer sees it. | 
|---|
| 1613 | */ | 
|---|
| 1614 | if (n != s->rtfSBasedOn) | 
|---|
| 1615 | { | 
|---|
| 1616 | RTFSetToken (rtfControl, rtfParAttr, rtfStyleNum, | 
|---|
| 1617 | s->rtfSBasedOn, "\\s"); | 
|---|
| 1618 | RTFRouteToken (); | 
|---|
| 1619 | } | 
|---|
| 1620 | /* | 
|---|
| 1621 | * Now route the tokens unique to this style.  RTFSetToken() | 
|---|
| 1622 | * isn't used because it would add the param value to the end | 
|---|
| 1623 | * of the token text, which already has it in. | 
|---|
| 1624 | */ | 
|---|
| 1625 | for (se = s->rtfSSEList; se != (RTFStyleElt *) NULL; se = se->rtfNextSE) | 
|---|
| 1626 | { | 
|---|
| 1627 | rtfClass = se->rtfSEClass; | 
|---|
| 1628 | rtfMajor = se->rtfSEMajor; | 
|---|
| 1629 | rtfMinor = se->rtfSEMinor; | 
|---|
| 1630 | rtfParam = se->rtfSEParam; | 
|---|
| 1631 | (void) strcpy (rtfTextBuf, se->rtfSEText); | 
|---|
| 1632 | rtfTextLen = strlen (rtfTextBuf); | 
|---|
| 1633 | RTFRouteToken (); | 
|---|
| 1634 | } | 
|---|
| 1635 | s->rtfExpanding = 0;    /* done - clear expansion flag */ | 
|---|
| 1636 | } | 
|---|
| 1637 |  | 
|---|
| 1638 |  | 
|---|
| 1639 | /* ---------------------------------------------------------------------- */ | 
|---|
| 1640 |  | 
|---|
| 1641 | /* | 
|---|
| 1642 | * Control symbol lookup routines | 
|---|
| 1643 | */ | 
|---|
| 1644 |  | 
|---|
| 1645 |  | 
|---|
| 1646 | typedef struct RTFKey   RTFKey; | 
|---|
| 1647 |  | 
|---|
| 1648 | struct RTFKey | 
|---|
| 1649 | { | 
|---|
| 1650 | int     rtfKMajor;      /* major number */ | 
|---|
| 1651 | int     rtfKMinor;      /* minor number */ | 
|---|
| 1652 | char    *rtfKStr;       /* symbol name */ | 
|---|
| 1653 | int     rtfKHash;       /* symbol name hash value */ | 
|---|
| 1654 | }; | 
|---|
| 1655 |  | 
|---|
| 1656 | /* | 
|---|
| 1657 | * A minor number of -1 means the token has no minor number | 
|---|
| 1658 | * (all valid minor numbers are >= 0). | 
|---|
| 1659 | */ | 
|---|
| 1660 |  | 
|---|
| 1661 | static RTFKey   rtfKey[] = | 
|---|
| 1662 | { | 
|---|
| 1663 | /* | 
|---|
| 1664 | * Special characters | 
|---|
| 1665 | */ | 
|---|
| 1666 |  | 
|---|
| 1667 | { rtfSpecialChar,       rtfIIntVersion,         "vern",         0 }, | 
|---|
| 1668 | { rtfSpecialChar,       rtfICreateTime,         "creatim",      0 }, | 
|---|
| 1669 | { rtfSpecialChar,       rtfIRevisionTime,       "revtim",       0 }, | 
|---|
| 1670 | { rtfSpecialChar,       rtfIPrintTime,          "printim",      0 }, | 
|---|
| 1671 | { rtfSpecialChar,       rtfIBackupTime,         "buptim",       0 }, | 
|---|
| 1672 | { rtfSpecialChar,       rtfIEditTime,           "edmins",       0 }, | 
|---|
| 1673 | { rtfSpecialChar,       rtfIYear,               "yr",           0 }, | 
|---|
| 1674 | { rtfSpecialChar,       rtfIMonth,              "mo",           0 }, | 
|---|
| 1675 | { rtfSpecialChar,       rtfIDay,                "dy",           0 }, | 
|---|
| 1676 | { rtfSpecialChar,       rtfIHour,               "hr",           0 }, | 
|---|
| 1677 | { rtfSpecialChar,       rtfIMinute,             "min",          0 }, | 
|---|
| 1678 | { rtfSpecialChar,       rtfISecond,             "sec",          0 }, | 
|---|
| 1679 | { rtfSpecialChar,       rtfINPages,             "nofpages",     0 }, | 
|---|
| 1680 | { rtfSpecialChar,       rtfINWords,             "nofwords",     0 }, | 
|---|
| 1681 | { rtfSpecialChar,       rtfINChars,             "nofchars",     0 }, | 
|---|
| 1682 | { rtfSpecialChar,       rtfIIntID,              "id",           0 }, | 
|---|
| 1683 |  | 
|---|
| 1684 | { rtfSpecialChar,       rtfCurHeadDate,         "chdate",       0 }, | 
|---|
| 1685 | { rtfSpecialChar,       rtfCurHeadDateLong,     "chdpl",        0 }, | 
|---|
| 1686 | { rtfSpecialChar,       rtfCurHeadDateAbbrev,   "chdpa",        0 }, | 
|---|
| 1687 | { rtfSpecialChar,       rtfCurHeadTime,         "chtime",       0 }, | 
|---|
| 1688 | { rtfSpecialChar,       rtfCurHeadPage,         "chpgn",        0 }, | 
|---|
| 1689 | { rtfSpecialChar,       rtfSectNum,             "sectnum",      0 }, | 
|---|
| 1690 | { rtfSpecialChar,       rtfCurFNote,            "chftn",        0 }, | 
|---|
| 1691 | { rtfSpecialChar,       rtfCurAnnotRef,         "chatn",        0 }, | 
|---|
| 1692 | { rtfSpecialChar,       rtfFNoteSep,            "chftnsep",     0 }, | 
|---|
| 1693 | { rtfSpecialChar,       rtfFNoteCont,           "chftnsepc",    0 }, | 
|---|
| 1694 | { rtfSpecialChar,       rtfCell,                "cell",         0 }, | 
|---|
| 1695 | { rtfSpecialChar,       rtfRow,                 "row",          0 }, | 
|---|
| 1696 | { rtfSpecialChar,       rtfPar,                 "par",          0 }, | 
|---|
| 1697 | /* newline and carriage return are synonyms for */ | 
|---|
| 1698 | /* \par when they are preceded by a \ character */ | 
|---|
| 1699 | { rtfSpecialChar,       rtfPar,                 "\n",           0 }, | 
|---|
| 1700 | { rtfSpecialChar,       rtfPar,                 "\r",           0 }, | 
|---|
| 1701 | { rtfSpecialChar,       rtfSect,                "sect",         0 }, | 
|---|
| 1702 | { rtfSpecialChar,       rtfPage,                "page",         0 }, | 
|---|
| 1703 | { rtfSpecialChar,       rtfColumn,              "column",       0 }, | 
|---|
| 1704 | { rtfSpecialChar,       rtfLine,                "line",         0 }, | 
|---|
| 1705 | { rtfSpecialChar,       rtfSoftPage,            "softpage",     0 }, | 
|---|
| 1706 | { rtfSpecialChar,       rtfSoftColumn,          "softcol",      0 }, | 
|---|
| 1707 | { rtfSpecialChar,       rtfSoftLine,            "softline",     0 }, | 
|---|
| 1708 | { rtfSpecialChar,       rtfSoftLineHt,          "softlheight",  0 }, | 
|---|
| 1709 | { rtfSpecialChar,       rtfTab,                 "tab",          0 }, | 
|---|
| 1710 | { rtfSpecialChar,       rtfEmDash,              "emdash",       0 }, | 
|---|
| 1711 | { rtfSpecialChar,       rtfEnDash,              "endash",       0 }, | 
|---|
| 1712 | { rtfSpecialChar,       rtfEmSpace,             "emspace",      0 }, | 
|---|
| 1713 | { rtfSpecialChar,       rtfEnSpace,             "enspace",      0 }, | 
|---|
| 1714 | { rtfSpecialChar,       rtfBullet,              "bullet",       0 }, | 
|---|
| 1715 | { rtfSpecialChar,       rtfLQuote,              "lquote",       0 }, | 
|---|
| 1716 | { rtfSpecialChar,       rtfRQuote,              "rquote",       0 }, | 
|---|
| 1717 | { rtfSpecialChar,       rtfLDblQuote,           "ldblquote",    0 }, | 
|---|
| 1718 | { rtfSpecialChar,       rtfRDblQuote,           "rdblquote",    0 }, | 
|---|
| 1719 | { rtfSpecialChar,       rtfFormula,             "|",            0 }, | 
|---|
| 1720 | { rtfSpecialChar,       rtfNoBrkSpace,          "~",            0 }, | 
|---|
| 1721 | { rtfSpecialChar,       rtfNoReqHyphen,         "-",            0 }, | 
|---|
| 1722 | { rtfSpecialChar,       rtfNoBrkHyphen,         "_",            0 }, | 
|---|
| 1723 | { rtfSpecialChar,       rtfOptDest,             "*",            0 }, | 
|---|
| 1724 | { rtfSpecialChar,       rtfLTRMark,             "ltrmark",      0 }, | 
|---|
| 1725 | { rtfSpecialChar,       rtfRTLMark,             "rtlmark",      0 }, | 
|---|
| 1726 | { rtfSpecialChar,       rtfNoWidthJoiner,       "zwj",          0 }, | 
|---|
| 1727 | { rtfSpecialChar,       rtfNoWidthNonJoiner,    "zwnj",         0 }, | 
|---|
| 1728 | /* is this valid? */ | 
|---|
| 1729 | { rtfSpecialChar,       rtfCurHeadPict,         "chpict",       0 }, | 
|---|
| 1730 |  | 
|---|
| 1731 | /* | 
|---|
| 1732 | * Character formatting attributes | 
|---|
| 1733 | */ | 
|---|
| 1734 |  | 
|---|
| 1735 | { rtfCharAttr,  rtfPlain,               "plain",        0 }, | 
|---|
| 1736 | { rtfCharAttr,  rtfBold,                "b",            0 }, | 
|---|
| 1737 | { rtfCharAttr,  rtfAllCaps,             "caps",         0 }, | 
|---|
| 1738 | { rtfCharAttr,  rtfDeleted,             "deleted",      0 }, | 
|---|
| 1739 | { rtfCharAttr,  rtfSubScript,           "dn",           0 }, | 
|---|
| 1740 | { rtfCharAttr,  rtfSubScrShrink,        "sub",          0 }, | 
|---|
| 1741 | { rtfCharAttr,  rtfNoSuperSub,          "nosupersub",   0 }, | 
|---|
| 1742 | { rtfCharAttr,  rtfExpand,              "expnd",        0 }, | 
|---|
| 1743 | { rtfCharAttr,  rtfExpandTwips,         "expndtw",      0 }, | 
|---|
| 1744 | { rtfCharAttr,  rtfKerning,             "kerning",      0 }, | 
|---|
| 1745 | { rtfCharAttr,  rtfFontNum,             "f",            0 }, | 
|---|
| 1746 | { rtfCharAttr,  rtfFontSize,            "fs",           0 }, | 
|---|
| 1747 | { rtfCharAttr,  rtfItalic,              "i",            0 }, | 
|---|
| 1748 | { rtfCharAttr,  rtfOutline,             "outl",         0 }, | 
|---|
| 1749 | { rtfCharAttr,  rtfRevised,             "revised",      0 }, | 
|---|
| 1750 | { rtfCharAttr,  rtfRevAuthor,           "revauth",      0 }, | 
|---|
| 1751 | { rtfCharAttr,  rtfRevDTTM,             "revdttm",      0 }, | 
|---|
| 1752 | { rtfCharAttr,  rtfSmallCaps,           "scaps",        0 }, | 
|---|
| 1753 | { rtfCharAttr,  rtfShadow,              "shad",         0 }, | 
|---|
| 1754 | { rtfCharAttr,  rtfStrikeThru,          "strike",       0 }, | 
|---|
| 1755 | { rtfCharAttr,  rtfUnderline,           "ul",           0 }, | 
|---|
| 1756 | { rtfCharAttr,  rtfDotUnderline,        "uld",          0 }, | 
|---|
| 1757 | { rtfCharAttr,  rtfDbUnderline,         "uldb",         0 }, | 
|---|
| 1758 | { rtfCharAttr,  rtfNoUnderline,         "ulnone",       0 }, | 
|---|
| 1759 | { rtfCharAttr,  rtfWordUnderline,       "ulw",          0 }, | 
|---|
| 1760 | { rtfCharAttr,  rtfSuperScript,         "up",           0 }, | 
|---|
| 1761 | { rtfCharAttr,  rtfSuperScrShrink,      "super",        0 }, | 
|---|
| 1762 | { rtfCharAttr,  rtfInvisible,           "v",            0 }, | 
|---|
| 1763 | { rtfCharAttr,  rtfForeColor,           "cf",           0 }, | 
|---|
| 1764 | { rtfCharAttr,  rtfBackColor,           "cb",           0 }, | 
|---|
| 1765 | { rtfCharAttr,  rtfRTLChar,             "rtlch",        0 }, | 
|---|
| 1766 | { rtfCharAttr,  rtfLTRChar,             "ltrch",        0 }, | 
|---|
| 1767 | { rtfCharAttr,  rtfCharStyleNum,        "cs",           0 }, | 
|---|
| 1768 | { rtfCharAttr,  rtfCharCharSet,         "cchs",         0 }, | 
|---|
| 1769 | { rtfCharAttr,  rtfLanguage,            "lang",         0 }, | 
|---|
| 1770 | /* this has disappeared from spec 1.2 */ | 
|---|
| 1771 | { rtfCharAttr,  rtfGray,                "gray",         0 }, | 
|---|
| 1772 |  | 
|---|
| 1773 | /* | 
|---|
| 1774 | * Paragraph formatting attributes | 
|---|
| 1775 | */ | 
|---|
| 1776 |  | 
|---|
| 1777 | { rtfParAttr,   rtfParDef,              "pard",         0 }, | 
|---|
| 1778 | { rtfParAttr,   rtfStyleNum,            "s",            0 }, | 
|---|
| 1779 | { rtfParAttr,   rtfHyphenate,           "hyphpar",      0 }, | 
|---|
| 1780 | { rtfParAttr,   rtfInTable,             "intbl",        0 }, | 
|---|
| 1781 | { rtfParAttr,   rtfKeep,                "keep",         0 }, | 
|---|
| 1782 | { rtfParAttr,   rtfNoWidowControl,      "nowidctlpar",  0 }, | 
|---|
| 1783 | { rtfParAttr,   rtfKeepNext,            "keepn",        0 }, | 
|---|
| 1784 | { rtfParAttr,   rtfOutlineLevel,        "level",        0 }, | 
|---|
| 1785 | { rtfParAttr,   rtfNoLineNum,           "noline",       0 }, | 
|---|
| 1786 | { rtfParAttr,   rtfPBBefore,            "pagebb",       0 }, | 
|---|
| 1787 | { rtfParAttr,   rtfSideBySide,          "sbys",         0 }, | 
|---|
| 1788 | { rtfParAttr,   rtfQuadLeft,            "ql",           0 }, | 
|---|
| 1789 | { rtfParAttr,   rtfQuadRight,           "qr",           0 }, | 
|---|
| 1790 | { rtfParAttr,   rtfQuadJust,            "qj",           0 }, | 
|---|
| 1791 | { rtfParAttr,   rtfQuadCenter,          "qc",           0 }, | 
|---|
| 1792 | { rtfParAttr,   rtfFirstIndent,         "fi",           0 }, | 
|---|
| 1793 | { rtfParAttr,   rtfLeftIndent,          "li",           0 }, | 
|---|
| 1794 | { rtfParAttr,   rtfRightIndent,         "ri",           0 }, | 
|---|
| 1795 | { rtfParAttr,   rtfSpaceBefore,         "sb",           0 }, | 
|---|
| 1796 | { rtfParAttr,   rtfSpaceAfter,          "sa",           0 }, | 
|---|
| 1797 | { rtfParAttr,   rtfSpaceBetween,        "sl",           0 }, | 
|---|
| 1798 | { rtfParAttr,   rtfSpaceMultiply,       "slmult",       0 }, | 
|---|
| 1799 |  | 
|---|
| 1800 | { rtfParAttr,   rtfSubDocument,         "subdocument",  0 }, | 
|---|
| 1801 |  | 
|---|
| 1802 | { rtfParAttr,   rtfRTLPar,              "rtlpar",       0 }, | 
|---|
| 1803 | { rtfParAttr,   rtfLTRPar,              "ltrpar",       0 }, | 
|---|
| 1804 |  | 
|---|
| 1805 | { rtfParAttr,   rtfTabPos,              "tx",           0 }, | 
|---|
| 1806 | /* | 
|---|
| 1807 | * FrameMaker writes \tql (to mean left-justified tab, apparently) | 
|---|
| 1808 | * although it's not in the spec.  It's also redundant, since lj | 
|---|
| 1809 | * tabs are the default. | 
|---|
| 1810 | */ | 
|---|
| 1811 | { rtfParAttr,   rtfTabLeft,             "tql",          0 }, | 
|---|
| 1812 | { rtfParAttr,   rtfTabRight,            "tqr",          0 }, | 
|---|
| 1813 | { rtfParAttr,   rtfTabCenter,           "tqc",          0 }, | 
|---|
| 1814 | { rtfParAttr,   rtfTabDecimal,          "tqdec",        0 }, | 
|---|
| 1815 | { rtfParAttr,   rtfTabBar,              "tb",           0 }, | 
|---|
| 1816 | { rtfParAttr,   rtfLeaderDot,           "tldot",        0 }, | 
|---|
| 1817 | { rtfParAttr,   rtfLeaderHyphen,        "tlhyph",       0 }, | 
|---|
| 1818 | { rtfParAttr,   rtfLeaderUnder,         "tlul",         0 }, | 
|---|
| 1819 | { rtfParAttr,   rtfLeaderThick,         "tlth",         0 }, | 
|---|
| 1820 | { rtfParAttr,   rtfLeaderEqual,         "tleq",         0 }, | 
|---|
| 1821 |  | 
|---|
| 1822 | { rtfParAttr,   rtfParLevel,            "pnlvl",        0 }, | 
|---|
| 1823 | { rtfParAttr,   rtfParBullet,           "pnlvlblt",     0 }, | 
|---|
| 1824 | { rtfParAttr,   rtfParSimple,           "pnlvlbody",    0 }, | 
|---|
| 1825 | { rtfParAttr,   rtfParNumCont,          "pnlvlcont",    0 }, | 
|---|
| 1826 | { rtfParAttr,   rtfParNumOnce,          "pnnumonce",    0 }, | 
|---|
| 1827 | { rtfParAttr,   rtfParNumAcross,        "pnacross",     0 }, | 
|---|
| 1828 | { rtfParAttr,   rtfParHangIndent,       "pnhang",       0 }, | 
|---|
| 1829 | { rtfParAttr,   rtfParNumRestart,       "pnrestart",    0 }, | 
|---|
| 1830 | { rtfParAttr,   rtfParNumCardinal,      "pncard",       0 }, | 
|---|
| 1831 | { rtfParAttr,   rtfParNumDecimal,       "pndec",        0 }, | 
|---|
| 1832 | { rtfParAttr,   rtfParNumULetter,       "pnucltr",      0 }, | 
|---|
| 1833 | { rtfParAttr,   rtfParNumURoman,        "pnucrm",       0 }, | 
|---|
| 1834 | { rtfParAttr,   rtfParNumLLetter,       "pnlcltr",      0 }, | 
|---|
| 1835 | { rtfParAttr,   rtfParNumLRoman,        "pnlcrm",       0 }, | 
|---|
| 1836 | { rtfParAttr,   rtfParNumOrdinal,       "pnord",        0 }, | 
|---|
| 1837 | { rtfParAttr,   rtfParNumOrdinalText,   "pnordt",       0 }, | 
|---|
| 1838 | { rtfParAttr,   rtfParNumBold,          "pnb",          0 }, | 
|---|
| 1839 | { rtfParAttr,   rtfParNumItalic,        "pni",          0 }, | 
|---|
| 1840 | { rtfParAttr,   rtfParNumAllCaps,       "pncaps",       0 }, | 
|---|
| 1841 | { rtfParAttr,   rtfParNumSmallCaps,     "pnscaps",      0 }, | 
|---|
| 1842 | { rtfParAttr,   rtfParNumUnder,         "pnul",         0 }, | 
|---|
| 1843 | { rtfParAttr,   rtfParNumDotUnder,      "pnuld",        0 }, | 
|---|
| 1844 | { rtfParAttr,   rtfParNumDbUnder,       "pnuldb",       0 }, | 
|---|
| 1845 | { rtfParAttr,   rtfParNumNoUnder,       "pnulnone",     0 }, | 
|---|
| 1846 | { rtfParAttr,   rtfParNumWordUnder,     "pnulw",        0 }, | 
|---|
| 1847 | { rtfParAttr,   rtfParNumStrikethru,    "pnstrike",     0 }, | 
|---|
| 1848 | { rtfParAttr,   rtfParNumForeColor,     "pncf",         0 }, | 
|---|
| 1849 | { rtfParAttr,   rtfParNumFont,          "pnf",          0 }, | 
|---|
| 1850 | { rtfParAttr,   rtfParNumFontSize,      "pnfs",         0 }, | 
|---|
| 1851 | { rtfParAttr,   rtfParNumIndent,        "pnindent",     0 }, | 
|---|
| 1852 | { rtfParAttr,   rtfParNumSpacing,       "pnsp",         0 }, | 
|---|
| 1853 | { rtfParAttr,   rtfParNumInclPrev,      "pnprev",       0 }, | 
|---|
| 1854 | { rtfParAttr,   rtfParNumCenter,        "pnqc",         0 }, | 
|---|
| 1855 | { rtfParAttr,   rtfParNumLeft,          "pnql",         0 }, | 
|---|
| 1856 | { rtfParAttr,   rtfParNumRight,         "pnqr",         0 }, | 
|---|
| 1857 | { rtfParAttr,   rtfParNumStartAt,       "pnstart",      0 }, | 
|---|
| 1858 |  | 
|---|
| 1859 | { rtfParAttr,   rtfBorderTop,           "brdrt",        0 }, | 
|---|
| 1860 | { rtfParAttr,   rtfBorderBottom,        "brdrb",        0 }, | 
|---|
| 1861 | { rtfParAttr,   rtfBorderLeft,          "brdrl",        0 }, | 
|---|
| 1862 | { rtfParAttr,   rtfBorderRight,         "brdrr",        0 }, | 
|---|
| 1863 | { rtfParAttr,   rtfBorderBetween,       "brdrbtw",      0 }, | 
|---|
| 1864 | { rtfParAttr,   rtfBorderBar,           "brdrbar",      0 }, | 
|---|
| 1865 | { rtfParAttr,   rtfBorderBox,           "box",          0 }, | 
|---|
| 1866 | { rtfParAttr,   rtfBorderSingle,        "brdrs",        0 }, | 
|---|
| 1867 | { rtfParAttr,   rtfBorderThick,         "brdrth",       0 }, | 
|---|
| 1868 | { rtfParAttr,   rtfBorderShadow,        "brdrsh",       0 }, | 
|---|
| 1869 | { rtfParAttr,   rtfBorderDouble,        "brdrdb",       0 }, | 
|---|
| 1870 | { rtfParAttr,   rtfBorderDot,           "brdrdot",      0 }, | 
|---|
| 1871 | { rtfParAttr,   rtfBorderDot,           "brdrdash",     0 }, | 
|---|
| 1872 | { rtfParAttr,   rtfBorderHair,          "brdrhair",     0 }, | 
|---|
| 1873 | { rtfParAttr,   rtfBorderWidth,         "brdrw",        0 }, | 
|---|
| 1874 | { rtfParAttr,   rtfBorderColor,         "brdrcf",       0 }, | 
|---|
| 1875 | { rtfParAttr,   rtfBorderSpace,         "brsp",         0 }, | 
|---|
| 1876 |  | 
|---|
| 1877 | { rtfParAttr,   rtfShading,             "shading",      0 }, | 
|---|
| 1878 | { rtfParAttr,   rtfBgPatH,              "bghoriz",      0 }, | 
|---|
| 1879 | { rtfParAttr,   rtfBgPatV,              "bgvert",       0 }, | 
|---|
| 1880 | { rtfParAttr,   rtfFwdDiagBgPat,        "bgfdiag",      0 }, | 
|---|
| 1881 | { rtfParAttr,   rtfBwdDiagBgPat,        "bgbdiag",      0 }, | 
|---|
| 1882 | { rtfParAttr,   rtfHatchBgPat,          "bgcross",      0 }, | 
|---|
| 1883 | { rtfParAttr,   rtfDiagHatchBgPat,      "bgdcross",     0 }, | 
|---|
| 1884 | { rtfParAttr,   rtfDarkBgPatH,          "bgdkhoriz",    0 }, | 
|---|
| 1885 | { rtfParAttr,   rtfDarkBgPatV,          "bgdkvert",     0 }, | 
|---|
| 1886 | { rtfParAttr,   rtfFwdDarkBgPat,        "bgdkfdiag",    0 }, | 
|---|
| 1887 | { rtfParAttr,   rtfBwdDarkBgPat,        "bgdkbdiag",    0 }, | 
|---|
| 1888 | { rtfParAttr,   rtfDarkHatchBgPat,      "bgdkcross",    0 }, | 
|---|
| 1889 | { rtfParAttr,   rtfDarkDiagHatchBgPat,  "bgdkdcross",   0 }, | 
|---|
| 1890 | { rtfParAttr,   rtfBgPatLineColor,      "cfpat",        0 }, | 
|---|
| 1891 | { rtfParAttr,   rtfBgPatColor,          "cbpat",        0 }, | 
|---|
| 1892 |  | 
|---|
| 1893 | /* | 
|---|
| 1894 | * Section formatting attributes | 
|---|
| 1895 | */ | 
|---|
| 1896 |  | 
|---|
| 1897 | { rtfSectAttr,  rtfSectDef,             "sectd",        0 }, | 
|---|
| 1898 | { rtfSectAttr,  rtfENoteHere,           "endnhere",     0 }, | 
|---|
| 1899 | { rtfSectAttr,  rtfPrtBinFirst,         "binfsxn",      0 }, | 
|---|
| 1900 | { rtfSectAttr,  rtfPrtBin,              "binsxn",       0 }, | 
|---|
| 1901 | { rtfSectAttr,  rtfSectStyleNum,        "ds",           0 }, | 
|---|
| 1902 |  | 
|---|
| 1903 | { rtfSectAttr,  rtfNoBreak,             "sbknone",      0 }, | 
|---|
| 1904 | { rtfSectAttr,  rtfColBreak,            "sbkcol",       0 }, | 
|---|
| 1905 | { rtfSectAttr,  rtfPageBreak,           "sbkpage",      0 }, | 
|---|
| 1906 | { rtfSectAttr,  rtfEvenBreak,           "sbkeven",      0 }, | 
|---|
| 1907 | { rtfSectAttr,  rtfOddBreak,            "sbkodd",       0 }, | 
|---|
| 1908 |  | 
|---|
| 1909 | { rtfSectAttr,  rtfColumns,             "cols",         0 }, | 
|---|
| 1910 | { rtfSectAttr,  rtfColumnSpace,         "colsx",        0 }, | 
|---|
| 1911 | { rtfSectAttr,  rtfColumnNumber,        "colno",        0 }, | 
|---|
| 1912 | { rtfSectAttr,  rtfColumnSpRight,       "colsr",        0 }, | 
|---|
| 1913 | { rtfSectAttr,  rtfColumnWidth,         "colw",         0 }, | 
|---|
| 1914 | { rtfSectAttr,  rtfColumnLine,          "linebetcol",   0 }, | 
|---|
| 1915 |  | 
|---|
| 1916 | { rtfSectAttr,  rtfLineModulus,         "linemod",      0 }, | 
|---|
| 1917 | { rtfSectAttr,  rtfLineDist,            "linex",        0 }, | 
|---|
| 1918 | { rtfSectAttr,  rtfLineStarts,          "linestarts",   0 }, | 
|---|
| 1919 | { rtfSectAttr,  rtfLineRestart,         "linerestart",  0 }, | 
|---|
| 1920 | { rtfSectAttr,  rtfLineRestartPg,       "lineppage",    0 }, | 
|---|
| 1921 | { rtfSectAttr,  rtfLineCont,            "linecont",     0 }, | 
|---|
| 1922 |  | 
|---|
| 1923 | { rtfSectAttr,  rtfSectPageWid,         "pgwsxn",       0 }, | 
|---|
| 1924 | { rtfSectAttr,  rtfSectPageHt,          "pghsxn",       0 }, | 
|---|
| 1925 | { rtfSectAttr,  rtfSectMarginLeft,      "marglsxn",     0 }, | 
|---|
| 1926 | { rtfSectAttr,  rtfSectMarginRight,     "margrsxn",     0 }, | 
|---|
| 1927 | { rtfSectAttr,  rtfSectMarginTop,       "margtsxn",     0 }, | 
|---|
| 1928 | { rtfSectAttr,  rtfSectMarginBottom,    "margbsxn",     0 }, | 
|---|
| 1929 | { rtfSectAttr,  rtfSectMarginGutter,    "guttersxn",    0 }, | 
|---|
| 1930 | { rtfSectAttr,  rtfSectLandscape,       "lndscpsxn",    0 }, | 
|---|
| 1931 | { rtfSectAttr,  rtfTitleSpecial,        "titlepg",      0 }, | 
|---|
| 1932 | { rtfSectAttr,  rtfHeaderY,             "headery",      0 }, | 
|---|
| 1933 | { rtfSectAttr,  rtfFooterY,             "footery",      0 }, | 
|---|
| 1934 |  | 
|---|
| 1935 | { rtfSectAttr,  rtfPageStarts,          "pgnstarts",    0 }, | 
|---|
| 1936 | { rtfSectAttr,  rtfPageCont,            "pgncont",      0 }, | 
|---|
| 1937 | { rtfSectAttr,  rtfPageRestart,         "pgnrestart",   0 }, | 
|---|
| 1938 | { rtfSectAttr,  rtfPageNumRight,        "pgnx",         0 }, | 
|---|
| 1939 | { rtfSectAttr,  rtfPageNumTop,          "pgny",         0 }, | 
|---|
| 1940 | { rtfSectAttr,  rtfPageDecimal,         "pgndec",       0 }, | 
|---|
| 1941 | { rtfSectAttr,  rtfPageURoman,          "pgnucrm",      0 }, | 
|---|
| 1942 | { rtfSectAttr,  rtfPageLRoman,          "pgnlcrm",      0 }, | 
|---|
| 1943 | { rtfSectAttr,  rtfPageULetter,         "pgnucltr",     0 }, | 
|---|
| 1944 | { rtfSectAttr,  rtfPageLLetter,         "pgnlcltr",     0 }, | 
|---|
| 1945 | { rtfSectAttr,  rtfPageNumHyphSep,      "pgnhnsh",      0 }, | 
|---|
| 1946 | { rtfSectAttr,  rtfPageNumSpaceSep,     "pgnhnsp",      0 }, | 
|---|
| 1947 | { rtfSectAttr,  rtfPageNumColonSep,     "pgnhnsc",      0 }, | 
|---|
| 1948 | { rtfSectAttr,  rtfPageNumEmdashSep,    "pgnhnsm",      0 }, | 
|---|
| 1949 | { rtfSectAttr,  rtfPageNumEndashSep,    "pgnhnsn",      0 }, | 
|---|
| 1950 |  | 
|---|
| 1951 | { rtfSectAttr,  rtfTopVAlign,           "vertalt",      0 }, | 
|---|
| 1952 | /* misspelled as "vertal" in specification 1.0 */ | 
|---|
| 1953 | { rtfSectAttr,  rtfBottomVAlign,        "vertalb",      0 }, | 
|---|
| 1954 | { rtfSectAttr,  rtfCenterVAlign,        "vertalc",      0 }, | 
|---|
| 1955 | { rtfSectAttr,  rtfJustVAlign,          "vertalj",      0 }, | 
|---|
| 1956 |  | 
|---|
| 1957 | { rtfSectAttr,  rtfRTLSect,             "rtlsect",      0 }, | 
|---|
| 1958 | { rtfSectAttr,  rtfLTRSect,             "ltrsect",      0 }, | 
|---|
| 1959 |  | 
|---|
| 1960 | /* I've seen these in an old spec, but not in real files... */ | 
|---|
| 1961 | /*rtfSectAttr,  rtfNoBreak,             "nobreak",      0,*/ | 
|---|
| 1962 | /*rtfSectAttr,  rtfColBreak,            "colbreak",     0,*/ | 
|---|
| 1963 | /*rtfSectAttr,  rtfPageBreak,           "pagebreak",    0,*/ | 
|---|
| 1964 | /*rtfSectAttr,  rtfEvenBreak,           "evenbreak",    0,*/ | 
|---|
| 1965 | /*rtfSectAttr,  rtfOddBreak,            "oddbreak",     0,*/ | 
|---|
| 1966 |  | 
|---|
| 1967 | /* | 
|---|
| 1968 | * Document formatting attributes | 
|---|
| 1969 | */ | 
|---|
| 1970 |  | 
|---|
| 1971 | { rtfDocAttr,   rtfDefTab,              "deftab",       0 }, | 
|---|
| 1972 | { rtfDocAttr,   rtfHyphHotZone,         "hyphhotz",     0 }, | 
|---|
| 1973 | { rtfDocAttr,   rtfHyphConsecLines,     "hyphconsec",   0 }, | 
|---|
| 1974 | { rtfDocAttr,   rtfHyphCaps,            "hyphcaps",     0 }, | 
|---|
| 1975 | { rtfDocAttr,   rtfHyphAuto,            "hyphauto",     0 }, | 
|---|
| 1976 | { rtfDocAttr,   rtfLineStart,           "linestart",    0 }, | 
|---|
| 1977 | { rtfDocAttr,   rtfFracWidth,           "fracwidth",    0 }, | 
|---|
| 1978 | /* \makeback was given in old version of spec, it's now */ | 
|---|
| 1979 | /* listed as \makebackup */ | 
|---|
| 1980 | { rtfDocAttr,   rtfMakeBackup,          "makeback",     0 }, | 
|---|
| 1981 | { rtfDocAttr,   rtfMakeBackup,          "makebackup",   0 }, | 
|---|
| 1982 | { rtfDocAttr,   rtfRTFDefault,          "defformat",    0 }, | 
|---|
| 1983 | { rtfDocAttr,   rtfPSOverlay,           "psover",       0 }, | 
|---|
| 1984 | { rtfDocAttr,   rtfDocTemplate,         "doctemp",      0 }, | 
|---|
| 1985 | { rtfDocAttr,   rtfDefLanguage,         "deflang",      0 }, | 
|---|
| 1986 |  | 
|---|
| 1987 | { rtfDocAttr,   rtfFENoteType,          "fet",          0 }, | 
|---|
| 1988 | { rtfDocAttr,   rtfFNoteEndSect,        "endnotes",     0 }, | 
|---|
| 1989 | { rtfDocAttr,   rtfFNoteEndDoc,         "enddoc",       0 }, | 
|---|
| 1990 | { rtfDocAttr,   rtfFNoteText,           "ftntj",        0 }, | 
|---|
| 1991 | { rtfDocAttr,   rtfFNoteBottom,         "ftnbj",        0 }, | 
|---|
| 1992 | { rtfDocAttr,   rtfENoteEndSect,        "aendnotes",    0 }, | 
|---|
| 1993 | { rtfDocAttr,   rtfENoteEndDoc,         "aenddoc",      0 }, | 
|---|
| 1994 | { rtfDocAttr,   rtfENoteText,           "aftntj",       0 }, | 
|---|
| 1995 | { rtfDocAttr,   rtfENoteBottom,         "aftnbj",       0 }, | 
|---|
| 1996 | { rtfDocAttr,   rtfFNoteStart,          "ftnstart",     0 }, | 
|---|
| 1997 | { rtfDocAttr,   rtfENoteStart,          "aftnstart",    0 }, | 
|---|
| 1998 | { rtfDocAttr,   rtfFNoteRestartPage,    "ftnrstpg",     0 }, | 
|---|
| 1999 | { rtfDocAttr,   rtfFNoteRestart,        "ftnrestart",   0 }, | 
|---|
| 2000 | { rtfDocAttr,   rtfFNoteRestartCont,    "ftnrstcont",   0 }, | 
|---|
| 2001 | { rtfDocAttr,   rtfENoteRestart,        "aftnrestart",  0 }, | 
|---|
| 2002 | { rtfDocAttr,   rtfENoteRestartCont,    "aftnrstcont",  0 }, | 
|---|
| 2003 | { rtfDocAttr,   rtfFNoteNumArabic,      "ftnnar",       0 }, | 
|---|
| 2004 | { rtfDocAttr,   rtfFNoteNumLLetter,     "ftnnalc",      0 }, | 
|---|
| 2005 | { rtfDocAttr,   rtfFNoteNumULetter,     "ftnnauc",      0 }, | 
|---|
| 2006 | { rtfDocAttr,   rtfFNoteNumLRoman,      "ftnnrlc",      0 }, | 
|---|
| 2007 | { rtfDocAttr,   rtfFNoteNumURoman,      "ftnnruc",      0 }, | 
|---|
| 2008 | { rtfDocAttr,   rtfFNoteNumChicago,     "ftnnchi",      0 }, | 
|---|
| 2009 | { rtfDocAttr,   rtfENoteNumArabic,      "aftnnar",      0 }, | 
|---|
| 2010 | { rtfDocAttr,   rtfENoteNumLLetter,     "aftnnalc",     0 }, | 
|---|
| 2011 | { rtfDocAttr,   rtfENoteNumULetter,     "aftnnauc",     0 }, | 
|---|
| 2012 | { rtfDocAttr,   rtfENoteNumLRoman,      "aftnnrlc",     0 }, | 
|---|
| 2013 | { rtfDocAttr,   rtfENoteNumURoman,      "aftnnruc",     0 }, | 
|---|
| 2014 | { rtfDocAttr,   rtfENoteNumChicago,     "aftnnchi",     0 }, | 
|---|
| 2015 |  | 
|---|
| 2016 | { rtfDocAttr,   rtfPaperWidth,          "paperw",       0 }, | 
|---|
| 2017 | { rtfDocAttr,   rtfPaperHeight,         "paperh",       0 }, | 
|---|
| 2018 | { rtfDocAttr,   rtfPaperSize,           "psz",          0 }, | 
|---|
| 2019 | { rtfDocAttr,   rtfLeftMargin,          "margl",        0 }, | 
|---|
| 2020 | { rtfDocAttr,   rtfRightMargin,         "margr",        0 }, | 
|---|
| 2021 | { rtfDocAttr,   rtfTopMargin,           "margt",        0 }, | 
|---|
| 2022 | { rtfDocAttr,   rtfBottomMargin,        "margb",        0 }, | 
|---|
| 2023 | { rtfDocAttr,   rtfFacingPage,          "facingp",      0 }, | 
|---|
| 2024 | { rtfDocAttr,   rtfGutterWid,           "gutter",       0 }, | 
|---|
| 2025 | { rtfDocAttr,   rtfMirrorMargin,        "margmirror",   0 }, | 
|---|
| 2026 | { rtfDocAttr,   rtfLandscape,           "landscape",    0 }, | 
|---|
| 2027 | { rtfDocAttr,   rtfPageStart,           "pgnstart",     0 }, | 
|---|
| 2028 | { rtfDocAttr,   rtfWidowCtrl,           "widowctrl",    0 }, | 
|---|
| 2029 |  | 
|---|
| 2030 | { rtfDocAttr,   rtfLinkStyles,          "linkstyles",   0 }, | 
|---|
| 2031 |  | 
|---|
| 2032 | { rtfDocAttr,   rtfNoAutoTabIndent,     "notabind",     0 }, | 
|---|
| 2033 | { rtfDocAttr,   rtfWrapSpaces,          "wraptrsp",     0 }, | 
|---|
| 2034 | { rtfDocAttr,   rtfPrintColorsBlack,    "prcolbl",      0 }, | 
|---|
| 2035 | { rtfDocAttr,   rtfNoExtraSpaceRL,      "noextrasprl",  0 }, | 
|---|
| 2036 | { rtfDocAttr,   rtfNoColumnBalance,     "nocolbal",     0 }, | 
|---|
| 2037 | { rtfDocAttr,   rtfCvtMailMergeQuote,   "cvmme",        0 }, | 
|---|
| 2038 | { rtfDocAttr,   rtfSuppressTopSpace,    "sprstsp",      0 }, | 
|---|
| 2039 | { rtfDocAttr,   rtfSuppressPreParSpace, "sprsspbf",     0 }, | 
|---|
| 2040 | { rtfDocAttr,   rtfCombineTblBorders,   "otblrul",      0 }, | 
|---|
| 2041 | { rtfDocAttr,   rtfTranspMetafiles,     "transmf",      0 }, | 
|---|
| 2042 | { rtfDocAttr,   rtfSwapBorders,         "swpbdr",       0 }, | 
|---|
| 2043 | { rtfDocAttr,   rtfShowHardBreaks,      "brkfrm",       0 }, | 
|---|
| 2044 |  | 
|---|
| 2045 | { rtfDocAttr,   rtfFormProtected,       "formprot",     0 }, | 
|---|
| 2046 | { rtfDocAttr,   rtfAllProtected,        "allprot",      0 }, | 
|---|
| 2047 | { rtfDocAttr,   rtfFormShading,         "formshade",    0 }, | 
|---|
| 2048 | { rtfDocAttr,   rtfFormDisplay,         "formdisp",     0 }, | 
|---|
| 2049 | { rtfDocAttr,   rtfPrintData,           "printdata",    0 }, | 
|---|
| 2050 |  | 
|---|
| 2051 | { rtfDocAttr,   rtfRevProtected,        "revprot",      0 }, | 
|---|
| 2052 | { rtfDocAttr,   rtfRevisions,           "revisions",    0 }, | 
|---|
| 2053 | { rtfDocAttr,   rtfRevDisplay,          "revprop",      0 }, | 
|---|
| 2054 | { rtfDocAttr,   rtfRevBar,              "revbar",       0 }, | 
|---|
| 2055 |  | 
|---|
| 2056 | { rtfDocAttr,   rtfAnnotProtected,      "annotprot",    0 }, | 
|---|
| 2057 |  | 
|---|
| 2058 | { rtfDocAttr,   rtfRTLDoc,              "rtldoc",       0 }, | 
|---|
| 2059 | { rtfDocAttr,   rtfLTRDoc,              "ltrdoc",       0 }, | 
|---|
| 2060 |  | 
|---|
| 2061 | /* | 
|---|
| 2062 | * Style attributes | 
|---|
| 2063 | */ | 
|---|
| 2064 |  | 
|---|
| 2065 | { rtfStyleAttr, rtfAdditive,            "additive",     0 }, | 
|---|
| 2066 | { rtfStyleAttr, rtfBasedOn,             "sbasedon",     0 }, | 
|---|
| 2067 | { rtfStyleAttr, rtfNext,                "snext",        0 }, | 
|---|
| 2068 |  | 
|---|
| 2069 | /* | 
|---|
| 2070 | * Picture attributes | 
|---|
| 2071 | */ | 
|---|
| 2072 |  | 
|---|
| 2073 | { rtfPictAttr,  rtfMacQD,               "macpict",      0 }, | 
|---|
| 2074 | { rtfPictAttr,  rtfPMMetafile,          "pmmetafile",   0 }, | 
|---|
| 2075 | { rtfPictAttr,  rtfWinMetafile,         "wmetafile",    0 }, | 
|---|
| 2076 | { rtfPictAttr,  rtfDevIndBitmap,        "dibitmap",     0 }, | 
|---|
| 2077 | { rtfPictAttr,  rtfWinBitmap,           "wbitmap",      0 }, | 
|---|
| 2078 | { rtfPictAttr,  rtfPixelBits,           "wbmbitspixel", 0 }, | 
|---|
| 2079 | { rtfPictAttr,  rtfBitmapPlanes,        "wbmplanes",    0 }, | 
|---|
| 2080 | { rtfPictAttr,  rtfBitmapWid,           "wbmwidthbytes", 0 }, | 
|---|
| 2081 |  | 
|---|
| 2082 | { rtfPictAttr,  rtfPicWid,              "picw",         0 }, | 
|---|
| 2083 | { rtfPictAttr,  rtfPicHt,               "pich",         0 }, | 
|---|
| 2084 | { rtfPictAttr,  rtfPicGoalWid,          "picwgoal",     0 }, | 
|---|
| 2085 | { rtfPictAttr,  rtfPicGoalHt,           "pichgoal",     0 }, | 
|---|
| 2086 | /* these two aren't in the spec, but some writers emit them */ | 
|---|
| 2087 | { rtfPictAttr,  rtfPicGoalWid,          "picwGoal",     0 }, | 
|---|
| 2088 | { rtfPictAttr,  rtfPicGoalHt,           "pichGoal",     0 }, | 
|---|
| 2089 | { rtfPictAttr,  rtfPicScaleX,           "picscalex",    0 }, | 
|---|
| 2090 | { rtfPictAttr,  rtfPicScaleY,           "picscaley",    0 }, | 
|---|
| 2091 | { rtfPictAttr,  rtfPicScaled,           "picscaled",    0 }, | 
|---|
| 2092 | { rtfPictAttr,  rtfPicCropTop,          "piccropt",     0 }, | 
|---|
| 2093 | { rtfPictAttr,  rtfPicCropBottom,       "piccropb",     0 }, | 
|---|
| 2094 | { rtfPictAttr,  rtfPicCropLeft,         "piccropl",     0 }, | 
|---|
| 2095 | { rtfPictAttr,  rtfPicCropRight,        "piccropr",     0 }, | 
|---|
| 2096 |  | 
|---|
| 2097 | { rtfPictAttr,  rtfPicMFHasBitmap,      "picbmp",       0 }, | 
|---|
| 2098 | { rtfPictAttr,  rtfPicMFBitsPerPixel,   "picbpp",       0 }, | 
|---|
| 2099 |  | 
|---|
| 2100 | { rtfPictAttr,  rtfPicBinary,           "bin",          0 }, | 
|---|
| 2101 |  | 
|---|
| 2102 | /* | 
|---|
| 2103 | * NeXT graphic attributes | 
|---|
| 2104 | */ | 
|---|
| 2105 |  | 
|---|
| 2106 | { rtfNeXTGrAttr,        rtfNeXTGWidth,          "width",        0 }, | 
|---|
| 2107 | { rtfNeXTGrAttr,        rtfNeXTGHeight,         "height",       0 }, | 
|---|
| 2108 |  | 
|---|
| 2109 | /* | 
|---|
| 2110 | * Destinations | 
|---|
| 2111 | */ | 
|---|
| 2112 |  | 
|---|
| 2113 | { rtfDestination,       rtfFontTbl,             "fonttbl",      0 }, | 
|---|
| 2114 | { rtfDestination,       rtfFontAltName,         "falt",         0 }, | 
|---|
| 2115 | { rtfDestination,       rtfEmbeddedFont,        "fonteb",       0 }, | 
|---|
| 2116 | { rtfDestination,       rtfFontFile,            "fontfile",     0 }, | 
|---|
| 2117 | { rtfDestination,       rtfFileTbl,             "filetbl",      0 }, | 
|---|
| 2118 | { rtfDestination,       rtfFileInfo,            "file",         0 }, | 
|---|
| 2119 | { rtfDestination,       rtfColorTbl,            "colortbl",     0 }, | 
|---|
| 2120 | { rtfDestination,       rtfStyleSheet,          "stylesheet",   0 }, | 
|---|
| 2121 | { rtfDestination,       rtfKeyCode,             "keycode",      0 }, | 
|---|
| 2122 | { rtfDestination,       rtfRevisionTbl,         "revtbl",       0 }, | 
|---|
| 2123 | { rtfDestination,       rtfInfo,                "info",         0 }, | 
|---|
| 2124 | { rtfDestination,       rtfITitle,              "title",        0 }, | 
|---|
| 2125 | { rtfDestination,       rtfISubject,            "subject",      0 }, | 
|---|
| 2126 | { rtfDestination,       rtfIAuthor,             "author",       0 }, | 
|---|
| 2127 | { rtfDestination,       rtfIOperator,           "operator",     0 }, | 
|---|
| 2128 | { rtfDestination,       rtfIKeywords,           "keywords",     0 }, | 
|---|
| 2129 | { rtfDestination,       rtfIComment,            "comment",      0 }, | 
|---|
| 2130 | { rtfDestination,       rtfIVersion,            "version",      0 }, | 
|---|
| 2131 | { rtfDestination,       rtfIDoccomm,            "doccomm",      0 }, | 
|---|
| 2132 | /* \verscomm may not exist -- was seen in earlier spec version */ | 
|---|
| 2133 | { rtfDestination,       rtfIVerscomm,           "verscomm",     0 }, | 
|---|
| 2134 | { rtfDestination,       rtfNextFile,            "nextfile",     0 }, | 
|---|
| 2135 | { rtfDestination,       rtfTemplate,            "template",     0 }, | 
|---|
| 2136 | { rtfDestination,       rtfFNSep,               "ftnsep",       0 }, | 
|---|
| 2137 | { rtfDestination,       rtfFNContSep,           "ftnsepc",      0 }, | 
|---|
| 2138 | { rtfDestination,       rtfFNContNotice,        "ftncn",        0 }, | 
|---|
| 2139 | { rtfDestination,       rtfENSep,               "aftnsep",      0 }, | 
|---|
| 2140 | { rtfDestination,       rtfENContSep,           "aftnsepc",     0 }, | 
|---|
| 2141 | { rtfDestination,       rtfENContNotice,        "aftncn",       0 }, | 
|---|
| 2142 | { rtfDestination,       rtfPageNumLevel,        "pgnhn",        0 }, | 
|---|
| 2143 | { rtfDestination,       rtfParNumLevelStyle,    "pnseclvl",     0 }, | 
|---|
| 2144 | { rtfDestination,       rtfHeader,              "header",       0 }, | 
|---|
| 2145 | { rtfDestination,       rtfFooter,              "footer",       0 }, | 
|---|
| 2146 | { rtfDestination,       rtfHeaderLeft,          "headerl",      0 }, | 
|---|
| 2147 | { rtfDestination,       rtfHeaderRight,         "headerr",      0 }, | 
|---|
| 2148 | { rtfDestination,       rtfHeaderFirst,         "headerf",      0 }, | 
|---|
| 2149 | { rtfDestination,       rtfFooterLeft,          "footerl",      0 }, | 
|---|
| 2150 | { rtfDestination,       rtfFooterRight,         "footerr",      0 }, | 
|---|
| 2151 | { rtfDestination,       rtfFooterFirst,         "footerf",      0 }, | 
|---|
| 2152 | { rtfDestination,       rtfParNumText,          "pntext",       0 }, | 
|---|
| 2153 | { rtfDestination,       rtfParNumbering,        "pn",           0 }, | 
|---|
| 2154 | { rtfDestination,       rtfParNumTextAfter,     "pntexta",      0 }, | 
|---|
| 2155 | { rtfDestination,       rtfParNumTextBefore,    "pntextb",      0 }, | 
|---|
| 2156 | { rtfDestination,       rtfBookmarkStart,       "bkmkstart",    0 }, | 
|---|
| 2157 | { rtfDestination,       rtfBookmarkEnd,         "bkmkend",      0 }, | 
|---|
| 2158 | { rtfDestination,       rtfPict,                "pict",         0 }, | 
|---|
| 2159 | { rtfDestination,       rtfObject,              "object",       0 }, | 
|---|
| 2160 | { rtfDestination,       rtfObjClass,            "objclass",     0 }, | 
|---|
| 2161 | { rtfDestination,       rtfObjName,             "objname",      0 }, | 
|---|
| 2162 | { rtfObjAttr,   rtfObjTime,             "objtime",      0 }, | 
|---|
| 2163 | { rtfDestination,       rtfObjData,             "objdata",      0 }, | 
|---|
| 2164 | { rtfDestination,       rtfObjAlias,            "objalias",     0 }, | 
|---|
| 2165 | { rtfDestination,       rtfObjSection,          "objsect",      0 }, | 
|---|
| 2166 | /* objitem and objtopic aren't documented in the spec! */ | 
|---|
| 2167 | { rtfDestination,       rtfObjItem,             "objitem",      0 }, | 
|---|
| 2168 | { rtfDestination,       rtfObjTopic,            "objtopic",     0 }, | 
|---|
| 2169 | { rtfDestination,       rtfObjResult,           "result",       0 }, | 
|---|
| 2170 | { rtfDestination,       rtfDrawObject,          "do",           0 }, | 
|---|
| 2171 | { rtfDestination,       rtfFootnote,            "footnote",     0 }, | 
|---|
| 2172 | { rtfDestination,       rtfAnnotRefStart,       "atrfstart",    0 }, | 
|---|
| 2173 | { rtfDestination,       rtfAnnotRefEnd,         "atrfend",      0 }, | 
|---|
| 2174 | { rtfDestination,       rtfAnnotID,             "atnid",        0 }, | 
|---|
| 2175 | { rtfDestination,       rtfAnnotAuthor,         "atnauthor",    0 }, | 
|---|
| 2176 | { rtfDestination,       rtfAnnotation,          "annotation",   0 }, | 
|---|
| 2177 | { rtfDestination,       rtfAnnotRef,            "atnref",       0 }, | 
|---|
| 2178 | { rtfDestination,       rtfAnnotTime,           "atntime",      0 }, | 
|---|
| 2179 | { rtfDestination,       rtfAnnotIcon,           "atnicn",       0 }, | 
|---|
| 2180 | { rtfDestination,       rtfField,               "field",        0 }, | 
|---|
| 2181 | { rtfDestination,       rtfFieldInst,           "fldinst",      0 }, | 
|---|
| 2182 | { rtfDestination,       rtfFieldResult,         "fldrslt",      0 }, | 
|---|
| 2183 | { rtfDestination,       rtfDataField,           "datafield",    0 }, | 
|---|
| 2184 | { rtfDestination,       rtfIndex,               "xe",           0 }, | 
|---|
| 2185 | { rtfDestination,       rtfIndexText,           "txe",          0 }, | 
|---|
| 2186 | { rtfDestination,       rtfIndexRange,          "rxe",          0 }, | 
|---|
| 2187 | { rtfDestination,       rtfTOC,                 "tc",           0 }, | 
|---|
| 2188 | { rtfDestination,       rtfNeXTGraphic,         "NeXTGraphic",  0 }, | 
|---|
| 2189 |  | 
|---|
| 2190 | /* | 
|---|
| 2191 | * Font families | 
|---|
| 2192 | */ | 
|---|
| 2193 |  | 
|---|
| 2194 | { rtfFontFamily,        rtfFFNil,               "fnil",         0 }, | 
|---|
| 2195 | { rtfFontFamily,        rtfFFRoman,             "froman",       0 }, | 
|---|
| 2196 | { rtfFontFamily,        rtfFFSwiss,             "fswiss",       0 }, | 
|---|
| 2197 | { rtfFontFamily,        rtfFFModern,            "fmodern",      0 }, | 
|---|
| 2198 | { rtfFontFamily,        rtfFFScript,            "fscript",      0 }, | 
|---|
| 2199 | { rtfFontFamily,        rtfFFDecor,             "fdecor",       0 }, | 
|---|
| 2200 | { rtfFontFamily,        rtfFFTech,              "ftech",        0 }, | 
|---|
| 2201 | { rtfFontFamily,        rtfFFBidirectional,     "fbidi",        0 }, | 
|---|
| 2202 |  | 
|---|
| 2203 | /* | 
|---|
| 2204 | * Font attributes | 
|---|
| 2205 | */ | 
|---|
| 2206 |  | 
|---|
| 2207 | { rtfFontAttr,  rtfFontCharSet,         "fcharset",     0 }, | 
|---|
| 2208 | { rtfFontAttr,  rtfFontPitch,           "fprq",         0 }, | 
|---|
| 2209 | { rtfFontAttr,  rtfFontCodePage,        "cpg",          0 }, | 
|---|
| 2210 | { rtfFontAttr,  rtfFTypeNil,            "ftnil",        0 }, | 
|---|
| 2211 | { rtfFontAttr,  rtfFTypeTrueType,       "fttruetype",   0 }, | 
|---|
| 2212 |  | 
|---|
| 2213 | /* | 
|---|
| 2214 | * File table attributes | 
|---|
| 2215 | */ | 
|---|
| 2216 |  | 
|---|
| 2217 | { rtfFileAttr,  rtfFileNum,             "fid",          0 }, | 
|---|
| 2218 | { rtfFileAttr,  rtfFileRelPath,         "frelative",    0 }, | 
|---|
| 2219 | { rtfFileAttr,  rtfFileOSNum,           "fosnum",       0 }, | 
|---|
| 2220 |  | 
|---|
| 2221 | /* | 
|---|
| 2222 | * File sources | 
|---|
| 2223 | */ | 
|---|
| 2224 |  | 
|---|
| 2225 | { rtfFileSource,        rtfSrcMacintosh,        "fvalidmac",    0 }, | 
|---|
| 2226 | { rtfFileSource,        rtfSrcDOS,              "fvaliddos",    0 }, | 
|---|
| 2227 | { rtfFileSource,        rtfSrcNTFS,             "fvalidntfs",   0 }, | 
|---|
| 2228 | { rtfFileSource,        rtfSrcHPFS,             "fvalidhpfs",   0 }, | 
|---|
| 2229 | { rtfFileSource,        rtfSrcNetwork,          "fnetwork",     0 }, | 
|---|
| 2230 |  | 
|---|
| 2231 | /* | 
|---|
| 2232 | * Color names | 
|---|
| 2233 | */ | 
|---|
| 2234 |  | 
|---|
| 2235 | { rtfColorName, rtfRed,                 "red",          0 }, | 
|---|
| 2236 | { rtfColorName, rtfGreen,               "green",        0 }, | 
|---|
| 2237 | { rtfColorName, rtfBlue,                "blue",         0 }, | 
|---|
| 2238 |  | 
|---|
| 2239 | /* | 
|---|
| 2240 | * Charset names | 
|---|
| 2241 | */ | 
|---|
| 2242 |  | 
|---|
| 2243 | { rtfCharSet,   rtfMacCharSet,          "mac",          0 }, | 
|---|
| 2244 | { rtfCharSet,   rtfAnsiCharSet,         "ansi",         0 }, | 
|---|
| 2245 | { rtfCharSet,   rtfPcCharSet,           "pc",           0 }, | 
|---|
| 2246 | { rtfCharSet,   rtfPcaCharSet,          "pca",          0 }, | 
|---|
| 2247 |  | 
|---|
| 2248 | /* | 
|---|
| 2249 | * Table attributes | 
|---|
| 2250 | */ | 
|---|
| 2251 |  | 
|---|
| 2252 | { rtfTblAttr,   rtfRowDef,              "trowd",        0 }, | 
|---|
| 2253 | { rtfTblAttr,   rtfRowGapH,             "trgaph",       0 }, | 
|---|
| 2254 | { rtfTblAttr,   rtfCellPos,             "cellx",        0 }, | 
|---|
| 2255 | { rtfTblAttr,   rtfMergeRngFirst,       "clmgf",        0 }, | 
|---|
| 2256 | { rtfTblAttr,   rtfMergePrevious,       "clmrg",        0 }, | 
|---|
| 2257 |  | 
|---|
| 2258 | { rtfTblAttr,   rtfRowLeft,             "trql",         0 }, | 
|---|
| 2259 | { rtfTblAttr,   rtfRowRight,            "trqr",         0 }, | 
|---|
| 2260 | { rtfTblAttr,   rtfRowCenter,           "trqc",         0 }, | 
|---|
| 2261 | { rtfTblAttr,   rtfRowLeftEdge,         "trleft",       0 }, | 
|---|
| 2262 | { rtfTblAttr,   rtfRowHt,               "trrh",         0 }, | 
|---|
| 2263 | { rtfTblAttr,   rtfRowHeader,           "trhdr",        0 }, | 
|---|
| 2264 | { rtfTblAttr,   rtfRowKeep,             "trkeep",       0 }, | 
|---|
| 2265 |  | 
|---|
| 2266 | { rtfTblAttr,   rtfRTLRow,              "rtlrow",       0 }, | 
|---|
| 2267 | { rtfTblAttr,   rtfLTRRow,              "ltrrow",       0 }, | 
|---|
| 2268 |  | 
|---|
| 2269 | { rtfTblAttr,   rtfRowBordTop,          "trbrdrt",      0 }, | 
|---|
| 2270 | { rtfTblAttr,   rtfRowBordLeft,         "trbrdrl",      0 }, | 
|---|
| 2271 | { rtfTblAttr,   rtfRowBordBottom,       "trbrdrb",      0 }, | 
|---|
| 2272 | { rtfTblAttr,   rtfRowBordRight,        "trbrdrr",      0 }, | 
|---|
| 2273 | { rtfTblAttr,   rtfRowBordHoriz,        "trbrdrh",      0 }, | 
|---|
| 2274 | { rtfTblAttr,   rtfRowBordVert,         "trbrdrv",      0 }, | 
|---|
| 2275 |  | 
|---|
| 2276 | { rtfTblAttr,   rtfCellBordBottom,      "clbrdrb",      0 }, | 
|---|
| 2277 | { rtfTblAttr,   rtfCellBordTop,         "clbrdrt",      0 }, | 
|---|
| 2278 | { rtfTblAttr,   rtfCellBordLeft,        "clbrdrl",      0 }, | 
|---|
| 2279 | { rtfTblAttr,   rtfCellBordRight,       "clbrdrr",      0 }, | 
|---|
| 2280 |  | 
|---|
| 2281 | { rtfTblAttr,   rtfCellShading,         "clshdng",      0 }, | 
|---|
| 2282 | { rtfTblAttr,   rtfCellBgPatH,          "clbghoriz",    0 }, | 
|---|
| 2283 | { rtfTblAttr,   rtfCellBgPatV,          "clbgvert",     0 }, | 
|---|
| 2284 | { rtfTblAttr,   rtfCellFwdDiagBgPat,    "clbgfdiag",    0 }, | 
|---|
| 2285 | { rtfTblAttr,   rtfCellBwdDiagBgPat,    "clbgbdiag",    0 }, | 
|---|
| 2286 | { rtfTblAttr,   rtfCellHatchBgPat,      "clbgcross",    0 }, | 
|---|
| 2287 | { rtfTblAttr,   rtfCellDiagHatchBgPat,  "clbgdcross",   0 }, | 
|---|
| 2288 | /* | 
|---|
| 2289 | * The spec lists "clbgdkhor", but the corresponding non-cell | 
|---|
| 2290 | * control is "bgdkhoriz".  At any rate Macintosh Word seems | 
|---|
| 2291 | * to accept both "clbgdkhor" and "clbgdkhoriz". | 
|---|
| 2292 | */ | 
|---|
| 2293 | { rtfTblAttr,   rtfCellDarkBgPatH,      "clbgdkhoriz",  0 }, | 
|---|
| 2294 | { rtfTblAttr,   rtfCellDarkBgPatH,      "clbgdkhor",    0 }, | 
|---|
| 2295 | { rtfTblAttr,   rtfCellDarkBgPatV,      "clbgdkvert",   0 }, | 
|---|
| 2296 | { rtfTblAttr,   rtfCellFwdDarkBgPat,    "clbgdkfdiag",  0 }, | 
|---|
| 2297 | { rtfTblAttr,   rtfCellBwdDarkBgPat,    "clbgdkbdiag",  0 }, | 
|---|
| 2298 | { rtfTblAttr,   rtfCellDarkHatchBgPat,  "clbgdkcross",  0 }, | 
|---|
| 2299 | { rtfTblAttr,   rtfCellDarkDiagHatchBgPat, "clbgdkdcross",      0 }, | 
|---|
| 2300 | { rtfTblAttr,   rtfCellBgPatLineColor, "clcfpat",       0 }, | 
|---|
| 2301 | { rtfTblAttr,   rtfCellBgPatColor,      "clcbpat",      0 }, | 
|---|
| 2302 |  | 
|---|
| 2303 | /* | 
|---|
| 2304 | * Field attributes | 
|---|
| 2305 | */ | 
|---|
| 2306 |  | 
|---|
| 2307 | { rtfFieldAttr, rtfFieldDirty,          "flddirty",     0 }, | 
|---|
| 2308 | { rtfFieldAttr, rtfFieldEdited,         "fldedit",      0 }, | 
|---|
| 2309 | { rtfFieldAttr, rtfFieldLocked,         "fldlock",      0 }, | 
|---|
| 2310 | { rtfFieldAttr, rtfFieldPrivate,        "fldpriv",      0 }, | 
|---|
| 2311 | { rtfFieldAttr, rtfFieldAlt,            "fldalt",       0 }, | 
|---|
| 2312 |  | 
|---|
| 2313 | /* | 
|---|
| 2314 | * Positioning attributes | 
|---|
| 2315 | */ | 
|---|
| 2316 |  | 
|---|
| 2317 | { rtfPosAttr,   rtfAbsWid,              "absw",         0 }, | 
|---|
| 2318 | { rtfPosAttr,   rtfAbsHt,               "absh",         0 }, | 
|---|
| 2319 |  | 
|---|
| 2320 | { rtfPosAttr,   rtfRPosMargH,           "phmrg",        0 }, | 
|---|
| 2321 | { rtfPosAttr,   rtfRPosPageH,           "phpg",         0 }, | 
|---|
| 2322 | { rtfPosAttr,   rtfRPosColH,            "phcol",        0 }, | 
|---|
| 2323 | { rtfPosAttr,   rtfPosX,                "posx",         0 }, | 
|---|
| 2324 | { rtfPosAttr,   rtfPosNegX,             "posnegx",      0 }, | 
|---|
| 2325 | { rtfPosAttr,   rtfPosXCenter,          "posxc",        0 }, | 
|---|
| 2326 | { rtfPosAttr,   rtfPosXInside,          "posxi",        0 }, | 
|---|
| 2327 | { rtfPosAttr,   rtfPosXOutSide,         "posxo",        0 }, | 
|---|
| 2328 | { rtfPosAttr,   rtfPosXRight,           "posxr",        0 }, | 
|---|
| 2329 | { rtfPosAttr,   rtfPosXLeft,            "posxl",        0 }, | 
|---|
| 2330 |  | 
|---|
| 2331 | { rtfPosAttr,   rtfRPosMargV,           "pvmrg",        0 }, | 
|---|
| 2332 | { rtfPosAttr,   rtfRPosPageV,           "pvpg",         0 }, | 
|---|
| 2333 | { rtfPosAttr,   rtfRPosParaV,           "pvpara",       0 }, | 
|---|
| 2334 | { rtfPosAttr,   rtfPosY,                "posy",         0 }, | 
|---|
| 2335 | { rtfPosAttr,   rtfPosNegY,             "posnegy",      0 }, | 
|---|
| 2336 | { rtfPosAttr,   rtfPosYInline,          "posyil",       0 }, | 
|---|
| 2337 | { rtfPosAttr,   rtfPosYTop,             "posyt",        0 }, | 
|---|
| 2338 | { rtfPosAttr,   rtfPosYCenter,          "posyc",        0 }, | 
|---|
| 2339 | { rtfPosAttr,   rtfPosYBottom,          "posyb",        0 }, | 
|---|
| 2340 |  | 
|---|
| 2341 | { rtfPosAttr,   rtfNoWrap,              "nowrap",       0 }, | 
|---|
| 2342 | { rtfPosAttr,   rtfDistFromTextAll,     "dxfrtext",     0 }, | 
|---|
| 2343 | { rtfPosAttr,   rtfDistFromTextX,       "dfrmtxtx",     0 }, | 
|---|
| 2344 | { rtfPosAttr,   rtfDistFromTextY,       "dfrmtxty",     0 }, | 
|---|
| 2345 | /* \dyfrtext no longer exists in spec 1.2, apparently */ | 
|---|
| 2346 | /* replaced by \dfrmtextx and \dfrmtexty. */ | 
|---|
| 2347 | { rtfPosAttr,   rtfTextDistY,           "dyfrtext",     0 }, | 
|---|
| 2348 |  | 
|---|
| 2349 | { rtfPosAttr,   rtfDropCapLines,        "dropcapli",    0 }, | 
|---|
| 2350 | { rtfPosAttr,   rtfDropCapType,         "dropcapt",     0 }, | 
|---|
| 2351 |  | 
|---|
| 2352 | /* | 
|---|
| 2353 | * Object controls | 
|---|
| 2354 | */ | 
|---|
| 2355 |  | 
|---|
| 2356 | { rtfObjAttr,   rtfObjEmb,              "objemb",       0 }, | 
|---|
| 2357 | { rtfObjAttr,   rtfObjLink,             "objlink",      0 }, | 
|---|
| 2358 | { rtfObjAttr,   rtfObjAutoLink,         "objautlink",   0 }, | 
|---|
| 2359 | { rtfObjAttr,   rtfObjSubscriber,       "objsub",       0 }, | 
|---|
| 2360 | { rtfObjAttr,   rtfObjPublisher,        "objpub",       0 }, | 
|---|
| 2361 | { rtfObjAttr,   rtfObjICEmb,            "objicemb",     0 }, | 
|---|
| 2362 |  | 
|---|
| 2363 | { rtfObjAttr,   rtfObjLinkSelf,         "linkself",     0 }, | 
|---|
| 2364 | { rtfObjAttr,   rtfObjLock,             "objupdate",    0 }, | 
|---|
| 2365 | { rtfObjAttr,   rtfObjUpdate,           "objlock",      0 }, | 
|---|
| 2366 |  | 
|---|
| 2367 | { rtfObjAttr,   rtfObjHt,               "objh",         0 }, | 
|---|
| 2368 | { rtfObjAttr,   rtfObjWid,              "objw",         0 }, | 
|---|
| 2369 | { rtfObjAttr,   rtfObjSetSize,          "objsetsize",   0 }, | 
|---|
| 2370 | { rtfObjAttr,   rtfObjAlign,            "objalign",     0 }, | 
|---|
| 2371 | { rtfObjAttr,   rtfObjTransposeY,       "objtransy",    0 }, | 
|---|
| 2372 | { rtfObjAttr,   rtfObjCropTop,          "objcropt",     0 }, | 
|---|
| 2373 | { rtfObjAttr,   rtfObjCropBottom,       "objcropb",     0 }, | 
|---|
| 2374 | { rtfObjAttr,   rtfObjCropLeft,         "objcropl",     0 }, | 
|---|
| 2375 | { rtfObjAttr,   rtfObjCropRight,        "objcropr",     0 }, | 
|---|
| 2376 | { rtfObjAttr,   rtfObjScaleX,           "objscalex",    0 }, | 
|---|
| 2377 | { rtfObjAttr,   rtfObjScaleY,           "objscaley",    0 }, | 
|---|
| 2378 |  | 
|---|
| 2379 | { rtfObjAttr,   rtfObjResRTF,           "rsltrtf",      0 }, | 
|---|
| 2380 | { rtfObjAttr,   rtfObjResPict,          "rsltpict",     0 }, | 
|---|
| 2381 | { rtfObjAttr,   rtfObjResBitmap,        "rsltbmp",      0 }, | 
|---|
| 2382 | { rtfObjAttr,   rtfObjResText,          "rslttxt",      0 }, | 
|---|
| 2383 | { rtfObjAttr,   rtfObjResMerge,         "rsltmerge",    0 }, | 
|---|
| 2384 |  | 
|---|
| 2385 | { rtfObjAttr,   rtfObjBookmarkPubObj,   "bkmkpub",      0 }, | 
|---|
| 2386 | { rtfObjAttr,   rtfObjPubAutoUpdate,    "pubauto",      0 }, | 
|---|
| 2387 |  | 
|---|
| 2388 | /* | 
|---|
| 2389 | * Associated character formatting attributes | 
|---|
| 2390 | */ | 
|---|
| 2391 |  | 
|---|
| 2392 | { rtfACharAttr, rtfACBold,              "ab",           0 }, | 
|---|
| 2393 | { rtfACharAttr, rtfACAllCaps,           "caps",         0 }, | 
|---|
| 2394 | { rtfACharAttr, rtfACForeColor,         "acf",          0 }, | 
|---|
| 2395 | { rtfACharAttr, rtfACSubScript,         "adn",          0 }, | 
|---|
| 2396 | { rtfACharAttr, rtfACExpand,            "aexpnd",       0 }, | 
|---|
| 2397 | { rtfACharAttr, rtfACFontNum,           "af",           0 }, | 
|---|
| 2398 | { rtfACharAttr, rtfACFontSize,          "afs",          0 }, | 
|---|
| 2399 | { rtfACharAttr, rtfACItalic,            "ai",           0 }, | 
|---|
| 2400 | { rtfACharAttr, rtfACLanguage,          "alang",        0 }, | 
|---|
| 2401 | { rtfACharAttr, rtfACOutline,           "aoutl",        0 }, | 
|---|
| 2402 | { rtfACharAttr, rtfACSmallCaps,         "ascaps",       0 }, | 
|---|
| 2403 | { rtfACharAttr, rtfACShadow,            "ashad",        0 }, | 
|---|
| 2404 | { rtfACharAttr, rtfACStrikeThru,        "astrike",      0 }, | 
|---|
| 2405 | { rtfACharAttr, rtfACUnderline,         "aul",          0 }, | 
|---|
| 2406 | { rtfACharAttr, rtfACDotUnderline,      "auld",         0 }, | 
|---|
| 2407 | { rtfACharAttr, rtfACDbUnderline,       "auldb",        0 }, | 
|---|
| 2408 | { rtfACharAttr, rtfACNoUnderline,       "aulnone",      0 }, | 
|---|
| 2409 | { rtfACharAttr, rtfACWordUnderline,     "aulw",         0 }, | 
|---|
| 2410 | { rtfACharAttr, rtfACSuperScript,       "aup",          0 }, | 
|---|
| 2411 |  | 
|---|
| 2412 | /* | 
|---|
| 2413 | * Footnote attributes | 
|---|
| 2414 | */ | 
|---|
| 2415 |  | 
|---|
| 2416 | { rtfFNoteAttr, rtfFNAlt,               "ftnalt",       0 }, | 
|---|
| 2417 |  | 
|---|
| 2418 | /* | 
|---|
| 2419 | * Key code attributes | 
|---|
| 2420 | */ | 
|---|
| 2421 |  | 
|---|
| 2422 | { rtfKeyCodeAttr,       rtfAltKey,              "alt",          0 }, | 
|---|
| 2423 | { rtfKeyCodeAttr,       rtfShiftKey,            "shift",        0 }, | 
|---|
| 2424 | { rtfKeyCodeAttr,       rtfControlKey,          "ctrl",         0 }, | 
|---|
| 2425 | { rtfKeyCodeAttr,       rtfFunctionKey,         "fn",           0 }, | 
|---|
| 2426 |  | 
|---|
| 2427 | /* | 
|---|
| 2428 | * Bookmark attributes | 
|---|
| 2429 | */ | 
|---|
| 2430 |  | 
|---|
| 2431 | { rtfBookmarkAttr, rtfBookmarkFirstCol, "bkmkcolf",     0 }, | 
|---|
| 2432 | { rtfBookmarkAttr, rtfBookmarkLastCol,  "bkmkcoll",     0 }, | 
|---|
| 2433 |  | 
|---|
| 2434 | /* | 
|---|
| 2435 | * Index entry attributes | 
|---|
| 2436 | */ | 
|---|
| 2437 |  | 
|---|
| 2438 | { rtfIndexAttr, rtfIndexNumber,         "xef",          0 }, | 
|---|
| 2439 | { rtfIndexAttr, rtfIndexBold,           "bxe",          0 }, | 
|---|
| 2440 | { rtfIndexAttr, rtfIndexItalic,         "ixe",          0 }, | 
|---|
| 2441 |  | 
|---|
| 2442 | /* | 
|---|
| 2443 | * Table of contents attributes | 
|---|
| 2444 | */ | 
|---|
| 2445 |  | 
|---|
| 2446 | { rtfTOCAttr,   rtfTOCType,             "tcf",          0 }, | 
|---|
| 2447 | { rtfTOCAttr,   rtfTOCLevel,            "tcl",          0 }, | 
|---|
| 2448 |  | 
|---|
| 2449 | /* | 
|---|
| 2450 | * Drawing object attributes | 
|---|
| 2451 | */ | 
|---|
| 2452 |  | 
|---|
| 2453 | { rtfDrawAttr,  rtfDrawLock,            "dolock",       0 }, | 
|---|
| 2454 | { rtfDrawAttr,  rtfDrawPageRelX,        "doxpage",      0 }, | 
|---|
| 2455 | { rtfDrawAttr,  rtfDrawColumnRelX,      "dobxcolumn",   0 }, | 
|---|
| 2456 | { rtfDrawAttr,  rtfDrawMarginRelX,      "dobxmargin",   0 }, | 
|---|
| 2457 | { rtfDrawAttr,  rtfDrawPageRelY,        "dobypage",     0 }, | 
|---|
| 2458 | { rtfDrawAttr,  rtfDrawColumnRelY,      "dobycolumn",   0 }, | 
|---|
| 2459 | { rtfDrawAttr,  rtfDrawMarginRelY,      "dobymargin",   0 }, | 
|---|
| 2460 | { rtfDrawAttr,  rtfDrawHeight,          "dobhgt",       0 }, | 
|---|
| 2461 |  | 
|---|
| 2462 | { rtfDrawAttr,  rtfDrawBeginGroup,      "dpgroup",      0 }, | 
|---|
| 2463 | { rtfDrawAttr,  rtfDrawGroupCount,      "dpcount",      0 }, | 
|---|
| 2464 | { rtfDrawAttr,  rtfDrawEndGroup,        "dpendgroup",   0 }, | 
|---|
| 2465 | { rtfDrawAttr,  rtfDrawArc,             "dparc",        0 }, | 
|---|
| 2466 | { rtfDrawAttr,  rtfDrawCallout,         "dpcallout",    0 }, | 
|---|
| 2467 | { rtfDrawAttr,  rtfDrawEllipse,         "dpellipse",    0 }, | 
|---|
| 2468 | { rtfDrawAttr,  rtfDrawLine,            "dpline",       0 }, | 
|---|
| 2469 | { rtfDrawAttr,  rtfDrawPolygon,         "dppolygon",    0 }, | 
|---|
| 2470 | { rtfDrawAttr,  rtfDrawPolyLine,        "dppolyline",   0 }, | 
|---|
| 2471 | { rtfDrawAttr,  rtfDrawRect,            "dprect",       0 }, | 
|---|
| 2472 | { rtfDrawAttr,  rtfDrawTextBox,         "dptxbx",       0 }, | 
|---|
| 2473 |  | 
|---|
| 2474 | { rtfDrawAttr,  rtfDrawOffsetX,         "dpx",          0 }, | 
|---|
| 2475 | { rtfDrawAttr,  rtfDrawSizeX,           "dpxsize",      0 }, | 
|---|
| 2476 | { rtfDrawAttr,  rtfDrawOffsetY,         "dpy",          0 }, | 
|---|
| 2477 | { rtfDrawAttr,  rtfDrawSizeY,           "dpysize",      0 }, | 
|---|
| 2478 |  | 
|---|
| 2479 | { rtfDrawAttr,  rtfCOAngle,             "dpcoa",        0 }, | 
|---|
| 2480 | { rtfDrawAttr,  rtfCOAccentBar,         "dpcoaccent",   0 }, | 
|---|
| 2481 | { rtfDrawAttr,  rtfCOBestFit,           "dpcobestfit",  0 }, | 
|---|
| 2482 | { rtfDrawAttr,  rtfCOBorder,            "dpcoborder",   0 }, | 
|---|
| 2483 | { rtfDrawAttr,  rtfCOAttachAbsDist,     "dpcodabs",     0 }, | 
|---|
| 2484 | { rtfDrawAttr,  rtfCOAttachBottom,      "dpcodbottom",  0 }, | 
|---|
| 2485 | { rtfDrawAttr,  rtfCOAttachCenter,      "dpcodcenter",  0 }, | 
|---|
| 2486 | { rtfDrawAttr,  rtfCOAttachTop,         "dpcodtop",     0 }, | 
|---|
| 2487 | { rtfDrawAttr,  rtfCOLength,            "dpcolength",   0 }, | 
|---|
| 2488 | { rtfDrawAttr,  rtfCONegXQuadrant,      "dpcominusx",   0 }, | 
|---|
| 2489 | { rtfDrawAttr,  rtfCONegYQuadrant,      "dpcominusy",   0 }, | 
|---|
| 2490 | { rtfDrawAttr,  rtfCOOffset,            "dpcooffset",   0 }, | 
|---|
| 2491 | { rtfDrawAttr,  rtfCOAttachSmart,       "dpcosmarta",   0 }, | 
|---|
| 2492 | { rtfDrawAttr,  rtfCODoubleLine,        "dpcotdouble",  0 }, | 
|---|
| 2493 | { rtfDrawAttr,  rtfCORightAngle,        "dpcotright",   0 }, | 
|---|
| 2494 | { rtfDrawAttr,  rtfCOSingleLine,        "dpcotsingle",  0 }, | 
|---|
| 2495 | { rtfDrawAttr,  rtfCOTripleLine,        "dpcottriple",  0 }, | 
|---|
| 2496 |  | 
|---|
| 2497 | { rtfDrawAttr,  rtfDrawTextBoxMargin,   "dptxbxmar",    0 }, | 
|---|
| 2498 | { rtfDrawAttr,  rtfDrawTextBoxText,     "dptxbxtext",   0 }, | 
|---|
| 2499 | { rtfDrawAttr,  rtfDrawRoundRect,       "dproundr",     0 }, | 
|---|
| 2500 |  | 
|---|
| 2501 | { rtfDrawAttr,  rtfDrawPointX,          "dpptx",        0 }, | 
|---|
| 2502 | { rtfDrawAttr,  rtfDrawPointY,          "dppty",        0 }, | 
|---|
| 2503 | { rtfDrawAttr,  rtfDrawPolyCount,       "dppolycount",  0 }, | 
|---|
| 2504 |  | 
|---|
| 2505 | { rtfDrawAttr,  rtfDrawArcFlipX,        "dparcflipx",   0 }, | 
|---|
| 2506 | { rtfDrawAttr,  rtfDrawArcFlipY,        "dparcflipy",   0 }, | 
|---|
| 2507 |  | 
|---|
| 2508 | { rtfDrawAttr,  rtfDrawLineBlue,        "dplinecob",    0 }, | 
|---|
| 2509 | { rtfDrawAttr,  rtfDrawLineGreen,       "dplinecog",    0 }, | 
|---|
| 2510 | { rtfDrawAttr,  rtfDrawLineRed,         "dplinecor",    0 }, | 
|---|
| 2511 | { rtfDrawAttr,  rtfDrawLinePalette,     "dplinepal",    0 }, | 
|---|
| 2512 | { rtfDrawAttr,  rtfDrawLineDashDot,     "dplinedado",   0 }, | 
|---|
| 2513 | { rtfDrawAttr,  rtfDrawLineDashDotDot,  "dplinedadodo", 0 }, | 
|---|
| 2514 | { rtfDrawAttr,  rtfDrawLineDash,        "dplinedash",   0 }, | 
|---|
| 2515 | { rtfDrawAttr,  rtfDrawLineDot,         "dplinedot",    0 }, | 
|---|
| 2516 | { rtfDrawAttr,  rtfDrawLineGray,        "dplinegray",   0 }, | 
|---|
| 2517 | { rtfDrawAttr,  rtfDrawLineHollow,      "dplinehollow", 0 }, | 
|---|
| 2518 | { rtfDrawAttr,  rtfDrawLineSolid,       "dplinesolid",  0 }, | 
|---|
| 2519 | { rtfDrawAttr,  rtfDrawLineWidth,       "dplinew",      0 }, | 
|---|
| 2520 |  | 
|---|
| 2521 | { rtfDrawAttr,  rtfDrawHollowEndArrow,  "dpaendhol",    0 }, | 
|---|
| 2522 | { rtfDrawAttr,  rtfDrawEndArrowLength,  "dpaendl",      0 }, | 
|---|
| 2523 | { rtfDrawAttr,  rtfDrawSolidEndArrow,   "dpaendsol",    0 }, | 
|---|
| 2524 | { rtfDrawAttr,  rtfDrawEndArrowWidth,   "dpaendw",      0 }, | 
|---|
| 2525 | { rtfDrawAttr,  rtfDrawHollowStartArrow,"dpastarthol",  0 }, | 
|---|
| 2526 | { rtfDrawAttr,  rtfDrawStartArrowLength,"dpastartl",    0 }, | 
|---|
| 2527 | { rtfDrawAttr,  rtfDrawSolidStartArrow, "dpastartsol",  0 }, | 
|---|
| 2528 | { rtfDrawAttr,  rtfDrawStartArrowWidth, "dpastartw",    0 }, | 
|---|
| 2529 |  | 
|---|
| 2530 | { rtfDrawAttr,  rtfDrawBgFillBlue,      "dpfillbgcb",   0 }, | 
|---|
| 2531 | { rtfDrawAttr,  rtfDrawBgFillGreen,     "dpfillbgcg",   0 }, | 
|---|
| 2532 | { rtfDrawAttr,  rtfDrawBgFillRed,       "dpfillbgcr",   0 }, | 
|---|
| 2533 | { rtfDrawAttr,  rtfDrawBgFillPalette,   "dpfillbgpal",  0 }, | 
|---|
| 2534 | { rtfDrawAttr,  rtfDrawBgFillGray,      "dpfillbggray", 0 }, | 
|---|
| 2535 | { rtfDrawAttr,  rtfDrawFgFillBlue,      "dpfillfgcb",   0 }, | 
|---|
| 2536 | { rtfDrawAttr,  rtfDrawFgFillGreen,     "dpfillfgcg",   0 }, | 
|---|
| 2537 | { rtfDrawAttr,  rtfDrawFgFillRed,       "dpfillfgcr",   0 }, | 
|---|
| 2538 | { rtfDrawAttr,  rtfDrawFgFillPalette,   "dpfillfgpal",  0 }, | 
|---|
| 2539 | { rtfDrawAttr,  rtfDrawFgFillGray,      "dpfillfggray", 0 }, | 
|---|
| 2540 | { rtfDrawAttr,  rtfDrawFillPatIndex,    "dpfillpat",    0 }, | 
|---|
| 2541 |  | 
|---|
| 2542 | { rtfDrawAttr,  rtfDrawShadow,          "dpshadow",     0 }, | 
|---|
| 2543 | { rtfDrawAttr,  rtfDrawShadowXOffset,   "dpshadx",      0 }, | 
|---|
| 2544 | { rtfDrawAttr,  rtfDrawShadowYOffset,   "dpshady",      0 }, | 
|---|
| 2545 |  | 
|---|
| 2546 | { rtfVersion,   -1,                     "rtf",          0 }, | 
|---|
| 2547 | { rtfDefFont,   -1,                     "deff",         0 }, | 
|---|
| 2548 |  | 
|---|
| 2549 | { 0,            -1,                     (char *) NULL,  0 } | 
|---|
| 2550 | }; | 
|---|
| 2551 |  | 
|---|
| 2552 |  | 
|---|
| 2553 | /* | 
|---|
| 2554 | * Initialize lookup table hash values.  Only need to do this once. | 
|---|
| 2555 | */ | 
|---|
| 2556 |  | 
|---|
| 2557 | static void | 
|---|
| 2558 | LookupInit () | 
|---|
| 2559 | { | 
|---|
| 2560 | static int      inited = 0; | 
|---|
| 2561 | RTFKey  *rp; | 
|---|
| 2562 |  | 
|---|
| 2563 | if (inited == 0) | 
|---|
| 2564 | { | 
|---|
| 2565 | for (rp = rtfKey; rp->rtfKStr != (char *) NULL; rp++) | 
|---|
| 2566 | rp->rtfKHash = Hash (rp->rtfKStr); | 
|---|
| 2567 | ++inited; | 
|---|
| 2568 | } | 
|---|
| 2569 | } | 
|---|
| 2570 |  | 
|---|
| 2571 |  | 
|---|
| 2572 | /* | 
|---|
| 2573 | * Determine major and minor number of control token.  If it's | 
|---|
| 2574 | * not found, the class turns into rtfUnknown. | 
|---|
| 2575 | */ | 
|---|
| 2576 |  | 
|---|
| 2577 | static void | 
|---|
| 2578 | Lookup (s) | 
|---|
| 2579 | char    *s; | 
|---|
| 2580 | { | 
|---|
| 2581 | RTFKey  *rp; | 
|---|
| 2582 | int     hash; | 
|---|
| 2583 |  | 
|---|
| 2584 | ++s;                    /* skip over the leading \ character */ | 
|---|
| 2585 | hash = Hash (s); | 
|---|
| 2586 | for (rp = rtfKey; rp->rtfKStr != (char *) NULL; rp++) | 
|---|
| 2587 | { | 
|---|
| 2588 | if (hash == rp->rtfKHash && strcmp (s, rp->rtfKStr) == 0) | 
|---|
| 2589 | { | 
|---|
| 2590 | rtfClass = rtfControl; | 
|---|
| 2591 | rtfMajor = rp->rtfKMajor; | 
|---|
| 2592 | rtfMinor = rp->rtfKMinor; | 
|---|
| 2593 | return; | 
|---|
| 2594 | } | 
|---|
| 2595 | } | 
|---|
| 2596 | rtfClass = rtfUnknown; | 
|---|
| 2597 | } | 
|---|
| 2598 |  | 
|---|
| 2599 |  | 
|---|
| 2600 | /* | 
|---|
| 2601 | * Compute hash value of symbol | 
|---|
| 2602 | */ | 
|---|
| 2603 |  | 
|---|
| 2604 | static int | 
|---|
| 2605 | Hash (s) | 
|---|
| 2606 | char    *s; | 
|---|
| 2607 | { | 
|---|
| 2608 | char    c; | 
|---|
| 2609 | int     val = 0; | 
|---|
| 2610 |  | 
|---|
| 2611 | while ((c = *s++) != '\0') | 
|---|
| 2612 | val += (int) c; | 
|---|
| 2613 | return (val); | 
|---|
| 2614 | } | 
|---|
| 2615 |  | 
|---|
| 2616 |  | 
|---|
| 2617 | /* ---------------------------------------------------------------------- */ | 
|---|
| 2618 |  | 
|---|
| 2619 | /* | 
|---|
| 2620 | * Memory allocation routines | 
|---|
| 2621 | */ | 
|---|
| 2622 |  | 
|---|
| 2623 |  | 
|---|
| 2624 | /* | 
|---|
| 2625 | * Return pointer to block of size bytes, or NULL if there's | 
|---|
| 2626 | * not enough memory available. | 
|---|
| 2627 | * | 
|---|
| 2628 | * This is called through RTFAlloc(), a define which coerces the | 
|---|
| 2629 | * argument to int.  This avoids the persistent problem of allocation | 
|---|
| 2630 | * failing under THINK C when a long is passed. | 
|---|
| 2631 | */ | 
|---|
| 2632 |  | 
|---|
| 2633 | char * | 
|---|
| 2634 | _RTFAlloc (size) | 
|---|
| 2635 | int     size; | 
|---|
| 2636 | { | 
|---|
| 2637 | return HeapAlloc(RICHED32_hHeap, 0, size); | 
|---|
| 2638 | } | 
|---|
| 2639 |  | 
|---|
| 2640 |  | 
|---|
| 2641 | /* | 
|---|
| 2642 | * Saves a string on the heap and returns a pointer to it. | 
|---|
| 2643 | */ | 
|---|
| 2644 |  | 
|---|
| 2645 |  | 
|---|
| 2646 | char * | 
|---|
| 2647 | RTFStrSave (s) | 
|---|
| 2648 | char    *s; | 
|---|
| 2649 | { | 
|---|
| 2650 | char    *p; | 
|---|
| 2651 |  | 
|---|
| 2652 | if ((p = RTFAlloc ((int) (strlen (s) + 1))) == (char *) NULL) | 
|---|
| 2653 | return ((char *) NULL); | 
|---|
| 2654 | return (strcpy (p, s)); | 
|---|
| 2655 | } | 
|---|
| 2656 |  | 
|---|
| 2657 |  | 
|---|
| 2658 | void | 
|---|
| 2659 | RTFFree (p) | 
|---|
| 2660 | char    *p; | 
|---|
| 2661 | { | 
|---|
| 2662 | if (p != (char *) NULL) | 
|---|
| 2663 | HeapFree(RICHED32_hHeap, 0, p); | 
|---|
| 2664 | } | 
|---|
| 2665 |  | 
|---|
| 2666 |  | 
|---|
| 2667 | /* ---------------------------------------------------------------------- */ | 
|---|
| 2668 |  | 
|---|
| 2669 |  | 
|---|
| 2670 | /* | 
|---|
| 2671 | * Token comparison routines | 
|---|
| 2672 | */ | 
|---|
| 2673 |  | 
|---|
| 2674 | int | 
|---|
| 2675 | RTFCheckCM (class, major) | 
|---|
| 2676 | int     class, major; | 
|---|
| 2677 | { | 
|---|
| 2678 | return (rtfClass == class && rtfMajor == major); | 
|---|
| 2679 | } | 
|---|
| 2680 |  | 
|---|
| 2681 |  | 
|---|
| 2682 | int | 
|---|
| 2683 | RTFCheckCMM (class, major, minor) | 
|---|
| 2684 | int     class, major, minor; | 
|---|
| 2685 | { | 
|---|
| 2686 | return (rtfClass == class && rtfMajor == major && rtfMinor == minor); | 
|---|
| 2687 | } | 
|---|
| 2688 |  | 
|---|
| 2689 |  | 
|---|
| 2690 | int | 
|---|
| 2691 | RTFCheckMM (major, minor) | 
|---|
| 2692 | int     major, minor; | 
|---|
| 2693 | { | 
|---|
| 2694 | return (rtfMajor == major && rtfMinor == minor); | 
|---|
| 2695 | } | 
|---|
| 2696 |  | 
|---|
| 2697 |  | 
|---|
| 2698 | /* ---------------------------------------------------------------------- */ | 
|---|
| 2699 |  | 
|---|
| 2700 |  | 
|---|
| 2701 | int | 
|---|
| 2702 | RTFCharToHex (c) | 
|---|
| 2703 | char    c; | 
|---|
| 2704 | { | 
|---|
| 2705 | if (isupper (c)) | 
|---|
| 2706 | c = tolower (c); | 
|---|
| 2707 | if (isdigit (c)) | 
|---|
| 2708 | return (c - '0');       /* '0'..'9' */ | 
|---|
| 2709 | return (c - 'a' + 10);          /* 'a'..'f' */ | 
|---|
| 2710 | } | 
|---|
| 2711 |  | 
|---|
| 2712 |  | 
|---|
| 2713 | int | 
|---|
| 2714 | RTFHexToChar (i) | 
|---|
| 2715 | int     i; | 
|---|
| 2716 | { | 
|---|
| 2717 | if (i < 10) | 
|---|
| 2718 | return (i + '0'); | 
|---|
| 2719 | return (i - 10 + 'a'); | 
|---|
| 2720 | } | 
|---|
| 2721 |  | 
|---|
| 2722 |  | 
|---|
| 2723 | /* ---------------------------------------------------------------------- */ | 
|---|
| 2724 |  | 
|---|
| 2725 | /* | 
|---|
| 2726 | * RTFReadOutputMap() -- Read output translation map | 
|---|
| 2727 | */ | 
|---|
| 2728 |  | 
|---|
| 2729 | /* | 
|---|
| 2730 | * Read in an array describing the relation between the standard character set | 
|---|
| 2731 | * and an RTF translator's corresponding output sequences.  Each line consists | 
|---|
| 2732 | * of a standard character name and the output sequence for that character. | 
|---|
| 2733 | * | 
|---|
| 2734 | * outMap is an array of strings into which the sequences should be placed. | 
|---|
| 2735 | * It should be declared like this in the calling program: | 
|---|
| 2736 | * | 
|---|
| 2737 | *      char *outMap[rtfSC_MaxChar]; | 
|---|
| 2738 | * | 
|---|
| 2739 | * reinit should be non-zero if outMap should be initialized | 
|---|
| 2740 | * zero otherwise. | 
|---|
| 2741 | * | 
|---|
| 2742 | */ | 
|---|
| 2743 |  | 
|---|
| 2744 | int | 
|---|
| 2745 | RTFReadOutputMap (outMap, reinit) | 
|---|
| 2746 | char    *outMap[]; | 
|---|
| 2747 | int     reinit; | 
|---|
| 2748 | { | 
|---|
| 2749 | int  i; | 
|---|
| 2750 | int  stdCode; | 
|---|
| 2751 | char *name, *seq; | 
|---|
| 2752 |  | 
|---|
| 2753 | if (reinit) | 
|---|
| 2754 | { | 
|---|
| 2755 | for (i = 0; i < rtfSC_MaxChar; i++) | 
|---|
| 2756 | { | 
|---|
| 2757 | outMap[i] = (char *) NULL; | 
|---|
| 2758 | } | 
|---|
| 2759 | } | 
|---|
| 2760 |  | 
|---|
| 2761 | for (i=0 ;i< sizeof(text_map)/sizeof(char*); i+=2) | 
|---|
| 2762 | { | 
|---|
| 2763 | name = text_map[i]; | 
|---|
| 2764 | seq  = text_map[i+1]; | 
|---|
| 2765 | stdCode = RTFStdCharCode( name ); | 
|---|
| 2766 | outMap[stdCode] = seq; | 
|---|
| 2767 | } | 
|---|
| 2768 |  | 
|---|
| 2769 | return (1); | 
|---|
| 2770 | } | 
|---|
| 2771 |  | 
|---|
| 2772 | /* ---------------------------------------------------------------------- */ | 
|---|
| 2773 |  | 
|---|
| 2774 | /* | 
|---|
| 2775 | * Open a library file. | 
|---|
| 2776 | */ | 
|---|
| 2777 |  | 
|---|
| 2778 |  | 
|---|
| 2779 | static FILE     *(*libFileOpen) () = NULL; | 
|---|
| 2780 |  | 
|---|
| 2781 |  | 
|---|
| 2782 |  | 
|---|
| 2783 | void | 
|---|
| 2784 | RTFSetOpenLibFileProc (proc) | 
|---|
| 2785 | FILE    *(*proc) (); | 
|---|
| 2786 | { | 
|---|
| 2787 | libFileOpen = proc; | 
|---|
| 2788 | } | 
|---|
| 2789 |  | 
|---|
| 2790 |  | 
|---|
| 2791 | FILE * | 
|---|
| 2792 | RTFOpenLibFile (file, mode) | 
|---|
| 2793 | char    *file; | 
|---|
| 2794 | char    *mode; | 
|---|
| 2795 | { | 
|---|
| 2796 | if (libFileOpen == NULL) | 
|---|
| 2797 | return ((FILE *) NULL); | 
|---|
| 2798 | return ((*libFileOpen) (file, mode)); | 
|---|
| 2799 | } | 
|---|
| 2800 |  | 
|---|
| 2801 |  | 
|---|
| 2802 | /* ---------------------------------------------------------------------- */ | 
|---|
| 2803 |  | 
|---|
| 2804 | /* | 
|---|
| 2805 | * Print message.  Default is to send message to stderr | 
|---|
| 2806 | * but this may be overridden with RTFSetMsgProc(). | 
|---|
| 2807 | * | 
|---|
| 2808 | * Message should include linefeeds as necessary.  If the default | 
|---|
| 2809 | * function is overridden, the overriding function may want to | 
|---|
| 2810 | * map linefeeds to another line ending character or sequence if | 
|---|
| 2811 | * the host system doesn't use linefeeds. | 
|---|
| 2812 | */ | 
|---|
| 2813 |  | 
|---|
| 2814 |  | 
|---|
| 2815 | static void | 
|---|
| 2816 | DefaultMsgProc (s) | 
|---|
| 2817 | char    *s; | 
|---|
| 2818 | { | 
|---|
| 2819 | fprintf (stderr, "%s", s); | 
|---|
| 2820 | } | 
|---|
| 2821 |  | 
|---|
| 2822 |  | 
|---|
| 2823 | static RTFFuncPtr       msgProc = DefaultMsgProc; | 
|---|
| 2824 |  | 
|---|
| 2825 |  | 
|---|
| 2826 | void | 
|---|
| 2827 | RTFSetMsgProc (proc) | 
|---|
| 2828 | RTFFuncPtr      proc; | 
|---|
| 2829 | { | 
|---|
| 2830 | msgProc = proc; | 
|---|
| 2831 | } | 
|---|
| 2832 |  | 
|---|
| 2833 |  | 
|---|
| 2834 | # ifdef STDARG | 
|---|
| 2835 |  | 
|---|
| 2836 | /* | 
|---|
| 2837 | * This version is for systems with stdarg | 
|---|
| 2838 | */ | 
|---|
| 2839 |  | 
|---|
| 2840 | void | 
|---|
| 2841 | RTFMsg (char *fmt, ...) | 
|---|
| 2842 | { | 
|---|
| 2843 | char    buf[rtfBufSiz]; | 
|---|
| 2844 |  | 
|---|
| 2845 | va_list args; | 
|---|
| 2846 | va_start (args,fmt); | 
|---|
| 2847 | vsprintf (buf, fmt, args); | 
|---|
| 2848 | va_end (args); | 
|---|
| 2849 | (*msgProc) (buf); | 
|---|
| 2850 | } | 
|---|
| 2851 |  | 
|---|
| 2852 | # else /* !STDARG */ | 
|---|
| 2853 |  | 
|---|
| 2854 | # ifdef VARARGS | 
|---|
| 2855 |  | 
|---|
| 2856 |  | 
|---|
| 2857 | /* | 
|---|
| 2858 | * This version is for systems that have varargs. | 
|---|
| 2859 | */ | 
|---|
| 2860 |  | 
|---|
| 2861 | void | 
|---|
| 2862 | RTFMsg (va_alist) | 
|---|
| 2863 | va_dcl | 
|---|
| 2864 | { | 
|---|
| 2865 | va_list args; | 
|---|
| 2866 | char    *fmt; | 
|---|
| 2867 | char    buf[rtfBufSiz]; | 
|---|
| 2868 |  | 
|---|
| 2869 | va_start (args); | 
|---|
| 2870 | fmt = va_arg (args, char *); | 
|---|
| 2871 | vsprintf (buf, fmt, args); | 
|---|
| 2872 | va_end (args); | 
|---|
| 2873 | (*msgProc) (buf); | 
|---|
| 2874 | } | 
|---|
| 2875 |  | 
|---|
| 2876 | # else  /* !VARARGS */ | 
|---|
| 2877 |  | 
|---|
| 2878 | /* | 
|---|
| 2879 | * This version is for systems that don't have varargs. | 
|---|
| 2880 | */ | 
|---|
| 2881 |  | 
|---|
| 2882 | void | 
|---|
| 2883 | RTFMsg (fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9) | 
|---|
| 2884 | char    *fmt; | 
|---|
| 2885 | char    *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8, *a9; | 
|---|
| 2886 | { | 
|---|
| 2887 | char    buf[rtfBufSiz]; | 
|---|
| 2888 |  | 
|---|
| 2889 | sprintf (buf, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9); | 
|---|
| 2890 | (*msgProc) (buf); | 
|---|
| 2891 | } | 
|---|
| 2892 |  | 
|---|
| 2893 | # endif /* !VARARGS */ | 
|---|
| 2894 | # endif /* !STDARG */ | 
|---|
| 2895 |  | 
|---|
| 2896 |  | 
|---|
| 2897 | /* ---------------------------------------------------------------------- */ | 
|---|
| 2898 |  | 
|---|
| 2899 |  | 
|---|
| 2900 | /* | 
|---|
| 2901 | * Process termination.  Print error message and exit.  Also prints | 
|---|
| 2902 | * current token, and current input line number and position within | 
|---|
| 2903 | * line if any input has been read from the current file.  (No input | 
|---|
| 2904 | * has been read if prevChar is EOF). | 
|---|
| 2905 | */ | 
|---|
| 2906 |  | 
|---|
| 2907 | static void | 
|---|
| 2908 | DefaultPanicProc (s) | 
|---|
| 2909 | char    *s; | 
|---|
| 2910 | { | 
|---|
| 2911 | fprintf (stderr, "%s", s); | 
|---|
| 2912 | /*exit (1);*/ | 
|---|
| 2913 | } | 
|---|
| 2914 |  | 
|---|
| 2915 |  | 
|---|
| 2916 | static RTFFuncPtr       panicProc = DefaultPanicProc; | 
|---|
| 2917 |  | 
|---|
| 2918 |  | 
|---|
| 2919 | void | 
|---|
| 2920 | RTFSetPanicProc (proc) | 
|---|
| 2921 | RTFFuncPtr      proc; | 
|---|
| 2922 | { | 
|---|
| 2923 | panicProc = proc; | 
|---|
| 2924 | } | 
|---|
| 2925 |  | 
|---|
| 2926 |  | 
|---|
| 2927 | # ifdef STDARG | 
|---|
| 2928 |  | 
|---|
| 2929 | /* | 
|---|
| 2930 | * This version is for systems with stdarg | 
|---|
| 2931 | */ | 
|---|
| 2932 |  | 
|---|
| 2933 | void | 
|---|
| 2934 | RTFPanic (char *fmt, ...) | 
|---|
| 2935 | { | 
|---|
| 2936 | char    buf[rtfBufSiz]; | 
|---|
| 2937 |  | 
|---|
| 2938 | va_list args; | 
|---|
| 2939 | va_start (args,fmt); | 
|---|
| 2940 | vsprintf (buf, fmt, args); | 
|---|
| 2941 | va_end (args); | 
|---|
| 2942 | (void) strcat (buf, "\n"); | 
|---|
| 2943 | if (prevChar != EOF && rtfTextBuf != (char *) NULL) | 
|---|
| 2944 | { | 
|---|
| 2945 | sprintf (buf + strlen (buf), | 
|---|
| 2946 | "Last token read was \"%s\" near line %ld, position %d.\n", | 
|---|
| 2947 | rtfTextBuf, rtfLineNum, rtfLinePos); | 
|---|
| 2948 | } | 
|---|
| 2949 | (*panicProc) (buf); | 
|---|
| 2950 | } | 
|---|
| 2951 |  | 
|---|
| 2952 | # else /* !STDARG */ | 
|---|
| 2953 |  | 
|---|
| 2954 | # ifdef VARARGS | 
|---|
| 2955 |  | 
|---|
| 2956 |  | 
|---|
| 2957 | /* | 
|---|
| 2958 | * This version is for systems that have varargs. | 
|---|
| 2959 | */ | 
|---|
| 2960 |  | 
|---|
| 2961 | void | 
|---|
| 2962 | RTFPanic (va_alist) | 
|---|
| 2963 | va_dcl | 
|---|
| 2964 | { | 
|---|
| 2965 | va_list args; | 
|---|
| 2966 | char    *fmt; | 
|---|
| 2967 | char    buf[rtfBufSiz]; | 
|---|
| 2968 |  | 
|---|
| 2969 | va_start (args); | 
|---|
| 2970 | fmt = va_arg (args, char *); | 
|---|
| 2971 | vsprintf (buf, fmt, args); | 
|---|
| 2972 | va_end (args); | 
|---|
| 2973 | (void) strcat (buf, "\n"); | 
|---|
| 2974 | if (prevChar != EOF && rtfTextBuf != (char *) NULL) | 
|---|
| 2975 | { | 
|---|
| 2976 | sprintf (buf + strlen (buf), | 
|---|
| 2977 | "Last token read was \"%s\" near line %ld, position %d.\n", | 
|---|
| 2978 | rtfTextBuf, rtfLineNum, rtfLinePos); | 
|---|
| 2979 | } | 
|---|
| 2980 | (*panicProc) (buf); | 
|---|
| 2981 | } | 
|---|
| 2982 |  | 
|---|
| 2983 | # else  /* !VARARGS */ | 
|---|
| 2984 |  | 
|---|
| 2985 | /* | 
|---|
| 2986 | * This version is for systems that don't have varargs. | 
|---|
| 2987 | */ | 
|---|
| 2988 |  | 
|---|
| 2989 | void | 
|---|
| 2990 | RTFPanic (fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9) | 
|---|
| 2991 | char    *fmt; | 
|---|
| 2992 | char    *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8, *a9; | 
|---|
| 2993 | { | 
|---|
| 2994 | char    buf[rtfBufSiz]; | 
|---|
| 2995 |  | 
|---|
| 2996 | sprintf (buf, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9); | 
|---|
| 2997 | (void) strcat (buf, "\n"); | 
|---|
| 2998 | if (prevChar != EOF && rtfTextBuf != (char *) NULL) | 
|---|
| 2999 | { | 
|---|
| 3000 | sprintf (buf + strlen (buf), | 
|---|
| 3001 | "Last token read was \"%s\" near line %ld, position %d.\n", | 
|---|
| 3002 | rtfTextBuf, rtfLineNum, rtfLinePos); | 
|---|
| 3003 | } | 
|---|
| 3004 | (*panicProc) (buf); | 
|---|
| 3005 | } | 
|---|
| 3006 |  | 
|---|
| 3007 | # endif /* !VARARGS */ | 
|---|
| 3008 | # endif /* !STDARG */ | 
|---|