ODS and Base Reporting

Build reports by using ODS to create HTML, PDF, RTF, Excel, text reports and more!
BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Natalie
Calcite | Level 5

Hi everyone,

I was trying out the line formatting in ODS RTF with ESCPECHAR and RTF control words ( \tab, \i, etc).

I'm very new on working with ODS RTF and started with few basics, but unfortunately the result does not look good:

a) using ESCAPECHAR - worked!

ODS RTF TEXT="Learning ESCAPECHAR: x superscript 2 is x^{SUPER 2}";

b) using RTF control words - worked!

ODS RTF TEXT="{Learning ESCAPECHAR:} \tab {\i this text appears after TAB}";

c) doing combination of both - did not work

ODS RTF TEXT="{Learning ESCAPECHAR:} \tab  {x superscript 2 is x^{SUPER 2}}";

Does anyone have an idea, what is wrong with case c)?

Thank you!

SAS-Code:

ODS LISTING CLOSE;

ODS RTF FILE="C:\Test.rtf";

ODS ESCAPECHAR="^";

   ODS RTF TEXT="Learning ESCAPECHAR: x superscript 2 is x^{SUPER 2}";

   ODS RTF TEXT="{Learning ESCAPECHAR:} \tab {\i this text appears after TAB}";

   ODS RTF TEXT="{Learning ESCAPECHAR:} \tab  {x superscript 2 is x^{SUPER 2}}";

ODS RTF CLOSE;

RTF-Output

Learning ESCAPECHAR: x superscript 2 is x2

Learning ESCAPECHAR:           this text appears after TAB

{Learning ESCAPECHAR:} \tab  {x superscript 2 is x2}

1 ACCEPTED SOLUTION

Accepted Solutions
Cynthia_sas
SAS Super FREQ

Hi:

  Actually, you are learning 2 different and separate things:

1) ODS ESCAPECHAR which is composed of 2 parts and works with destinations like HTML, RTF and PDF:

    1a: declaring your escape character in an ODS ESCAPECHAR statement

    1b: using your escape character with other functions and controls to perform in-line formatting (examples of ODS ESCAPECHAR controls and functions are ESCAPECHAR+{super} or ESCAPECHAR+{thispage}. If ODS ESCAPECHAR were declared to be ^ then ^{super 2} would use ODS to put a superscript 2 into the HTML, RTF or PDF document

and

2) RTF control strings -- this is NOT part of ODS -- the RTF control strings use the backslash \ as the command character or control character. Sometimes { and } are used to surround text a command like \tab\i has nothing to do with ODS and would be ignored in your output by PDF or HTML destinations. In \tab\i the \ is the control character and 'tab' or 'i' is the formatting command or control word. The unit \tab\i has nothing to do with ODS and nothing to do with ODS ESCAPECHAR and is an pure RTF control string or control group. RTF control strings are just a different way to perform in-line formatting. There are some RTF-specific controls (like \tab or \highlight) that you cannot do with ODS ESCAPECHAR.

The thing that both #1 and #2 have in common is the use of the curly braces. For ODS ESCAPECHAR, the curly braces are required and in some instances (such as STYLE= override options), you can substitute square brackets [ ] for curly braces. But with ODS ESCAPECHAR in-line formatting, you must use curly braces. For ODS ESCAPECHAR, the escape character gets ODS attention in order to alter the formatting of what follows the ESCAPECHAR special character.

When you use RTF control words or control strings like \tab, \i, \b, \super in your ODS steps, you generally have to also turn the style attribute PROTECTSPECIALCHARS=OFF because otherwise, SAS and ODS might try to "protect" the backslash character. In the same fashion, if you were using pure HTML tags in your HTML step, you would need to turn protection off for any < or > that surrounded HTML tags in your code.

I am not entirely clear on the use of { and } in the RTF spec. I tend to use them sparingly. Generally, I find they work best for me, when I use them to enclose text which I want to format with RTF control strings. In the code below, for example, I have this:

title2 'This is the title {\super 2} \nosuper{with superscript in the middle}';

ODS RTF TEXT="3 Learning ESCAPECHAR: \tab x superscript 2 is x^{SUPER 2}";

ODS RTF TEXT="\b{4 }\i{Learning ESCAPECHAR:}\i0\b0\tab{x superscript 2 is x}\super 2";

   

The TITLE statement and #4 RTF TEXT= statement use pure RTF control strings. No ODS ESCAPECHAR was used in either of those statements. in the screen shot of the output, you will see that the 4 and 'Learning ESCAPECHAR' are both bold, but 'Learning ESCAPECHAR' is also italic. Really, #4 is Learning RTF control strings and NOT learning ESCAPECHAR.

On the other hand, #3 RTF TEXT= statement uses a combo of RTF control words (in pink) and ODS ESCAPECHAR (in blue). While it might work on and off to not set PROTECTSPECIALCHARS=OFF, I find that it is unreliable to skip this setting. Any time I am using pure RTF control strings or pure HTML tags, I always turn PROTECTSPECIALCHARS=OFF as a best practice. So in my code, you will see that I have a style template step for this. In my PROC REPORT code, I have used an RTF control string in the column header for NAME. Note how I use PROTECTSPECIALCHARS in the STYLE= option -- the \highlight3 is an RTF control string that turns on the cyan highlight to my text string for NAME variable header. Look at the header for HEIGHT, on the other hand, without PROTECTSPECIALCHARS=OFF, the \highlight2 just gets passed to the RTF document, because ODS tried to "protect" the backslash for you.

  

After running the code, I got the results shown in the attached screenshot. Here's a paper that talks about just using pure RTF control strings:

http://www.nesug.org/Proceedings/nesug10/po/po40.pdf  Then, here are a few papers that talk about using ODS ESCAPECHAR - -there was a slightly  different syntax for 9.0/9.1 versus 9.2/9.3 for ODS ESCAPECHAR. These papers show both ways and generally, the earlier method will still work in later versions of SAS:

http://support.sas.com/resources/papers/proceedings10/215-2010.pdf

http://www.nesug.org/proceedings/nesug08/np/np10.pdf

http://www2.sas.com/proceedings/forum2007/099-2007.pdf

http://www2.sas.com/proceedings/sugi31/227-31.pdf

A description of the RTF spec is here (on the Microsoft site): http://msdn.microsoft.com/en-us/library/Aa140277 (remember that RTF is a Microsoft description of a document that can be opened in an RTF reader -- generally, a word processing application).

The R&D/Tech Support notes about ODS RTF and ESCAPECHAR is here:

http://support.sas.com/rnd/base/ods/templateFAQ/Template_rtf.html#escapechar

Hope this helps.

cynthia

    

ODS LISTING CLOSE;
ods path work.tmp(update) sasuser.templat(update)
         sashelp.tmplmst(read);

** one way to turn PROTECTSPECIALCHARS=OFF is a style template;
proc template;
  define style styles.rtf_text;
  parent=styles.rtf;
  class usertext /
    protectspecialchars=off;
  class systemtitle /
    protectspecialchars=off;
  end;
run;

   

ODS RTF FILE='C:\temp\Testx.rtf' style=styles.rtf_text;
ODS ESCAPECHAR='^';

   proc report data=sashelp.class(obs=2) nowd;

     title 'This is the title with superscript\super 2';

     title2 'This is the title {\super 2} \nosuper{with superscript in the middle}';

     title3 'the backslash is an RTF control word and NOT ODS ESCAPECHAR';

     columns name sex age height weight;

     define name / '\highlight3{The Name}'

            style(header)={protectspecialchars=off}

     define height / '\highlight2{Height}';

   run;

            
   ODS RTF TEXT='1 Learning ESCAPECHAR: x superscript 2 is x^{SUPER 2}';
   ODS RTF TEXT="2 Learning ESCAPECHAR: \tab\i this text appears after TAB";
   ODS RTF TEXT="3 Learning ESCAPECHAR: \tab x superscript 2 is x^{SUPER 2}";
   ODS RTF TEXT="\b{4 }\i{Learning ESCAPECHAR:}\i0\b0\tab{x superscript 2 is x}\super 2";
ODS RTF CLOSE;


undefined

View solution in original post

5 REPLIES 5
Cynthia_sas
SAS Super FREQ

Hi:

  Actually, you are learning 2 different and separate things:

1) ODS ESCAPECHAR which is composed of 2 parts and works with destinations like HTML, RTF and PDF:

    1a: declaring your escape character in an ODS ESCAPECHAR statement

    1b: using your escape character with other functions and controls to perform in-line formatting (examples of ODS ESCAPECHAR controls and functions are ESCAPECHAR+{super} or ESCAPECHAR+{thispage}. If ODS ESCAPECHAR were declared to be ^ then ^{super 2} would use ODS to put a superscript 2 into the HTML, RTF or PDF document

and

2) RTF control strings -- this is NOT part of ODS -- the RTF control strings use the backslash \ as the command character or control character. Sometimes { and } are used to surround text a command like \tab\i has nothing to do with ODS and would be ignored in your output by PDF or HTML destinations. In \tab\i the \ is the control character and 'tab' or 'i' is the formatting command or control word. The unit \tab\i has nothing to do with ODS and nothing to do with ODS ESCAPECHAR and is an pure RTF control string or control group. RTF control strings are just a different way to perform in-line formatting. There are some RTF-specific controls (like \tab or \highlight) that you cannot do with ODS ESCAPECHAR.

The thing that both #1 and #2 have in common is the use of the curly braces. For ODS ESCAPECHAR, the curly braces are required and in some instances (such as STYLE= override options), you can substitute square brackets [ ] for curly braces. But with ODS ESCAPECHAR in-line formatting, you must use curly braces. For ODS ESCAPECHAR, the escape character gets ODS attention in order to alter the formatting of what follows the ESCAPECHAR special character.

When you use RTF control words or control strings like \tab, \i, \b, \super in your ODS steps, you generally have to also turn the style attribute PROTECTSPECIALCHARS=OFF because otherwise, SAS and ODS might try to "protect" the backslash character. In the same fashion, if you were using pure HTML tags in your HTML step, you would need to turn protection off for any < or > that surrounded HTML tags in your code.

I am not entirely clear on the use of { and } in the RTF spec. I tend to use them sparingly. Generally, I find they work best for me, when I use them to enclose text which I want to format with RTF control strings. In the code below, for example, I have this:

title2 'This is the title {\super 2} \nosuper{with superscript in the middle}';

ODS RTF TEXT="3 Learning ESCAPECHAR: \tab x superscript 2 is x^{SUPER 2}";

ODS RTF TEXT="\b{4 }\i{Learning ESCAPECHAR:}\i0\b0\tab{x superscript 2 is x}\super 2";

   

The TITLE statement and #4 RTF TEXT= statement use pure RTF control strings. No ODS ESCAPECHAR was used in either of those statements. in the screen shot of the output, you will see that the 4 and 'Learning ESCAPECHAR' are both bold, but 'Learning ESCAPECHAR' is also italic. Really, #4 is Learning RTF control strings and NOT learning ESCAPECHAR.

On the other hand, #3 RTF TEXT= statement uses a combo of RTF control words (in pink) and ODS ESCAPECHAR (in blue). While it might work on and off to not set PROTECTSPECIALCHARS=OFF, I find that it is unreliable to skip this setting. Any time I am using pure RTF control strings or pure HTML tags, I always turn PROTECTSPECIALCHARS=OFF as a best practice. So in my code, you will see that I have a style template step for this. In my PROC REPORT code, I have used an RTF control string in the column header for NAME. Note how I use PROTECTSPECIALCHARS in the STYLE= option -- the \highlight3 is an RTF control string that turns on the cyan highlight to my text string for NAME variable header. Look at the header for HEIGHT, on the other hand, without PROTECTSPECIALCHARS=OFF, the \highlight2 just gets passed to the RTF document, because ODS tried to "protect" the backslash for you.

  

After running the code, I got the results shown in the attached screenshot. Here's a paper that talks about just using pure RTF control strings:

http://www.nesug.org/Proceedings/nesug10/po/po40.pdf  Then, here are a few papers that talk about using ODS ESCAPECHAR - -there was a slightly  different syntax for 9.0/9.1 versus 9.2/9.3 for ODS ESCAPECHAR. These papers show both ways and generally, the earlier method will still work in later versions of SAS:

http://support.sas.com/resources/papers/proceedings10/215-2010.pdf

http://www.nesug.org/proceedings/nesug08/np/np10.pdf

http://www2.sas.com/proceedings/forum2007/099-2007.pdf

http://www2.sas.com/proceedings/sugi31/227-31.pdf

A description of the RTF spec is here (on the Microsoft site): http://msdn.microsoft.com/en-us/library/Aa140277 (remember that RTF is a Microsoft description of a document that can be opened in an RTF reader -- generally, a word processing application).

The R&D/Tech Support notes about ODS RTF and ESCAPECHAR is here:

http://support.sas.com/rnd/base/ods/templateFAQ/Template_rtf.html#escapechar

Hope this helps.

cynthia

    

ODS LISTING CLOSE;
ods path work.tmp(update) sasuser.templat(update)
         sashelp.tmplmst(read);

** one way to turn PROTECTSPECIALCHARS=OFF is a style template;
proc template;
  define style styles.rtf_text;
  parent=styles.rtf;
  class usertext /
    protectspecialchars=off;
  class systemtitle /
    protectspecialchars=off;
  end;
run;

   

ODS RTF FILE='C:\temp\Testx.rtf' style=styles.rtf_text;
ODS ESCAPECHAR='^';

   proc report data=sashelp.class(obs=2) nowd;

     title 'This is the title with superscript\super 2';

     title2 'This is the title {\super 2} \nosuper{with superscript in the middle}';

     title3 'the backslash is an RTF control word and NOT ODS ESCAPECHAR';

     columns name sex age height weight;

     define name / '\highlight3{The Name}'

            style(header)={protectspecialchars=off}

     define height / '\highlight2{Height}';

   run;

            
   ODS RTF TEXT='1 Learning ESCAPECHAR: x superscript 2 is x^{SUPER 2}';
   ODS RTF TEXT="2 Learning ESCAPECHAR: \tab\i this text appears after TAB";
   ODS RTF TEXT="3 Learning ESCAPECHAR: \tab x superscript 2 is x^{SUPER 2}";
   ODS RTF TEXT="\b{4 }\i{Learning ESCAPECHAR:}\i0\b0\tab{x superscript 2 is x}\super 2";
ODS RTF CLOSE;


undefined
Natalie
Calcite | Level 5

Dear Synthia,

thank you very much for your reply. 

I recently joined the community and I was amazed, how quickly I got the reply for my post.

Your detailed explanation was very helpful, I tried few things out, it's working Smiley Happy

I was looking for papers myself, thank you for including the good ones in your e-mail.

Natalie

Duong
Obsidian | Level 7

Hi Natalie

This is a topic I see people asked again and again because SAS Institute have not document this properly.

A few years ago I spent quite a bit of time experimenting this and have documented my findings

in this paper  http://www.lexjansen.com/phuse/2007/po/po06.pdf  I believe it is complete.

With this topic I think you'll need to understand its fundamentals otherwise you will keep coming up with

questions - why works here and not there etc. If you go through the paper above thoroughly hopefully you

won't have these issue again.

Regards

Duong

Natalie
Calcite | Level 5

Hi Duong,

thank you very much for sharing your paper!

In the beginning I was very confused indeed, where to put brakets, when to set ESCAPECHAR, PROTECTSPECIALCHARS etc.? And as you mentioned, it is not documented properly (and in one place), so I struggled a lot.

Now went through your paper and it's very helpful!  It explains the basic concept, exactly what I was looking for.  Thanks again!

Natalie

ballardw
Super User

Natalie;

Also you can get different results when using ODS RTF and ODS TAGSETS.RTF, at least with 9.2.0 and 9.2.3.

sas-innovate-white.png

Our biggest data and AI event of the year.

Don’t miss the livestream kicking off May 7. It’s free. It’s easy. And it’s the best seat in the house.

Join us virtually with our complimentary SAS Innovate Digital Pass. Watch live or on-demand in multiple languages, with translations available to help you get the most out of every session.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 5 replies
  • 9365 views
  • 5 likes
  • 4 in conversation