I am trying to get a grasp of the flow of events in TAGSETS.RTF in order to create my own template. I read I should use the MARKUP command in combination with EVENT_MAP to find out which events are triggered in what order. When I open the tagset RTF from the template directory (via Results in SAS) I can see that there are events like 'define event make_titles;' defined, but I cannot find them in the event map generated by the EVENT_MAP option. Also, it is not a customized one I think since it is not called somewhere in the PROC template code of TAGETS.RTF (nor it is defined in its parent graph_rtf). The only thing mentioned about titles in the EVENT_MAP file is called 'system_title_setup_group'. I found MEAS_EVENT_MAP but that is new in 9.3 and consequently it is not available in 9.2 (gives an error and it reverts back to a default one). Does anyone knows where make_titles comes from? Or where it is definied? Or am I missing something in my reasoning?
Hi:
There are 2 fundamental ways that events are triggered to process event variables. If you don't understand this, it will make your ttask harder:
1) the event is sent from a procedure (like PROC MEANS, PROC FREQ, etc) TO ODS and the event variables are handled by the event
2) the event is defined inside PROC TEMPLATE code, and the event is triggered by another event (possibly a #1 type of event)
For example, most procedures send a DOC event to signal the beginning of output creation. If you wanted to write something to your output file one time and only one time, then you would create a new template that would modify the DOC event. What I usually do is leave in the DOC event the things that I am OK with and then I make my own event and put a TRIGGER statement inside the DOC event to execute my statements. That way, it is easier for me to debug my statements and separate them from the SAS-supplied event handlers.
The EVENT_MAP tagset template doesn't really show you exactly what any destination is doing. It only shows you the ORDER in which the EVENTS were sent from your PROCEDURE to ODS, more specifically to the "output delivery agent" (ODA), that every open destination has.. The ODA is responsible for taking the events, sent from the procedure and finding the proper event handler in the MARKUP destination, and then executing that event.
So my understanding of the EVENT_MAP tagset is that it only reveals the ORDER in which the ODA will execute events in the MARKUP destination that you will otherwise choose. So, for example, the DOC event for the ODS HTML destination will write different "header" information to the output file, than the DOC event for TAGSETS.EXCELXP, or TAGSETS.RTF.
For destinations which are MARKUP destinations (TAGSETS.EXCELXP, HTML, CSV, CSVALL, TAGSETS.RTF, TAGSETS.MSOFFICE2K_X), the same event can (and usually does) result in different text strings being written to the output file. If you cannot find an event in the EVENT_MAP output, then, to me, this is a clue that the procedure is not "pitching" that event for the ODA to "catch and handle" (#1 above). To me, this implies that the event you are looking for is "triggered" internally (#2 above).
The bottom line is that a #2 type of event will not show up in EVENT_MAP. In fact, I do not think that MAKE_TITLE will ever show up in an EVENT_MAP output. The EVENT_MAP tagsets were initially created for diagnostic purposes, if, for example, you were going to write your own markup language tagset template (such as you might do if you needed to generate custom XML to conform to an XML specification).
So, if you are concerned about TITLE handling (which is implied by the event you're looking at, but you didn't really explain WHAT it is about TITLE handling that you want to change or investigate in TAGSETS.RTF), then look at the different events surfaced by the different diagnostic tagsets:
ods markup(1) tagset=meas_event_map file='c:\temp\mem1.txt';
ods markup(2) tagset=event_map file='c:\temp\em2.txt';
proc means data=sashelp.class;
title 'This is My Title';
var height;
run;
ods _all_ close;
The string 'This is My Title' will be handled by the SYSTEM_TITLE event for ODS HTML, ODS CSV, etc. (and there is some setup event stuff too)
<title_container_row event_name="title_container_row" trigger_name="attr_out" section="body" colcount="1" index="IDX" just="c">
<system_title event_name="system_title" trigger_name="attr_out" section="body" class="systemtitle" value="This is My Title" row="1" data_row="1" colcount="1" col="1" type="string" index="IDX" just="c">
</system_title>
</title_container_row>
However, the event surfaced by MEAS_EVENT_MAP shows a different event (ROW and DATA event):
<row event_name="row" trigger_name="attr_out" transparency="0" section="BODY" colcount="1" index="IDX" just="c" font-size="16" font-weight="0" font-style="0" foreground="1" background="0" leftmargin="360" rightmargin="360" topmargin="360" bottommargin="360" BorderColorDark="1" BorderColorLight="1" outputheight="15840" outputwidth="12240">
<data event_name="data" trigger_name="attr_out" transparency="0" value="This is My Title" rowspan="1" colspan="1" colcount="1" col="1" index="IDX" just="c" vjust="t" font-size="16" font-weight="0" font-style="0" foreground="1" background="0" leftmargin="360" rightmargin="360" topmargin="360" bottommargin="360" BorderColorDark="1" BorderColorLight="1" outputheight="181" outputwidth="12240" colwidth="0"/>
</row>
So, if you want to figure out what's happening, you would look at the DATA event in TAGSETS.RTF. I no longer have 9.2 to test with and, honestly, I don't recommend that you really try to alter a TAGSET template for TAGSETS.RTF unless you have an open track with Tech Support and they are working closely with you on the revision. If there is any way to accomplish what you want to do without making a TAGSET template change, Tech Support will either tell you how to do it OR Tech Support will tell you that a template change is your only alternative.
Chances are good that if what you want is something that other folks have asked for -- there might already be a template to do what you want. (see, for example, this paper about the rtf_sample tagset template http://support.sas.com/rnd/base/ods/odsrtf/067-31-updated.pdf and this Forum posting that discusses a possible usage scenario for the RTF_SAMPLE tagset: https://communities.sas.com/thread/39133?start=0&tstart=0)
If not, Tech Support can consult with the TAGSETS.RTF developer (who is an RTF expert) to figure out if what you want to do can, in fact, be accomplished with a template change. You did not say what you wanted to do. That is critical information. If it was Tech Support who told you to make a template change, then this question should go to them. If you did not consult with Tech Support before going down the template road, especially changing TAGSETS.RTF (or TAGSETS.EXCELXP), then I recommend that you gather up a sample of your data, a sample of your code using the DEFAULT TAGSETS.RTF template and open a track to tell them what you need to change. Then, let Tech Support tell you that a template change is the only way to accomplish what you want.
Sorry I can't be of more help. Without 9.2 to test with, it is hard to do any further tracing, and, since you didn't explain your reason for a change, I'm not convinced that you need to alter the TAGSETS.RTF template since 95-99% of the time, in my experience, the things that people need to accomplish do not involve a template change.
cynthia
Thank you for your input. My purpose is to add some text to the first title only (and create a TOC referring to that) on the same level which is mentioned in the 067-31-updated.pdf paper (thus using those keywords and writing some RTF tags in front of the titles before these are written to a stream). If there would be some info/an API about the inner workings that would be great, in stead of guessing commands which I probably need to do now.
Hi:
Well, if TAGSETS.RTF_SAMPLE (mentioned in that paper) does not work for you, then I really, REALLY recommend working with Tech Support. As far as I know, there are suboptions to build the RTF TOC, so I would not think you would need to put your own TOC commands into the first TITLE statement.
If you DO need to put RTF control strings into the TITLE for TOC inclusion, you may be able to do that using ODS ESCAPECHAR to insert the TOC info directly into the TITLE, which would not require a TAGSET template change. I do not know the RTF control strings for TOC control, but the inclusion would be something similar to this, shown using the RTF for highlighting ( \highlight3) in the code below.
I would still recommend working with Tech Support for this. The "newer" syntax for ODS ESCAPECHAR is shown for TITLE2, while the "original" syntax for ODS ESCAPECHAR is shown in TITLE1. I send the RTF control string \highlight3 to the RTF destination by using the PRETEXT style attribute. The RTF control string needs to be passed (unchanged) directly to the RTF destination, so the PROTECTSPECIALCHARS=OFF style attribute also needs to be modified.
As I said, I do not know the TOC controls for RTF, but as a general proof of concept, I hope this illustrates how you can use RTF controls to impact titles without making a tagset template change. Have I mentioned that I think you should consider opening a track with Tech Support? I bet they even know the RTF control strings you might need for the RTF TOC.
cynthia
ods tagsets.rtf file='c:\temp\tr_highlight_title.rtf';
ods escapechar='^';
proc print data=sashelp.class(obs=2);
title '^S={protectspecialchars=off pretext="\highlight3"}Title1';
title2 '^{style[protectspecialchars=off pretext="\highlight3"]Title2}';
run;
ods _all_ close;
Thank you for your answer. I am familiair with adding styles using the ESCAPECHAR en RTF control strings the way you describe. My idea was to remove redundant code from my programs (thus not coping the same code - with all those 'weird' rtf commands - over and over again for every program I create) by using templates and keep a simple front-end. I will have a look again if there are some more possibilities using a TOC using pretext etc since I might have overlooked some things.
Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.
Register today!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.
Select SAS Training centers are offering in-person courses. View upcoming courses for: