File: rtflib.html

package info (click to toggle)
cost 2.2p1-3
  • links: PTS
  • area: main
  • in suites: woody
  • size: 1,032 kB
  • ctags: 1,728
  • sloc: ansic: 12,123; tcl: 2,702; sh: 209; makefile: 161
file content (1054 lines) | stat: -rw-r--r-- 53,926 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- This file was automatically generated.  DO NOT EDIT BY HAND. -->
<HTML>
<HEAD>
<TITLE>RATFINK</TITLE>
<META NAME=Creator CONTENT="Cost 2.1a1">
<LINK REV=MADE HREF="mailto:joe@flightlab.com">
</HEAD>
<BODY>
<DIV CLASS=header><H1 CLASS=title>RATFINK</H1>
<H2 CLASS=subtitle>A library of RTF output utilities for Tcl<BR>Version 0.9<BR></H2><P>Joe English<BR><I>Last updated: Sunday 27 June 1999, 15:31 PDT</I></DIV><HR>
<UL CLASS=TOC>
<LI CLASS=TOCENTRY><A HREF="#SECT1">1 Introduction</A>
<UL CLASS=TOC>
<LI CLASS=TOCENTRY><A HREF="#SECT2">1.1 Overview</A>
<LI CLASS=TOCENTRY><A HREF="#SECT3">1.2 A brief description of RTF</A>
</UL>
<LI CLASS=TOCENTRY><A HREF="#RTFDECLS">2 Declaration commands</A>
<UL CLASS=TOC>
<LI CLASS=TOCENTRY><A HREF="#SECT4">2.1 Stylesheet entries</A>
<UL CLASS=TOC>
<LI CLASS=TOCENTRY><A HREF="#DIMENSIONS">2.1.1 Dimensions</A>
<LI CLASS=TOCENTRY><A HREF="#FONTTBL">2.1.2 Fonts</A>
<LI CLASS=TOCENTRY><A HREF="#TABSTOPS">2.1.3 Tab stops</A>
<LI CLASS=TOCENTRY><A HREF="#RULES">2.1.4 Rules and borders</A>
</UL>
<LI CLASS=TOCENTRY><A HREF="#CHARSTYLES">2.2 Character styles</A>
<LI CLASS=TOCENTRY><A HREF="#PARASTYLES">2.3 Paragraph styles</A>
<LI CLASS=TOCENTRY><A HREF="#SECTSTYLES">2.4 Section styles</A>
<LI CLASS=TOCENTRY><A HREF="#DOCFMT">2.5 Document-wide formatting properties</A>
<LI CLASS=TOCENTRY><A HREF="#MAGICSTYLES">2.6 Special style names</A>
</UL>
<LI CLASS=TOCENTRY><A HREF="#RTFOUTPUT">3 RTF output commands</A>
<UL CLASS=TOC>
<LI CLASS=TOCENTRY><A HREF="#SECT5">3.1 Document structure</A>
<LI CLASS=TOCENTRY><A HREF="#SECT6">3.2 Text</A>
<LI CLASS=TOCENTRY><A HREF="#SPECIALS">3.3 Special characters</A>
<LI CLASS=TOCENTRY><A HREF="#SECT7">3.4 Miscellaneous</A>
<LI CLASS=TOCENTRY><A HREF="#DESTINATIONS">3.5 Destination groups</A>
<LI CLASS=TOCENTRY><A HREF="#HDRFTR">3.6 Page headers and footers</A>
<LI CLASS=TOCENTRY><A HREF="#FOOTNOTES">3.7 Footnotes</A>
<LI CLASS=TOCENTRY><A HREF="#BOOKMARKS">3.8 Bookmarks</A>
<LI CLASS=TOCENTRY><A HREF="#TABLES">3.9 Tables</A>
<LI CLASS=TOCENTRY><A HREF="#FIELDS">3.10 Fields</A>
</UL>
<LI CLASS=TOCENTRY><A HREF="#SGMLCONV">4 SGML Conversion</A>
<UL CLASS=TOC>
<LI CLASS=TOCENTRY><A HREF="#SECT8">4.1 Generated text</A>
<LI CLASS=TOCENTRY><A HREF="#SECT9">4.2 Nested paragraphs</A>
<LI CLASS=TOCENTRY><A HREF="#SECT10">4.3 Line-specific text</A>
<LI CLASS=TOCENTRY><A HREF="#SECT11">4.4 Sections</A>
<LI CLASS=TOCENTRY><A HREF="#SECT12">4.5 Data entities</A>
<LI CLASS=TOCENTRY><A HREF="#SECT13">4.6 RATFINK architectural forms</A>
</UL>
<LI CLASS=TOCENTRY><A HREF="#SECT14">5 Bugs, limitations, and oddities</A>
<LI CLASS=TOCENTRY><A HREF="#SECT15">6 References and related material</A>
<LI CLASS=TOCENTRY><A HREF="#SECT16">7 Acknowledgments</A>
</UL><HR>
<H2><A NAME=SECT1>1 Introduction</A></H2>
<HR>

<UL CLASS=TOC>
<LI CLASS=TOCENTRY><A HREF="#SECT2">1.1 Overview</A>
<LI CLASS=TOCENTRY><A HREF="#SECT3">1.2 A brief description of RTF</A>
</UL><HR>
<P>RTF, or Rich Text Format, is Microsoft's interchange format
for word processing files.
RATFINK is a set of Tcl routines for creating RTF files,
and a Cost interface for converting SGML to RTF.
<P>RTF is also the basis for Windows Help (WINHELP) format.
RATFINK does not currently contain any direct support for WINHELP.
<P><TT>rtflib.tcl</TT> contains the low-level utility routines.
This file is not Cost-specific and may be used in any Tcl script.
<TT>RTF.spec</TT> contains the extra Cost commands for SGML conversion.

<H3><A NAME=SECT2>1.1 Overview</A></H3>
<P>To use RATFINK with Cost, create a translation script that
does the following:

<OL><LI>Load the library code with the command <SAMP>require RTF.spec</SAMP></LI><LI>Define the style sheet entries using <B>rtf:paraStyle</B> and
the other commands described in <A HREF="#RTFDECLS">2. ``Declaration commands''</A></LI><LI>Define a Cost <EM>specification</EM>
mapping each element type in the source DTD to one of the
RATFINK processing forms as described in <A HREF="#SGMLCONV">4. ``SGML Conversion''</A></LI><LI>Call <B>rtf:start</B> to begin RTF output</LI><LI>Call <B>rtf:convert</B> to process the document</LI><LI>Call <B>rtf:end</B> to finish RTF output.</LI></OL>

<P CLASS=NOTE>NOTE -- The last three steps may be done in the <B>main</B> procedure.<P>Then run
<PRE>
sgmls <VAR>sgmldecl</VAR> <VAR>yourdoc.sgml</VAR> | costsh -S <VAR>yourscript.spec</VAR> &gt; <VAR>output.rtf</VAR>
</PRE>
to convert <VAR>yourdoc.sgml</VAR> to RTF.
<H4>A short example</H4><PRE>
# Define stylesheet:
rtf:paraStyle body "Body Text" {
    Font Roman
    FontSize 10pt
    LeftIndent 0.5in
}
rtf:paraStyle heading "Heading 1" {
    Font Sans
    FontSize 14pt
    Bold 1
    LeftIndent 0pt
}

# Specify processing for each element type:
specification rtfSpec {
  {element P} {
    rtf para
    paraStyle body
  }
  {element H1} {
    rtf para
    paraStyle heading
  }
}

