1{\rtf1\mac\deff1
2{\fonttbl
3{\f6\fnil Bookman;}
4{\f5\fnil Palatino;}
5{\f4\fnil Symbol;}
6{\f3\fnil Courier;}
7{\f2\fnil Helvetica;}
8{\f1\fnil Times;}
9}
10\paperh15840 \paperw12240
11\margl1440 \margr2160 \pard \f1\i0\b0
12\fs20 \fs16 \fs20 \fs24 \f1\i0\b0
13\b \fs28 \pard \qc \sl280
14\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
15A Tool for RTF Processing
16\par
17{\sl-140\sa0\sb0\par}
18Release 1.10
19\par
20\f1\i0\b0
21\i {\sl-280\sa0\sb0\par}
22\fs20 Paul DuBois
23\par
24dubois@primate.wisc.edu
25\par
26\f1\i0\b0
27{\sl-140\sa0\sb0\par}
28Wisconsin Regional Primate Research Center
29\par
30Revision date:  5 April 1994
31\par
32{\sl-280\sa0\sb0\par}
33\fs28 \f1\i0\b0
34\b \pard \qj \sl320
35\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
36Introduction\f1\i0\b0
37
38\par
39{\sl-320\sa0\sb0\par}
40\fs20 {\sl-120\sa0\sb0\par}
41\pard \qj \sl240
42\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
43This document describes a general purpose tool for
44processing RTF files\'d1an RTF reader which may be
45configured in a well-defined manner to allow it to
46be used with a variety of writers generating different
47output formats. This provides a method for generating
48RTF-to-\f1\i0\b0
49
50\i XXX\f1\i0\b0
51 translators.
52\par
53{\sl-120\sa0\sb0\par}
54I assume that you have some familiarity with RTF syntax
55and semantics, and that you\'d5re willing to study
56the source code of the RTF distribution described here.
57If you don\'d5t have the RTF specification, you can
58get it from the FTP site listed under \'d2Distribution
59Availability\'d3 at the end of this document. References
60to \'d2the specification\'d3 refer to the RTF specification
61document.
62\par
63{\sl-120\sa0\sb0\par}
64If you use this tool and find that you have an RTF
65file that won\'d5t pass through the sample translator
66\f1\i0\b0
67\i rtf2null\f1\i0\b0
68, or for which \f1\i0\b0
69
70\i rtf2null\f1\i0\b0
71 announces unknown symbols, please contact
72me so the tool can be improved. It is best if you can
73supply the RTF file for which this behavior is observed.
74\par
75{\sl-240\sa0\sb0\par}
76\fs28 \f1\i0\b0
77\b \pard \qj \sl320
78\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
79Theory of Operation\f1\i0\b0
80
81\par
82{\sl-320\sa0\sb0\par}
83{\sl-320\sa0\sb0\par}
84\fs20 \fs24 \f1\i0\b0
85\b \pard \qj \sl280
86\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
87Translator Architecture\f1\i0\b0
88
89\par
90{\sl-280\sa0\sb0\par}
91\fs20 {\sl-120\sa0\sb0\par}
92\pard \qj \sl240
93\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
94This is a brief description of how translators are
95designed. For more details, see the document \f1\i0\b0
96
97\i RTF Tools Translator Architecture\f1\i0\b0
98.
99\par
100{\sl-120\sa0\sb0\par}
101There are three components to an RTF translator: reader
102code, writer code, and driver code. These break down
103as follows.
104\par
105{\sl-120\sa0\sb0\par}
106\pard \qj \li500 \fi-500 \sl240
107\tx1000 \tx500 \tqr
108reader\tab
109\par
110\pard \qj \li500 \sl240
111\tx1000 \tx500 \tqr
112Responsible for peeling tokens out of the input stream,
113classifying them, and causing the writer to process
114them.
115\par
116{\sl-120\sa0\sb0\par}
117\pard \qj \li500 \fi-500 \sl240
118\tx1000 \tx500 \tqr
119writer\tab
120\par
121\pard \qj \li500 \sl240
122\tx1000 \tx500 \tqr
123Responsible for translating tokens from the input stream
124into the required output format.
125\par
126{\sl-120\sa0\sb0\par}
127\pard \qj \li500 \fi-500 \sl240
128\tx1000 \tx500 \tqr
129driver\tab
130\par
131\pard \qj \li500 \sl240
132\tx1000 \tx500 \tqr
133Responsible for making sure the reader and writer are
134initialized, and for calling the reader, to cause translation
135to occur.
136\par
137{\sl-120\sa0\sb0\par}
138\pard \qj \sl240
139\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
140This architecture allows the reader to remain constant,
141so that different translators can be built by supplying
142different writer and driver code. Also, for a given
143translator, the reader and writer remain constant and
144the translator can be ported to different types of
145systems by supplying system-specific driver code.
146\par
147{\sl-120\sa0\sb0\par}
148In practice, to build a new translator, you supply
149a \f1\i0\b0
150
151\i main()\f1\i0\b0
152 function and the writer code, and link in the
153RTF reader. \f1\i0\b0
154
155\i main()\f1\i0\b0
156 includes the driver code and is responsible
157to see that the following are done:
158\par
159{\sl-120\sa0\sb0\par}
160\pard \qj \li300 \fi-300 \sl240
161\tx600 \tx300 \tqr
162\'a5\tab Determine which files are to be translated
163\par
164{\sl-120\sa0\sb0\par}
165\'a5\tab Configure the reader, which may involve:
166\par
167{\sl-120\sa0\sb0\par}
168\pard \qj \li600 \fi-300 \sl240
169\tx900 \tx300 \tqr
170\'d1\tab Reset the input stream if necessary
171\par
172{\sl-120\sa0\sb0\par}
173\pard \qj \li600 \fi-300 \sl240
174\tx900 \tx300 \tqr
175\'d1\tab Configure other reader behavior, such as whether
176or not to process the font and color tables internally
177\par
178{\sl-120\sa0\sb0\par}
179\'d1\tab Install writer callbacks into the reader so
180it knows what functions to call when various kinds
181of tokens occur
182\par
183{\sl-120\sa0\sb0\par}
184{\sl-120\sa0\sb0\par}
185\pard \qj \li300 \fi-300 \sl240
186\tx600 \tx300 \tqr
187\'a5\tab Initialize the writer
188\par
189{\sl-120\sa0\sb0\par}
190\pard \qj \li300 \fi-300 \sl240
191\tx600 \tx300 \tqr
192\'a5\tab Call the reader to process the input stream
193\par
194{\sl-120\sa0\sb0\par}
195\'a5\tab Terminate the writer
196\par
197{\sl-120\sa0\sb0\par}
198\pard \qj \sl240
199\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
200A minimal translator (for a UNIX system) looks something
201like this:
202\par
203{\sl-120\sa0\sb0\par}
204\fs16 \f3\i0\b0
205\pard \ql \li400 \sl200
206\tx720 \tx1040 \tx1360 \tx1680 \tx2000 \tx2320 \tx2640 \tx2960 \tx3280 \tx3600 \tx3920 \tx4240 \tx4560 \tx4880 \tx5200 \tx5520 \tx5840 \tx6160 \tx6480 \tx6800
207# include\tab <stdio.h>
208\par
209# include\tab "rtf.h"
210\par
211{\sl-200\sa0\sb0\par}
212int
213\par
214main ()
215\par
216\{
217\par
218\tab RTFSetOpenLibFileProc (UnixOpenLibFile);
219\par
220\tab RTFInit ();
221\par
222\tab RTFRead ();
223\par
224\tab exit (0);
225\par
226\}
227\par
228{\sl-120\sa0\sb0\par}
229\fs20 \f1\i0\b0
230\pard \qj \sl240
231\tx720 \tx1040 \tx1360 \tx1680 \tx2000 \tx2320 \tx2640 \tx2960 \tx3280 \tx3600 \tx3920 \tx4240 \tx4560 \tx4880 \tx5200 \tx5520 \tx5840 \tx6160 \tx6480 \tx6800
232This installs a function that\'d5s suitable for opening
233RTF library files on a UNIX system, initializes the
234reader, and calls it to read \f1\i0\b0
235
236\i stdin\f1\i0\b0
237 (the default input stream). The writer portion
238is null (i.e., there is no writer), so all that happens
239is that the reader tokenizes the input and discards
240it. That isn\'d5t very interesting; most of the sample
241translators are examples of more elaborate translators.
242\par
243{\sl-240\sa0\sb0\par}
244\fs24 \f1\i0\b0
245\b \pard \qj \sl280
246\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
247Reader Operation\f1\i0\b0
248
249\par
250{\sl-280\sa0\sb0\par}
251\fs20 {\sl-120\sa0\sb0\par}
252\pard \qj \sl240
253\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
254Each time a token is read, several global variables
255are set:
256\par
257{\sl-120\sa0\sb0\par}
258{\sl-120\sa0\sb0\par}
259\f1\i0\b0
260\i \pard \ql \li720 \sl240
261\tx2880
262rtfClass\f1\i0\b0
263\tab token class
264\par
265\f1\i0\b0
266\i rtfMajor\f1\i0\b0
267\tab token major number
268\par
269\f1\i0\b0
270\i rtfMinor\f1\i0\b0
271\tab token minor number
272\par
273\f1\i0\b0
274\i rtfParam\f1\i0\b0
275\tab token parameter value
276\par
277\f1\i0\b0
278\i rtfTextBuf\f1\i0\b0
279\tab token text
280\par
281\f1\i0\b0
282\i rtfTextLen\f1\i0\b0
283\tab length of token (including parameter
284text)
285\par
286{\sl-120\sa0\sb0\par}
287{\sl-120\sa0\sb0\par}
288\pard \qj \sl240
289\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
290Tokens are classified using up to three numbers: token
291class, and major and minor numbers. The major and minor
292numbers may be meaningless depending on the kind of
293token.
294\par
295{\sl-120\sa0\sb0\par}
296The class number can be:
297\par
298{\sl-120\sa0\sb0\par}
299{\sl-120\sa0\sb0\par}
300\f1\i0\b0
301\i \pard \ql \li720 \sl240
302\tx2880
303rtfUnknown\f1\i0\b0
304\tab unrecognized token
305\par
306\f1\i0\b0
307\i rtfGroup\f1\i0\b0
308\tab \'d2\{\'d3 or \'d2\}\'d3
309\par
310\f1\i0\b0
311\i rtfText\f1\i0\b0
312\tab plain text character
313\par
314\f1\i0\b0
315\i rtfControl\f1\i0\b0
316\tab token beginning with \'d2\\\'d3
317\par
318\f1\i0\b0
319\i rtfEOF\f1\i0\b0
320\tab fake class number; indicates end of input
321stream
322\par
323{\sl-120\sa0\sb0\par}
324{\sl-120\sa0\sb0\par}
325\pard \qj \sl240
326\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
327There are some exceptions. A few tokens beginning with
328\f3\i0\b0
329\\\f1\i0\b0
330 actually belong to other classes, a tab character
331is treated like \f3\i0\b0
332\\tab\f1\i0\b0
333, and unrecognized tokens are
334put in class \f1\i0\b0
335
336\i rtfUnknown\f1\i0\b0
337 no matter what they look like.
338\par
339{\sl-120\sa0\sb0\par}
340Within a class, tokens are assigned a major number,
341and perhaps a minor number. For the \f1\i0\b0
342
343\i rtfText\f1\i0\b0
344 class, the major number is the value of the
345input character (0..255), and the minor number is assigned
346a standard character code. Text characters have different
347mappings in different RTF character sets, so to avoid
348the problems associated with this, the reader maps
349the character onto a standard character code using
350a charset-dependent translation table. Translators
351should generally use the standard character code in
352\f1\i0\b0
353\i rtfMinor\f1\i0\b0
354 rather than the raw character code in \f1\i0\b0
355
356\i rtfMajor\f1\i0\b0
357. Character mapping issues are described further
358in the document \f1\i0\b0
359
360\i RTF Tools Character Mapping\f1\i0\b0
361.
362\par
363{\sl-120\sa0\sb0\par}
364A \'d2plain text\'d3 character can be a literal character,
365a character specified in hex notation (\f3\i0\b0
366\\'\f1\i0\b0
367\f1\i0\b0
368
369\i xx\f1\i0\b0
370) or one of the special escaped characters (\f3\i0\b0
371\\\{\f1\i0\b0
372,
373\f3\i0\b0
374\\\}\f1\i0\b0
375, \f3\i0\b0
376\\\\\f1\i0\b0
377). The sequence \f3\i0\b0
378\\:\f1\i0\b0
379 is treated as a plain
380text colon. This is arguably wrong; the rationale is
381given later under the description of the \f1\i0\b0
382
383\i RTFGetToken()\f1\i0\b0
384 function.
385\par
386{\sl-120\sa0\sb0\par}
387For the \f1\i0\b0
388
389\i rtfControl\f1\i0\b0
390 class, most tokens have both a major and
391minor number. For instance, all paragraph attribute
392control symbols have major number \f1\i0\b0
393
394\i rtfParAttr\f1\i0\b0
395 and a minor number indicating a paragraph
396formatting property, such as \f1\i0\b0
397
398\i rtfLeftIndent\f1\i0\b0
399 or \f1\i0\b0
400
401\i rtfSpaceBefore\f1\i0\b0
402. A few oddball control tokens have no
403minor number.
404\par
405{\sl-120\sa0\sb0\par}
406Control symbols may have a parameter value, e.g., \f3\i0\b0
407\\margr720\f1\i0\b0
408
409specifies a right margin (in units of 720 twentieths
410of a point).
411\par
412{\sl-120\sa0\sb0\par}
413If no parameter value is given, \f1\i0\b0
414
415\i rtfParam\f1\i0\b0
416 is \f1\i0\b0
417
418\i rtfNoParam\f1\i0\b0
419.
420\par
421{\sl-120\sa0\sb0\par}
422Ideally, there should never be any tokens in the \f1\i0\b0
423
424\i rtfUnknown\f1\i0\b0
425 class, but as the RTF standard continues
426to develop, unknown tokens are inevitable.
427\par
428{\sl-120\sa0\sb0\par}
429To write a translator, you\'d5ll need to familiarize
430yourself with the token classification scheme by reading
431\f1\i0\b0
432\i rtf.h\f1\i0\b0
433. A skeleton translator \f1\i0\b0
434
435\i rtfskel\f1\i0\b0
436 is included with the distribution and may be
437used as a basis for new translators.
438\par
439{\sl-120\sa0\sb0\par}
440As of release 1.10, the reader allows an 8-bit character
441set since the current RTF specification (version 1.2)
442now allows 8-bit characters. Formerly, if the reader
443saw an 8-bit character, it converted the character
444to the equivalent \f3\i0\b0
445\\'\f1\i0\b0
446\f1\i0\b0
447
448\i xx\f1\i0\b0
449 hex notation sequence and returned that as the token.
450\par
451{\sl-120\sa0\sb0\par}
452Generally, a translator will configure the RTF reader
453to call particular writer functions when certain kinds
454of tokens are encountered in the input stream. These
455functions are known as \f1\i0\b0
456
457\i class callbacks\f1\i0\b0
458. Writer callbacks can be registered
459with the reader using \f1\i0\b0
460
461\i RTFSetClassCallback()\f1\i0\b0
462 for each token class.
463\par
464{\sl-120\sa0\sb0\par}
465The reader reads each token, classifies it, and sends
466it to a token routing function \f1\i0\b0
467
468\i RTFRouteToken()\f1\i0\b0
469, which tries to find a writer callback
470function to process the token. Tokens in a given class
471are ignored if no callback is registered for the class.
472\par
473{\sl-120\sa0\sb0\par}
474Class callbacks make it quite easy to receive notification
475when certain types of tokens occur in the input. For
476instance, a crude RTF text extractor could be written
477by installing a callback function for the \f1\i0\b0
478
479\i rtfText\f1\i0\b0
480 class.[1]
481\fs16 \par
482{\sl-60\sa0\sb0\par}
483\pard \qj \ri720 \fi200 \sl200 [1] Reasons this is a crude translator are that: (i)
484some text characters occur in contexts where the characters
485are not intended to be output, e.g., font tables, stylesheets;
486(ii) some control symbols like \f3\i0\b0
487\\tab\f1\i0\b0
488 represent output
489text characters; (iii) it writes output based on the
490raw input character value in \f1\i0\b0
491
492\i rtfMajor\f1\i0\b0
493 rather than mapping the standard character
494code in \f1\i0\b0
495
496\i rtfMinor\f1\i0\b0
497. The sample translator \f1\i0\b0
498
499\i rtf2text\f1\i0\b0
500 addresses these problems in a (slightly) more
501sophisticated manner.
502\par
503\fs20 \pard \qj \sl240
504\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
505Whenever the function is invoked, \f1\i0\b0
506
507\i rtfMajor\f1\i0\b0
508 will contain a value in the range 0..255 representing
509the character value.
510\par
511{\sl-120\sa0\sb0\par}
512\fs16 \f3\i0\b0
513\pard \ql \li400 \sl200
514\tx720 \tx1040 \tx1360 \tx1680 \tx2000 \tx2320 \tx2640 \tx2960 \tx3280 \tx3600 \tx3920 \tx4240 \tx4560 \tx4880 \tx5200 \tx5520 \tx5840 \tx6160 \tx6480 \tx6800
515# include\tab <stdio.h>
516\par
517# include\tab "rtf.h"
518\par
519{\sl-200\sa0\sb0\par}
520void
521\par
522TextCallback ()
523\par
524\{
525\par
526\tab putchar (rtfMajor);
527\par
528\}
529\par
530{\sl-120\sa0\sb0\par}
531\fs20 \f1\i0\b0
532{\sl-120\sa0\sb0\par}
533\fs16 \f3\i0\b0
534int
535\par
536main ()
537\par
538\{
539\par
540\tab RTFSetOpenLibFileProc (UnixOpenLibFile);
541\par
542\tab RTFInit ();
543\par
544\tab RTFSetClassCallback (rtfText, TextCallback);
545\par
546\tab RTFRead ();
547\par
548\tab exit (0);
549\par
550\}
551\par
552{\sl-120\sa0\sb0\par}
553\fs20 \f1\i0\b0
554\pard \qj \sl240
555\tx720 \tx1040 \tx1360 \tx1680 \tx2000 \tx2320 \tx2640 \tx2960 \tx3280 \tx3600 \tx3920 \tx4240 \tx4560 \tx4880 \tx5200 \tx5520 \tx5840 \tx6160 \tx6480 \tx6800
556Callbacks for the \f1\i0\b0
557
558\i rtfControl\f1\i0\b0
559 and \f1\i0\b0
560
561\i rtfGroup\f1\i0\b0
562 classes typically operate by selecting on
563the token major number to determine the action to take.
564A callback for the \f1\i0\b0
565
566\i rtfGroup\f1\i0\b0
567 class usually will do something like this:
568\par
569{\sl-120\sa0\sb0\par}
570\fs16 \f3\i0\b0
571\pard \ql \li400 \sl200
572\tx720 \tx1040 \tx1360 \tx1680 \tx2000 \tx2320 \tx2640 \tx2960 \tx3280 \tx3600 \tx3920 \tx4240 \tx4560 \tx4880 \tx5200 \tx5520 \tx5840 \tx6160 \tx6480 \tx6800
573void
574\par
575BraceCallback ()
576\par
577\{
578\par
579\tab switch (rtfMajor)
580\par
581\tab \{
582\par
583\tab case rtfBeginGroup:
584\par
585\tab \tab \f1\i0\b0
586
587\i ...push state...\f1\i0\b0
588
589\par
590\tab \tab break;
591\par
592\tab case rtfEndGroup:
593\par
594\tab \tab \f1\i0\b0
595
596\i ...pop state...\f1\i0\b0
597
598\par
599\tab \tab break;
600\par
601\tab \}
602\par
603\}
604\par
605{\sl-120\sa0\sb0\par}
606\fs20 {\sl-240\sa0\sb0\par}
607\fs24 \f1\i0\b0
608\b \pard \qj \sl280
609\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
610Destination Readers\f1\i0\b0
611
612\par
613{\sl-280\sa0\sb0\par}
614\fs20 {\sl-120\sa0\sb0\par}
615\pard \qj \sl240
616\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
617Grouping in RTF documents occurs within braces \'d2\{\'d3
618and \'d2\}\'d3. One kind of group is the \f1\i0\b0
619
620\i destination\f1\i0\b0
621. The token immediately following the opening
622brace is a destination control symbol. These indicate
623such things as headers, footers, footnotes, etc.
624\par
625{\sl-120\sa0\sb0\par}
626Three destinations which specify information for internal
627use (i.e., information which affects output but isn\'d5t
628itself written) are the font table, color table and
629stylesheet. Since these three destinations occur so
630commonly and have a special syntax, the RTF reader
631by default gobbles them up itself when it recognizes
632them. The functions which do this are called \f1\i0\b0
633
634\i destination readers\f1\i0\b0
635 and are probably the nearest thing
636in the reader to what might be called parsers. They
637are installed by default so that translators can be
638written without the burden of understanding the syntax
639or digesting the contents of these destinations. Each
640of them constructs a list of the entries specified
641in the destination and the reader includes functions
642providing access to these lists.
643\par
644{\sl-120\sa0\sb0\par}
645Translators can turn off or override these defaults
646with \f1\i0\b0
647
648\i RTFSetDestinationCallback()\f1\i0\b0
649 if necessary. To override
650one, pass the address of a different destination reader
651function. To turn one off, pass \f3\i0\b0
652NULL\f1\i0\b0
653.
654\par
655{\sl-120\sa0\sb0\par}
656Destination callbacks may be called for any destination,
657not just \f1\i0\b0
658
659\i rtfFontTbl\f1\i0\b0
660, \f1\i0\b0
661
662\i rtfColorTbl\f1\i0\b0
663 and \f1\i0\b0
664
665\i rtfStyleSheet\f1\i0\b0
666. Destinations for which no callback is
667registered are not treated specially.
668\par
669{\sl-120\sa0\sb0\par}
670Other destinations for which there is a default reader
671are the information (\f3\i0\b0
672\\info\f1\i0\b0
673), picture (\f3\i0\b0
674\\pict\f1\i0\b0
675), and
676object (\f3\i0\b0
677\\object\f1\i0\b0
678) destinations; all they do is skip
679to the end of the group.
680\par
681{\sl-240\sa0\sb0\par}
682\f1\i0\b0
683\b Using the Built-in Destination Readers\f1\i0\b0
684
685\par
686{\sl-240\sa0\sb0\par}
687{\sl-120\sa0\sb0\par}
688The font table, color table and stylesheet information
689is maintained internally, and the reader either acts
690on that information itself, or allows itself to be
691queried by the writer about it, as described below.
692These descriptions do not apply if the translator shuts
693off or overrides the default destination readers, of
694course.
695\par
696{\sl-120\sa0\sb0\par}
697\f1\i0\b0
698\b Stylesheet\'d1\f1\i0\b0
699The reader acts on this itself. When
700the stylesheet destination is encountered, the style
701contents are remembered. Thereafter, whenever the writer
702receives notification that a style number control symbol
703(\f3\i0\b0
704\\s\f1\i0\b0
705\f1\i0\b0
706
707\i nnn\f1\i0\b0
708) has occurred, it can call \f1\i0\b0
709
710\i RTFExpandStyle(rtfParam)\f1\i0\b0
711 to cause the style to be expanded.
712The reader consults contents of the stylesheet and
713each token in the style definition is routed in turn
714back to the writer. This effects a sort of macro expansion.
715\par
716{\sl-120\sa0\sb0\par}
717If the writer doesn\'d5t care about style expansion,
718it simply refrains from calling \f1\i0\b0
719
720\i RTFExpandStyle()\f1\i0\b0
721.
722\par
723{\sl-120\sa0\sb0\par}
724If the writer wants information about a style, it can
725call \f1\i0\b0
726
727\i RTFGetStyle()\f1\i0\b0
728.
729\par
730{\sl-120\sa0\sb0\par}
731\f1\i0\b0
732\b Font table\'d1\f1\i0\b0
733For each entry in the font table, the
734font number, type and name are maintained by the reader.
735The writer finds out that a font number has been specified
736in the input when its control class callback is invoked
737and \f1\i0\b0
738
739\i rtfMajor\f1\i0\b0
740 = \f1\i0\b0
741
742\i rtfCharAttr\f1\i0\b0
743 and \f1\i0\b0
744
745\i rtfMinor\f1\i0\b0
746 = \f1\i0\b0
747
748\i rtfFontNum\f1\i0\b0
749. To obtain a pointer to the appropriate
750\f1\i0\b0
751\i RTFFont\f1\i0\b0
752 structure, the reader function \f1\i0\b0
753
754\i RTFGetFont(rtfParam)\f1\i0\b0
755 may be called.
756\par
757{\sl-120\sa0\sb0\par}
758\f1\i0\b0
759\b Color table\'d1\f1\i0\b0
760For each entry in the color table, the
761color number is maintained along with the red, green
762and blue values. The writer finds out that a color
763number has been specified in the input when its control
764class callback is invoked and \f1\i0\b0
765
766\i rtfMajor\f1\i0\b0
767 = \f1\i0\b0
768
769\i rtfCharAttr\f1\i0\b0
770 and \f1\i0\b0
771
772\i rtfMinor\f1\i0\b0
773 = \f1\i0\b0
774
775\i rtfColorNum\f1\i0\b0
776. To obtain a pointer to the appropriate
777\f1\i0\b0
778\i RTFColor\f1\i0\b0
779 structure, the reader function \f1\i0\b0
780
781\i RTFGetColor(rtfParam)\f1\i0\b0
782 may be called.
783\par
784{\sl-120\sa0\sb0\par}
785One subtle point about the built-in destination readers:
786destinations cannot be recognized until \f1\i0\b0
787
788\i after\f1\i0\b0
789 the occurrence of the \'d2\{\'d3 symbol that
790begins the destination. This means the writer, if it
791maintains a state stack, will already have pushed a
792state. In order to allow the writer to properly pop
793that state in response to the \'d2\}\'d3, these destination
794readers feed the \'d2\}\'d3 back into the token router
795after they pull it from the input stream. What the
796writer actually sees is a \'d2\{\'d3 followed immediately
797by a \'d2\}\'d3.
798\par
799{\sl-120\sa0\sb0\par}
800Applications that maintain a state stack may find it
801necessary to do something similar if they supply their
802own destination readers.
803\par
804{\sl-240\sa0\sb0\par}
805\fs28 \f1\i0\b0
806\b \pard \qj \sl320
807\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
808Programming Interface\f1\i0\b0
809
810\par
811{\sl-320\sa0\sb0\par}
812\fs20 {\sl-120\sa0\sb0\par}
813\pard \qj \sl240
814\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
815Source files using the RTF reader should #include \f1\i0\b0
816
817\i rtf.h\f1\i0\b0
818. The library files common to all translators
819are used to build a library \f1\i0\b0
820
821\i librtf.a\f1\i0\b0
822 in the distribution\'d5s \f1\i0\b0
823
824\i lib\f1\i0\b0
825 directory. This library should be part of the final
826application link.
827\par
828{\sl-120\sa0\sb0\par}
829The best way to learn how these source files work is
830to study the sample translators, which vary in complexity
831from very simple (e.g., \f1\i0\b0
832
833\i rtf2text\f1\i0\b0
834, \f1\i0\b0
835
836\i rtfwc\f1\i0\b0
837), to wretchedly messy (e.g., \f1\i0\b0
838
839\i rtf2troff\f1\i0\b0
840). You should be aware that one implication
841of the way the translators are built (callbacks and
842switch statements) is that it\'d5s quite easy to build
843them incrementally. You can start with a very bare-bones
844model, and start plugging in callbacks as you progress.
845Within the callbacks, your switch statements can progressively
846handle more cases.
847\par
848{\sl-120\sa0\sb0\par}
849An alternative approach is to start with a copy of
850\f1\i0\b0
851\i rtfskel\f1\i0\b0
852, which includes a full set of class callbacks
853and complete switch statements for all tokens. Each
854case is empty; you simply add code for those cases
855you want to handle. You can also rip out the code for
856the cases you don\'d5t care about.
857\par
858{\sl-240\sa0\sb0\par}
859\fs24 \f1\i0\b0
860\b \pard \qj \sl280
861\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
862Types\f1\i0\b0
863
864\par
865{\sl-280\sa0\sb0\par}
866\fs20 {\sl-120\sa0\sb0\par}
867\pard \qj \sl240
868\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
869Most types are pretty standard. The one of note is
870\f1\i0\b0
871\i RTFFuncPtr\f1\i0\b0
872, a generic function pointer which is defined
873like so:
874\par
875{\sl-120\sa0\sb0\par}
876\fs16 \f3\i0\b0
877\pard \ql \li400 \sl200
878\tx720 \tx1040 \tx1360 \tx1680 \tx2000 \tx2320 \tx2640 \tx2960 \tx3280 \tx3600 \tx3920 \tx4240 \tx4560 \tx4880 \tx5200 \tx5520 \tx5840 \tx6160 \tx6480 \tx6800
879typedef\tab void (*RTFFuncPtr) ();
880\par
881{\sl-120\sa0\sb0\par}
882\fs20 \f1\i0\b0
883\pard \qj \sl240
884\tx720 \tx1040 \tx1360 \tx1680 \tx2000 \tx2320 \tx2640 \tx2960 \tx3280 \tx3600 \tx3920 \tx4240 \tx4560 \tx4880 \tx5200 \tx5520 \tx5840 \tx6160 \tx6480 \tx6800
885That is, it\'d5s a pointer to a function that takes
886no arguments and returns no value.
887\par
888{\sl-240\sa0\sb0\par}
889\fs24 \f1\i0\b0
890\b \pard \qj \sl280
891\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
892Global variables\f1\i0\b0
893
894\par
895{\sl-280\sa0\sb0\par}
896\fs20 {\sl-120\sa0\sb0\par}
897\pard \qj \sl240
898\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
899The global RTF reader variables are:
900\par
901{\sl-120\sa0\sb0\par}
902{\sl-120\sa0\sb0\par}
903\pard \ql \li720 \sl240
904\tx1584 \tx3600
905int\tab rtfClass;\tab token class
906\par
907int\tab rtfMajor;\tab token major number
908\par
909int\tab rtfMinor;\tab token minor number
910\par
911int\tab rtfParam;\tab parameter value for control symbols
912\par
913char\tab *rtfTextBuf;\tab token text
914\par
915int\tab rtfTextLen;\tab length of token text
916\par
917{\sl-120\sa0\sb0\par}
918{\sl-120\sa0\sb0\par}
919\pard \qj \sl240
920\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
921These variables always apply to the token with which
922the writer should be concerned. This may be either
923the last token read or the current token within a style
924which is being reprocessed.
925\par
926{\sl-120\sa0\sb0\par}
927\f1\i0\b0
928\b Warning:\f1\i0\b0
929 \f1\i0\b0
930
931\i rtfTextBuf\f1\i0\b0
932 is \f3\i0\b0
933NULL\f1\i0\b0
934 until \f1\i0\b0
935
936\i RTFInit()\f1\i0\b0
937 has been called.
938\par
939{\sl-120\sa0\sb0\par}
940Two other global variables which may be of interest
941provide the current input line number and position
942within the line:
943\par
944{\sl-120\sa0\sb0\par}
945{\sl-120\sa0\sb0\par}
946\pard \ql \li720 \sl240
947\tx1584 \tx3600
948long\tab rtfLineNum;\tab current input line
949\par
950int\tab rtfLinePos;\tab position within current line
951\par
952{\sl-120\sa0\sb0\par}
953{\sl-120\sa0\sb0\par}
954\pard \qj \sl240
955\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
956These variables can be used to provide feedback to
957the user when a problem is found in an input file as
958to the location of the problem. They indicate the position
959immediately after the last token read.
960\par
961{\sl-240\sa0\sb0\par}
962\fs24 \f1\i0\b0
963\b \pard \qj \sl280
964\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
965Functions\f1\i0\b0
966
967\par
968{\sl-280\sa0\sb0\par}
969\fs20 {\sl-120\sa0\sb0\par}
970\f3\i0\b0
971\pard \ql \sl240
972\tx1152
973void
974\par
975RTFInit ()
976\par
977\fs24 \f1\i0\b0
978\fs20 \f3\i0\b0
979\fs24 \f1\i0\b0
980{\sl-120\sa0\sb0\par}
981\pard \qj \li360 \sl280
982\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
983Initialize the RTF reader. This should be called once
984for each input file to be processed. It performs some
985initialization such as computing hash values for the
986token lookup table and installation of some built-in
987destination and token class readers.
988\par
989{\sl-140\sa0\sb0\par}
990\f1\i0\b0
991\i RTFInit()\f1\i0\b0
992 may be called multiple times. Each invocation
993resets the reader\'d5s state completely, except that
994the input stream is not disturbed.
995\par
996\fs20 \f3\i0\b0
997{\sl-120\sa0\sb0\par}
998\f1\i0\b0
999\f3\i0\b0
1000\pard \ql \sl240
1001\tx1152
1002void
1003\par
1004RTFRead ()
1005\par
1006\fs24 \f1\i0\b0
1007\fs20 \f3\i0\b0
1008\fs24 \f1\i0\b0
1009{\sl-120\sa0\sb0\par}
1010\f1\i0\b0
1011\i \pard \qj \li360 \sl280
1012\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
1013RTFRead()\f1\i0\b0
1014 calls \f1\i0\b0
1015
1016\i RTFGetToken()\f1\i0\b0
1017 to tokenize the input stream and \f1\i0\b0
1018
1019\i RTFRouteToken()\f1\i0\b0
1020 to process each token, until input
1021is exhausted. When \f1\i0\b0
1022
1023\i RTFRead()\f1\i0\b0
1024 returns, input has been completely read and
1025the writer can perform any cleanup or termination needed.
1026\par
1027{\sl-140\sa0\sb0\par}
1028If you want to read multiple files per invocation of
1029your translator, you should do the following for each
1030file: call \f1\i0\b0
1031
1032\i RTFInit()\f1\i0\b0
1033, install callbacks, etc., then call \f1\i0\b0
1034
1035\i RTFRead()\f1\i0\b0
1036.
1037\par
1038\fs20 \f3\i0\b0
1039{\sl-120\sa0\sb0\par}
1040\f1\i0\b0
1041\f3\i0\b0
1042\pard \ql \sl240
1043\tx1152
1044void
1045\par
1046RTFRouteToken ()
1047\par
1048\fs24 \f1\i0\b0
1049\fs20 \f3\i0\b0
1050\fs24 \f1\i0\b0
1051{\sl-120\sa0\sb0\par}
1052\pard \qj \li360 \sl280
1053\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
1054This routine decides what to do with the current token
1055and routes it to the correct place for processing.
1056Usually this is directly to the writer via a class
1057callback. The token is \f1\i0\b0
1058
1059\i not\f1\i0\b0
1060 passed to the writer (i.e., the class callback
1061is bypassed) when it is a destination token for which
1062a reader callback is installed.
1063\par
1064{\sl-140\sa0\sb0\par}
1065By default, built-in readers are installed for font
1066table, color table, stylesheet and information and
1067picture group destinations. The built-in readers can
1068be disabled if the writer wants to see all tokens directly.
1069\par
1070\fs20 \f3\i0\b0
1071{\sl-120\sa0\sb0\par}
1072\f1\i0\b0
1073\f3\i0\b0
1074\pard \ql \sl240
1075\tx1152
1076int
1077\par
1078RTFGetToken ()
1079\par
1080\fs24 \f1\i0\b0
1081\fs20 \f3\i0\b0
1082\fs24 \f1\i0\b0
1083{\sl-120\sa0\sb0\par}
1084\pard \qj \li360 \sl280
1085\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
1086Reads one token from the input stream, classifies it,
1087sets the global variables, and returns the class number.
1088If the class is \f1\i0\b0
1089
1090\i rtfEOF\f1\i0\b0
1091 the end of the input stream has been reached.
1092Newlines (\f3\i0\b0
1093\\n\f1\i0\b0
1094), carriage returns (\f3\i0\b0
1095\\r\f1\i0\b0
1096), and nulls are
1097silently discarded by \f1\i0\b0
1098
1099\i RTFGetToken()\f1\i0\b0
1100, as they have no meaning. All are passed
1101to the token hook if one is installed, however.
1102\par
1103{\sl-140\sa0\sb0\par}
1104The sequence \f3\i0\b0
1105\\:\f1\i0\b0
1106 is treated as a plain text character,
1107with \f1\i0\b0
1108
1109\i rtfClass\f1\i0\b0
1110 set to \f1\i0\b0
1111
1112\i rtfText\f1\i0\b0
1113 and \f1\i0\b0
1114
1115\i rtfMajor\f1\i0\b0
1116 set to the colon ASCII code. Strictly speaking,
1117\f3\i0\b0
1118\\:\f1\i0\b0
1119 is the control word for an index subentry, but
1120some versions of Microsoft Word write out plain text
1121colons with a preceding backslash, while others don\'d5t.
1122This unfortunate ambiguity results in an ugly dilemma.
1123It seems the lesser burden to require translators to
1124recognize that plain text colons should \'d2really\'d3
1125be treated as index subentry indicators while inside
1126of an index entry destination, than to recognize that
1127an index subentry control word should \'d2really\'d3
1128be treated as a plain text colon everywhere else.
1129\par
1130{\sl-140\sa0\sb0\par}
1131Writer code usually does not call \f1\i0\b0
1132
1133\i RTFGetToken()\f1\i0\b0
1134 directly except within specialized destination
1135readers. Driver code usually does not call \f1\i0\b0
1136
1137\i RTFGetToken()\f1\i0\b0
1138 if it calls \f1\i0\b0
1139
1140\i RTFRead()\f1\i0\b0
1141. However, the following loop is an alternative
1142to \f1\i0\b0
1143
1144\i RTFRead()\f1\i0\b0
1145:
1146\par
1147{\sl-120\sa0\sb0\par}
1148\fs16 \f3\i0\b0
1149\pard \ql \li760 \sl200
1150\tx1080 \tx1400 \tx1720 \tx2040 \tx2360 \tx2680 \tx3000 \tx3320 \tx3640 \tx3960 \tx4280 \tx4600 \tx4920 \tx5240 \tx5560 \tx5880 \tx6200 \tx6520 \tx6840 \tx7160
1151while (RTFGetToken () != rtfEOF)
1152\par
1153\{
1154\par
1155\tab RTFRouteToken ();
1156\par
1157\}
1158\par
1159{\sl-120\sa0\sb0\par}
1160\fs24 \f1\i0\b0
1161\pard \qj \li360 \sl280
1162\tx1080 \tx1400 \tx1720 \tx2040 \tx2360 \tx2680 \tx3000 \tx3320 \tx3640 \tx3960 \tx4280 \tx4600 \tx4920 \tx5240 \tx5560 \tx5880 \tx6200 \tx6520 \tx6840 \tx7160
1163If a driver wants to regain control after reading each
1164token, this loop may be preferable to \f1\i0\b0
1165
1166\i RTFRead()\f1\i0\b0
1167.
1168\par
1169\fs20 \f3\i0\b0
1170{\sl-120\sa0\sb0\par}
1171\f1\i0\b0
1172\f3\i0\b0
1173\pard \ql \sl240
1174\tx1152
1175int
1176\par
1177RTFUngetToken ()
1178\par
1179\fs24 \f1\i0\b0
1180\fs20 \f3\i0\b0
1181\fs24 \f1\i0\b0
1182{\sl-120\sa0\sb0\par}
1183\pard \qj \li360 \sl280
1184\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1185Pushes the last token back on the input stream so that
1186\f1\i0\b0
1187\i RTFGetToken()\f1\i0\b0
1188 returns it again. You can\'d5t put back
1189the same token twice unless you read it again in the
1190interim.
1191\par
1192\fs20 \f3\i0\b0
1193{\sl-120\sa0\sb0\par}
1194\f1\i0\b0
1195\f3\i0\b0
1196\pard \ql \sl240
1197\tx1152
1198int
1199\par
1200RTFPeekToken ()
1201\par
1202\fs24 \f1\i0\b0
1203\fs20 \f3\i0\b0
1204\fs24 \f1\i0\b0
1205{\sl-120\sa0\sb0\par}
1206\pard \qj \li360 \sl280
1207\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1208Reads a token from the input stream and sets the global
1209token variables, but does not remove the token from
1210the input stream.
1211\par
1212\fs20 \f3\i0\b0
1213{\sl-120\sa0\sb0\par}
1214\f1\i0\b0
1215\f3\i0\b0
1216\pard \ql \sl240
1217\tx1152
1218void
1219\par
1220RTFSetToken (class, major, minor, param, text)
1221\par
1222int\tab class, major, minor, param;
1223\par
1224char\tab *text;
1225\par
1226\fs24 \f1\i0\b0
1227\fs20 \f3\i0\b0
1228\fs24 \f1\i0\b0
1229{\sl-120\sa0\sb0\par}
1230\pard \qj \li360 \sl280
1231\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1232It is sometimes useful to construct a fake token and
1233run it through the token router to cause the effects
1234of the token to be applied. \f1\i0\b0
1235
1236\i RTFSetToken()\f1\i0\b0
1237 allows you to do this, by setting the
1238reader\'d5s global variables to the values supplied.
1239If \f1\i0\b0
1240
1241\i param\f1\i0\b0
1242 is \f1\i0\b0
1243
1244\i rtfNoParam\f1\i0\b0
1245, the token text \f1\i0\b0
1246
1247\i rtfTextBuf\f1\i0\b0
1248 is constructed from \f1\i0\b0
1249
1250\i text\f1\i0\b0
1251 and \f1\i0\b0
1252
1253\i param\f1\i0\b0
1254, otherwise \f1\i0\b0
1255
1256\i rtfTextBuf\f1\i0\b0
1257 is just copied from \f1\i0\b0
1258
1259\i text\f1\i0\b0
1260.
1261\par
1262\fs20 \f3\i0\b0
1263{\sl-120\sa0\sb0\par}
1264\f1\i0\b0
1265\f3\i0\b0
1266\pard \ql \sl240
1267\tx1152
1268void
1269\par
1270RTFSetReadHook (f)
1271\par
1272RTFFuncPtr\tab f;
1273\par
1274\fs24 \f1\i0\b0
1275\fs20 \f3\i0\b0
1276\fs24 \f1\i0\b0
1277{\sl-120\sa0\sb0\par}
1278\pard \qj \li360 \sl280
1279\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1280Install a function to be called by \f1\i0\b0
1281
1282\i RTFGetToken()\f1\i0\b0
1283 after each token is read from the input
1284stream. The function takes no arguments and returns
1285no value. Within the function, information about the
1286current token can be obtained from the global variables.
1287This function is for token examination purposes only,
1288and should not modify those variables.
1289\par
1290\fs20 \f3\i0\b0
1291{\sl-120\sa0\sb0\par}
1292\f1\i0\b0
1293\f3\i0\b0
1294\pard \ql \sl240
1295\tx1152
1296RTFFuncPtr
1297\par
1298RTFGetReadHook ()
1299\par
1300\fs24 \f1\i0\b0
1301\fs20 \f3\i0\b0
1302\fs24 \f1\i0\b0
1303{\sl-120\sa0\sb0\par}
1304\pard \qj \li360 \sl280
1305\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1306Returns a pointer to the current read hook, or \f3\i0\b0
1307NULL\f1\i0\b0
1308
1309if there isn\'d5t one.
1310\par
1311\fs20 \f3\i0\b0
1312{\sl-120\sa0\sb0\par}
1313\f1\i0\b0
1314\f3\i0\b0
1315\pard \ql \sl240
1316\tx1152
1317void
1318\par
1319RTFSkipGroup ()
1320\par
1321\fs24 \f1\i0\b0
1322\fs20 \f3\i0\b0
1323\fs24 \f1\i0\b0
1324{\sl-120\sa0\sb0\par}
1325\pard \qj \li360 \sl280
1326\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1327This function can be called to skip to the end of the
1328current group (including any subgroups). It\'d5s useful
1329for explicitly ignoring \f3\i0\b0
1330\\*\\\f1\i0\b0
1331\f1\i0\b0
1332
1333\i dest\f1\i0\b0
1334 groups, where \f1\i0\b0
1335
1336\i dest\f1\i0\b0
1337 is an unrecognized destination, or for causing
1338groups that you don\'d5t want to deal with to effectively
1339\'d2disappear\'d3 from the input stream.
1340\par
1341{\sl-140\sa0\sb0\par}
1342Calling this function in the middle of expanding a
1343style may cause problems. However, it is typically
1344called when you have just seen a destination symbol,
1345which won\'d5t happen during a style expansion\'d1I
1346think.
1347\par
1348{\sl-140\sa0\sb0\par}
1349Be careful with this function if your writer maintains
1350a state stack, because you will already have pushed
1351a state when the opening group brace was seen. After
1352\f1\i0\b0
1353\i RTFSkipGroup()\f1\i0\b0
1354 returns, the group closing brace has
1355been read, and you\'d5ll need to pop a state. All global
1356token variables will still be set to the closing brace,
1357so you may only need to call \f1\i0\b0
1358
1359\i RTFRouteToken()\f1\i0\b0
1360 to cause the state to be unstacked.
1361\par
1362\fs20 \f3\i0\b0
1363{\sl-120\sa0\sb0\par}
1364\f1\i0\b0
1365\f3\i0\b0
1366\pard \ql \sl240
1367\tx1152
1368void
1369\par
1370RTFExpandStyle (num)
1371\par
1372int\tab num;
1373\par
1374\fs24 \f1\i0\b0
1375\fs20 \f3\i0\b0
1376\fs24 \f1\i0\b0
1377{\sl-120\sa0\sb0\par}
1378\pard \qj \li360 \sl280
1379\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1380Performs style expansion of the given style number,
1381or does nothing if there is no such style. The writer
1382should call this when it notices that the current token
1383is a style number indicator.
1384\par
1385\fs20 \f3\i0\b0
1386{\sl-120\sa0\sb0\par}
1387\f1\i0\b0
1388\f3\i0\b0
1389\pard \ql \sl240
1390\tx1152
1391void
1392\par
1393RTFSetStream (stream)
1394\par
1395FILE\tab *stream;
1396\par
1397\fs24 \f1\i0\b0
1398\fs20 \f3\i0\b0
1399\fs24 \f1\i0\b0
1400{\sl-120\sa0\sb0\par}
1401\pard \qj \li360 \sl280
1402\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1403Redirects the RTF reader to the given stream. This
1404should be called before any reading is done. The default
1405input stream is \f1\i0\b0
1406
1407\i stdin\f1\i0\b0
1408. An alternative to \f1\i0\b0
1409
1410\i RTFSetStream()\f1\i0\b0
1411 is to simply \f1\i0\b0
1412
1413\i freopen()\f1\i0\b0
1414 the input file on \f1\i0\b0
1415
1416\i stdin\f1\i0\b0
1417 (that\'d5s what all the sample translators do).
1418\par
1419{\sl-140\sa0\sb0\par}
1420The input stream is \f1\i0\b0
1421
1422\i not\f1\i0\b0
1423 modified by \f1\i0\b0
1424
1425\i RTFInit()\f1\i0\b0
1426.
1427\par
1428\fs20 \f3\i0\b0
1429{\sl-120\sa0\sb0\par}
1430\f1\i0\b0
1431\f3\i0\b0
1432\pard \ql \sl240
1433\tx1152
1434void
1435\par
1436RTFSetClassCallback (class, callback)
1437\par
1438int\tab \tab class;
1439\par
1440RTFFuncPtr\tab callback;
1441\par
1442\fs24 \f1\i0\b0
1443\fs20 \f3\i0\b0
1444\fs24 \f1\i0\b0
1445{\sl-120\sa0\sb0\par}
1446\pard \qj \li360 \sl280
1447\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1448Installs a writer callback function for the given token
1449class. The first argument is a class number, the second
1450is the function to call when tokens from that class
1451are encountered in the input stream. This will cause
1452\f1\i0\b0
1453\i RTFRouteToken()\f1\i0\b0
1454 to invoke the callback when it encounters
1455a token in the class. If \f1\i0\b0
1456
1457\i callback\f1\i0\b0
1458 is \f3\i0\b0
1459NULL\f1\i0\b0
1460 (which is the default for all classes),
1461tokens in the class are ignored, i.e., discarded.
1462\par
1463{\sl-140\sa0\sb0\par}
1464The callback should take no arguments and return no
1465value. Within the callback, information about the current
1466token can be obtained from the global variables.
1467\par
1468{\sl-140\sa0\sb0\par}
1469Installing a callback for the \f1\i0\b0
1470
1471\i rtfEOF\f1\i0\b0
1472 \'d2class\'d3 is silly and has no effect.
1473\par
1474\fs20 \f3\i0\b0
1475{\sl-120\sa0\sb0\par}
1476\f1\i0\b0
1477\f3\i0\b0
1478\pard \ql \sl240
1479\tx1152
1480RTFFuncPtr
1481\par
1482RTFGetClassCallback (class)
1483\par
1484int\tab class;
1485\par
1486\fs24 \f1\i0\b0
1487\fs20 \f3\i0\b0
1488\fs24 \f1\i0\b0
1489{\sl-120\sa0\sb0\par}
1490\pard \qj \li360 \sl280
1491\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1492Returns a pointer to the callback function for the
1493given token class, or \f3\i0\b0
1494NULL\f1\i0\b0
1495 if there isn\'d5t one.
1496\par
1497\fs20 \f3\i0\b0
1498{\sl-120\sa0\sb0\par}
1499\f1\i0\b0
1500\f3\i0\b0
1501\pard \ql \sl240
1502\tx1152
1503void
1504\par
1505RTFSetDestinationCallback (dest, callback)
1506\par
1507int\tab \tab dest;
1508\par
1509RTFFuncPtr\tab callback;
1510\par
1511\fs24 \f1\i0\b0
1512\fs20 \f3\i0\b0
1513\fs24 \f1\i0\b0
1514{\sl-120\sa0\sb0\par}
1515\pard \qj \li360 \sl280
1516\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1517Installs a callback function for the given destination
1518(\f1\i0\b0
1519
1520\i dest\f1\i0\b0
1521 is a token minor number). When \f1\i0\b0
1522
1523\i RTFRouteToken()\f1\i0\b0
1524 sees a token with class \f1\i0\b0
1525
1526\i rtfControl\f1\i0\b0
1527 and major number \f1\i0\b0
1528
1529\i rtfDestination\f1\i0\b0
1530, it checks whether there is a callback
1531for the destination indicated by the minor number.
1532If so, it invokes it. If \f1\i0\b0
1533
1534\i callback\f1\i0\b0
1535 is \f3\i0\b0
1536NULL\f1\i0\b0
1537, the given destination is not treated
1538specially (the control class callback is invoked as
1539usual). By default, destination callbacks are installed
1540for the font table, color table, stylesheet, and information
1541and picture group.
1542\par
1543{\sl-140\sa0\sb0\par}
1544The callback should take no arguments and return no
1545value. When the functon is invoked, the current token
1546will be the destination token following the destination\'d5s
1547initial opening brace \f3\i0\b0
1548\{\f1\i0\b0
1549. (For optional destinations,
1550the destination token follows the \f3\i0\b0
1551\\*\f1\i0\b0
1552 symbol.)
1553\par
1554\fs20 \f3\i0\b0
1555{\sl-120\sa0\sb0\par}
1556\f1\i0\b0
1557\f3\i0\b0
1558\pard \ql \sl240
1559\tx1152
1560RTFFuncPtr
1561\par
1562RTFGetDestinationCallback (dest)
1563\par
1564int\tab dest;
1565\par
1566\fs24 \f1\i0\b0
1567\fs20 \f3\i0\b0
1568\fs24 \f1\i0\b0
1569{\sl-120\sa0\sb0\par}
1570\pard \qj \li360 \sl280
1571\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1572Returns a pointer to the callback function for the
1573given token class, or \f3\i0\b0
1574NULL\f1\i0\b0
1575 if there isn\'d5t one.
1576\par
1577\fs20 \f3\i0\b0
1578{\sl-120\sa0\sb0\par}
1579\f1\i0\b0
1580\f3\i0\b0
1581\pard \ql \sl240
1582\tx1152
1583RTFStyle *
1584\par
1585RTFGetStyle (num)
1586\par
1587int\tab num;
1588\par
1589\fs24 \f1\i0\b0
1590\fs20 \f3\i0\b0
1591\fs24 \f1\i0\b0
1592{\sl-120\sa0\sb0\par}
1593\pard \qj \li360 \sl280
1594\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1595Returns a pointer to the \f1\i0\b0
1596
1597\i RTFStyle\f1\i0\b0
1598 structure for the given style number. The
1599\'d2Normal\'d3 style number is 0. Pass \'d01 to get
1600a pointer to the first style in the list. Styles are
1601not stored in any particular order.
1602\par
1603{\sl-140\sa0\sb0\par}
1604Be sure to check the result; it might be \f3\i0\b0
1605NULL\f1\i0\b0
1606.
1607\par
1608{\sl-140\sa0\sb0\par}
1609This function is meaningless if the default stylesheet
1610destination reader is overridden.
1611\par
1612\fs20 \f3\i0\b0
1613{\sl-120\sa0\sb0\par}
1614\f1\i0\b0
1615\f3\i0\b0
1616\pard \ql \sl240
1617\tx1152
1618RTFFont *
1619\par
1620RTFGetFont (num)
1621\par
1622int\tab num;
1623\par
1624\fs24 \f1\i0\b0
1625\fs20 \f3\i0\b0
1626\fs24 \f1\i0\b0
1627{\sl-120\sa0\sb0\par}
1628\pard \qj \li360 \sl280
1629\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1630Returns a pointer to the \f1\i0\b0
1631
1632\i RTFFont\f1\i0\b0
1633 structure for the given font number. Pass \'d01
1634to get a pointer to the first font in the list. Fonts
1635are not stored in any particular order.
1636\par
1637{\sl-140\sa0\sb0\par}
1638Be sure to check the result; it might be \f3\i0\b0
1639NULL\f1\i0\b0
1640. In particular,
1641you might think that passing the number specified with
1642the \f3\i0\b0
1643\\deff\f1\i0\b0
1644 (default font) control symbol would always
1645yield a valid font structure, but that\'d5s not true.
1646The default font might not be listed in the font table.
1647\par
1648{\sl-140\sa0\sb0\par}
1649This function is meaningless if the default font table
1650destination reader is overridden.
1651\par
1652\fs20 \f3\i0\b0
1653{\sl-120\sa0\sb0\par}
1654\f1\i0\b0
1655\f3\i0\b0
1656\pard \ql \sl240
1657\tx1152
1658RTFColor *
1659\par
1660RTFGetColor (num)
1661\par
1662int\tab num;
1663\par
1664\fs24 \f1\i0\b0
1665\fs20 \f3\i0\b0
1666\fs24 \f1\i0\b0
1667{\sl-120\sa0\sb0\par}
1668\pard \qj \li360 \sl280
1669\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1670Returns a pointer to the \f1\i0\b0
1671
1672\i RTFColor\f1\i0\b0
1673 structure for the given color number. Pass
1674\'d01 to get a pointer to the first color in the list.
1675Colors are not stored in any particular order. If the
1676color values in the entry are \'d01, the default color
1677should be used. The default color is translator-dependent.
1678\par
1679{\sl-140\sa0\sb0\par}
1680Be sure to check the result; it might be \f3\i0\b0
1681NULL\f1\i0\b0
1682. I think
1683this means you should use the default color.
1684\par
1685{\sl-140\sa0\sb0\par}
1686This function is meaningless if the default color table
1687destination reader is overridden.
1688\par
1689\fs20 \f3\i0\b0
1690{\sl-120\sa0\sb0\par}
1691\f1\i0\b0
1692\f3\i0\b0
1693\pard \ql \sl240
1694\tx1152
1695int
1696\par
1697RTFCheckCM (class, major)
1698\par
1699int\tab class, major;
1700\par
1701\fs24 \f1\i0\b0
1702\fs20 \f3\i0\b0
1703\fs24 \f1\i0\b0
1704{\sl-120\sa0\sb0\par}
1705\pard \qj \li360 \sl280
1706\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1707Returns non-zero if \f1\i0\b0
1708
1709\i rtfClass\f1\i0\b0
1710 and \f1\i0\b0
1711
1712\i rtfMajor\f1\i0\b0
1713 are equal to \f1\i0\b0
1714
1715\i class\f1\i0\b0
1716 and \f1\i0\b0
1717
1718\i major\f1\i0\b0
1719, respectively, zero otherwise.
1720\par
1721\fs20 \f3\i0\b0
1722{\sl-120\sa0\sb0\par}
1723\f1\i0\b0
1724\f3\i0\b0
1725\pard \ql \sl240
1726\tx1152
1727int
1728\par
1729RTFCheckCMM (class, major, minor)
1730\par
1731int\tab class, major, minor;
1732\par
1733\fs24 \f1\i0\b0
1734\fs20 \f3\i0\b0
1735\fs24 \f1\i0\b0
1736{\sl-120\sa0\sb0\par}
1737\pard \qj \li360 \sl280
1738\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1739Returns non-zero if \f1\i0\b0
1740
1741\i rtfClass\f1\i0\b0
1742, \f1\i0\b0
1743
1744\i rtfMajor\f1\i0\b0
1745 and \f1\i0\b0
1746
1747\i rtfMinor\f1\i0\b0
1748 are equal to \f1\i0\b0
1749
1750\i class\f1\i0\b0
1751, \f1\i0\b0
1752
1753\i major\f1\i0\b0
1754 and \f1\i0\b0
1755
1756\i minor\f1\i0\b0
1757, respectively, zero otherwise.
1758\par
1759\fs20 \f3\i0\b0
1760{\sl-120\sa0\sb0\par}
1761\f1\i0\b0
1762\f3\i0\b0
1763\pard \ql \sl240
1764\tx1152
1765int
1766\par
1767RTFCheckMM (major, minor)
1768\par
1769int\tab major, minor;
1770\par
1771\fs24 \f1\i0\b0
1772\fs20 \f3\i0\b0
1773\fs24 \f1\i0\b0
1774{\sl-120\sa0\sb0\par}
1775\pard \qj \li360 \sl280
1776\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1777Returns non-zero if \f1\i0\b0
1778
1779\i rtfMajor\f1\i0\b0
1780 and \f1\i0\b0
1781
1782\i rtfMinor\f1\i0\b0
1783 are equal to \f1\i0\b0
1784
1785\i major\f1\i0\b0
1786 and \f1\i0\b0
1787
1788\i minor\f1\i0\b0
1789, respectively, zero otherwise.
1790\par
1791\fs20 \f3\i0\b0
1792{\sl-120\sa0\sb0\par}
1793\f1\i0\b0
1794\f3\i0\b0
1795\pard \ql \sl240
1796\tx1152
1797char *
1798\par
1799RTFAlloc (size)
1800\par
1801int\tab size;
1802\par
1803\fs24 \f1\i0\b0
1804\fs20 \f3\i0\b0
1805\fs24 \f1\i0\b0
1806{\sl-120\sa0\sb0\par}
1807\pard \qj \li360 \sl280
1808\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1809Returns a pointer to a block of memory \f1\i0\b0
1810
1811\i size\f1\i0\b0
1812 bytes long, or \f3\i0\b0
1813NULL\f1\i0\b0
1814 if insufficient memory was
1815available.
1816\par
1817\fs20 \f3\i0\b0
1818{\sl-120\sa0\sb0\par}
1819\f1\i0\b0
1820\f3\i0\b0
1821\pard \ql \sl240
1822\tx1152
1823char *
1824\par
1825RTFStrSave (s)
1826\par
1827char\tab *s;
1828\par
1829\fs24 \f1\i0\b0
1830\fs20 \f3\i0\b0
1831\fs24 \f1\i0\b0
1832{\sl-120\sa0\sb0\par}
1833\pard \qj \li360 \sl280
1834\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1835Allocates a block of memory big enough for a copy of
1836the given string (including terminating null byte),
1837copies the string into it, and returns a pointer to
1838the copy. Returns \f3\i0\b0
1839NULL\f1\i0\b0
1840 if insufficient memory was available.
1841\par
1842\fs20 \f3\i0\b0
1843{\sl-120\sa0\sb0\par}
1844\f1\i0\b0
1845\f3\i0\b0
1846\pard \ql \sl240
1847\tx1152
1848void
1849\par
1850RTFFree (p)
1851\par
1852char\tab *p;
1853\par
1854\fs24 \f1\i0\b0
1855\fs20 \f3\i0\b0
1856\fs24 \f1\i0\b0
1857{\sl-120\sa0\sb0\par}
1858\pard \qj \li360 \sl280
1859\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1860Frees the block of memory pointed to by \f1\i0\b0
1861
1862\i p\f1\i0\b0
1863, which should have been allocated by \f1\i0\b0
1864
1865\i RTFAlloc()\f1\i0\b0
1866 or \f1\i0\b0
1867
1868\i RTFStrSave()\f1\i0\b0
1869. It is safe to pass \f3\i0\b0
1870NULL\f1\i0\b0
1871 to this routine.
1872\par
1873\fs20 \f3\i0\b0
1874{\sl-120\sa0\sb0\par}
1875\f1\i0\b0
1876\f3\i0\b0
1877\pard \ql \sl240
1878\tx1152
1879void
1880\par
1881RTFCharToHex (c)
1882\par
1883char\tab c;
1884\par
1885\fs24 \f1\i0\b0
1886\fs20 \f3\i0\b0
1887\fs24 \f1\i0\b0
1888{\sl-120\sa0\sb0\par}
1889\pard \qj \li360 \sl280
1890\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1891Returns 0..15 for the characters \'d40\'d4..\'d49\'d4,\'d4a\'d4..\'d4f\'d4.
1892\par
1893\fs20 \f3\i0\b0
1894{\sl-120\sa0\sb0\par}
1895\f1\i0\b0
1896\f3\i0\b0
1897\pard \ql \sl240
1898\tx1152
1899void
1900\par
1901RTFHexToChar (i)
1902\par
1903int\tab i;
1904\par
1905\fs24 \f1\i0\b0
1906\fs20 \f3\i0\b0
1907\fs24 \f1\i0\b0
1908{\sl-120\sa0\sb0\par}
1909\pard \qj \li360 \sl280
1910\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1911Returns the characters \'d40\'d4..\'d49\'d4,\'d4a\'d4..\'d4f\'d4
1912for 0..15.
1913\par
1914\fs20 \f3\i0\b0
1915{\sl-120\sa0\sb0\par}
1916\f1\i0\b0
1917\f3\i0\b0
1918\pard \ql \sl240
1919\tx1152
1920int
1921\par
1922RTFReadCharSetMap (file, csId)
1923\par
1924char\tab *file;
1925\par
1926int\tab csId;
1927\par
1928\fs24 \f1\i0\b0
1929\fs20 \f3\i0\b0
1930\fs24 \f1\i0\b0
1931{\sl-120\sa0\sb0\par}
1932\pard \qj \li360 \sl280
1933\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1934Reads a charset map file into the charset map indicated
1935by \f1\i0\b0
1936
1937\i csId\f1\i0\b0
1938, which should be either \f1\i0\b0
1939
1940\i rtfCSGeneral\f1\i0\b0
1941 or \f1\i0\b0
1942
1943\i rtfCSSymbol\f1\i0\b0
1944. Returns non-zero for success, zero otherwise.
1945\par
1946\fs20 \f3\i0\b0
1947{\sl-120\sa0\sb0\par}
1948\f1\i0\b0
1949\f3\i0\b0
1950\pard \ql \sl240
1951\tx1152
1952void
1953\par
1954RTFSetCharSetMap (file, csId)
1955\par
1956char\tab *file;
1957\par
1958int\tab csId;
1959\par
1960\fs24 \f1\i0\b0
1961\fs20 \f3\i0\b0
1962\fs24 \f1\i0\b0
1963{\sl-120\sa0\sb0\par}
1964\pard \qj \li360 \sl280
1965\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
1966Specify the name of the file to be read for the charset
1967map indicated by \f1\i0\b0
1968
1969\i csId\f1\i0\b0
1970 (which should be either \f1\i0\b0
1971
1972\i rtfCSGeneral\f1\i0\b0
1973 or \f1\i0\b0
1974
1975\i rtfCSSymbol\f1\i0\b0
1976) when auto-charset-file reading is done.
1977This can be used to override the default charset map
1978names. \f1\i0\b0
1979
1980\i RTFSetCharSetMap()\f1\i0\b0
1981 should be called after \f1\i0\b0
1982
1983\i RTFInit()\f1\i0\b0
1984 but before you begin reading any input.
1985\par
1986\fs20 \f3\i0\b0
1987{\sl-120\sa0\sb0\par}
1988\f1\i0\b0
1989\f3\i0\b0
1990\pard \ql \sl240
1991\tx1152
1992void
1993\par
1994RTFSetCharSet (csId)
1995\par
1996int\tab csId;
1997\par
1998\fs24 \f1\i0\b0
1999\fs20 \f3\i0\b0
2000\fs24 \f1\i0\b0
2001{\sl-120\sa0\sb0\par}
2002\pard \qj \li360 \sl280
2003\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
2004Switches to the charset map given by \f1\i0\b0
2005
2006\i csId\f1\i0\b0
2007, which should be either \f1\i0\b0
2008
2009\i rtfCSGeneral\f1\i0\b0
2010 or \f1\i0\b0
2011
2012\i rtfCSSymbol\f1\i0\b0
2013.
2014\par
2015\fs20 \f3\i0\b0
2016{\sl-120\sa0\sb0\par}
2017\f1\i0\b0
2018\f3\i0\b0
2019\pard \ql \sl240
2020\tx1152
2021int
2022\par
2023RTFGetCharSet ()
2024\par
2025\fs24 \f1\i0\b0
2026\fs20 \f3\i0\b0
2027\fs24 \f1\i0\b0
2028{\sl-120\sa0\sb0\par}
2029\pard \qj \li360 \sl280
2030\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
2031Returns the id of the current charset map, either \f1\i0\b0
2032
2033\i rtfCSGeneral\f1\i0\b0
2034 or \f1\i0\b0
2035
2036\i rtfCSSymbol\f1\i0\b0
2037.
2038\par
2039\fs20 \f3\i0\b0
2040{\sl-120\sa0\sb0\par}
2041\f1\i0\b0
2042\f3\i0\b0
2043\pard \ql \sl240
2044\tx1152
2045int
2046\par
2047RTFMapChar (c)
2048\par
2049int\tab c;
2050\par
2051\fs24 \f1\i0\b0
2052\fs20 \f3\i0\b0
2053\fs24 \f1\i0\b0
2054{\sl-120\sa0\sb0\par}
2055\pard \qj \li360 \sl280
2056\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
2057Maps in input character onto a standard character code.
2058\par
2059\fs20 \f3\i0\b0
2060{\sl-120\sa0\sb0\par}
2061\f1\i0\b0
2062\f3\i0\b0
2063\pard \ql \sl240
2064\tx1152
2065int
2066\par
2067RTFStdCharCode (name)
2068\par
2069char\tab *name;
2070\par
2071\fs24 \f1\i0\b0
2072\fs20 \f3\i0\b0
2073\fs24 \f1\i0\b0
2074{\sl-120\sa0\sb0\par}
2075\pard \qj \li360 \sl280
2076\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
2077Given a standard character name, returns the standard
2078code corresponding to the name, or \'d01 if the name
2079is unknown.
2080\par
2081\fs20 \f3\i0\b0
2082{\sl-120\sa0\sb0\par}
2083\f1\i0\b0
2084\f3\i0\b0
2085\pard \ql \sl240
2086\tx1152
2087char *
2088\par
2089RTFStdCharName (code)
2090\par
2091int\tab code;
2092\par
2093\fs24 \f1\i0\b0
2094\fs20 \f3\i0\b0
2095\fs24 \f1\i0\b0
2096{\sl-120\sa0\sb0\par}
2097\pard \qj \li360 \sl280
2098\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
2099Given a standard character code, returns a string pointing
2100to the standard character name, or \f3\i0\b0
2101NULL\f1\i0\b0
2102 if the code
2103is unknown.
2104\par
2105\fs20 \f3\i0\b0
2106{\sl-120\sa0\sb0\par}
2107\f1\i0\b0
2108\f3\i0\b0
2109\pard \ql \sl240
2110\tx1152
2111int
2112\par
2113RTFReadOutputMap (file, outMap, reinit)
2114\par
2115char\tab *file;
2116\par
2117char\tab *outMap[];
2118\par
2119int\tab reinit;
2120\par
2121\fs24 \f1\i0\b0
2122\fs20 \f3\i0\b0
2123\fs24 \f1\i0\b0
2124{\sl-120\sa0\sb0\par}
2125\pard \qj \li360 \sl280
2126\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
2127Reads an output map from the named file into \f1\i0\b0
2128
2129\i outMap\f1\i0\b0
2130. If \f1\i0\b0
2131
2132\i reinit\f1\i0\b0
2133 is non-zero, the map is cleared first. See the
2134document \f1\i0\b0
2135
2136\i RTF Tools Character Mapping\f1\i0\b0
2137 for further details.
2138\par
2139{\sl-140\sa0\sb0\par}
2140Generally, the output map needs to be read only once.
2141\par
2142\fs20 \f3\i0\b0
2143{\sl-120\sa0\sb0\par}
2144\f1\i0\b0
2145\f3\i0\b0
2146\pard \ql \sl240
2147\tx1152
2148void
2149\par
2150RTFSetInputName (name)
2151\par
2152char\tab *name;
2153\par
2154\fs24 \f1\i0\b0
2155\fs20 \f3\i0\b0
2156\fs24 \f1\i0\b0
2157{\sl-120\sa0\sb0\par}
2158\fs20 \f3\i0\b0
2159{\sl-120\sa0\sb0\par}
2160\f1\i0\b0
2161\f3\i0\b0
2162void
2163\par
2164RTFSetOutputName (name)
2165\par
2166char\tab *name;
2167\par
2168\fs24 \f1\i0\b0
2169\fs20 \f3\i0\b0
2170\fs24 \f1\i0\b0
2171{\sl-120\sa0\sb0\par}
2172\pard \qj \li360 \sl280
2173\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
2174These functions tell the RTF library the input or output
2175file names. They\'d5re called by driver code so that
2176writer code can determine the names by calling \f1\i0\b0
2177
2178\i RTFGetInputName()\f1\i0\b0
2179 and \f1\i0\b0
2180
2181\i RTFGetOutputName()\f1\i0\b0
2182. Since \f1\i0\b0
2183
2184\i RTFInit()\f1\i0\b0
2185 sets the names to \f3\i0\b0
2186NULL\f1\i0\b0
2187, the driver should
2188set the names after calling \f1\i0\b0
2189
2190\i RTFInit()\f1\i0\b0
2191 but before calling the writer to tell it
2192to set up for a new file.
2193\par
2194\fs20 \f3\i0\b0
2195{\sl-120\sa0\sb0\par}
2196\f1\i0\b0
2197\f3\i0\b0
2198\pard \ql \sl240
2199\tx1152
2200char *
2201\par
2202RTFGetInputName ()
2203\par
2204\fs24 \f1\i0\b0
2205\fs20 \f3\i0\b0
2206\fs24 \f1\i0\b0
2207{\sl-120\sa0\sb0\par}
2208\fs20 \f3\i0\b0
2209{\sl-120\sa0\sb0\par}
2210\f1\i0\b0
2211\f3\i0\b0
2212char *
2213\par
2214RTFGetOutputName ()
2215\par
2216\fs24 \f1\i0\b0
2217\fs20 \f3\i0\b0
2218\fs24 \f1\i0\b0
2219{\sl-120\sa0\sb0\par}
2220\pard \qj \li360 \sl280
2221\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
2222These functions return pointers to the current input
2223and output file names, assuming the driver has set
2224them up. The caller should make a copy of the strings
2225returned if it wants to modify them.
2226\par
2227\fs20 \f3\i0\b0
2228{\sl-120\sa0\sb0\par}
2229\f1\i0\b0
2230\f3\i0\b0
2231\pard \ql \sl240
2232\tx1152
2233void
2234\par
2235RTFMsg (args ...)
2236\par
2237\fs24 \f1\i0\b0
2238\fs20 \f3\i0\b0
2239\fs24 \f1\i0\b0
2240{\sl-120\sa0\sb0\par}
2241\pard \qj \li360 \sl280
2242\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
2243This function generates a diagnostic message. It takes
2244\f1\i0\b0
2245\i printf()\f1\i0\b0
2246-like arguments.
2247\par
2248{\sl-140\sa0\sb0\par}
2249See the description of \f1\i0\b0
2250
2251\i RTFSetMsgProc()\f1\i0\b0
2252.
2253\par
2254\fs20 \f3\i0\b0
2255{\sl-120\sa0\sb0\par}
2256\f1\i0\b0
2257\f3\i0\b0
2258\pard \ql \sl240
2259\tx1152
2260void
2261\par
2262RTFPanic (args ...)
2263\par
2264\fs24 \f1\i0\b0
2265\fs20 \f3\i0\b0
2266\fs24 \f1\i0\b0
2267{\sl-120\sa0\sb0\par}
2268\pard \qj \li360 \sl280
2269\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
2270This function generates an error message and terminates
2271the process. It takes \f1\i0\b0
2272
2273\i printf()\f1\i0\b0
2274-like arguments.
2275\par
2276{\sl-140\sa0\sb0\par}
2277See the description of \f1\i0\b0
2278
2279\i RTFSetPanicProc()\f1\i0\b0
2280.
2281\par
2282\fs20 \f3\i0\b0
2283{\sl-120\sa0\sb0\par}
2284\f1\i0\b0
2285\f3\i0\b0
2286\pard \ql \sl240
2287\tx1152
2288FILE *
2289\par
2290RTFOpenLibFile (name, mode)
2291\par
2292char\tab *name;
2293\par
2294char\tab *mode;
2295\par
2296\fs24 \f1\i0\b0
2297\fs20 \f3\i0\b0
2298\fs24 \f1\i0\b0
2299{\sl-120\sa0\sb0\par}
2300\pard \qj \li360 \sl280
2301\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
2302This function opens a library file and returns a \f3\i0\b0
2303FILE\f1\i0\b0
2304
2305pointer to it, or \f3\i0\b0
2306NULL\f1\i0\b0
2307 if the file could not be opened.
2308\par
2309{\sl-140\sa0\sb0\par}
2310See the description of \f1\i0\b0
2311
2312\i RTFSetOpenLibFileProc()\f1\i0\b0
2313.
2314\par
2315\fs20 \f3\i0\b0
2316{\sl-120\sa0\sb0\par}
2317\f1\i0\b0
2318\f3\i0\b0
2319\pard \ql \sl240
2320\tx1152
2321void
2322\par
2323RTFSetMsgProc (proc)
2324\par
2325void\tab (*proc) ();
2326\par
2327\fs24 \f1\i0\b0
2328\fs20 \f3\i0\b0
2329\fs24 \f1\i0\b0
2330{\sl-120\sa0\sb0\par}
2331\pard \qj \li360 \sl280
2332\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
2333This function installs a function for use by \f1\i0\b0
2334
2335\i RTFMsg()\f1\i0\b0
2336; see \f1\i0\b0
2337
2338\i RTF Tools Translator Architecture\f1\i0\b0
2339 for details.
2340\par
2341\fs20 \f3\i0\b0
2342{\sl-120\sa0\sb0\par}
2343\f1\i0\b0
2344\f3\i0\b0
2345\pard \ql \sl240
2346\tx1152
2347void
2348\par
2349RTFSetPanicProc (proc)
2350\par
2351void\tab (*proc) ();
2352\par
2353\fs24 \f1\i0\b0
2354\fs20 \f3\i0\b0
2355\fs24 \f1\i0\b0
2356{\sl-120\sa0\sb0\par}
2357\pard \qj \li360 \sl280
2358\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
2359This function installs a function for use by \f1\i0\b0
2360
2361\i RTFPanic()\f1\i0\b0
2362; see \f1\i0\b0
2363
2364\i RTF Tools Translator Architecture\f1\i0\b0
2365 for details.
2366\par
2367\fs20 \f3\i0\b0
2368{\sl-120\sa0\sb0\par}
2369\f1\i0\b0
2370\f3\i0\b0
2371\pard \ql \sl240
2372\tx1152
2373void
2374\par
2375RTFSetOpenLibFileProc (proc)
2376\par
2377FILE\tab *(*proc) ();
2378\par
2379\fs24 \f1\i0\b0
2380\fs20 \f3\i0\b0
2381\fs24 \f1\i0\b0
2382{\sl-120\sa0\sb0\par}
2383\pard \qj \li360 \sl280
2384\tx320 \tx640 \tx960 \tx1280 \tx1600 \tx1920 \tx2240 \tx2560 \tx2880 \tx3200 \tx3520 \tx3840 \tx4160 \tx4480 \tx4800 \tx5120 \tx5440 \tx5760 \tx6080 \tx6400
2385This function installs a function that the library
2386will use to open library files. The driver must call
2387this when it starts up or \f1\i0\b0
2388
2389\i RTFOpenLibFile()\f1\i0\b0
2390 will always return \f3\i0\b0
2391NULL\f1\i0\b0
2392. The function
2393should take a library file basename and open mode,
2394open the file, and return the \f3\i0\b0
2395FILE\f1\i0\b0
2396 pointer, or \f3\i0\b0
2397NULL\f1\i0\b0
2398
2399if the file could not be found and opened.
2400\par
2401{\sl-280\sa0\sb0\par}
2402\fs20 \fs28 \f1\i0\b0
2403\b \pard \qj \sl320
2404\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
2405Distribution Availability\f1\i0\b0
2406
2407\par
2408{\sl-320\sa0\sb0\par}
2409\fs20 {\sl-120\sa0\sb0\par}
2410\pard \qj \sl240
2411\tx500 \tx1000 \tx1500 \tx2000 \tx2500 \tx3000 \tx3500 \tx4000 \tx4500 \tx5000 \tx5500 \tx6000 \tx6500 \tx7000 \tx7500
2412This software may be redistributed without restriction
2413and used for any purpose whatsoever.
2414\par
2415{\sl-120\sa0\sb0\par}
2416The RTF Tools distribution is available for anonymous
2417\f1\i0\b0
2418\i ftp\f1\i0\b0
2419 access on \f1\i0\b0
2420
2421\i ftp.primate.wisc.edu\f1\i0\b0
2422. Look in the \f1\i0\b0
2423
2424\i /pub/RTF\f1\i0\b0
2425 directory. Updates appear there as they become
2426available.
2427\par
2428{\sl-120\sa0\sb0\par}
2429A version of the RTF specification is available in
2430this directory, as a binhex\'d5ed Word for Macintosh
2431document and in RTF and PostScript formats.
2432\par
2433{\sl-120\sa0\sb0\par}
2434The software and documentation may also be accessed
2435using gopher by connecting to \f1\i0\b0
2436
2437\i gopher.primate.wisc.edu\f1\i0\b0
2438 or using World Wide Web by
2439connecting to \f1\i0\b0
2440
2441\i www.primate.wisc.edu\f1\i0\b0
2442 using the URL \f1\i0\b0
2443
2444\i http://www.primate.wisc.edu/\f1\i0\b0
2445. In both cases, look under
2446\'d2Primate Center Software Archives\'d3.
2447\par
2448{\sl-120\sa0\sb0\par}
2449If you do not have Internet access, send requests to
2450\f1\i0\b0
2451\i software@primate.wisc.edu\f1\i0\b0
2452. Bug reports and questions
2453should be sent to this address as well.
2454\par
2455{\sl-120\sa0\sb0\par}
2456If you use this software as the basis for a translater
2457not included in the current collection, please send
2458me a description that indicates how it may be obtained
2459and I\'d5ll add the description to the archive site.
2460\par
2461}
2462