I'm not aware of a straightforward way to include SAS program source in ODS output in SAS 9.1 or earlier releases. In SAS 9.2, there is a preproduction feature in PROC DOCUMENT that will permit you to import and subsequently replay any text file, including a SAS program, to active destinations, e.g.:
proc document name=mydoc;
import textfile="myjob.sas" to ^;
The ODS DOCUMENT method sounds cool! The only way I've been able to include any ancillary information (like a TXT file or a SAS program) in ODS output is to code a DATA step program to read the program file. I use $VARYING in my INPUT statement and make a dataset with 2 variables: LINENUM and PGMLINE.
Then I use PROC REPORT with NOHEADERS and RULES=NONE to display the program data set. I do have an example of such a program, but it's old, so it's on a drive that I don't have attached at the moment. But you get the idea. My method is sort of a brute force method, but does get the SAS program at the end of the ODS output file.
Assume that the folder c:\sas programs has a file called prtclass.sas which does a simple proc print of sashelp.class:
proc print data=sashelp.class noobs;
title 'proc print';
Next, the program shown below will first do a %include of the PRTCLASS.SAS program, which will cause the code of interest to be included, then compiled and executed. Finally, the DATA step reads in the program and displays the PRTCLASS.SAS program as output via the PROC REPORT step.
I like using PROC REPORT so I can use NOHEADERS on the column header and NOPRINT on the LINENUM. Note the blank line in the program and how I use linelength to preserve this white space (which would normally be ignored). I used RTF because the only students who've asked me about this have wanted RTF output.
Depending on your macro skills, you could further "macro-ize" the program, but like I said, this program is old and is "un-macro-ized" for simplicity.
length linenum 8 pgmline $200;
infile "c:\sas programs\prtclass.sas" length=linelen lrecl=256 missover;
linenum = _n_;
if linelen = . then do;
** have a blank line and want to keep it in the output;
pgmline = ' ';
if linelen gt 0 then do;
** have a program line and want to read it;
input @1 pgmline $varying. linelen;
keep linenum pgmline linelen;
nice thing about proc report for program syntax is the text flow available.
There is something similar in proc sql, but report provides more support (I think)
$varying should be fairly irrelevant these days with truncover and _infile_ so much more manageable (After all, all sas data set string variables hold trailing spaces - when not filled)