BookmarkSubscribeRSS Feed
SmithCJGVSU
Obsidian | Level 7

Is it possible given an output destination (e.g. Tagsets.Rtf) and a procedure (e.g. PROC REPORT) that we can identity the style elements being used?

5 REPLIES 5
PGStats
Opal | Level 21

The report style is specified with the style= option in the ods tagsets.rtf statement. Each table is produced according to a template. Specify ODS TRACE ON; before calling the proc to see which templates are used. Then refer to

 

https://documentation.sas.com/?docsetId=odsgs&docsetTarget=n04iz137n5otuyn1ahqg2h1ogzpq.htm&docsetVe...

 

to learn how to browse the templates.

PG
SmithCJGVSU
Obsidian | Level 7

Hi @PGStats,

 

Templates are made up of style elements.  Style elements are made up of attributes.  However, certain procedures only use certain style elements.  On top of that, certain destinations, say html, will use style elements that RTF does not.  I’m curious if there is a generalized way to determine which STYLE ELEMENTS are being used for a particular Destination+Procedure combination.  This way it might be easier to pinpoint the elements a need to modify for my own style.  Something like ODS Trace functionality would be nice, but that only specifies the output object, not the style elements.

 

Thanks!

Cynthia_sas
SAS Super FREQ

Hi:

  You are correct that style templates contain style elements and that style elements define style attributes. There are a LOT of style elements, but typically, you don't need to worry about procedure specific or destination specific settings.

 

  For example, if you have  TITLE statement, then no matter what procedure you use or what destination, the SystemTitle element in the Style template will provide the style attributes as needed. If you have a visible By line, then the BYLINE element will provide the attributes for that style in the output. If you don't have a BY line, then the BYLINE element won't be called into service.

 

  I like to think of the style template as being the entire universe of possible style elements that might be needed by any SAS procedure. But in actual usage, many procedures use the same elements. For example,  one quick way to see what style elements are used by any procedure (without regard to destination) is to take advantage of an ODS HTML feature. Even if you are interested in RTF or PDF output, at least one time, run your output to ODS HTML. Then, OK, look in the browser at the output -- but THEN, go one step deeper and open the HTML file with Notepad. You can do this by explicitly opening the file with Notepad from where you saved it or some browsers allow you to right click in the HTML window and do a View Source.

 

  If I run this code -- with PROC FREQ and PROC MEANS steps:

proc sort data=sashelp.class out=class;
by age;
where age le 13;
run;

ods html path='c:\temp' file='see_style.html';
  proc freq data=class;
    by age;
    tables sex;
  run;

  proc means data=class min median mean max;
    class age;
	var height;
run;
ods html close;

  And then open the HTML file with Notepad, I see this for PROC FREQ:

style_elements_proc_freq.png

 

And I see this for PROC MEANS:

style_elements_proc_means.png

The CLASS= property in the HTML code shows you the name of the style element that is being used for this portion of the tabular output. In the above output, note how Systemtitle, Proctitle, Header, Data and Table are used in both procedures, while BYLINE is only used in the FREQ output.

 

So now, if I do this (because I like purple, pink and green):


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

proc template;
  define style mypurple;
  parent=styles.htmlblue;
  class Header /
    background =purple
	color=pink;
  class RowHeader /
    background=pink
	color=purple;
  class Byline /
    background=lightpink
	color=purple;
  class SystemTitle/
    font_size=20pt
	color=purple;
  class ProcTitle /
    background=verylightgreen
	color=darkgreen;
 end;
run;

ods html path='c:\temp' file='see_stylechange.html' style=mypurple;
  proc freq data=class;
    by age;
    tables sex;
  run;

  proc means data=class min median mean max;
    class age;
	var height;
run;
ods html close;

I can change the output from both PROC FREQ and PROC MEANS with one style template:

see_style_change.png

 

And if I use the template with different procedures like PROC TABULATE and PROC REG and ODS RTF:

tab_reg_tables_rtf.png

 