# Main routine:
proc main {} {
    rtf:start
    rtf:convert rtfSpec
    rtf:end
}
</PRE>
<H3><A NAME=SECT3>1.2 A brief description of RTF</A></H3>
<P>Lexically, RTF files are a simple stream of
<EM>text</EM>, <EM>control words</EM>, and <EM>groups</EM>,
All text is seven-bit ASCII.
Control words are lowercase alphabetic tokens beginning with a backslash,
followed by an optional integer parameter, and terminated by a space
or a non-alphanumeric character.
Groups are nested data enclosed in curly braces.
<P>Semantically, things start to get complicated.
<P>RTF files start with a <EM>header</EM>, which contains a
font table, color table, stylesheet, and other metainformation.
The header is followed by the document data.
Everything in the document is a <EM>paragraph</EM>,
except for the stuff that isn't.
The stuff that isn't a paragraph includes
<UL><LI>section text, which contains paragraphs and tables;</LI><LI>table rows, which contain cells, which contain paragraphs; </LI><LI>field instructions (see <A HREF="#FIELDS">3.10. ``Fields''</A>),
which can appear inside paragraphs; and</LI><LI>other stuff.</LI></UL>
<P>Actually it's all very messy and you shouldn't have to worry
about it too much except to note that
<EM>every</EM> block of displayed data is
considered a <EM>paragraph</EM>, and that
RTF has a ``flat'' structure:
sections, paragraphs, and table rows <EM>do not nest</EM>.

<P CLASS=NOTE>NOTE -- Groups on the other hand do nest, and group boundaries
can cross section, paragraph, row, and cell boundaries, but don't
worry about that either.
<H2><A NAME=RTFDECLS>2 Declaration commands</A></H2>
<HR>

<UL CLASS=TOC>
<LI CLASS=TOCENTRY><A HREF="#SECT4">2.1 Stylesheet entries</A>
<LI CLASS=TOCENTRY><A HREF="#CHARSTYLES">2.2 Character styles</A>
<LI CLASS=TOCENTRY><A HREF="#PARASTYLES">2.3 Paragraph styles</A>
<LI CLASS=TOCENTRY><A HREF="#SECTSTYLES">2.4 Section styles</A>
<LI CLASS=TOCENTRY><A HREF="#DOCFMT">2.5 Document-wide formatting properties</A>
<LI CLASS=TOCENTRY><A HREF="#MAGICSTYLES">2.6 Special style names</A>
</UL><HR>

<H3><A NAME=SECT4>2.1 Stylesheet entries</A></H3>
<HR>

<UL CLASS=TOC>
<LI CLASS=TOCENTRY><A HREF="#DIMENSIONS">2.1.1 Dimensions</A>
<LI CLASS=TOCENTRY><A HREF="#FONTTBL">2.1.2 Fonts</A>
<LI CLASS=TOCENTRY><A HREF="#TABSTOPS">2.1.3 Tab stops</A>
<LI CLASS=TOCENTRY><A HREF="#RULES">2.1.4 Rules and borders</A>
</UL><HR>
<P>Formatting is determined by <EM>stylesheet entries</EM>.
There are three types of stylesheet entries in RTF:
<EM>character styles</EM>, <EM>paragraph styles</EM>, and <EM>section styles</EM>.
These are defined with the commands
<B>rtf:charStyle</B>, <B>rtf:paraStyle</B>, and <B>rtf:sectStyle</B>,
respectively
All three commands have the same syntax:
<PRE>
rtf:<VAR>xxx</VAR>Style <I>id</I> "<I>description</I>"  [ <B>-basedon</B> <I>styleid</I> ] {
    <VAR>param</VAR> <VAR>value</VAR>
    <VAR>param</VAR> <VAR>value</VAR>
    ...
}
</PRE><P>Each stylesheet entry has a symbolic <I>id</I>
by which it is referenced in other commands,
and a textual <I>description</I>,
which is inserted into the RTF file as the style name.

<P CLASS=NOTE>TIP -- Some RTF style names are interpreted specially
by various word processors;
see <A HREF="#MAGICSTYLES">2.6. ``Special style names''</A>, below.<P>If <B>-basedon</B> is specified,
then all of the style properties listed in the
named <I>styleid</I> are copied to the style being defined.
Parameters in the new style override those in the
base style.  <I>styleid</I> must be the <I>id</I>
of a previously-defined style of the same type
(paragraph, character, or section).
<P>Style properties are specified as a list
of <I>param</I>-<I>value</I> pairs.
Parameters map (more or less) onto RTF control words.
Parameter values take one of several forms,
depending on the parameter.
<EM>Boolean</EM> parameters specify true/false values;
the value must be 1 or 0.
<EM>Flag</EM> parameters are like booleans, but the
parameter can only be turned on (flag parameters correspond
to properties which are off by default and turned on by the
presence of an RTF control word.)
<EM>Dimension</EM> parameters specify a length
as a number followed by a unit name,
e.g., <SAMP>12pt</SAMP>, <SAMP>0.5in</SAMP>; see <A HREF="#DIMENSIONS">2.1.1. ``Dimensions''</A> for more details.
Other parameters may be integers, a list of enumerated values,
or some other type as described below.

<H4><A NAME=DIMENSIONS>2.1.1 Dimensions</A></H4>
<P>Most RTF control words expect lengths to be specified in <EM>twips</EM>;
others expect them to be specified in half-points.
There are 20 twips to a <EM>point</EM>, and
there are 72 points to an inch.
<P CLASS=NOTE>NOTE -- There are several definitions of a ``point'';
RTF uses the conventional DTP definition of exactly 72 points to the inch.<P>Since twips and half-points are not a very convenient way to specify lengths,
RATFINK allows you to specify dimensions in terms of other units
and converts to twips or half-points as appropriate.
<P><EM>Dimension specifications</EM> are decimal numbers,
with an optional minus sign and fractional part,
followed immediately by one of the following units:
<DL><DT>in</DT><DD>inches</DD><DT>pt</DT><DD>points (1 point = 72 inches)</DD><DT>pc</DT><DT>pica</DT><DD>picas (6 picas = 1 inch)</DD><DT>twip</DT><DD>1/20th point</DD><DT>mm</DT><DD>millimeters (but see note)</DD><DT>cm</DT><DD>centimers (but see note)</DD></DL>

<P CLASS=NOTE>NOTE -- Due to roundoff errors in converting millimeters to twips,
the metric units are unreliable.  Also, different versions of Word
seem to use <EM>different</EM> rounding conventions.
It's best to avoid <SAMP>cm</SAMP> and <SAMP>mm</SAMP> if possible.<P>For example,
<PRE>
rtf:paraStyle body "Body Text" {
    FontSize  10pt
    LineSpacing  12pt
    LeftMargin  1in
    FirstIndent  0.5in
}
</PRE>
<P>The <B>rtf:cvTwips</B> and <B>rtf:cvHalfpts</B> functions
convert dimension specifications to twips and half-points, respectively.
<PRE>
<B>rtf:cvTwips</B> <VAR>dimension</VAR>
</PRE><P>Returns the value of <VAR>dimension</VAR> in twips, rounded
to the nearest integer.
<PRE>
<B>rtf:cvHalfpts</B> <VAR>dimension</VAR>
</PRE><P>The same as <B>rtf:cvTwips</B>, but returns the value in half-points.

<H4><A NAME=FONTTBL>2.1.2 Fonts</A></H4>

<P CLASS=NOTE>NOTE -- At present, the available fonts are hard-coded and may
not be changed.<P>The available fonts are:
<DL><DT>roman</DT><DD>The default font; currently Times New Roman</DD><DT>sans</DT><DD>A sans-serif font; currently Arial</DD><DT>mono</DT><DD>A monospaced font; currently Courier New</DD></DL>


<H4><A NAME=TABSTOPS>2.1.3 Tab stops</A></H4>
<P>Every paragraph style may include its own set of tab stops.
This is specified by the <SAMP>TabStops</SAMP> 
<A HREF="#PARASTYLES">paragraph style property</A>.
<P>Tab stops are specified as a list of <EM>tabspecs</EM>; 
each <VAR>tabspec</VAR> is a list consisting of a <VAR>dimension</VAR> 
followed by any of the following property specifications:

<DL><DT>Align</DT><DD>Specifies how the text following the tab is to be aligned with
respect to this tab stop.  One of:
<SAMP>Left</SAMP>,
<SAMP>Right</SAMP>,
<SAMP>Center</SAMP>, or
<SAMP>Decimal</SAMP>.</DD><DT>Leaders</DT><DD>One of:
    <DL><DT>Dot</DT><DD>Leader dots or periods
	</DD><DT>Thick</DT><DD>Leader thick line
	</DD><DT>Underscore</DT><DD>Leader underline
	</DD><DT>Equal</DT><DD>Leader equal sign (<SAMP>=</SAMP>)
	</DD><DT>Hyphen</DT><DD>Leader hyphens (<SAMP>-</SAMP>)
    </DD></DL></DD></DL>
<P>Tab stops may also be defined with the <B>rtf:tabStops</B> command:
<PRE>
<B>rtf:tabStops</B> <VAR>name</VAR> { <VAR>tabspec</VAR> ... }
</PRE><P>Defines and assigns to <VAR>name</VAR> a set of tab stops.
<VAR>name</VAR> may be referenced by a <SAMP>TabStops</SAMP> parameter
in subsequent paragraph style definitions.
<P>For example,
<PRE>
rtf:tabStops normaltabs {
    80pt 160pt 240pt 320pt 400pt 480pt 560pt 640pt 720pt
}
rtf:tabStops threepart {
	"3in Align Center"
	"6in Align Right"
}
rtf:paraStyle header "Page header" {
    TabStops threepart
}
rtf:tabStops toctabs { "6in  Align Left  Leaders Dot" }
</PRE>
<P>The <SAMP>TabStops</SAMP> paragraph style property may not be
overridden: tab stops in a paragraph style are added to
those in the base paragraph style.

<P CLASS=NOTE>NOTE -- The RATFINK syntax for tab stops is messy and counterintuitive,
and will probably change...
<H4><A NAME=RULES>2.1.4 Rules and borders</A></H4>
<P>RATFINK predefines the rule styles
<SAMP>thin</SAMP>, <SAMP>thick</SAMP>, and <SAMP>double</SAMP>.
Additional rule and border styles may be defined with the
<B>rtf:ruleStyle</B> command.
Like <B>rtf:tabStops</B>, this defines a symbolic name for a particular
rule style that is referenced as the value of other stylesheet parameters.
<PRE>
<B>rtf:ruleStyle</B> <I>name</I> {
    <I>param</I> <I>value</I>
    ...
}
</PRE><P>Defines a rule style named <I>name</I>.  Allowable parameters are:
<DL><DT>Style</DT><DD>One of the symbols <SAMP>Normal</SAMP>, <SAMP>Thick</SAMP>, <SAMP>Double</SAMP>,
<SAMP>Shadow</SAMP>, <SAMP>Dash</SAMP>, <SAMP>Dot</SAMP>, or <SAMP>Hairline</SAMP>.
<SAMP>Thick</SAMP> specifies a double-thickness border; <SAMP>Normal</SAMP> is the default.</DD><DT>Thickness</DT><DD>Dimension: thickness of the rule</DD><DT>Margin</DT><DD>Dimension: space to leave between the rule and the text
to which the rule is attached.</DD></DL>

<P CLASS=NOTE>NOTE -- It is unclear what
the <SAMP>\brdrhair</SAMP> (<SAMP>Style Hairline</SAMP>)
control word means, since the thickness of the rule is actually determined by
the <SAMP>\brdrw</SAMP> (<SAMP>Thickness</SAMP>) control word.<P>RATFINK makes sure that all the control words are output in the
correct order.


<H3><A NAME=CHARSTYLES>2.2 Character styles</A></H3>
<P>Character styles are used for regions of text within a paragraph.
All of the character style parameters are also valid
paragraph style parameters.
<PRE>
<B>rtf:charStyle</B> <I>id</I> <I>"description"</I> <B>-basedon</B> <I>styleid</I> {
    <I>param</I> <I>value</I>
    ...
}
</PRE><P>Available parameters are:<DL><DT>Font</DT><DD>One of the symbolic font names defined in the font table;
e.g., <SAMP>roman</SAMP>, <SAMP>sans</SAMP>, or <SAMP>mono</SAMP>.
See <A HREF="#FONTTBL">2.1.2. ``Fonts''</A>.</DD><DT>FontSize</DT><DD>Dimension: height of the font.  If no units are specified,
defaults to half-points.  Does not include leading.</DD><DT>Bold</DT><DD>Boolean: if set, use bold font variant</DD><DT>Italic</DT><DD>Boolean: if set, use italic font variant.</DD><DT>AllCaps</DT><DD>Boolean: if set, folds all text to uppercase</DD><DT>SmallCaps</DT><DD>Boolean: if set, folds lowercase letters to small caps.</DD><DT>Hidden</DT><DD>Boolean: hidden text.</DD><DT>Underline</DT><DD>One of:
<DL><DT>0</DT><DT>None</DT><DD>No underline</DD><DT>1</DT><DT>Single</DT><DD>Single (continuous) underline</DD><DT>Double</DT><DD>Double underline</DD><DT>Dot</DT><DD>Dotted underline</DD><DT>Word</DT><DD>Underline words only (single underline)</DD></DL></DD></DL>
<P CLASS=NOTE>NOTE -- The ``shadow'' and ``outline'' character formatting properties
have been omitted on aesthetic grounds.
Considering how Word typically renders ``small caps,''
that should probably be avoided as well.
<P CLASS=NOTE>NOTE -- Apparently it is not possible in RTF to specify double word underline.
<H3><A NAME=PARASTYLES>2.3 Paragraph styles</A></H3>
<PRE>
<B>rtf:paraStyle</B> <I>id</I> <I>"description"</I> <B>-basedon</B> <I>styleid</I> {
    <I>param</I> <I>value</I>
    ...
}
</PRE><P>Defines a paragraph style, which may be referenced by <I>id</I>
in a later call to <B>rtf:startPara</B>.
<P>Available parameters are:

<DL><DT>LeftIndent</DT><DD>Dimension: Left margin, relative to page margin </DD><DT>RightIndent</DT><DD>Dimension: Right margin, relative to page margin</DD><DT>FirstIndent</DT><DD>Dimension: Indentation of first line, relative to <SAMP>LeftIndent</SAMP>.</DD><DT>Quadding</DT><DD>One of the symbols
<DL><DT>Left</DT><DD>Flush left, ragged right
    </DD><DT>Right</DT><DD>Flush right, ragged left
    </DD><DT>Center</DT><DD>Each line centered
    </DD><DT>Justify</DT><DD>Both margins aligned</DD></DL></DD><DT>SpaceBefore</DT><DD>Dimension: vertical whitespace inserted before the paragraph</DD><DT>SpaceAfter</DT><DD>Dimension: vertical whitespace inserted after the paragraph</DD><DT>LineSpacing</DT><DD>Dimension: minimum height of each line (including leading).
If omitted or set to zero, the font height is used.</DD><DT>TabStops</DT><DD>Reference to a set of tab stops previously defined with <SAMP>rtf:tabStops</SAMP>
(see <A HREF="#TABSTOPS">2.1.3. ``Tab stops''</A>).</DD><DT>Hyphenate</DT><DD>Boolean: enable (1) or disable (0) hyphenation for this paragraph.</DD><DT>PageBreakBefore</DT><DD>Force a page break before this paragraph</DD><DT>KeepTogether</DT><DD>Flag: disallow page breaks within this paragraph</DD><DT>KeepWithNext</DT><DD>Flag: disallow page break between this paragraph and the next one.</DD><DT>TopBorder</DT><DT>BottomBorder</DT><DT>LeftBorder</DT><DT>RightBorder</DT><DD>Argument is a <EM>rule style</EM> as described in <A HREF="#RULES">2.1.4. ``Rules and borders''</A>.
Specifies that a rule is to be drawn above, below, to the left, or
to the right of the paragraph.</DD><DT>InnerBorders</DT><DD>Flag: border specifications apply to individual paragraphs.</DD></DL>
<P>In addition, all of the character formatting style attributes
(see <A HREF="#CHARSTYLES">2.2. ``Character styles''</A>)
may be specified for a paragraph style.

