An RTF Document Index: Easier Than You Think

advertisement
NESUG 2007
Coders' Corner
An RTF Document Index: Easier Than You Think
Electra Small, MDRC, New York, NY
ABSTRACT
With the ODS (Output Delivery System) RTF destination, SAS® users build tables that are opened directly in MS
Word and other word-processing packages. A natural next step is to automate the creation of tables of contents and
indexes for documents. The table of contents (TOC) and the index provide readers with road maps to find the tables
of greatest interest to them. SAS does not yet build document indexes but there are RTF commands for building
indexes. Further, SAS provides methods for embedding RTF commands in the Rich Text Format (RTF) documents it
generates. This paper uses examples to clearly demonstrate how to mark words or phrases in SAS generated output
for inclusion in an index in a RTF destination document.
INTRODUCTION
This is the third in a series of papers that chronicles a project that utilized SAS to create a book in a completely
automated fashion. “The survey results book” had a title page, a table of contents, text and tables, and at the end a
document index. In phase 1 of the project, Proc Tabulate was used to produce nicely formatted MS Word tables that
documented the questions and responses from a telephone survey. This phase of the project was detailed in a paper
presented at NESUG 2005. Phase 2 of the project utilized SAS to add a table of contents to the results book. This
process was documented in a paper presented at NESUG 2006. The focus of this paper, Phase 3 of the project, used
SAS to construct a document index. The index created an alphabetical listing of every table or set of survey results
(e.g. age, gender, employment status) presented in the book. The title page will be the topic of a future paper.
There are currently no commands that trigger SAS to build an index at the end of the results it generates. But SAS
has methods for passing RTF commands from a SAS program into a RTF document and there are RTF commands
that can be used to trigger RTF software (such as MS Word) to build document indexes. As can be imagined, SAS
doesn’t recognize or process the RTF commands. Interspersing these RTF commands in a SAS program can cause
SAS syntax errors unless done carefully. This paper uses 5 examples to demonstrate the SAS syntax to pass RTF
commands from SAS into a RTF document. The paper focuses on how to pass RTF index building commands to
mark words or phrases in SAS generated output for inclusion in the document index. When the SAS generated RTF
document is opened in a word processor, the word processor completes the work by creating the index.
CREATING INDEXES IN MS WORD
To understand the RTF commands that must be passed from SAS to the RTF document, it is helpful to have some
background knowledge about how indexes are produced in MS Word documents. One method of creating an index is
to highlight a word or phrase (the index entry) and mark it for inclusion by pressing ALT+SHIFT+X and then clicking
“Mark.” You will notice that {XE “Marked text”} appears next to the highlighted area; these codes are RTF index entry
commands. After marking all the index entries, position the cursor where the index is to be located. From the menu,
select InsertÆReferenceÆIndex and TablesÆIndexÆOK. MS Word collects all the index entries that were marked
and places these alphabetically in the document index. This “index table” is also generated by RTF commands that
are hidden behind the document index. To view the RTF commands, press ALT+F9 (a toggle), which reveals: {INDEX
\c "2" \z "1033}. This command and parameters are detailed later. For now, note that to mark words for inclusion in
the index the {XE “Marked text”} command must be passed. To build the document index table at the end of the
document the {INDEX \c "2" \z "1033} command must be passed.
As an aside, if the SAS-generated RTF document is “post edited” (i.e., adding text or custom headers, page breaks,
tables), these modifications may change the page locations of the index entries. In MS Word to update a document
index after any document edits, press Ctrl+A (to select all) and then F9 (to update the index), selecting “entire table” if
prompted. This step is also advisable if changes are made to the page size or even printer selection.
USING SAS TO PASS RTF COMMANDS
The next step is to use SAS to pass the RTF commands into the RTF document. RTF documents are text
documents. Open an RTF document with any text editor (e.g., Notepad); RTF commands are interspersed with the
text, as shown in the left-hand column in the following table. Open this document with any RTF reader software (e.g.,
MS Word); formatted text as shown in the right-hand column is displayed.
Text with RTF control strings or commands
{I was }{\b very }{\ul happy}{ to hear}.
Text rendered in MS Word
I was very happy to hear.
1
NESUG 2007
Coders' Corner
The RTF command \b is responsible for formatting the word “very” into boldface type, and \ul causes the word “happy”
to be underlined. Note that the RTF commands (or RTF control words) are translated into formatting when such
documents are opened with RTF reader software. The focus of this paper concerns similar RTF commands that can
signal RTF readers to mark index entries and build the document index. To use a SAS program to build an automated
document with an index these steps are followed: 1) use SAS to build tables (via Proc Tabulate, Report, Freq,
Means…) 2) use ODS to send the tables to the RTF destination 3) use SAS to pass along RTF commands (that you
supply) to the RTF destination without interfering with your SAS program.
Notice in the table above {and \ are RTF evaluation triggers. These symbols don’t show in the display document they
are triggers that request evaluation by the RTF software. But the {and \ symbols could also be part of literal text that
might need to be displayed in the document. For example: TITLE “Printed from D:\Files”; The \ symbol in the text of
the Title statement should be displayed, it is not the start of an RTF control word to be evaluated by the reader
software. By default SAS signals the RTF reader software that all special characters (e.g. \ {) are to be displayed and
not evaluated. In SAS’ terms it protects special characters. To embed RTF commands in a destination document SAS
syntax must be used that signals to SAS that the text that follows is not to be protected in the destination document,
otherwise {\b very }{\ul happy} will be displayed literally as {\b very }{\ul happy} in the document.
The destination is the RTF document being created through SAS. The following command, ODS RTF
FILE="C:\Files\TEST.RTF", creates an RTF destination document, TEST.RTF, on the C: drive, in the Files directory.
There are two ways to place, or “pass,” RTF commands into the TEST.RTF document.
Pass Technique 1 utilizes the ODS ESCAPECHAR statement and escape character sequences. Similar to the macro
trigger characters (%,&), the escape character lets the SAS compiler know that what follows are RTF commands to
be passed to the destination document. First, declare an ODS escape character: ODS ESCAPECHAR=’^’;. From this
point forward, using the declared ODS escape character combined with any of the allowed escape sequence codes
causes these codes to be passed to the destination document. Escape sequence code combinations are allowed
wherever SAS allows a text string (e.g., titles, footnotes, labels, character variable values). The following example
shows an ODS escape sequence. Example: TITLE '^R/RTF"\b" Very ^R/RTF"\b0\ul" Happy';. Notice the RTF
commands are surrounded by quotes within the title quotes. This statement passes the \b, \b0 (bold off), and \ul RTF
formatting commands to the RTF document, and Very Happy becomes the title line in your output. The ^R signals
SAS that what follows is not to be protected from RTF evaluation. The /RTF signals that the text string that follows
should be passed to the RTF document only. On occasion programmer use ODS to write to two or more types of
destinations at the same time. If writing to RTF and PDF documents simultaneously the /RTF"\b" and /RTF"\b0\ul"
commands are not passed to the PDF destination document. This is important since these commands are only
understood by RTF readers. This technique uses a SAS raw text (^R) escape sequence, which is handy when only a
few control words need to be unprotected. The syntax of this technique involves nesting single and double quotes;
therefore, including any text with macro triggers or literal quote marks becomes a challenge.
Pass Technique 2 utilizes RTF control words directly. To use this technique PROTECTSPECIALCHARS=OFF must
be specified as an inline style on the proc (print, tabulate, report) or as a style attribute in a PROC TEMPLATE
statement before the proc. This tells SAS to pass special characters (<>&/{), tags, and control words to the
destination document without any translation, which allows the reader software to decide how to handle them. Once
PROTECTSPECIALCHARS is turned off RTF control words can be used in your SAS program wherever a text string
is allowed. Example: TITLE ‘\b Very \b0 \ul Happy’. This statement passes the \b,\b0, and \ul RTF formatting
commands to the RTF document, and Very Happy becomes the title line in the output. Unfortunately, SAS does not
currently have a way of setting the PROTECTSPECIALCHARS attribute to off for a whole document, instead
commands must be issued to turn this attribute to off in each area of the output where RTF control words will be used
(e.g. titles and footers, by lines, data, column headers, row headers…). Programmers who are not comfortable with
PROC TEMPLATE or in-line styles find this cumbersome.
This section reviewed the methods available for passing RTF commands from SAS to RTF destination documents.
The following sections detail the use of these concepts to build indexes in RTF documents.
MARKING INDEX ENTRIES IN SAS GENERATED OUTPUT
Here is a simple programming example using the standard SASHELP.CLASS data set. One-way tables are produced
using Proc Freq. ODS is used to create an RTF document named INDEX.RTF containing the Proc Freq output. This
is a very simple and routine programming task. However, when the one-way tables are generated they must also be
marked for inclusion in the document index. The Label statement is used just before the Proc Freq to label the
variables. Since the RTF \xe control word is included as part of the variable labels when Proc Freq displays the
variable label in the SAS generated tables the word processor will not only see the variable label it will also see an
embedded command to include the variable label when the document index is built.
2
NESUG 2007
Coders' Corner
data class; set sashelp.class;
label
Name ="^R/RTF'
Sex
="^R/RTF'
Age
="^R/RTF'
Height="^R/RTF'
Weight="^R/RTF'
{\xe
{\xe
{\xe
{\xe
{\xe
name}'"
sex}'"
age}'"
height}'"
weight}'"; run;
ods rtf file="index.rtf" notoc_data;
ods noproctitle;
ods escapechar='^';
title; run;
proc freq data=class; run;
ODS RTF startpage=now;
ods rtf text="{\pard\f2\b\fs32\qc {Index of Variable Names} \par}"; run;
/* ods rtf text="{\field{\*\fldinst {\\INDEX \\e ""
}}}" ; run; */
ods rtf close; run;
"" \\c ""4"" \\z ""1033""
Note the NOTOC_DATA option on the first ODS RTF statement. This turns off the version 9 default behavior of
including TOC information in the destination document. This option is not needed; it was included here to keep the
destination document clean and simple to understand. The NOPROCTIITLE statement on the second ODS RTF
statement is also optional (without it “The Frequency Procedure” title would be displayed before each table). This was
also included to keep the destination document clean and simple to understand.
The ODS RTF STARTPAGE=NOW statement places a hard page break after all of the tables produced by the Proc
Freq and just before the index section header we created using the ODS RTF TEXT= statement.
The RTF TEXT= is similar to a SAS Title statement. The Title statement places the specified text on the top of every
page of output until it is cancelled or replaced. With the ODS RTF TEXT= statement the text is displayed on only one
page in the place where the command is issued. Notice that RTF formatting control words are used here to format the
text. This RTF TEXT= statement generates a 16pt. (\fs32, specified in half points) centered (\qc) and bolded (\b)
section header: “Index of Variables Names.” The \pard and \par control words mark off a paragraph. The document’s
default font 2 (\f2) will be used.
If you are running SAS version 8 the last ODS RTF TEXT= statement (which has been commented out) will build the
document index. SAS changed the way the RTF TEXT= statement works in version 9 and as a result this command
no longer works. Don’t despair. First, the hardest part of building a document index is marking all of the entries. In this
example we marked the index entries as part of the variable label statement. The method of marking index entries
with the \xe control word works in version 8 and 9. As displayed in an earlier section of this paper in MS Word building
the index table at the end of the document is just a few menu keystrokes (InsertÆReferenceÆIndex and
TablesÆIndexÆOK). Secondly, there is a SAS version 9 workaround for building the index table from within a SAS
program. The workaround is a bit complicated and it is a hacker’s solution so some might not feel it is worth the
trouble. Therefore, for the time being, version 8 and 9 users should keep this line commented out and in a section
later in the paper this command will be revisited with a full discussion of its use and its version 9 workaround.
In the screen shot below a portion of the last frequency table and the document index is displayed. (Remember for
now we are marking the index entries via the SAS program but we are generating the document index at the end of
the document via MS Word commands: (InsertÆReferenceÆIndex and TablesÆIndexÆOK).
3
NESUG 2007
Coders' Corner
To view the INDEX.RTF document created by the program open it in MS Word. To view the index entry (\xe) RTF
control commands we have hidden in this document select the Show/Hide ¶ icon on the Standard toolbar.
The previous example demonstrated the use of a Label statement to mark index entries. The next programming
example demonstrates the use of a procedure option to mark index entries. This program creates two-way tables
using Proc Tabulate. The statistic requested for each of the tables is a mean. In this example instead of using the
variable label statement to mark the index entries the BOX= option of Proc Tabulate is used to pass the \xe control
word and mark each index entries. For those who know Proc Tabulate the coding of this example should be clear.
ods rtf file="index.rtf" notoc_data ;
ods noproctitle;
ods escapechar='^';
title; run;
PROC TABULATE data=sashelp.class;
var age height weight;
CLASS sex;
table age
*MEAN,sex /BOX=[label="Item 1 ^R/RTF' {\xe age}" ];
table height*MEAN,sex /BOX=[label="Item 2 ^R/RTF' {\xe height}" ];
table weight*MEAN,sex /BOX=[label="Item 3 ^R/RTF' {\xe weight}" ];
RUN; ODS RTF startpage=now;
ods rtf text="{\pard\f2\b\fs32\qc {Index of Variable Names} \par}"; run;
ods rtf close; run;
Tip: In the code above the single quote started just after the /RTF clause is not closed. The terminating quote is not
required if no standard text follows the RTF index entry command. This is a helpful tip when programmers want to
use ODS raw text escape sequences together with macro triggers that will not resolve within single quotes.
Below is a screen shot of the last Proc Tabulate table and the document index that was produced: (Remember use
MS Word commands to build the index table: (InsertÆReferenceÆIndex and TablesÆIndexÆOK).
Again to view the INDEX.RTF document created by the program open it in MS Word. To view the index entry (\xe)
RTF control commands we have hidden in this document select the Show/Hide ¶ icon on the Standard toolbar.
The third example employs the Title statement to mark index entries. In this example Proc Report is used to generate
a print of the data for each record. The records are sorted and printed by name using by-group processing and Proc
Report. Since by-group processing is used the #BYVAR and #BYVAL options on the Title statement can be used.
During by-group processing the #BYVAR options can be used to display in the SAS title the variable name(s) by
which the file is being processed. Similarly, the #BYVAL options can be used to display the current value of the by
variable(s) in the SAS title. In the following example the file is processed by name so including the #BYVAL option in
the Title statement will cause the title on the top of each page to change and display the value of name on the current
record. SAS is changing the name on each page in an automated fashion, therefore, by embedding the RTF index
entry control word (\xe) in the Title statement each time SAS generates a new title that new value of name in the title
is marked for inclusion in the document index.
4
NESUG 2007
Coders' Corner
options nocenter nobyline;
proc template ;
define style RTFCW;
parent=styles.rtf;
style data from data /protectspecialchars=off;
style header from header /protectspecialchars=off;
style rowheader from rowheader / protectspecialchars=off;
style systemtitle from systemtitle /protectspecialchars=off;
style systemfooter from systemfooter /protectspecialchars=off;
style usertext from usertext /protectspecialchars=off;
style byline from byline /protectspecialchars=off;
end; run;
ods rtf file="index.rtf" notoc_data style=rtfcw bodytitle;
ods noproctitle; run;
PROC sort data=sashelp.class out=class; by name;
PROC REPORT data=class;
column sex age height weight; by name;
title "Printing one person per page. This page is for #byvar(name)= {\xe
#byval(name)}";
RUN; title;
ODS RTF
ods rtf
\par}";
ods rtf
startpage=now;
text="{\pard\f2\b\fs32\qc {Listing of Persons Included in this Document}
run;
close; run;
Notice that NOBYLINE is specified in the option statement. SAS procedures by default document changes in by
variables and by values in the output. However, when using the Title statement to document the changes in by
variables and by values use the NOBYLINES system option to cause the procedures to suppress this default
behavior because the programming of the Title statement will document this in a more custom manner.
In this example SAS passes RTF control words directly to the destination document without using an ODS
ESCAPECHAR (e.g. ^ in previous examples). When passing ODS controls words directly without using an escape
sequence PROCTECTSPECIALCHARS must be turned to OFF. Proc Template was used to do this by creating a
new style template: RTFCW. The first ODS RTF statement references this new style (style=rtfcw) when INDEX.RTF
is opened. The BODYTITLE option is also specified, this requests that the SAS titles be included in the body of the
document not in the header section of the document. Index entries are only collected from the body of the document
so the BODYTITLE option must be specified anytime the index entry information is marked in the SAS titles.
Next a standard Proc Sort and Proc Report are used to create the printed report. One person’s data will be printed on
each page of the RTF document until every record in the dataset has been printed.
Notice that {\xe #byval} is included as part of Title statement. Each time the value of #byval changes that new value
will be marked as an index entry by the \xe control word that has been embedded in the Title statement.
Below is a screen shot of the last page of the Proc Report and a portion of the document index that was produced:
(Remember for now we are marking the index entries via the SAS program but we are generating the document index
at the end of the document via MS Word commands: (InsertÆReferenceÆIndex and TablesÆIndexÆOK).
5
NESUG 2007
Coders' Corner
The fourth example makes use of user defined formats. Proc Format’s Value statement is used to mark index entries.
This is another simple and straightforward programming task. Split the class roster into two listing, females in the
class on one listing and males on the other. A Proc Print is done by sex to create the gender based rosters. The index
is to list the page numbers of each roster. A user defined format is created that give F and M the more reader friendly
Male and Female labels. This Proc Format also includes the index entry control word along with the Male and Female
labels. Next the $fsex format that was created with Proc Format is assigned to GENDER on the Proc Print. Note that
the RTFCW style template created in the last example is also referenced here. This style template is referenced to
turn off PROTECTSPECIALCHARS in all relevant sections of the output.
proc format; value $fsex "M"="{\xe Males}" "F"="{\xe Females}";
data class; set sashelp.class;
Gender=Sex;
label Gender="Student's Gender"; run;
ods rtf file="index.rtf" notoc_data style=RTFCW;
ods noproctitle; run;
proc sort; by Gender Name;
PROC print data=class; by Gender; pageby Gender;
var Name Sex Age Height Weight; format Gender $fsex.;
Title "Reporting Class List by Gender"; RUN;
Title;
ODS RTF startpage=now;
ods rtf text="{\pard\f2\b\fs32\qc {Reports} \par}"; run;
ods rtf close; run;
Below is a screen shot of the last page of the Proc Print and the document index that was produced: (Remember for
now we are marking the index entries via the SAS program but we are generating the document index at the end of
the document via in MS Word commands: (InsertÆReferenceÆIndex and TablesÆIndexÆOK).
6
NESUG 2007
Coders' Corner
The programming segment in the previous example is tweaked slightly for our next example. The fifth and last
example provides an example of marking variable values for inclusion in the document index. Names are sometime
unisex and it might not be clear if the sought for name would be found on the female roster or the male roster.
Therefore, the page numbers of each student’s name are added to the index listing. The \xe index entry marker is
concatenated to variables values (names) using an assignment statement in the data step.
proc format; value $fsex "M"="{\xe Males}" "F"="{\xe Females}";
data class;
set sashelp.class;
Gender=Sex;
label Gender="Student's Gender";
xName="{\xe "||Name||"}";
run;
ods rtf file="index.rtf" notoc_data style=RTFCW;
ods noproctitle; run;
proc sort; by Gender Name;
PROC print data=class; by Gender; pageby Gender;
var xName Sex Age Height Weight; format Gender $fsex.;
Title "Reporting Class List by Gender"; RUN;
Title;
ODS RTF startpage=now;
ods rtf text="{\pard\f2\b\fs32\qc {Index} \par}"; run;
ods rtf close;
run;
Below is a screen shot of the last page of the Proc Print and the document index that was produced: (Remember for
now we are marking the index entries via the SAS program but we are generating the document index at the end of
the document via MS Word commands: (InsertÆReferenceÆIndex and TablesÆIndexÆOK).
7
NESUG 2007
Coders' Corner
Five examples have been given that illustrate ways to mark parts of SAS generated output for inclusion in a document
index. The Label statement, the BOX= options of Proc Tabulate, the Title statement, the format procedure, and the
data step assignment statement were all used to mark words or phrases in SAS output for inclusion in the document
index. Output from Proc Freq, Tabulate, Report, and Print were all marked in some way. These are just examples and
many more options for marking portions of SAS output are available. The key to generalizing the principles
demonstrated here to other SAS output situations is the understanding of how to use SAS to pass the RTF index
entry control word (\xe) to the destination document. In the examples above RTF control words were passed using
ODS raw text escape sequences. Direct RTF controls words were also passed after turning
PROTECTSPECIALCHARS=OFF. The RTF TEXT statement was also used to pass control words. This was
demonstrated in the way we used the RTF TEXT statement and direct RTF control words to place a formatted header
or title just before each index table. The next section will discuss the use of the RTF TEXT statement to pass the
\index control word to build the index table.
GENERATING THE DOCUMENT INDEX
The document index is really a dynamic table that is generated by MS Word. It needs to be dynamic because if a
page break is added, the paper size is changed, or a word that had been marked for inclusion in the index is deleted
then the table that MS Word created will need to be regenerated or updated to reflect these changes. To issue a RTF
command via SAS to build the dynamic index the following command in version 8 will work:
ods rtf text="{\field{\*\fldinst {\\INDEX \\e ""
"" \\c ""4"" \\z ""1033"" }}}" ;
run;
The \index control word is a field code control word. MS Word has field codes like date, file name, and time. Field
code controls are dynamic. The values of field codes can change; therefore, the use of these controls requires
execution and if conditions change these commands must be re-executed. The \e “” parameter specifies that the
words in the index and the page numbers in the index should be separated by blanks. The parameter \c “4” specifies
that the index table should have 4 columns. The \z “1033” parameter specifies that the index should be built in
English.
Having included this command in the SAS program the next step is to open the generated RTF document in MS
Word. Go to the end of the document (or to the place in the document where the above command was issued). No
table will be visible in the document. The command to build the table is embedded in the document (you can see the
embedded command by toggling ATL+F9) but the command must be executed. Press Ctrl+A (to select all) and then
F9 (to buld/update the index), selecting “entire table” if prompted. Because the index table is build dynamically by
using the whole of the document settings at the point when the command is executed this step must always be taken.
There is no way to automate this step. Further, if any changes are made after “executing” the table the steps should
be repeated to rebuild the table. So it might be asked what steps does issuing
ods rtf text="{\field{\*\fldinst {\\INDEX \\e ""
"" \\c ""4"" \\z ""1033"" }}}" ;
run;
save the user? When you issue the above command via SAS the user does not have to select the following from the
MS Word menu: InsertÆReferenceÆIndex and TablesÆIndexÆOK.
Why doesn’t passing the \index control word work in version 9? In version 8 the text of a RTF TEXT= command is
placed in a paragraph in the destination document. In version 9 the text of a RTF TEXT= command is placed in a
table in the destination document. The \index command is a field code that builds a table dynamically so it can’t be
8
NESUG 2007
Coders' Corner
placed inside of another table. MS Word interprets this as a dynamic table being executed within a static table and
this generates an error. There is a version 9 workaround that first closes the static table that SAS opened and then
issues the \index field command:
ODS RTF startpage=now;
ods rtf text="{\pard\f2\b\fs32\qc {Index of Variable Names}
\par\cell}{\row}\pard{\field{\*\fldinst {\\INDEX \\e ""
"" \\c ""4"" \\z ""1033""
}}}\par\trowd\trgaph180\cellx1440\pard\intbl{}"; run;
This is admittedly a hacker’s solution and may not be worth the bother of placing this tedious and somewhat foreign
code into a SAS program. It is included in the paper because some readers will feel comfortable with it. Programmers
who are familiar with advanced RTF commands won’t find it foreign coding. In later releases of version 9 SAS has
promised that there will be way to do this via custom tagsets. But RTF tagsets are not fully functional in version 9.1.3.
CONCLUSION
Regardless of which method you use, there are three steps that must be taken to build an index in a RTF document.
First, throughout the document intersperse the text (words, phrases, etc.) that will eventually become entries in the
index. Next, as these words are added throughout the document, they must also be marked with codes that indicate
that this is the text that should become a part of the index. Third, create the index.
The paper demonstrated the automating of this process using SAS. This was done by passing the RTF index entry
control word (\xe) along with other SAS text strings in the example programs. In this way SAS allows users to embed
RTF commands along with other text in SAS programs. Any where in a SAS program where you can specify a literal
text string (e.g., titles, footnotes, labels, text variable values) you can embed the RTF index entry control word (\xe)
that would mark that text string for inclusion in the document index. Once text strings have been marked for inclusion
in the index, next an index table must be built. This can be done using the menu in MS Word or by passing RTF
commands (\index) using the ODS RTF TEXT statement. In either case you populate and update the index when you
open the RTF document by pressing Ctrl-A+F9.
REFERENCES
SAS Live Web Training Class: Advanced Output Delivery System Topics Course.
Support.sas.com FAQ on proc template and ODS:
http://support.sas.com/faq/040/FAQ04018.html TOC via \R/RTF"\s1 "
RTF specification information:
http://msdn.microsoft.com/library/?url=/library/en-us/dnrtfspec/html/rtfspec.asp
http://www.oreilly.com/catalog/rtfpg/ Resource guidebook for sale
Microsoft’s TOC and Index tutorials:
http://office.microsoft.com/training/training.aspx?AssetID=RC011356771033
http://office.microsoft.com/training/training.aspx?AssetID=RC011525811033
Papers:
How to Do Horrible Things with Raw RTF Specifications and the SAS RTF ODA,
http://support.sas.com/rnd/papers/sugi27/rtfoda.pdf
Skinning the Cat This Way and That: Using ODS to Create Word Documents that Work for You, Elizabeth
Axelrod, David Shamlin, http://www2.sas.com/proceedings/sugi29/084-29.pdf
Markup 101: Markup Basics, Cynthia Zender, http://support.sas.com/rnd/papers/sugi29/markupbasics.pdf
Applying Microsoft Word Styles to ODS RTF, Output Lauren Haworth,
http://www2.sas.com/proceedings/sugi30/043-30.pdf
9
NESUG 2007
Coders' Corner
ACKNOWLEDGMENTS
Cynthia Zender, Chevell Parker, Paulette Staum, Wayne Hester, and Eric Gebhart all helped by answering questions,
providing information, reviewing the paper, recommending resources, and/or proofreading.
CONTACT INFORMATION
Electra Small
Senior Technical Associate II
MDRC
212-340-8824 (Direct)
16 East 34th Street, 19th Floor
New York, NY 10016
Electra.Small@mdrc.org
SAS and all other SAS Institute Inc. product or service names are registered trademarks or trademarks of SAS
Institute Inc. in the USA and other countries. ® indicates USA registration.
Other brand and product names are trademarks of their respective companies.
10
Download