I wrote a REXX program to take SYSOUT with ANSI control characters and
generates an XML file. It comes out looking very nice in MS-Word. From there
I print it to PDF using PDF Creator. I'm attaching the source for the REXX, as
well as the XML Style Sheet that it references. To run the REXX on your PC,
you will need to install Regina Rexx (http://regina-rexx.sourceforge.net/)
Theoretically, you could take it a step further and generate the Word document
directly. Here's a link to get started down that path...
http://msdn.microsoft.com/en-us/library/bb264572.aspx
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN
/* REXX */
SIGNAL ON NOVALUE /* Enable the conditions and */
SIGNAL ON SYNTAX /* point at reasonable */
SIGNAL ON FAILURE /* condition handling */
SIGNAL ON HALT
REXX_name_long = "SYSOUT Formatter"
REXX_name_short = "SYSOUT"
Update_date = "21 Feb 2012" /* See Change Log */
/*
SYSOUT - SYSOUT Formatter
This REXX EXEC formats SYSOUT for printing. It takes SYSOUT in
text format creates an XML file for use with SYSOUT.XSL
*/
/* Output data: */
msgo_DD = "MSGO" /* Output message file */
xmlo_DD = "xmlo" /* Output reformatted transaction data */
xmlo_filename = "SYSOUT.xml"
msgo = "SYSOUT REXX Messages.txt"
/* Input data: */
/* SYSOUT Text file */
csvi_DD = "csvi"
csvi_filename = "SYSOUT.txt"
/* Initialize stems for numeric fields and logical switches */
ctr. = 0; sw. = 0
/*
Determine the execution environment
*/
exec_env = ADDRESS()
PARSE SOURCE OS .
SELECT
WHEN exec_env = "TSO" THEN DO /* TSO (IKJEFT01) */
sw.mainFrame = 1
user_interface = SYSVAR("SYSENV") /* FORE or BACK */
END
WHEN exec_env = "MVS" THEN DO /* Batch (IRXJCL) */
sw.mainFrame = 1
user_interface = "BACK"
END
WHEN exec_env = "SYSTEM" THEN DO
user_interface = "BACK"
IF OS ^= "WIN32" THEN SIGNAL A010_unexpected_environment
sw.use_say = 1
END
OTHERWISE SIGNAL A010_unexpected_environment
END
SIGNAL A011_got_env
/*
If we cannot determine the execution environment...
1. Issue an error
2. Set the return code
3. Quit
*/
A010_unexpected_environment:
SAY "Unexpected execution environment"
SAY "Address:" exec_env
SAY "OS:" OS
ctr.return_code = 16
SIGNAL QUIT
/*
Free and allocate data files for interactive execution (Skip for
background execution)
*/
A011_got_env:
IF user_interface = "BACK" THEN SIGNAL A020_alloc_done
sw.use_say = 1
hlq='HCHRJK0.PERSONAL'
msgo_DSN = "'"hlq||"."||REXX_name_short||"."||msgo_DD||"'"
xmlo_DSN = "'"hlq||"."||REXX_name_short||"."||xmlo_DD||"'"
csvi_DSN = "'"hlq||"."||REXX_name_short||"."||csvi_DD||"'"
/*
Free and allocate data files for interactive execution
Skip FREE and ALLOC for batch execution
*/
"FREE F("MSGO_DD")"
"FREE F("xmlo_DD")"
"FREE F("csvi_DD")"
"ALLOC DA("||msgo_DSN||") F("msgo_DD") OLD REUSE"
"ALLOC DA("||xmlo_DSN||") F("xmlo_DD") OLD REUSE"
"ALLOC DA("||csvi_DSN||") F("csvi_DD") SHR REUSE"
A020_alloc_done:
/* For Mainframe, open the output files */
IF sw.mainFrame THEN DO
"EXECIO 0 DISKW " msgo_DD " (OPEN"
"EXECIO 0 DISKW " xmlo_DD " (OPEN"
END
/* Write the title lines in the message file */
msgo_rec =REXX_name_long 'Last Updated:' Update_date
CALL G100_msg_out
/*
Queue up the input TXT file. If it is empty, issue an error
message and quit.
*/
IF sw.mainFrame THEN
"EXECIO * DISKR " csvi_DD " (STEM line_csvi. FINIS"
ELSE DO
line_csvi.0 = 0
DO sub=1 WHILE LINES(csvi_filename)
line_csvi.sub = LINEIN(csvi_filename)
line_csvi.0 = sub
END
END
IF line_csvi.0 > 0 THEN SIGNAL A040_do_xml
SIGNAL A020_error01;A020_error01:
msg_line=SIGL+2;sIGNAL A020_error01o
' '
'**********************************************************************'
'*** SYSOUT ERROR01 ***'
'*** No records in the input TXT file ***'
'**********************************************************************'
' '
A020_error01o:
DO msg_sub=msg_line WHILE SOURCELINE(msg_sub) ^= 'A020_error01o:'
INTERPRET 'msgo_rec = ' SOURCELINE(msg_sub);CALL G100_msg_out
END
ctr.return_code = 16
SIGNAL Quit
A040_do_xml:
/*
Write the DTD and top-level element
*/
SIGNAL A040_DTDo;A040_DTDo:
xml_line=SIGL+2;SIGNAL A040_DTDoo
'<?xml version="1.0" encoding="iso-8859-7"?>'
'<?xml-stylesheet type="text/xsl" href="sysout.xsl" ?>'
'<!-- Created by sysout.rexx -->'
'<!DOCTYPE Sysout ['
'<!ELEMENT Sysout (line+) >'
'<!ELEMENT line (Carriage_Control,line_text) >'
'<!ELEMENT Carriage_Control (#PCDATA)>'
'<!ELEMENT line_text (#PCDATA)>'
']>'
'<Sysout>'
A040_DTDoo:
DO xml_sub=xml_line WHILE SOURCELINE(xml_sub) ^= 'A040_DTDoo:'
INTERPRET 'xmlo_rec = ' SOURCELINE(xml_sub);CALL G110_xml_out
END
/*
Process the input file
*/
DO csvi_cursor=1 WHILE csvi_cursor <= line_csvi.0
CALL A100_do_xml
END
/* Add closing top-level element to XML output */
xmlo_rec = "</Sysout>";CALL G110_xml_out
/* Add ending messages to the queue */
SIGNAL A040_msg999;A040_msg999:
msg_line=SIGL+2;SIGNAL A040_msg999o
' '
'Output data:'
'Output Lines =' ctr.linesout_xml
' '
'Input data:'
'Input Lines Queued =' line_csvi.0
'Input Lines Processed =' ctr.csvi
A040_msg999o:
DO msg_sub=msg_line WHILE SOURCELINE(msg_sub) ^= 'A040_msg999o:'
INTERPRET 'msgo_rec = ' SOURCELINE(msg_sub);CALL G100_msg_out
END
/* Write the records to the message file */
IF sw.mainFrame THEN
"EXECIO * DISKW MSGO ( STEM msgout."
ELSE DO
retc = LINEOUT(msgo,msgout.1,1)
DO sub=2 WHILE ctr.msgsout>=SUB
retc = LINEOUT(msgo,msgout.sub)
END
END
/* Write the records to the output XML file */
IF sw.mainFrame THEN
"EXECIO * DISKW xmlo ( STEM xmloUT."
ELSE DO
retc = LINEOUT(xmlo_filename,xmlout.1,1)
DO sub=2 WHILE ctr.linesout_xml>=SUB
retc = LINEOUT(xmlo_filename,xmlout.sub)
END
END
Quit: EXIT ctr.return_code
/*
Internal sub-routines
*/
A100_do_xml:
/*
Get the next record from the queue and and update the counters
*/
line_csvi_cur = line_csvi.csvi_cursor
line_words = words(line_csvi_cur) /* Count the words in the line */
ctr.csvi = ctr.csvi + 1
ctr.wordcount_csvi = ctr.wordcount_csvi + line_words
ctr.chars = ctr.chars + LENGTH(line_csvi_cur)
Carriage_Control = LEFT(line_csvi_cur,1)
PARSE VAR line_csvi_cur,
1 Carriage_Control,
2 line_text
/* Start the next line */
xmlo_rec = " <line>";CALL G110_xml_out
xmlo_rec =,
" <Carriage_Control>"||,
Carriage_Control||,
"</Carriage_Control>"
CALL G110_xml_out
xmlo_rec =,
" <line_text><![CDATA["||,
line_text||,
"]]></line_text>"
CALL G110_xml_out
xmlo_rec = " </line>";CALL G110_xml_out
RETURN
G100_msg_out:
/*
Add a record to the output buffer of the messages file and
display it
*/
ctr.msgsout = ctr.msgsout + 1
sub = ctr.msgsout
msgout.sub = msgo_rec
IF sw.use_say THEN SAY msgo_rec
RETURN
G110_xml_out:
/*
Add a record to the output buffer of the transaction file
*/
ctr.linesout_xml = ctr.linesout_xml + 1
sub = ctr.linesout_xml
xmlout.sub = xmlo_rec
RETURN
/*
Condition handling
Taken from "What's wrong with Rexx?" by Walter Pachl, IBM Retiree
Downloaded from www.rexxla.org/events/2004/walterp.pdf
*/
NOVALUE:
SAY 'Novalue raised in line' SIGL /* line in error number */
SAY SOURCELINE(SIGL) /* and text */
SAY 'Variable' CONDITION('D') /* the bad variable reference */
SIGNAL Lookaround /* common interactive code */
SYNTAX:
SAY 'Syntax raised in line' SIGL /* line in error number */
SAY SOURCELINE(SIGL) /* and text */
SAY 'rc='rc '('errortext(rc)')' /* the error code and message */
HALT:
Lookaround: /* common interactive code */
IF user_interface = 'FORE' THEN DO /* when running in foreground */
SAY 'You can look around now.' /* tell user what he can do */
TRACE ?R /* start interactive trace */
NOP /* and cause the first prompt */
END
ctr.return_code = 16
SIGNAL Quit
Z999_Change_log:
/*
Change Log
Future Enhancements
- xxx
12 Feb 2012
Initial deployment.
*/
/*
TRACE ?A /* testing - Display all clauses before execution */
TRACE ?R /* testing - Display final results */
TRACE ?I /* testing - Display intermediate results */
*/
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
SYSOUT.xsl
Created using the Compuware Editor powered by SlickEdit
This stylesheet is designed for use with SYSOUT.XML as created by SYSOUT.REXX
-->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:preserve-space elements="*" />
<xsl:template match="/">
<html>
<pre style="font-family:Lucida Console;font-size:9pt">
<strong><xsl:value-of select="line_text" /></strong>
<xsl:for-each select="Sysout/line">
<xsl:choose>
<xsl:when test="Carriage_Control=1">
<div style="page-break-before: always"><strong><xsl:value-of
select="line_text" /></strong></div>
</xsl:when>
<xsl:when test="Carriage_Control=0">
<br/><xsl:value-of select="line_text" /><br/>
</xsl:when>
<xsl:when test="Carriage_Control = '-'">
<br/><br/><xsl:value-of select="line_text" /><br/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="line_text" /><br/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</pre>
</html>
</xsl:template>
</xsl:stylesheet>
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN