The SAS Output Delivery System and reporting techniques

TEMPLATE: mapping attribute names to procedures

Accepted Solution Solved
Reply
Frequent Contributor
Posts: 83
Accepted Solution

TEMPLATE: mapping attribute names to procedures

I can obtain the Style elements and their attributes for the Style default Pearl:

 

   class fonts /
      'TitleFont2' = ("<MTsans-serif>, Albany",10pt,bold)
      'TitleFont' = ("<MTsans-serif>, Albany",11pt,bold)
      'StrongFont' = ("<MTsans-serif>, Albany",8pt,bold)
      'EmphasisFont' = ("<MTsans-serif>, Albany",8pt,italic)
      'FixedEmphasisFont' = ("<MTmonospace>, Courier",7pt)
      'FixedStrongFont' = ("<MTmonospace>, Courier",7pt,bold)
      'FixedHeadingFont' = ("<MTmonospace>, Courier",7pt,bold)
      'BatchFixedFont' = ("SAS Monospace, <MTmonospace>, Courier",6pt)
      'FixedFont' = ("<MTmonospace>, Courier",7pt)
      'headingEmphasisFont' = ("<MTsans-serif>, Albany",9pt,bold italic)
      'headingFont' = ("<MTsans-serif>, Albany",8pt,bold)
      'docFont' = ("<MTsans-serif>, Albany",8pt);

 

SI demonstratres the appearance:

http://support.sas.com/documentation/cdl/en/odsug/67921/HTML/default/viewer.htm#odsugwhatsnew93.htm
New Default Style for Printer Family Destinations

 

and the code to run it oneself is:

 

http://support.sas.com/documentation/cdl/en/odsgs/65323/HTML/default/viewer.htm#n1e7xvouhnvlc2n1oaxm...
(First TABULATE procedure).

 

The tip for the style-attribute-specification(s) for both the the CLASS and SYTLE statements states:

Tip
If style-attribute-name refers to a user-defined attribute, then enclose the name in quotation marks. If style-attribute-name refers to an attribute that is listed in “Style Attributes Tables ” on page 473, then do not enclose the name in quotation marks.

 

It would appear that the default Pearl uses user-defined attributes, based on the presence of the quotation marks and the absences of these names from the list in the documentation.


How can I link the style attributes to the various procedures, like REPORT or PRINT, that might use them?  For instance, both TITLE1 and TITLE2 appear to be controlled by 'TitleFont', as does a FOOTNOTE1, if one experiments by adding this statement.

It would be great to obtain the "raw" code for the procudure that "names" the attributes or a graphic with the elements being the attribute names above.  For instance, what if I what the first title (TITLE1) to be Bold, but not the other titles or footnotes?  I experimented and obtain 9 pt font as I desired, but what if another element not present in the experiment appears in my production code with a different size/family because I did not specify it?


Thank you,

Kevin


Accepted Solutions
Solution
‎09-13-2016 08:52 AM
SAS Super FREQ
Posts: 8,866

Re: TEMPLATE: mapping attribute names to procedures

[ Edited ]
Posted in reply to KevinViel

Hi:
Please look at pages 10 and 11 of this paper: https://support.sas.com/resources/papers/proceedings10/033-2010.pdf for the example of Figure 7, which shows how you can change SystemTitle1 style element, SystemTitle2 style element and SystemTitle3 style element to have different characteristics. By default, these are all defined to inherit their attributes from TitlesandFooters, -- well the way it was defined in BASE.TEMPLATE.STYLES is that SystemTitle1 inherits from TitlesandFooters and SystemTitle2 inherits from SystemTitle1 and SystemTitle3 inherits from SystemTitle2, etc -- which means that indirectly, they all inherit from TitlesandFooters -- but if you want to make a change in them all, then you only need to change SystemTitle1 for the change to cascade down.

But if you want to change the title strings directly, then instead of using the FONT table, do your change directly in the style element. That is the way I prefer to work. The level of attribute nesting that you find for colors and fonts sometimes makes me crazy and I find it easier to just go to the style elements directly instead of messing with the font and color tables.

And, in our Report Writing 1 class, we talk about which style elements impact which pieces of the PRINT, TABULATE and REPORT procedures. Focusing on the SystemTitle is not specific to any of those procedures.

And, if all you want to do is impact SAS Title and Footnote statements, they have always been able to be impacted by code like this, no matter which procedure you were using, as long as your destination supported style changes (without using ODS ESCAPECHAR):
title c=green h=16pt bold 'My Title';
title2 c=purple h=12pt bold j=l 'Left Justified';
title3 c=red h=10pt bold j=r 'Right Justified';

For PRINT, REPORT and TABULATE, there are not many style elements you have to worry about. The ones they use in common are:
Header
RowHeader
Data

and then:
NoteContent (if you have lines in PROC REPORT)
UserText (if you use ODS TEXT statements)

PRINT, for example, has a way to change OBS and OBSHEADER that is independent of the STYLE template:
proc print data=sashelp.class
style(obs)={color=red font_weight=bold}
style(obsheader)={color=purple font_weight=bold};

Some procedures that support BY group processing and produce a BYLINE will also support the BYLINE and BylineContainer style elements. They also inherit from TitlesandFooters -- but again, not specific to PRINT, REPORT and TABULATE.

In the other paper that I referenced in a different track, https://support.sas.com/resources/papers/proceedings09/227-2009.pdf on pages 9, 10 and 11, there is an example of using tagsets.style_popup to show you exactly what attributes are being used by which portion of the procedure -- no matter which procedure you are using -- so, for example, one time, you use TAGSETS.STYLE_POPUP and then, assuming that your browser supports popup windows and JavaScript, you should be able to click on an area of the procedure output and get a popup window that shows the style attributes being used.

You said that it would be great to obtain the "raw" code for the procedure. That is sort of hard. Depending on your procedure of choice and your destination of choice, the TABLE template (if there is one) is bound to the data values created by the procedure and then the STYLE information from the active style template and any STYLE overrides is added to the output object before it is sent forward to the destination. That is how the TITLE statement used with ODS HTML is coded appropriately in HTML tags vs how the TITLE statement with ODS RTF is coded appropriately in RTF control strings. So I'm not sure what "raw" code you're looking for, but it seems unlikely to me that style templates and procedures work the way you envision.

To do what you asked for:
"For instance, what if I what the first title (TITLE1) to be Bold, but not the other titles or footnotes? " is fairly simple, you know there can only be 10 titles and 10 footnotes. So if you really want to control this, then you only need to code each of the style elements the way you want. The challenge comes in deploying your template so that you are not the only person who has access to it. Someone without access to your template will not see the same changes when they use your code.

I think I have an example that illustrates the point, based on the Style template paper that I referenced first.

cynthia

 

Here's the code:

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

proc template;
  define style styles.dotitle;
  parent=styles.pearl;
      class SystemTitle from TitlesAndFooters /
           font_size=30pt; 
      class SystemTitle2 from SystemTitle  /
           font_size=28pt;                                    
      class SystemTitle3 from SystemTitle2  /
           font_size=26pt;                                 
      class SystemTitle4 from SystemTitle3  /
           font_size=24pt;                               
      class SystemTitle5 from SystemTitle4  /
           font_size=22pt;                                 
      class SystemTitle6 from SystemTitle5  /
           font_size=20pt;                                 
      class SystemTitle7 from SystemTitle6 /
           font_size=18pt;                              
      class SystemTitle8 from SystemTitle7  /
           font_size=16pt;                               
      class SystemTitle9 from SystemTitle8 /
           font_size=14pt;                                
      class SystemTitle10 from SystemTitle9 /
           font_size=12pt;                                 
      class SystemFooter from TitlesAndFooters /
           font_size=12pt;                                
      class SystemFooter2 from SystemFooter /
           font_size=14pt;                                   
      class SystemFooter3 from SystemFooter2  /
           font_size=16pt;                             
      class SystemFooter4 from SystemFooter3  /
           font_size=18pt;                             
      class SystemFooter5 from SystemFooter4  /
           font_size=20pt;                             
      class SystemFooter6 from SystemFooter5  /
           font_size=22pt;                             
      class SystemFooter7 from SystemFooter6 /
           font_size=24pt;                          
      class SystemFooter8 from SystemFooter7  /
           font_size=26pt;                            
      class SystemFooter9 from SystemFooter8 /
           font_size=28pt;                            
      class SystemFooter10 from SystemFooter9 /
           font_size=30pt;  
end;
run; 

ods html file='c:\temp\showtitle.html' style=styles.dotitle;
ods pdf file='c:\temp\showtitle.pdf' style=styles.dotitle;
ods rtf file='c:\temp\showtitle.rtf' style=styles.dotitle;


title1 'My title 1';
title2 'My title 2';
title3 'My title 3';
title4 'My title 4';
title5 'My title 5';
title6 'My title 6';
title7 'My title 7';
title8 'My title 8';
title9 'My title 9';
title10 'My title 10';
footnote1 'My footnote 1';
footnote2 'My footnote 2';
footnote3 'My footnote 3';
footnote4 'My footnote 4';
footnote5 'My footnote 5';
footnote6 'My footnote 6';
footnote7 'My footnote 7';
footnote8 'My footnote 8';
footnote9 'My footnote 9';
footnote10 'My footnote 10';
proc print data=sashelp.class(obs=1);
run;

