PROC TEMPLATE features:
DEFINE TAGSET statement
DEFINE EVENT statement
PUT statement
Tagset attribute:
PARENT= attribute
Other ODS features:
ODS PATH statement
ODS MARKUP statement
This example defines a new tagset name TAGSET.MYTAGS that creates customized HTML output. The new tagset is created through inheritance. Most of the required formatting is available in the tagset TAGSETS. CHTML that SAS supplies .
Define a new tagset. The DEFINE TAGSET statement creates a new tagset definition called tagsets.mytags . The PARENT= attribute is used in order for the new tagset tagsets.mytags to inherit events from TAGSETS.CHTML. Note that the ODS PATH statement is specified at the beginning to establish the search path.
ods path sasuser.templat (update) sashelp.tmplmst (read); proc template; define tagset tagsets.mytags /store=sasuser.templat; parent=tagsets.chtml;
Define three events. The DEFINE EVENT statements create three events called colspecs, table, and system_title . The colspecs event specifies text. The table event specifies tags to include in the definition. The system_title event deletes titles.
define event colspecs; put "These are my new colspecs" nl; end; define event table; put "<p>" nl "<table>"; finish: put "</table>"; end; define event system_title; end;
End the tagset definition. This END statement ends the tagset definition. The RUN statement executes the PROC TEMPLATE step.
end; run;
Specify the user -defined tagset. The following code tells ODS to use the user-defined tagset TAGSETS.MYTAGS as the tagset definition for the output.
ods tagsets.mytags body='custom-tagset-filename.html';
Print the data set. PROC PRINT creates the report. ODS writes the report to the body file.
proc print data=sashelp.class; run;
Stop the creation of the tagset definition. The ODS TAGSET. MYTAGS CLOSE statement closes the MARKUP destination and all the files that are associated with it. You must close the destination before you can view the output with a browser.
ods tagsets.mytags close;
To see the customized CHTML tags, view the source from your web browser:
These are my new colspecs |
Obs | Name | Sex | Age | Hight | Weight |
---|---|---|---|---|---|
1 | Alfred | M | 14 | 69.0 | 112.5 |
2 | Alice | F | 13 | 56.5 | 84.0 |
3 | Barbera | F | 13 | 65.3 | 98.0 |
4 | Carol | F | 14 | 62.8 | 102.5 |
5 | Henry | M | 14 | 63.5 | 102.5 |
6 | James | M | 12 | 57.3 | 83.0 |
7 | Jane | F | 12 | 59.8 | 84.5 |
8 | Janet | F | 15 | 62.5 | 112.5 |
9 | Jeffrey | M | 13 | 62.5 | 84.0 |
10 | John | M | 12 | 59.0 | 99.5 |
11 | Joyce | F | 11 | 51.3 | 50.5 |
12 | Judy | F | 14 | 64.3 | 90.0 |
13 | Louise | F | 12 | 56.3 | 77.0 |
14 | Mary | F | 15 | 66.5 | 112.0 |
15 | Philip | M | 16 | 72.0 | 150.0 |
16 | Robert | M | 12 | 64.8 | 128.0 |
17 | Ronald | M | 15 | 67.0 | 133.0 |
18 | Thomas | M | 11 | 57.5 | 85.0 |
19 | William | M | 15 | 66.5 | 112.0 |
Use the tagset TAGSETS.CHTML that is provided by SAS. To compare the output from TAGSETS.MYTAGS to the TAGSETS.CHTML that is supplied by SAS, the following ODS code specifies the SAS tagset. Note that you can specify any tagset by using TYPE= in an ODS MARKUP statement.
ods markup type=tagsets.chtml body='default-tagset-filename.html'; proc print data=sashelp.class; run; ods markup close;
To see the default CHTML tags, view the source from your web browser:
|
The SAS System | |||||
---|---|---|---|---|---|
Obs | Name | Sex | Age | Hight | Weight |
1 | Alfred | M | 14 | 69.0 | 112.5 |
2 | Alice | F | 13 | 56.5 | 84.0 |
3 | Barbera | F | 13 | 65.3 | 98.0 |
4 | Carol | F | 14 | 62.8 | 102.5 |
5 | Henry | M | 14 | 63.5 | 102.5 |
6 | James | M | 12 | 57.3 | 83.0 |
7 | Jane | F | 12 | 59.8 | 84.5 |
8 | Janet | F | 15 | 62.5 | 112.5 |
9 | Jeffrey | M | 13 | 62.5 | 84.0 |
10 | John | M | 12 | 59.0 | 99.5 |
11 | Joyce | F | 11 | 51.3 | 50.5 |
12 | Judy | F | 14 | 64.3 | 90.0 |
13 | Louise | F | 12 | 56.3 | 77.0 |
14 | Mary | F | 15 | 66.5 | 112.0 |
15 | Philip | M | 16 | 72.0 | 150.0 |
16 | Robert | M | 12 | 64.8 | 128.0 |
17 | Ronald | M | 15 | 67.0 | 133.0 |
18 | Thomas | M | 11 | 57.5 | 85.0 |
19 | William | M | 15 | 66.5 | 112.0 |
PROC TEMPLATE features:
SOURCE statement
DEFINE TAGSET
DEFINE EVENT
This example copies the source for a tagset which SAS supplies, modifies the definition, then builds a new tagset definition for custom output. To create a new tagset, you can use the SOURCE statement in PROC TEMPLATE to copy a tagset's source. Then you can customize the definition as needed.
Copy the SAS tagset to an external file. The following statements copy the tagset definition source from the SAS tagset TAGSETS.CSV to the SAS log.
proc template; source tagsets.csv; run;
This is the default CSV tagset definition that SAS supplies.
define tagset Tagsets.Csv; notes "This is the CSV definition"; define event put_value; put VALUE; end; define event put_value_cr; put VALUE NL; end; define event table; finish: put NL; end; define event row; finish: put NL; end; define event header; start: put "," /if ^cmp( COLSTART, "1"); put """"; put VALUE; finish: put """"; end; define event data; start: put "," /if ^cmp( COLSTART, "1"); put """"; put VALUE; finish: put """"; end; define event colspanfill; put ","; end; define event rowspanfill; put "," /if ^exists( VALUE); end; define event breakline; put NL; end; define event splitline; put NL; end; registered_tm = "(r)"; trademark = "(tm)"; copyright = "(c)"; output_type = "csv"; stacked_columns = OFF; end;
Create your new customized tagset. Submit the following PROC TEMPLATE code to create your new customized tagset tagsets.mycsv . The DEFINE EVENT TABLE statement adds two blank lines to the output file by using the PUT NL statements. One blank line is placed before the table and the other is placed after the table.
define tagset Tagsets.mycsv; notes "This is the My CSV definition"; define event table; start: put nl; finish: put nl; end; define event put_value;
put VALUE; end; define event put_value_cr; put VALUE NL; end; define event row; finish: put NL; end; define event header; start: put "," /if ^cmp( COLSTART, "1"); put """"; put VALUE; finish: put """"; end; define event data; start: put "," /if ^cmp( COLSTART, "1"); put """"; put VALUE; finish: put """"; end; define event colspanfill; put ","; end; define event rowspanfill; put "," /if ^exists( VALUE); end; define event breakline; put NL; end; define event splitline; put NL; end; registered_tm = "(r)"; trademark = "(tm)"; copyright = "(c)"; output_type = "csv"; stacked_columns = OFF; end;
To view the customized CSV Tagsets.mycsv,submit the following code:
proc template; source tagsets.mycsv; run;
proc template; define tagset Tagsets.Mycsv / store = SASUSER.TEMPLAT; notes "This is the My CSV definition"; define event table; start: put NL; finish: put NL; end; define event put_value; put VALUE; end; define event put_value_cr; put VALUE NL; end; define event row; finish: put NL; end; define event header; start: put "," /if ^cmp( COLSTART, "1"); put """"; put VALUE; finish: put """"; end; define event data; start: put "," /if ^cmp( COLSTART, "1"); put """"; put VALUE; finish: put """"; end; define event colspanfill; put ","; end; define event rowspanfill; put "," /if ^exists( VALUE); end; define event breakline; put NL; end; define event splitline; put NL; end; output_type = "csv"; copyright = "(c)"; trademark = "(tm)"; registered_tm = "(r)"; stacked_columns = OFF; end; run;
PROC TEMPLATE features:
DEFINE TAGSET statement
NOTES statement
DEFINE EVENT statement
NDENT statement
PUT statement
TRIGGER statement
XDENT statement
Tagset Attributes:
DEFAULT_EVENT attribute
INDENT= attribute
OUTPUT_TYPE attribute
MAP= attribute
MAPSUB= attribute
NOBREAKSPACE= attribute
SPLIT= attribute
STACKED_COLUMNS= attribute
This example shows a new tagset definition that does not inherit events from another tagset definition. This is a customized tagset definition for specific PROC FREQ output.
Create the new tagset Tagsets.newloc . The DEFINE TAGSET statement creates a new tagset Tagsets.newloc and specifies where you want to store the tagset.
proc template; define tagset Tagsets.newloc / store = SASUSER.TEMPLAT; notes "This is the Location Report Definition";
Define seven events. The seven DEFINE statements create the events named basic, doc, system_title, header, data, country, and frequency .
define event basic; end; define event doc; start: put "" nl nl; put "" nl; put "" nl; put "" nl; ndent; finish: xdent;
put nl; put ""; end; define event system_title; put ""; put VALUE; put ""; put nl nl; end; define event header; start: trigger country /if cmp(LABEL, "EmpCountry"); end; define event data; start: trigger frequency /if cmp(name, "Frequency"); end; define event country; put "" nl ; ndent ; put "" ; put VALUE ; put "" nl ; end; define event frequency; put "" ; put VALUE ; put "" nl ; xdent ; put "" nl ; end; output_type = "xml"; default_event = "basic"; indent = 2; split = ""; nobreakspace = " "; mapsub = "/</>/&/"; map = "<>&"; stacked_columns=off; end; run;
proc template; define tagset Tagsets.Newloc / store = SASUSER.TEMPLAT; notes "This is the Location Report Definition"; define event basic; end; define event doc; start: put "" NL NL; put "" NL; put "" NL; put "" NL; ndent; finish: xdent; put NL; put ""; end; define event system_title; put ""; put VALUE; put ""; put NL NL; end; define event header; start: trigger country /if cmp( LABEL, "EmpCountry"); end; define event data; start: trigger frequency /if cmp( name, "Frequency"); end; define event country; put "" NL; ndent; put ""; put VALUE; put "" NL; end; define event frequency; put ""; put VALUE; put "" NL; xdent; put "" NL; end; map = %nrstr("<>&"); mapsub = %nrstr("//&/"); nobreakspace = " "; split = ""; indent = 2; default_event = "basic"; output_type = "xml"; stacked_columns = OFF; end; run;
PROC TEMPLATE features:
DEFINE TAGSET statement
DEFINE EVENT statement
PUT statement
TRIGGER statement
Other ODS features:
ODS directory.tagset-name statement
This example illustrates how to execute events.
Execute different events. The TRIGGER statement executes another event. For example, the start section of DOC triggers the start section of MYTEST and OTHEREVENTA. MYTEST has a start section, so output is generated. OTHEREVENTA is stateless (no start or finish sections), but output is generated.
proc template; define tagset tagsets.mytagset; define event doc; start: put "start of doc" nl; trigger mytest; trigger otherevent; finish: trigger mytest; put "finish of doc" nl; trigger mytest start; trigger otherevent; trigger mytest finish; end; define event mytest; start: put "start of mytest" nl; finish: put "finish of mytest" nl; end; define event otherevent; put "This is my other event" nl; end; end; run; ods tagsets.mytagset file='custom-tagset-filename.txt'; ods tagsets.mytagset close;
To view the output tagsets.mytagset , open the file in a text editor.
start of doc start of mytest This is my other event finish of mytest finish of doc start of mytest This is my other event finish of mytest
PROC TEMPLATE features:
DEFINE TAGSET statement
DEFINE EVENT statement
PUT statement
NDENT statement
TRIGGER statement
XDENT statement
TAGSET attributes:
INDENT= attribute
Other ODS features:
ODS directory.tagset-name statement
This example illustrates how to indent your output using a tagset.
Note: When you view a file with an extension of .xml in an XML-compliant browser, any indention in the file is ignored by the browser in favor of its own indention algorithm.
Set your beginning indention level and then proceed to increment your indention levels. The INDENT= tagset definition attribute determines how much the NDENT and XDENT event statements indent output.
proc template; define tagset tagsets.mytagset2; indent = 4; define event doc; start: put "start of doc" nl; ndent; trigger mytest; trigger otherevent; finish: trigger mytest; xdent; put "finish of doc" nl; trigger mytest start; trigger otherevent; trigger mytest finish; end; define event mytest; start: put "start of mytest" nl; ndent; finish: xdent; put "finish of mytest" nl; end; define event otherevent; put "This is my other event" nl; end; end; run; ods tagsets.mytagset2 file='custom-tagset-filename.txt'; ods tagsets.mytagset2 close;
start of doc start of mytest This is my other event finish of mytest finish of doc start of mytest This is my other event finish of mytest
PROC TEMPLATE features:
DEFINE EVENT statement
PUT statement
TRIGGER statement
Event attribute:
STYLE= attribute
This example shows you how to use different styles for events.
Specify the event definitions. The following event definitions are from the SAS tagset TAGSETS.HTMLCSS, and they show how ODS creates notes. By defining the Gnote event and setting the proper style in the right place, ODS creates a two-cell table that has a banner using the appropriate banner style and a content cell that has the appropriate content style.
define event Gnote; start: put "<div>"; trigger align; put ">"; put "<table>"; put "<tr>" nl; finish: put "</tr>" nl; put "</table>" nl;
put "</div>"; end; define event GBanner; put "" nl; trigger pre_post; put "" nl; end; define event GNContent; put ""; trigger pre_post start; put VALUE; trigger pre_post finish; put ""; end; define event noteBanner; style="NoteBanner"; trigger GBanner; end; define event NoteContent; style="NoteContent"; trigger GNContent; end; define event note; trigger Gnote start; trigger noteBanner; trigger noteContent; trigger Gnote finish; end; define event WarnBanner; style="WarnBanner"; trigger GBanner; end; define event WarnContent; style="WarnContent"; trigger GNContent; end; define event Warning; trigger Gnote start; trigger WarnBanner; trigger WarnContent; trigger Gnote finish; end;
PROC TEMPLATE features:
DEFINE EVENT statement
PUTQ statement
The following program provides some example code that you can use to link previously created stylesheet to an event that you define.
Define an event that links to a stylesheet. This code shows you how to define an event that creates a link to a previously created stylesheet instead of the SAS generated stylesheet.
define event stylesheet_link; putq '<link rel= "STYLESHEET" type="text/css" href=' URL '>' nl / if exists(url); putq '<link rel= "STYLESHEET" type="text/css" href="http://your/stylesheet/url/goes/here">' nl; putq '<link rel= "STYLESHEET" type="text/css" href="http://your/stylesheet/url/goes/here">' nl; end;
PROC TEMPLATE features:
DEFINE TAGSET statement
DEFINE EVENT statement
PUT statement
NOTES statement
Tagset attributes:
OUTPUT_TYPE= attribute
PARENT= attribute
STACKED_COLUMNS= attribute
Other ODS features:
ODS directory.tagset-name statement
ODS directory.tagset-name CLOSE statement
Data set: GRAIN_PRODUCTION'' on page 97
This example creates a customized tagset tagset.semisv which inherits attributes from the CSV tagset that SAS provides. This program deletes all the events that do not have a comma, keeps all the events that do have commas, and then changes all the commas to semicolons.
Use the SAS provided tagset definition tagsets.csv . Tagsets.csv is the tagset that SAS provides to produce tabular output that contains columns of data values, which are separated by commas. The following code is the template that is used to create the tagset tagsets.csv .
proc template; define tagset Tagsets.Csv; notes "This is the CSV definition"; define event put_value; put VALUE; put NL /if cmp( htmlclass, "batch"); end; define event table; finish: put NL; end; define event row; finish: put NL; end; define event header; start: put "," /if ^cmp( COLSTART, "1"); put """"; put VALUE; finish: put """"; end; define event data; start: put "," /if ^cmp( COLSTART, "1"); put """"; put VALUE; finish: put """"; end; define event colspanfill; put ","; end; define event rowspanfill; put "," /if ^exists( VALUE); end; define event breakline; put NL; end; define event splitline; put NL; end; registered_tm = "(r)"; trademark = "(tm)"; copyright = "(c)"; output_type = "csv"; stacked_columns = OFF; end; run;
Create a new tagset tagsets.semisv from the parent tagset tagsets.csv . The DEFINE TAGSET statement creates a new tagset tagsets.semisv . The new tagset inherits its attributes from the parent tagset tagsets.csv which SAS provides. The NOTES statement adds information about the tagset which becomes part of the compiled tagset definition.
proc template; define tagset tagsets.semisv; notes "This is the SEMI-CSV definition"; parent = tagsets.csv;
Define four events that insert semicolon delimiters. The four DEFINE EVENT statements create the events header, data, colspafill, rowspanfill . The PUT statements insert a semicolon between each column, and enclose each table cell value with quotation marks.
define event header; start: put ';' / if !cmp(COLSTART, "1"); put '"'; put VALUE; finish: put '"'; end; define event data; start: put ';' / if !cmp(COLSTART, "1"); put '"'; put VALUE; finish: put '"'; end; define event colspanfill; put ';'; end; define event rowspanfill; put ';' /if ! exists(VALUE); end; end; run;
Specify the user-defined tagset. The following code tells ODS to use the user-defined tagset TAGSETS.SEMISV as the tagset definition for the output.
ods tagsets.semisv file='custom-tagset-filename.html';
Print the data set. PROC PRINT creates the report. ODS writes the report to the body file.
proc print data=grain_production label; run;
Stop the creation of the tagset definition. The ODS TAGSET. SEMISV CLOSE statement closes the MARKUP destination and all the files that are associated with it. You must close the destination before you can view the output with a viewer.
ods tagsets.semisv close;
PROC TEMPLATE features:
DEFINE TABLE statement
NOTES statement
COLUMN statement
DEFINE statement (for columns)
DEFINE TAGSET
Tagset attribute:
PARENT= attribute
STACKED_COLUMNS= attribute
Other ODS features:
ODS directory.tagset-name statement
ODS PHTML statement
ODS _ALL_ CLOSE statement
This example shows the difference between stacking data one column on top of another, or placing data side by side. (For more information on stacked columns, see the 'DEFINE TABLE Statement' on page 410.)
Create a table definition. The DEFINE TABLE statement creates the table definition Base.Standard .
proc template; define table Base.Standard; notes "Table definition for PROC Standard."; column name (mean std) n label; define name; header="Name" varname="Name" style=RowHeader; end; define mean; header="Mean/Std Dev" varname="Mean" format=D12.; end; define std; header="/Standard/Deviation" varname="stdDev" format=D12.; end; define n; header="N" format=best.; end; define label; header="Label" varname="Label"; end; byline wrap required_space=3; end; run; proc template; define tagset tagsets.myhtml; parent=tagsets.phtml; stacked_columns=no; end; run;
Customize the tagset by stacking the values side by side. This customized tagset has STACKED_COLUMNS= NO. Note that the SAS tagset, TAGSETS.PHTML, has STACKED_COLUMNS=YES.
proc template; define tagset tagsets.myhtml; parent=tagsets.phtml; stacked_columns=no; end; run;
Create HTML output and specify the location for storing the HTML output. The ODS TAGSETS.MYHTML statement opens the markup language destination and creates the HTML output. The output objects are sent to the external file not_stacked.html in the current directory. The PROC STANDARD statement generates the statistics for the sashelp.class data set. The PRINT option prints the report.
ods tagsets.myhtml file="not_stacked.html"; proc standard print data=sashelp.class; run;
Stop the creation of the HTML output. The ODS _ALL_ CLOSE statement closes all open destinations and all files associated with them. For HTML output, you must close the HTML destination before you can view the output with a browser.
ods _all_ close;
The SAS System The STANDERD Procedure | |||
---|---|---|---|
Name | Mean/Std Dev | Standerd Deviation | N |
Age | 13.315789 | 1.492672 | 19 |
Height | 62.336842 | 5.127075 | 19 |
Weight | 100.026316 | 22.773933 | 19 |
Create the same file but with values stacked. The STACKED_COLUMNS=YES statement shows the same values stacked in the SAS tagset PHTML.
ods phtml file="stacked.html"; proc standard print data=sashelp.class; run; ods _all_ close;
The SAS System The STANDERD Procedur | |||
---|---|---|---|
Name | Mean/Std Dev | N | |
Age | 13.315789 1.492672 | 19 | |
Height | 62.336842 5.127075 | 19 | |
Weight | 100.026316 22.773933 | 19 |