<P CLASS=NOTE>TIP -- To achieve ``hanging indentation'', use a negative value
for <SAMP>FirstIndent</SAMP>.
<P CLASS=NOTE>NOTE -- If a series of successive paragraphs specify the same set of borders,
the borders are drawn around the group as a whole unless the <SAMP>InnerBorders</SAMP>
flag is specified.
<H3><A NAME=SECTSTYLES>2.4 Section styles</A></H3>
<PRE>
<B>rtf:sectStyle</B> <I>id</I> <I>"description"</I> <B>-basedon</B> <I>styleid</I> {
    <I>param</I> <I>value</I>
    ...
}
</PRE><P>Defines a section style, which may be referenced by <I>id</I>
in a later call to <B>rtf:startSection</B>.
<DL><DT>PageWidth</DT><DT>PageHeight</DT><DD>Dimensions: width and height of the page for this section.
Default taken from <A HREF="#DOCFMT">document formatting properties</A>.</DD><DT>LeftMargin</DT><DT>RightMargin</DT><DT>TopMargin</DT><DT>BottomMargin</DT><DD>Dimension: left, right, top, and bottom page margins.
Default taken from <A HREF="#DOCFMT">document formatting properties</A>.</DD><DT>Landscape</DT><DD>Flag: if set, page orientation is landscape instead of portrait
for this section.

<P CLASS=NOTE>NOTE -- It is unclear how this affects the interpretation
of the page size and margin control words.</DD><DT>HasTitlePage</DT><DD>Flag: if set, the first page of this section may use a
different header and footer than the rest of the section.
See <A HREF="#HDRFTR">3.6. ``Page headers and footers''</A>.</DD><DT>HeaderPosition</DT><DD>Dimension: Distance from the top of the page to the page header.</DD><DT>FooterPosition</DT><DD>Dimension: Distance from the botom of the page to the page footer.

<P CLASS=NOTE>NOTE -- It is unclear whether these specify distance to the
top or the bottom of the header and footer.</DD><DT>SectionBreak</DT><DD>One of the following symbols:
<DL><DT>None</DT><DD>No explicit page break before this section</DD><DT>Page</DT><DD>Section starts on a new page</DD><DT>EvenPage</DT><DD>Section starts on the next even-numbered page</DD><DT>OddPage</DT><DD>Section starts on the next odd-numbered page</DD></DL>
</DD><DT>VAlign</DT><DD>Specifies the vertical alignment of the text with 
respect to the page margins.  One of the following
symbolic values:
<DL><DT>Top</DT><DD>Ragged-bottom pages, aligned with the top margin (default).</DD><DT>Justify</DT><DD>Text is set flush-bottom.</DD><DT>Middle</DT><DD>Text is centered between the top and bottom margins.</DD><DT>Bottom</DT><DD>Text is aligned with the bottom margin.</DD></DL>
</DD><DT>PageNumbering</DT><DD>Determines the format for the <SAMP>PageNumber</SAMP> special control word
(see <A HREF="#SPECIALS">3.3. ``Special characters''</A>).
One of <SAMP>Arabic</SAMP>, <SAMP>UCRoman</SAMP>, <SAMP>LCRoman</SAMP>,
<SAMP>UCAlpha</SAMP>, or <SAMP>LCAlpha</SAMP>,
for arabic (decimal), uppercase roman numerals, lowercase roman numerals,
uppercase letters, and lowercase letters, respectively.</DD><DT>RestartPageNumbers</DT><DD>Boolean: if set, page numbering starts over at this section.</DD><DT>FirstPageNumber</DT><DD>Integer: starting page number for this section
if <SAMP>RestartPageNumbers</SAMP> is set (1).
</DD></DL>

<H3><A NAME=DOCFMT>2.5 Document-wide formatting properties</A></H3>
<P>The <B>rtf:documentFormat</B> command 
specifies formatting properties for the document as a whole.
This command is optional; the default values for these
parameters should be sufficient unless you need finer control
over the layout.
<PRE>
<B>rtf:documentFormat</B> {
    <I>param</I> <I>value</I>
    ...
}
</PRE><P>Available document formatting parameters are:

<DL><DT>PaperWidth</DT><DT>PaperHeight</DT><DD>Dimension:  specify the width and height of the paper.
Default depends on the output device;
typically US letter (8.5in by 11in).
</DD><DT>PaperSize</DT><DD>Shorthand way of specifying <SAMP>PaperWidth</SAMP> and <SAMP>PaperHeight</SAMP>.
One of the symbolic values
<SAMP>A4</SAMP>, <SAMP>A5</SAMP>, <SAMP>B5</SAMP>, <SAMP>Letter</SAMP>, <SAMP>Legal</SAMP>, or <SAMP>Executive</SAMP>.</DD><DT>LeftMargin</DT><DT>RightMargin</DT><DT>TopMargin</DT><DT>BottomMargin</DT><DD>Dimension: specifies the left, right, top, and bottom page margins.
May be overridden on a per-section basis.</DD><DT>TwoSide</DT><DD>Flag: if set, specifies two-sided format.
This affects headers and footers; see <A HREF="#HDRFTR">3.6. ``Page headers and footers''</A>.</DD><DT>MirrorMargins</DT><DD>Flag: if set, swaps the values of <SAMP>LeftMargin</SAMP> and <SAMP>RightMargin</SAMP>
on verso (even-numbered) pages.
<SAMP>MirrorMargins</SAMP> is only valid if <SAMP>TwoSide</SAMP> is set.

<P CLASS=NOTE>NOTE -- The RTF spec says only that this control word
``switches margin definitions on left and right pages,''
which is ambiguous.
By experimentation,
<SAMP>LeftMargin</SAMP> corresponds to the ``inner'' margin
and <SAMP>RightMargin</SAMP> corresponds to the ``outer'' margin,
at least in Word for Windows 95 Version 7</DD><DT>Landscape</DT><DD>Flag: if set, the entire document is set with landscape
orientation.

<P CLASS=NOTE>NOTE -- It is unclear how the top, bottom, left, and right margins
are interpreted if landscape orientation is specified.</DD><DT>Protection</DT><DD>Enables ``document protection'' for  programs which support this feature.
Allowable values are:
<DL><DT>AllProtected</DT><DD>Document may not be modified.</DD><DT>Annotations</DT><DD>Document may be annotated but not modified.</DD><DT>Revisions</DT><DD>Document may be modified, but revision tracking is enabled.</DD></DL></DD><DT>Hyphenate</DT><DD>Boolean: enables automatic hyphenation for this document.</DD><DT>HyphenationHotZone</DT><DD>Dimension: specifies the ``hyphenation hot zone,''
the distance from the right margin in which words may be hyphenated.</DD><DT>HyphenationLadderCount</DT><DD>Integer: maximum allowable number of consecutive hyphenated lines.</DD><DT>HyphenateAllCaps</DT><DD>Boolean: allow hyphenation for words consisting of all capital letters
if set.</DD></DL>
<P>See also <A HREF="#FOOTNOTES">3.7. ``Footnotes''</A>.
<H3><A NAME=MAGICSTYLES>2.6 Special style names</A></H3>
<P>Word uses the paragraph style names
<SAMP>Heading 1</SAMP>, <SAMP>Heading 2</SAMP>, etc.,
as the source text for building a table of contents.
Use these names as the description
for heading entries in the text to facilitate automatic TOC generation.
<P>Word applies the paragraph styles
<SAMP>TOC 1</SAMP>, <SAMP>TOC 2</SAMP>, etc.,
to entries in automatically-generated tables of contents.
If you include definitions for these styles in the stylesheet,
Word will use them to format the table of contents.


<H2><A NAME=RTFOUTPUT>3 RTF output commands</A></H2>
<HR>

<UL CLASS=TOC>
<LI CLASS=TOCENTRY><A HREF="#SECT5">3.1 Document structure</A>
<LI CLASS=TOCENTRY><A HREF="#SECT6">3.2 Text</A>
<LI CLASS=TOCENTRY><A HREF="#SPECIALS">3.3 Special characters</A>
<LI CLASS=TOCENTRY><A HREF="#SECT7">3.4 Miscellaneous</A>
<LI CLASS=TOCENTRY><A HREF="#DESTINATIONS">3.5 Destination groups</A>
<LI CLASS=TOCENTRY><A HREF="#HDRFTR">3.6 Page headers and footers</A>
<LI CLASS=TOCENTRY><A HREF="#FOOTNOTES">3.7 Footnotes</A>
<LI CLASS=TOCENTRY><A HREF="#BOOKMARKS">3.8 Bookmarks</A>
<LI CLASS=TOCENTRY><A HREF="#TABLES">3.9 Tables</A>
<LI CLASS=TOCENTRY><A HREF="#FIELDS">3.10 Fields</A>
</UL><HR>
<P>Call <B>rtf:start</B> after all declarations and before
writing any output.  Call <B>rtf:end</B> at the end of processing.
<PRE>
<B>rtf:start</B>
</PRE><P>Begins the top-level RTF group,
emits the style sheet and other header information,
and
sets any <A HREF="#DOCFMT">document-wide formatting properties</A>
specified by <B>rtf:documentFormat</B>. 
<PRE>
<B>rtf:end</B>
</PRE><P>Closes the top-level RTF group.
Must be called at the end of processing.