ods _all_ close;

and the results (as you can tell, I am a big fan of the opening credits of Star Wars):

show_title.png

View solution in original post


All Replies
Occasional Contributor
Posts: 18

Re: TEMPLATE: mapping attribute names to procedures

Posted in reply to KevinViel

I would suggest looking at some of the ods escapechar options so you can control the different attributes of the titles and footnotes that you want to use if it is different then what the style has. The escapechar is very handy when you want to bold a certain title or you want to justify a footnote. Here is a paper that I have found to go back to quite a bit to look at the different options.
http://www2.sas.com/proceedings/forum2007/099-2007.pdf

 

Here is what the SAS documentation says about escapechar:

http://support.sas.com/documentation/cdl/en/odsug/61723/HTML/default/viewer.htm#a002233270.htm

Solution
‎09-13-2016 08:52 AM
SAS Super FREQ
Posts: 8,866

Re: TEMPLATE: mapping attribute names to procedures

[ Edited ]
Posted in reply to KevinViel

Hi:
Please look at pages 10 and 11 of this paper: https://support.sas.com/resources/papers/proceedings10/033-2010.pdf for the example of Figure 7, which shows how you can change SystemTitle1 style element, SystemTitle2 style element and SystemTitle3 style element to have different characteristics. By default, these are all defined to inherit their attributes from TitlesandFooters, -- well the way it was defined in BASE.TEMPLATE.STYLES is that SystemTitle1 inherits from TitlesandFooters and SystemTitle2 inherits from SystemTitle1 and SystemTitle3 inherits from SystemTitle2, etc -- which means that indirectly, they all inherit from TitlesandFooters -- but if you want to make a change in them all, then you only need to change SystemTitle1 for the change to cascade down.

But if you want to change the title strings directly, then instead of using the FONT table, do your change directly in the style element. That is the way I prefer to work. The level of attribute nesting that you find for colors and fonts sometimes makes me crazy and I find it easier to just go to the style elements directly instead of messing with the font and color tables.

And, in our Report Writing 1 class, we talk about which style elements impact which pieces of the PRINT, TABULATE and REPORT procedures. Focusing on the SystemTitle is not specific to any of those procedures.

And, if all you want to do is impact SAS Title and Footnote statements, they have always been able to be impacted by code like this, no matter which procedure you were using, as long as your destination supported style changes (without using ODS ESCAPECHAR):
title c=green h=16pt bold 'My Title';
title2 c=purple h=12pt bold j=l 'Left Justified';
title3 c=red h=10pt bold j=r 'Right Justified';

For PRINT, REPORT and TABULATE, there are not many style elements you have to worry about. The ones they use in common are:
Header
RowHeader
Data

and then:
NoteContent (if you have lines in PROC REPORT)
UserText (if you use ODS TEXT statements)

PRINT, for example, has a way to change OBS and OBSHEADER that is independent of the STYLE template:
proc print data=sashelp.class
style(obs)={color=red font_weight=bold}
style(obsheader)={color=purple font_weight=bold};

Some procedures that support BY group processing and produce a BYLINE will also support the BYLINE and BylineContainer style elements. They also inherit from TitlesandFooters -- but again, not specific to PRINT, REPORT and TABULATE.

In the other paper that I referenced in a different track, https://support.sas.com/resources/papers/proceedings09/227-2009.pdf on pages 9, 10 and 11, there is an example of using tagsets.style_popup to show you exactly what attributes are being used by which portion of the procedure -- no matter which procedure you are using -- so, for example, one time, you use TAGSETS.STYLE_POPUP and then, assuming that your browser supports popup windows and JavaScript, you should be able to click on an area of the procedure output and get a popup window that shows the style attributes being used.

You said that it would be great to obtain the "raw" code for the procedure. That is sort of hard. Depending on your procedure of choice and your destination of choice, the TABLE template (if there is one) is bound to the data values created by the procedure and then the STYLE information from the active style template and any STYLE overrides is added to the output object before it is sent forward to the destination. That is how the TITLE statement used with ODS HTML is coded appropriately in HTML tags vs how the TITLE statement with ODS RTF is coded appropriately in RTF control strings. So I'm not sure what "raw" code you're looking for, but it seems unlikely to me that style templates and procedures work the way you envision.

To do what you asked for:
"For instance, what if I what the first title (TITLE1) to be Bold, but not the other titles or footnotes? " is fairly simple, you know there can only be 10 titles and 10 footnotes. So if you really want to control this, then you only need to code each of the style elements the way you want. The challenge comes in deploying your template so that you are not the only person who has access to it. Someone without access to your template will not see the same changes when they use your code.

I think I have an example that illustrates the point, based on the Style template paper that I referenced first.

cynthia

 

Here's the code:

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

proc template;
  define style styles.dotitle;
  parent=styles.pearl;
      class SystemTitle from TitlesAndFooters /
           font_size=30pt; 
      class SystemTitle2 from SystemTitle  /
           font_size=28pt;                                    
      class SystemTitle3 from SystemTitle2  /
           font_size=26pt;                                 
      class SystemTitle4 from SystemTitle3  /
           font_size=24pt;                               
      class SystemTitle5 from SystemTitle4  /
           font_size=22pt;                                 
      class SystemTitle6 from SystemTitle5  /
           font_size=20pt;                                 
      class SystemTitle7 from SystemTitle6 /
           font_size=18pt;                              
      class SystemTitle8 from SystemTitle7  /
           font_size=16pt;                               
      class SystemTitle9 from SystemTitle8 /
           font_size=14pt;                                
      class SystemTitle10 from SystemTitle9 /
           font_size=12pt;                                 
      class SystemFooter from TitlesAndFooters /
           font_size=12pt;                                
      class SystemFooter2 from SystemFooter /
           font_size=14pt;                                   
      class SystemFooter3 from SystemFooter2  /
           font_size=16pt;                             
      class SystemFooter4 from SystemFooter3  /
           font_size=18pt;                             
      class SystemFooter5 from SystemFooter4  /
           font_size=20pt;                             
      class SystemFooter6 from SystemFooter5  /
           font_size=22pt;                             
      class SystemFooter7 from SystemFooter6 /
           font_size=24pt;                          
      class SystemFooter8 from SystemFooter7  /
           font_size=26pt;                            
      class SystemFooter9 from SystemFooter8 /
           font_size=28pt;                            
      class SystemFooter10 from SystemFooter9 /
           font_size=30pt;  
end;
run; 

ods html file='c:\temp\showtitle.html' style=styles.dotitle;
ods pdf file='c:\temp\showtitle.pdf' style=styles.dotitle;
ods rtf file='c:\temp\showtitle.rtf' style=styles.dotitle;


title1 'My title 1';
title2 'My title 2';
title3 'My title 3';
title4 'My title 4';
title5 'My title 5';
title6 'My title 6';
title7 'My title 7';
title8 'My title 8';
title9 'My title 9';
title10 'My title 10';
footnote1 'My footnote 1';
footnote2 'My footnote 2';
footnote3 'My footnote 3';
footnote4 'My footnote 4';
footnote5 'My footnote 5';
footnote6 'My footnote 6';
footnote7 'My footnote 7';
footnote8 'My footnote 8';
footnote9 'My footnote 9';
footnote10 'My footnote 10';
proc print data=sashelp.class(obs=1);
run;

ods _all_ close;

and the results (as you can tell, I am a big fan of the opening credits of Star Wars):

show_title.png

Frequent Contributor
Posts: 83

Re: TEMPLATE: mapping attribute names to procedures

Posted in reply to Cynthia_sas

I may have missed it, but if I gather correctly some style is the base or master.  That could be styles.default.  So if I submitted:

 

proc template ;

  edit styles.default ;

    class fonts

        / "TitleFont"           = ( "Times New Roman PSMT" , 10pt )

          "TitleFont2"          = ( "Times New Roman PSMT" , 10pt )

          "StrongFont"          = ( "Times New Roman PSMT" , 10pt , bold )

          "EmphasisFont"        = ( "Times New Roman PSMT" , 9pt , italic )

          "FixedEmphasisFont"   = ( "Courier New" , 9pt )

          "FixedStrongFont"     = ( "Courier New" , 9pt , bold )

          "FixedHeadingFont"    = ( "Courier New" , 9pt , bold )

          "BatchFixedFont"      = ( "Courier New" , 9pt )

          "FixedFont"           = ( "Courier New" , 9pt )

          "headingEmphasisFont" = ( "Times New Roman PSMT" , 9pt , bold italic )

          "headingFont"         = ( "Times New Roman PSMT" , 9pt , bold )

          "docFont"             = ( "Times New Roman PSMT" , 9pt )

          ;

  end ;

run ;

 

EXCEPT that a style like Pearl also has a similar class statement.  Yet, I created a user-defined style using Pearl as the parent, then used an ODS PDF statement with a STYLE= option and the PDF document still has a non-defined font family, namely Thorndale, for items like the PAGENO and the GLM headers (including row):

 

Class Level Information

 

I would be quite shocked if I had to identify EVERY template using TRACE to make a change:

 

STAT.GLM.ClassLevels

STAT.GLM.NObsTitle

Stat.GLM.ExpectedMeanSquares

stat.GLM.Estimates

stat.GLM.FitStatistics

stat.GLM.LSMeans

stat.GLM.OverallANOVA

stat.GLM.Tests

 

especially since I have no idea what procedures my programmers might need.

 

Given that the FDA guidance stipulates 9-12pt font of Arial or Times New Roman, I am more surprised than I thought I would be trying to find a working solution.

 

Thank you,

 

Kevin

SAS Super FREQ
Posts: 8,866

Re: TEMPLATE: mapping attribute names to procedures

Posted in reply to KevinViel

Hi:
  There is ONE "master" template that defines the inheritance path for each style element. That is BASE.TEMPLATE.STYLE. And, Styles.DEFAULT is the default or implicit parent for most of the style template. If there is a style element that is NOT in STYLES.DEFAULT you should find it in BASE.TEMPLATE.STYLE.

  If you change STYLES.DEFAULT and make your own copy (as you do in your code), then you have ONLY changed STYLES.DEFAULT. You have NOT changed STYLES.PEARL or any of the other templates that inherit from STYLES.DEFAULT. The changes you make to STYLES.DEFAULT will not be reflected or used in STYLES.PEARL.

  Rather than use the Edit statement to make your own copy of STYLES.DEFAULT it would be better to make a new template, as you tried to do initially (something called STYLES.FDA) that inherits from STYLES.PEARL (if Pearl is the style you want to have as your "base".

  I do not observe what you observe. When I make a template that is based on Pearl and change the fonts, I see that the RowHeader uses Times New Roman (I don't have a font named Times New Roman PSMT -- so I used simple "Times New Roman" for my example.

But I am confused because you listed SAS/STAT TABLE templates as procedures to look up, which are NOT the same as STYLE templates. Typically TABLE templates, if they refer to any style at all, will ONLY refer to a STYLE element name whose values come from the style template. And, since you can request the same procedure using different styles, that is what allows STYLES.ANALYSIS output to look different from STYLES.PEARL output.

And, there's really no need to look at the TABLE templates because, for example, if you look at the TABLE template STAT.GLM.ESTIMATES, you will only find one reference to STYLE, as in STYLE=RowHeader -- which does not contain any colors or fonts or style information. It merely instructs the TABLE template to use the RowHeader style information from whatever style template is used for the destination of interest.

  When you say that "Yet, I created a user-defined style using Pearl as the parent, then used an ODS PDF statement with a STYLE= option and the PDF document still has a non-defined font family, namely Thorndale, for items like the PAGENO and the GLM headers (including row)"

  The PAGENO style element is defined this way in STYLES.DEFAULT:
      class PageNo /                                                          
         verticalalign = top                                                  
         textalign = right                                                    
         borderspacing = 0                                                    
         cellpadding = 0                                                      
         font = fonts('strongFont');

so you should be seeing your value of 'strongFont' used for the Page number (As long as you did NOT change the PageNo style element in your new template, then whatever you define for strongFont should be used.) If it is not, then you will want to open a track with Tech Support.

When I ran my test (not using the EDIT statement and NOT using the PSMT name for Times New Roman), I did get Courier New used for the page number as far as I can tell. I do see that the Cumberland AMT font was automatically embedded in the PDF properties. I don't know why -- this is a question for Tech Support.

cynthia

Frequent Contributor
Posts: 83

Re: TEMPLATE: mapping attribute names to procedures

Posted in reply to Cynthia_sas

Cynthia,

 

 You cited the issue correctly: '...uses Times New Roman (I don't have a font named Times New Roman PSMT -- so I used simple "Times New Roman" for my example.'

 

  I realized that when I used the Arial style, that I did not have the page numbers in Thorndale.  So I made a temporary change to:


"TitleFont"           = ( "Times New Roman"   , 10pt )

 

and it worked as expected.  Even the table headers from GLM were in TNR.  I had obtained the "official" PDF name from Acrobat Distiller and I thought I confirmed it with a web search, but that was 12 hours ago...

 

Thank you for your effort and patience.

 

Have a good evening,

 

Kevin

☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 5 replies
  • 577 views
  • 3 likes
  • 3 in conversation