Then most of the tabular output from TABULATE and REG use the color scheme from the style. But I did not change any graphic elements, so those objects still use the original parent style colors -- only the titles come from the style template MYPURPLE:

graf_output_some_style.png

 

  To find out which graphic elements to change, you'd need to look in the ODS GRAPHICS documentation for graph elements. I covered a bit of that in my papers on templates: https://support.sas.com/resources/papers/proceedings09/227-2009.pdf and on styles: https://support.sas.com/resources/papers/proceedings10/033-2010.pdf .

 

  There are some diagnostic templates that you can use with your procedures, but they only document tabular style elements. In my paper, Tiptoe Through the Templates, I showed the style_popup diagnostic tagset on page 9 of the 2009 paper. You must be able to run JavaScript to run the code I show on page 9. But if you do, when you hover your mouse over a piece of the table, it changes color and shows the style class= info in a popup window -- cute pet tricks with templates --

style_popup.png

 

  The JavaScript comes in because if it is enabled and you double click in a highlighted area, a popup window should open that shows you all the style attributes that are being used for that style element:

popup_window.png

 

...note that the code in the window can be copied and pasted into a template for modifying. But I prefer to just read the HTML file and look for CLASS= and then just change the attributes I need to change in my new template.

 

  I am hoping that this isn't an infodump that crosses into overload territory. But it should be enough to get you started. My rule of thumb is to change one thing at a time, make sure it works and then change another thing (in the template) and make sure I didn't break any styles with the second change. Then keep going until the output is the way I want it to looks.

 

Cynthia

 

SmithCJGVSU
Obsidian | Level 7

Thanks @Cynthia_sas!

 

Definately not an info dump.  I’ve been sniffing around the PROC TEMPLATE documentation and some of your books you co-authored, ODS BASICS AND BEYOND for weeks.  This is all useful stuff, and will definitely put them to use in my diagnostic toolkit.  This will get me to where I need to go, so thanks for that.  

 

My question came about about when I saw TAGSETS.RTF has a TABLES_OFF=STYLE_ELEMENTS that sent style element information to the log.  A part of me was thinking how wonderful it would be if there was a universal way to see which elements are getting triggered for the users destination and procedure being used.  I think that’s one of the biggest disconnects with the templates is trying to figure which style element needs to be updated to impact the output.  It’s a steep learning curve, but your html trick and ODS MARKUP helps close most of that gap.  Perhaps there will be an ODS TRACE_ELEMENTS ON/OFF in the works Robot Happy in a future SAS version.

 

Thanks Again!  Your infinite wisdom on ODS is always welcomed and appreciated.

Cynthia_sas
SAS Super FREQ
Hi:
Once you start digging, you discover that most procedures use the same elements. There is more "in-depth" like containers to hold things, like a BylineContainer or SysTitleandFooterContainer but usually, if you zero in on what it is you want to change specifically, you'll find it is probably one of the ones I showed in my FREQ and MEANS examples -- TABLE, HEADER, DATA, ROWHEADER, SYSTEMTITLE, PROC TITLE and BYLINE.

The thing is that a table is a table is a table. A header is a header is a header. A note is a note is a note. A datacell .. well you get the idea. Tabular output can only have so many piece parts. No matter what procedure you use, except for PROC COMPARE, almost all other procedures use HEADER, ROWHEADER and DATA style elements. Doesn't matter the procedure, doesn't matter the destination.

So dumping style elements to the log based on a particular destination isn't attractive to me. If you want to change the header cells for ODS RTF, you change them with the same code and the same attributes as you do for ODS HTML. The only place where style templates can get a bit wonky for a particular destination has to do with borders or interior table lines in a template. Typically, when I need to change borders for one destination or another, that's when I might need a special style that is tailored to a particular destination (giving the stink eye to Excel on this one).

Good luck in your template endeavors. And I'm glad you've benefited from the book and papers.

Cynthia

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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
  • 1155 views
  • 0 likes
  • 3 in conversation