<H3><A NAME=SECT5>3.1 Document structure</A></H3>
<P>The basic unit of text in RTF is the <EM>paragraph</EM>.
In RTF, a paragraph is any block of displayed text --
including section headings, list items, and table cell entries --
not necessarily a conventional paragraph.
<PRE>
<B>rtf:startPara</B> <I>styleid</I>
# generate paragraph text...
<B>rtf:endPara</B>
</PRE><P><B>rtf:startPara</B> and <B>rtf:endPara</B> delimit the
start and end of paragraphs.
<I>styleid</I> is the name of a paragraph style defined with
<B>rtf:paraStyle</B>.
Since paragraphs do not nest, <B>rtf:endPara</B> is optional.
<PRE>
<B>rtf:startPhrase</B> <I>styleid</I>
# ...
<B>rtf:endPhrase</B>
</PRE><P>Use <B>rtf:startPhrase</B> and <B>rtf:endPhrase</B> to apply
special formatting to text within a paragraph.
<I>styleid</I> is the name of a character style defined with
<B>rtf:charStyle</B>.
<P><B>rtf:endPhrase</B> is <EM>not</EM> optional.
Phrase boundaries must not cross paragraph boundaries.
(Actually RTF doesn't care if they do, but this confuses RATFINK).
<P>RTF documents may optionally be broken into sections.<PRE>
<B>rtf:startSection</B> <I>styleid</I>
<B>rtf:endSection</B>
</PRE><P><I>styleid</I> is a section style declared with <B>rtf:startSection</B>.
Since sections do not nest in RTF, <B>rtf:endSection</B> is optional.

<H3><A NAME=SECT6>3.2 Text</A></H3>
<PRE>
<B>rtf:text</B> "<I>text</I>"
</PRE><P>Writes <I>text</I> to the output file,
escaping backslashes and braces so they are not interpreted 
as RTF markup.
<P><B>rtf:text</B> makes sure that the output is inside
a paragraph.
If not, it starts a new paragraph
and issues a warning.
<P><B>rtf:text</B> also replaces sequences of
two consecutive hyphens with an en-dash,
three hyphens with an em-dash,
two backquotes (<SAMP>`</SAMP>) with a left double quote,
and two apostrophes (<SAMP>'</SAMP>) with a right double quote.
<PRE>
<B>rtf:insert</B> <I>data</I>
</PRE><P>Inserts <I>data</I> into the current paragraph verbatim,
leaving backslashes and braces as-is.
<PRE>
<B>rtf:write</B> "<I>data</I>"
</PRE><P><B>rtf:write</B> inserts <I>data</I> into the output verbatim.
<I>data</I> may contain RTF control codes.

<P CLASS=NOTE>NOTE -- Be very careful when using <B>rtf:write</B> to 
generate RTF commands directly.
<H3><A NAME=SPECIALS>3.3 Special characters</A></H3>
<P>The <B>rtf:special</B> command inserts a special character into the
output stream, ensuring that the output is currently inside a paragraph.
<P>The global array <SAMP>rtfSpecial</SAMP> maps symbolic character names
to the corresponding RTF control words.
<PRE>
<B>rtf:special</B> <I>name</I>
<B>rtf:insert</B> $rtfSpecial(<I>name</I>)
</PRE><P><I>name</I> is one of the following symbolic names:

<DL><DT>Tab</DT><DD>``Hard'' tab</DD><DT>LineBreak</DT><DD>``Hard'' line break (carriage return)</DD><DT>EmDash</DT><DD>A wide or ``em'' dash</DD><DT>EnDash</DT><DD>A short or ``en'' dash</DD><DT>EmSpace</DT><DD>Space the width of an em dash</DD><DT>EnSpace</DT><DD>Space the width of an en dash</DD><DT>Bullet</DT><DD>Filled dot (for lists, etc.)</DD><DT>LSQuote</DT><DD>Left (opening) single quote</DD><DT>RSQuote</DT><DD>Right (closing) single quote</DD><DT>LDQuote</DT><DD>Left (opening) double quote</DD><DT>RDQuote</DT><DD>Right (closing) double quote</DD><DT>PageNumber</DT><DD>Current page number (useful in page header and footer)</DD><DT>SectionNumber</DT><DD>Current section number (not useful at all)</DD><DT>FootnoteNumber</DT><DD>Current footnote number</DD></DL>

<P CLASS=NOTE>NOTE -- The <SAMP>$rtfSpecial</SAMP> array may also be referenced in
<SAMP>prefix</SAMP> and <SAMP>suffix</SAMP> parameters in Cost specifications, for example.
<H3><A NAME=SECT7>3.4 Miscellaneous</A></H3>
<PRE>
<B>rtf:tab</B>
<B>rtf:lineBreak</B>
<B>rtf:pageBreak</B>
<B>rtf:columnBreak</B>
</PRE><P>These commands generate a ``hard'' tab, line break, page break,
and column break control word, respectively.
<B>rtf:tab</B> and <B>rtf:lineBreak</B> may only be used inside a paragraph.

<H3><A NAME=DESTINATIONS>3.5 Destination groups</A></H3>
<P>RTF <EM>destination groups</EM> are used for text that does not appear
in the main flow; e.g., page headers or footnotes.
The <B>rtf:divert</B> command starts a new destination group.
<PRE>
<B>rtf:divert</B> <I>destination</I>
# generate data for destination...
<B>rtf:undivert</B>
</PRE><P>See <A HREF="#HDRFTR">3.6. ``Page headers and footers''</A> and <A HREF="#FOOTNOTES">3.7. ``Footnotes''</A> for more information.

<H3><A NAME=HDRFTR>3.6 Page headers and footers</A></H3>
<P>Header and footer text is specified in
<A HREF="#DESTINATIONS">destination groups</A>.
There are several different destinations related to headers
and footers; which ones are applicable depend on various
document and section style properties.
<UL><LI>Header</LI><LI>Footer</LI><LI>LeftHeader</LI><LI>LeftFooter</LI><LI>RightHeader</LI><LI>RightFooter</LI><LI>FirstPageHeader</LI><LI>FirstPageFooter</LI></UL><P>The <SAMP>Header</SAMP> and <SAMP>Footer</SAMP> destination groups
specify the default header and footer, respectively.
<SAMP>LeftHeader</SAMP>, <SAMP>LeftFooter</SAMP>, <SAMP>RightHeader</SAMP> and <SAMP>RightFooter</SAMP>
specify the header and footer for left (verso) and right (recto)
pages; these are only applicable if the <SAMP>TwoSide</SAMP>
<A HREF="#DOCFMT">document formatting property</A> is set.
<SAMP>FirstPageHeader</SAMP> and <SAMP>FirstPageFooter</SAMP> specify
the header and footer for the first page of the section;
these are only applicable if the <SAMP>HasTitlePage</SAMP>
<A HREF="#SECTSTYLES">section formatting property</A> is
specified for the section.
<P>Headers and footers should be specified immediately
after the call to <B>rtf:startSection</B>.
If a particular applicable header or footer is not specified,
then it is inherited from the previous section.
<P>Headers and footers contain ordinary paragraph text.
<P>The <SAMP>PageNumber</SAMP> <A HREF="#SPECIALS">special character</A>
may be useful in headers and footers.

<H3><A NAME=FOOTNOTES>3.7 Footnotes</A></H3>
<P>Footnotes are generated with a <SAMP>Footnote</SAMP>
<A HREF="#DESTINATIONS">destination group</A>.
<PRE>
<B>rtf:special</B> FootnoteNumber
<B>rtf:divert</B> Footnote
# generate footnote text ...
<B>rtf:undivert</B>
</PRE><P>Footnotes are ``anchored'' to the character that
immediately precedes the destination group.
Use the <SAMP>FootnoteNumber</SAMP> <A HREF="#SPECIALS">special character</A>
to obtain automatically-numbered footnotes. 
<P>The following document-wide formatting properties
affect how footnotes are formatted; they may be specified
with the <B>rtf:documentFormat</B> command prior to the start of output.

<DL><DT>FootnoteNumbering</DT><DD>Format for automatic footnote numbers.
One of <SAMP>Arabic</SAMP>, <SAMP>UCRoman</SAMP>, <SAMP>LCRoman</SAMP>,
<SAMP>UCAlpha</SAMP>, or <SAMP>LCAlpha</SAMP>,
for arabic (decimal), uppercase roman numerals, lowercase roman numberals,
uppercase letters, and lowercase letters, respectively.</DD><DT>FootnoteRestart</DT><DD>One of the following:
<DL><DT>AtPage</DT><DD>Footnote numbers restart at the beginning of each page.
    </DD><DT>Continuous</DT><DD>Footnotes are numbered continuously.
    </DD><DT>AtSection</DT><DD>Footnote numbers restart at the beginning of each section.</DD></DL></DD><DT>FootnoteLocation</DT><DD>Specifies that footnotes appear other than at the end of the page.
Possible values:
<DL><DT><SAMP>EndOfSection</SAMP></DT><DD>Footnotes appear at the end of the section.
    </DD><DT><SAMP>EndOfDocument</SAMP></DT><DD>Footnotes appear at the end of the document.</DD></DL>
<P>If <SAMP>FootnoteLocation</SAMP> is not specified, footnotes appear ath
the bottom of each page.</DD><DT>FootnotePlacement</DT><DD>Specifies placement of footnotes on the page.
One of:
<DL><DT>PageBottom</DT><DD>Footnotes are placed at the bottom of the page.
    </DD><DT>BeneathText</DT><DD>Footnotes appear directly beneath the text.</DD></DL></DD></DL>

<P CLASS=NOTE>NOTE -- RTF also has ``alternate'' footnotes, used to
put both footnotes and endnotes in the document.
RATFINK does not support alternate footnotes.
<H3><A NAME=BOOKMARKS>3.8 Bookmarks</A></H3>
<P>RTF allows sections of text to be defined as a <EM>bookmark</EM>.
It is not clear from the RTF specification what this feature does;
presumably it is used by word processing software.
<PRE>
<B>rtf:startBookmark</B> <VAR>name</VAR>
<B>rtf:endBookmark</B> <VAR>name</VAR>
</PRE><P>The bookmark <VAR>name</VAR> may be any character data.
<B>rtf:startBookmark</B> must be followed by a matching
<B>rtf:endBookmark</B>; bookmarks may overlap however. 

<H3><A NAME=TABLES>3.9 Tables</A></H3>

<P CLASS=NOTE>NOTE -- Table support is still in beta.  This interface 
has not been very well tested or debugged, and is subject to change.<P>In RTF, a table is a consecutive series of rows,
each of which contains a series of cells.  
Cells contain either a series of one or more paragraphs
or inline text.
<P>RTF has no explicit control words
for the beginning and end of a table.
Instead, tables are specified as a sequence of rows.
Cell properties (sizes and rules) are specified
all at once at the beginning of each row, 
followed by the cells themselves.
<P>RATFINK makes the following simplifying assumptions:
<UL><LI>Horizontal and vertical rules always extend all the way across the table.
except where they cross spanning cells.</LI></UL>
<PRE>
<B>rtf:startTable</B>
    ( <B>-numcols</B> <I>n</I>
      | <B>-abswidths</B> "<I>w1 w2 ... wn</I>"
      | <B>-relwidths</B> "<I>w1 w2 ... wn</I>"  )
    [ <B>-width</B> <I>dimension</I> ]
    [ <B>-frame</B> <I>rulestyle</I> ]
    [ <B>-rowsep</B> <I>rulestyle</I> ]
    [ <B>-colsep</B> <I>rulestyle</I> ]
    [ <B>-align</B> (Left|Right|Center) ]

# ...
<B>rtf:endTable</B>
</PRE><P><B>rtf:startTable</B> begins a table.
Exactly one of <B>-numcols</B>, <B>-relwidths</B>, or <B>-abswidths</B>
must be specified to define the number of columns in the table.
<DL><DT><B>-numcols</B> <I>n</I></DT><DD>Specifies that the table has <I>n</I> equal-width columns.</DD><DT><B>-abswidths</B> "<I>w1 w2 ... wn</I>"</DT><DD>Specifies that the table has <I>n</I> columns,
with the specified widths, where each <VAR>w</VAR> is
a <A HREF="#DIMENSIONS">dimension</A> specification.</DD><DT><B>-relwidths</B> "<I>w1 w2 ... wn</I>"</DT><DD>Specifies that the table has <I>n</I> columns.
The width specifiers <I>w1</I> through <I>wn</I>
are integers.
Each <I>w</I> is interpreted as a relative width
and the total width of the table is proportionally divided among the
columns.</DD></DL>
<P>The other options are:
<DL><DT><B>-width</B> <I>dimension</I></DT><DD>Specifies the total width of the table.
Ignored if <B>-abswidths</B> is specified.
Default: the width of the page.
 (Actually, the default is only a guess at the page width,
since RATFINK does not currently keep track of this...) </DD><DT><B>-frame</B> <I>rulestyle</I></DT><DT><B>-rowsep</B> <I>rulestyle</I></DT><DT><B>-colsep</B> <I>rulestyle</I></DT><DD>Specifies the default outer borders,
default horizontal rules between rows,
and default vertical rules between columns.
<I>rulestyle</I> is the name of a rule style
previously defined with <B>rtf:ruleStyle</B>
(Note: <B>-frame</B> only works for the
top, left, and right table borders;
the bottom border must be re-specified on the final row.)</DD><DT><B>-align</B> (left|right|center)</DT><DD>Specifies the alignment of the table as a whole relative to the page.</DD></DL>
<PRE>
<B>rtf:startRow</B> [ <B>-colspans</B> "<I>s1 s2 ... sm</I>" ]
    [ <B>-toprule</B> <I>rulestyle</I> ]
    [ <B>-botrule</B> <I>rulestyle</I> ]
    [ <B>-colsep</B> <I>rulestyle</I> ]
    [ <B>-rowheight</B> <I>dimension</I> ]
    
# ...
<B>rtf:endRow</B>
</PRE><P><B>rtf:startRow</B> begins a new table row.
<DL><DT><B>-colspans</B> "<I>s1 s2 ... sm</I>"</DT><DD>specifies that this row contains only <I>m</I> cells;
cell <I>i</I> spans <I>si</I> columns of the table.
The sum of <I>s1</I> through <I>sm</I> must equal the total
number of table columns.</DD><DT><B>-toprule</B> <I>rulestyle</I></DT><DD>Specifies the rule above this row.
Only legal for the first row in the table.
Default: the table <B>-frame</B> option if this is the first row,
the bottom rule of the preceding row otherwise.</DD><DT><B>-botrule</B> <I>rulestyle</I></DT><DD>Specifies the rule below this row.
Default: the <I>-rowsep</I> rule style for the table.</DD><DT><B>-colsep</B> <I>rulestyle</I></DT><DD>Specifies the style of all vertical rules between cells for this row.
Default: the table <I>-colsep</I> value.</DD><DT><B>-height</B> <I>dimension</I></DT><DD>Specifies the minimum height of this row.
Default: The height of the enclosed text.</DD></DL>
<P><B>rtf:endRow</B> and <B>rtf:endCell</B> are optional.
<PRE>
<B>rtf:startCell</B> [ <B>paraStyle</B> ]
...
<B>rtf:endCell</B>
</PRE><P>Begins a new cell.  Cells can contain inline text, or 
a series of paragraphs.  <P><B>rtf:endCell</B> is optional.  It marks the end of the current cell.

<H3><A NAME=FIELDS>3.10 Fields</A></H3>
<P>A <EM>field</EM> in RTF is a hook for specifying program-specific
commands to the word processor reading the RTF file.
Fields contain two parts: a <EM>field instruction</EM>,
which is the actual command;
and an optional <EM>field result</EM>, which holds the results of processing
the field.  (The field result may be used to provide 
default text in case the application does not understand
how to process the field instruction.)<P>There are two ways to insert fields with RATFINK:<PRE>
<B>rtf:insertField</B> {<VAR>instruction</VAR>} [ "<VAR>result text...</VAR>" ]
</PRE><P>Inserts a field instruction.
<VAR>instruction</VAR> is any character data; backslashes and other
special characters will be escaped before writing to the output.
The second parameter is optional; if supplied it will be used
as the text of the field result.
<PRE>
<B>rtf:startField</B> "<VAR>field instruction</VAR>"
# ... generate field result ...
<B>rtf:endField</B>
</PRE><P>Like <B>rtf:insertField</B>, except the field result
may contain arbitrary RTF text instead of a simple character string.

<P CLASS=NOTE>NOTE -- Many field instructions have optional parameters that
are specified with sequences beginning with a backslash.
Note that these are <EM>not</EM> RTF control words
(except for <SAMP>\fldalt</SAMP>, but that's too horrifying to get into...).<P>The available field instructions vary from application to application;
check the documentation for the program in question. 

<H2><A NAME=SGMLCONV>4 SGML Conversion</A></H2>
<HR>

<UL CLASS=TOC>
<LI CLASS=TOCENTRY><A HREF="#SECT8">4.1 Generated text</A>
<LI CLASS=TOCENTRY><A HREF="#SECT9">4.2 Nested paragraphs</A>
<LI CLASS=TOCENTRY><A HREF="#SECT10">4.3 Line-specific text</A>
<LI CLASS=TOCENTRY><A HREF="#SECT11">4.4 Sections</A>
<LI CLASS=TOCENTRY><A HREF="#SECT12">4.5 Data entities</A>
<LI CLASS=TOCENTRY><A HREF="#SECT13">4.6 RATFINK architectural forms</A>
</UL><HR>
<P>The commands described in the previous section and defined
in <TT>rtflib.tcl</TT> are all general-purpose Tcl utilities for
creating RTF, and may be used independently of Cost or SGML.
The file <TT>RTF.spec</TT> is a high-level Cost script
to assist in converting SGML to RTF.  
<PRE>
<B>rtf:convert</B> <I>specname</I>
</PRE><P>To specify the processing for a particular DTD,
define a Cost <EM>specification</EM> supplying
RATFINK processing parameters for each element type,
then call the <B>rtf:convert</B> command with the name of 
your specification.
(This is in addition to 
defining a stylesheet and document formatting properties as described
<A HREF="#RTFDECLS">above</A>.)

<P CLASS=NOTE>NOTE -- A Cost specification maps document nodes to parameters
based on <EM>queries</EM>; see the Cost reference manual for full details.<P>For example:

<PRE>
specification rtfSpec {
  {element P} {
    rtf para  
    paraStyle body 
  }
  {elements "DFN EM"} {
    rtf phrase
    charStyle hp0 
  }
  {elements "UL OL"} {
    rtf #IMPLIED
  }
  {element LI} {
    rtf para
    paraStyle litem
  }
  {element LI in UL} {
    prefix {$rtfSpecial(Bullet)$rtfSpecial(Tab)}
  } 
  {element LI in OL} {
    prefix {[childNumber].$rtfSpecial(Tab)}
  }
  {element PRE} {
    rtf linespecific
    paraStyle verbatim
  }
  {element H1} { rtf para  paraStyle heading1 }
  {element H2} { rtf para  paraStyle heading2 }
  ... etc.
}

rtf:convert rtfSpec
</PRE>

<P CLASS=NOTE>TIP -- <B>rtf:convert</B> is reentrant and may be
called recursively, possibly with a different specification,
for complex processing.<P>There is one mandatory parameter for every element: <SAMP>rtf</SAMP>.
This specifies one of the following ``architectural forms'':
<DL><DT>para</DT><DD>A paragraph or other displayed block.
The required parameter <SAMP>paraStyle</SAMP> specifies the id of the paragraph
style to use for this element.</DD><DT>phrase</DT><DD>Inline text with special character formatting.
The required parameter <SAMP>charStyle</SAMP> specifies the id of the character
style to use for this element.</DD><DT>section</DT><DD>A section. The <SAMP>sectStyle</SAMP> parameter, ditto.</DD><DT>linespecific</DT><DD>A displayed block in which record-ends (newlines) are significant.</DD><DT>special</DT><DD>Special-purpose processing.
Use the parameters <SAMP>startAction</SAMP> and <SAMP>endAction</SAMP>
to specify how to process this element. 
</DD><DT>#IMPLIED</DT><DD>No special processing for this element.</DD></DL>
<P>The optional parameters <SAMP>startAction</SAMP> and <SAMP>endAction</SAMP>
are valid for every element.
They specify Tcl code to execute at the start and end of the element,
respectively.
The code is evaluated at global scope.
<P>Tcl variable- and command- replacement is performed on the
<SAMP>charStyle</SAMP>, <SAMP>paraStyle</SAMP>, and <SAMP>sectStyle</SAMP> parameters.

<P CLASS=NOTE>NOTE -- The RTF translation routine prints a warning if there is no
<SAMP>rtf</SAMP> parameter specified for an element.
<H3><A NAME=SECT8>4.1 Generated text</A></H3>
<P>The following parameters may be specified for any element node,
and may be used to specify automatically-generated text:

<DL><DT>before</DT><DD>Data to insert before processing the element</DD><DT>prefix</DT><DD>Data to insert at the beginning of the element,
after the start-of-element processing.</DD><DT>suffix</DT><DD>Data to insert at the end of the element,
before the end-of-element processing.</DD><DT>after</DT><DD>Data to insert after processing the element.</DD></DL>
<P>Tcl variable- and command- replacement is performed on these
parameters with the <B>subst</B> command.
The result is inserted directly into the output file and 
may contain RTF control words.
You should use the <B>rtf:Escape</B> command
if the value might contain data that looks like an RTF control instruction;
for example,
<PRE>
  {element IMG} {
    rtf #IMPLIED
    prefix {[rtf:Escape [q attval ALT]]}
  }
</PRE>

<H3><A NAME=SECT9>4.2 Nested paragraphs</A></H3>
<P>Paragraphs do not nest in RTF, but they do in many SGML applications.
For example, it is often legal to include
<UL><LI>bulleted lists,</LI><LI>code examples,</LI><LI>equations,</LI></UL>
and other displayed material in the middle of a paragraph.
<P>For <SAMP>para</SAMP>-form elements,
the optional <SAMP>continuedStyle</SAMP> parameter names a paragraph style
for subsequent blocks of text that are part of a logical 
paragraph in the SGML document but are treated as separate
paragraphs in RTF.


<H3><A NAME=SECT10>4.3 Line-specific text</A></H3>
<P>Normally, record-ends are converted to spaces.
If <SAMP>rtf linespecific</SAMP> is specified for an element,
then record-ends are processed as hard line breaks.
The element is formatted as a single paragraph,
and the <SAMP>paraStyle</SAMP> parameter also applies.

<H3><A NAME=SECT11>4.4 Sections</A></H3>
<P>If <SAMP>rtf section</SAMP> is specified for an element, RATFINK 
starts a new section with <B>rtf:startSection</B> at the
beginning of the element.
(It does <EM>not</EM> call <B>rtf:endSection</B> at the end of the element,
since in general sections may nest in an SGML document
while they may not in RTF; keep this in mind.)
<P>The <SAMP>startAction</SAMP> and <SAMP>endAction</SAMP> parameters are
also evaluated for section-form elements.
These parameters 
contain arbitrary Tcl code, evaluated at top-level (global) scope.
(<SAMP>startAction</SAMP> may be used to generate headers and footers,
for example.) 

<H3><A NAME=SECT12>4.5 Data entities</A></H3>
<P>The processing of data entities and data entity references
is controlled by the <SAMP>content</SAMP> parameter.
This is evaluated as Tcl code at global scope.

<PRE>
{dataent withdcn EPS} {
  content {
    rtf:insertField "INCLUDEPICTURE \"[query sysid]\"" {Picture goes here...}
  }
}
</PRE>

<H3><A NAME=SECT13>4.6 RATFINK architectural forms</A></H3>
<P>The following meta-DTD describes the basic structure
of the RATFINK output process:

<PRE>
&lt;!-- Meta-DTD for RATFINK RTF conversion --&gt;
&lt;!doctype ratfink [
&lt;!element ratfink	- - (section+|para+)&gt;
&lt;!element section 	- O (headings?, para+)&gt;
&lt;!attlist section
    sectStyle	CDATA	#REQUIRED	
&gt;
&lt;!element para		- O (#PCDATA|phrase)*&gt;
&lt;!attlist para
    paraStyle	CDATA	#REQUIRED	
&gt;
&lt;!element phrase	- - (#PCDATA)&gt;
&lt;!attlist phrase
    charStyle	CDATA	#REQUIRED
&gt;
&lt;!entity % headings "(fphead|fpfoot|head|foot|lhead|lfoot|rhead|rfoot)"&gt;
&lt;!element headings	O O ( fphead? &amp; fpfoot? &amp; 
				((head? &amp; foot?) | 
				 (lhead? &amp; lfoot? &amp; rhead? &amp; rfoot?)) ) 
&gt;
&lt;!element %headings;  - -  (para+ | (#PCDATA|phrase)*)&gt;
]&gt;
</PRE>
<P>Note that this DTD is not actually used by RATFINK; it is for
descriptive purposes only.
<P>Conceptually, the mapping from source document elements onto
architectural forms is determined by the <SAMP>rtf</SAMP> parameter,
which specifies the result element type; other parameters correspond
to result attributes.  The <SAMP>%headings;</SAMP> architectural forms
do not corrsepond to source elements; they are instead generated
by the application.

<H2><A NAME=SECT14>5 Bugs, limitations, and oddities</A></H2>
<P>There is currently no way to set formatting properties 
for a section, paragraph, or phrase without defining a stylesheet entry.
<P>Handling nested lists and other such things is more difficult
than it ought to be.
<P>RATFINK does not always output control words in the order
prescribed by the RTF syntax productions
(but neither does Microsoft Word, for what it's worth...)
<P>There is no support for pictures, drawing objects, embedded
objects, or other features.
<P CLASS=NOTE>NOTE -- I'd really like to support of bitmapped images,
but the RTF spec is extremely unhelpful on this point.<P>Does not handle context-sensitive style information very well.
For example, if the DTD allows bulleted lists inside regular
paragraphs and inside notes, and the desired formatting is to
set regular paragraphs in a roman font and notes in a
sans-serif font, then there must be distinct RTF paragraph styles
for lists inside notes and lists inside regular paragraphs.
<P>If a style overrides a parameter in its base style,
the corresponding control word will be emitted more than once.
Since the later setting takes precedence, this usually makes no difference,
but it means that ``flag'' control words cannot be turned off
if they are turned on in a base style, and that tab stops
in a base paragraph style may not be cleared.
<P>I've done my best to make sure that this library only generates
legal RTF (as far as my understanding of the specification goes),
but it is <EM>still</EM> possible in certain obscure circumstances
for the output to crash Word.
<P>RTF has control words to embed table of contents entries,
and index entries; however, there are no control words 
to <EM>build</EM> a table of contents or index.
Consequently, I haven't bothered to support these features
in RATFINK.

<P CLASS=NOTE>NOTE -- With Word for Windows 95 Version 7 you can do these things with
<A HREF="#FIELDS">field instructions</A>, so they may be useful after all.<P>RTF supports automatic numbering of lists and headings,
but not very well.  For example, if you include
a paragraph inside a list item Word resets the counter
for the next item; and if you have two numbered
lists in a row with no intervening paragraphs there is no
way to restart the list numbers at 1.
Consequently, I haven't bothered to support these features either.
<P>Many SGML applications assume an application convention
whereby multiple spaces are equivalent to a single space.
Many text formatting utilities (TeX, n/troff, Scribe, etc.)
work this way, but RTF does not: all spaces are significant.
RATFINK does not do anything to compress multiple spaces
by default; however you can do some tricks with short reference
maps to take care of this in the parser.<P>The output of RATFINK has been extensively tested with
Microsoft Word for Windows 95 Version 7, and to some
extent with Microsoft Word for Macintosh Version 5.1a.
I have no idea how well it will work, if at all,
with other word processors; chances are good that there
will be differences in other applications' interpretations 
of the specification.
<P>It takes a lot of work to get any sort of decent typography out of Word.

<H2><A NAME=SECT15>6 References and related material</A></H2>
<P>Information about Cost can be found at
<A HREF="http://www.flightlab.com/cost/">http://www.flightlab.com/cost/</A>.
<P>Another tool for converting SGML to RTF
is JADE, James Clark's amazing DSSSL engine.
See <A HREF="http://www.jclark.com/">http://www.jclark.com/</A> for details. 
This program works under Win32 and most Unix variants.
<P>The RTF format is defined
in the Application Note <TT>GC0165</TT>, available
on the Microsoft FTP server
at <A HREF="ftp://ftp.microsoft.com/Softlib/mslfiles/gc0165.exe">ftp://ftp.microsoft.com/Softlib/mslfiles/gc0165.exe</A>.

<P CLASS=NOTE>NOTE -- The 1.4 RTF spec also includes a sample RTF reader program,
but it isn't very good; Paul Dubois' RTF tools are a better bet.<P>The Microsoft material is only supplied as a self-extracting DOS executable.
If you don't have a DOS system available,
you're not <EM>completely</EM> out of luck:
the Info-ZIP project <B>UNZIP</B> utility
runs on just about every system imaginable 
and is able to unpack this format.
See <A HREF="ftp://ftp.uunet.net/pub/archiving/zip/">ftp://ftp.uunet.net/pub/archiving/zip/</A>
and elsewhere (ask Archie; it's widely mirrored).
You'll still need a copy of Microsoft Word to read
the RTF specification, though.
<P>Information about WINHELP may be found in the
Windows Help Authoring Toolkit at
<A HREF="ftp://ftp.microsoft.com/Softlib/mslfiles/what6.exe">ftp://ftp.microsoft.com/Softlib/mslfiles/what6.exe</A>,
and
the Usenet newsgroup <SAMP>comp.os.ms-windows.programmer.winhelp</SAMP>,
and its related FAQ.

<P CLASS=NOTE>WARNING -- Winhelp is not for the faint of heart or weak of stomach.
RTF is pretty messed up, but Winhelp is a complete abomination.<P>To <EM>parse</EM> RTF files,
check out Paul Dubois' excellent RTF tools
at <A HREF="http://www.primate.wisc.edu/software/RTF/">http://www.primate.wisc.edu/software/RTF/</A>.
See also rtftohtml at
<A HREF="http://www.sunpack.com/RTF/">http://www.sunpack.com/RTF/</A>.
<P>OSF's ``Rainmaker'' software can convert RTF documents to
the Rainbow SGML document type;
see <A HREF="ftp://ftp.ebt.com/pub/nv/dtd/rainbow/">ftp://ftp.ebt.com/pub/nv/dtd/rainbow/</A>

<H2><A NAME=SECT16>7 Acknowledgments</A></H2>
<P>Many thanks to Boris Tobotras for testing, bugfixes, and
enhancements.
</BODY></HTML>