| REXXTAGS.org ::  | Samples: XML highlighter tag |  
  
 
 
Home 
 Samples
 File: rexxtags.xmlhighlight.tag [download (.tag file, 8 KB)]
  Author: José María 
  Blasco<jm@jmblasco.com> 
Contributed on: 2002-12-05
Description: This REXX tag allows for a simple form of XML code highlighting. You can
surround any XML code between <rexxtags:xmlhighlight> and 
</rexxtags:xmlhighlight> tags, and the unformatted code will be shown,
highlighted, in your page. This is the same REXX tag used in
the REXXTAGS tutorial.
  Example: Here's the XML code (please substitute "*exxtags" for "rexxtags" in the code),
  1:<*exxtags:xmlhighlight lineno="yes">
  2:  <p style="text-align:justify>The quick brown <b>fox</b> jumps over
  3:   <i>the
  4:lazy</i>
  5:   dog.
  6:  </p>
  7:</*exxtags:xmlhighlight>
  8:
and here's the generated output:
  1:  <p style="text-align:justify>The quick brown <b>fox</b> jumps over
  2:   <i>the
  3:lazy</i>
  4:   dog.
  5:  </p>
  6:
Program code:
  1:/* <rexxtags:xmlhighlight>: a quick and dirty REXX tag to highlight XML code  */
  2:/*                                                                            */
  3:/* Parameters:                                                                */
  4:/*   lineno="[YES|1|NO|0]"       (Optional; default: NO)                      */
  5:/*   file="[filename]"           (Optional; default: "")                      */
  6:/*                                                                            */
  7:/* Version:     1.0                                                           */
  8:/*                                                                            */
  9:/* Author:      (c) Jose Maria Blasco <jm@jmblasco.com>                       */
 10:/*                                                                            */
 11:/* This software is subject to the terms of the Common Public License. You    */
 12:/* must accept the terms of this license to use this software. Refer to       */
 13:/* the license at the following URL for more information:                     */
 14:/* http://oss.software.ibm.com/developerworks/opensource/CPLv1.0.htm          */
 15:/*                                                                            */
 16:/* Description: A quick-and-dirty XML code highlighter which is used          */
 17:/* in the REXXTAGS tutorial (and elsewhere on the REXXTAGS site,              */
 18:/* http://www.rexxtags.org ). I wrote it in 30 minutes to test code           */
 19:/* highlighting, and invested later some more time so that the code is        */
 20:/* readable and has some documentation                                        */
 21:/*                                                                            */
 22:/* Disclaimer: I wrote this program for my own needs (mainly, for the         */
 23:/* REXXTAGS tutorial). It is NOT a complete XML highlighter, nor does it      */
 24:/* handle all syntactical cases. Use at your own risk.                        */
 25:/*                                                                            */
 26:/* Modifications:                                                             */
 27:/*                                                                            */
 28:/* Date       Author      Description                                         */
 29:/* ---------- ----------- --------------------------------------------------- */
 30:/* 2002/12/05 J.M.Blasco  v1.0 Initial release                                */
 31:
 32:Parse arg verb, parms, body /* Standard parse for tags which do body handling */
 33:
 34:Call GetParms               /* We'll need the parameters in many of the calls */
 35:
 36:
 37:/*----------------------------------------------------------------------------*/
 38:/* The tag is TAGDEPENDENT or not _depending_ on whether we are specifying    */
 39:/* a 'file' parameter.                                                        */
 40:/*----------------------------------------------------------------------------*/
 41:
 42:If verb == 'QUERY BODY CONTENT' Then 
 43:  If file == '' Then Return 'TAGDEPENDENT'
 44:  Else Return 0 
 45:
 46:/*----------------------------------------------------------------------------*/
 47:/* If a 'file' parameter is specified, the tag should not have a body, and    */
 48:/* all processing occurs at the start tag; otherwise, we delay processing     */
 49:/* until the body has been processed (that is, until the 'BODY' call).        */
 50:/*----------------------------------------------------------------------------*/
 51:
 52:If verb == 'START' Then 
 53:  If file == '' Then Return ''
 54:  Else Signal StartTag 
 55:
 56:If verb == 'BODY' Then Do   /* Standard body processing                       */
 57:  Interpret body 
 58:  Signal Body 
 59:End 
 60:
 61:If verb == 'END' Then Return ''
 62:
 63:Return 0 
 64:
 65:/*----------------------------------------------------------------------------*/
 66:/* This routine gets called only when a 'file' parameter has been specified   */
 67:/* and this is the 'START' call. The routine reads the file into a 'body.'    */
 68:/* stems, and then branches to normal body processing.                        */
 69:/*----------------------------------------------------------------------------*/
 70:
 71:StartTag: 
 72:  Call on notready name seteof 
 73:  eof = 0 
 74:  body.0 = 0 
 75:  file = Stream(file,'c','query exists') 
 76:
 77:  If file == '' Then Signal Body 
 78:  l = LineIn(file) 
 79:  Do lineno = 1 By 1 While eof == 0 
 80:    body.lineno = l 
 81:    body.0 = lineno 
 82:    l = LineIn(file) 
 83:  End 
 84:  Signal Body 
 85:
 86:/*----------------------------------------------------------------------------*/
 87:/* This is to set an end-of-file indicator for StartTag's main read loop.     */
 88:/*----------------------------------------------------------------------------*/
 89:
 90:SetEof: 
 91:  eof = 1 
 92:Return 
 93:
 94:/*----------------------------------------------------------------------------*/
 95:/* Parse the XML parameters                                                   */
 96:/*----------------------------------------------------------------------------*/
 97:
 98:GetParms: 
 99:
100:  Parse var parms 'lineno="'lineno'"'
101:  If Translate(lineno) == "YES" Then lineno = 1 
102:  If lineno \= 1 Then lineno = 0 
103:  printlinenos = lineno 
104:
105:  Parse var parms 'file="'file'"'
106:
107:Return 
108:
109:/*----------------------------------------------------------------------------*/
110:/* Body processing routine. Does all the highlighting.                        */
111:/*----------------------------------------------------------------------------*/
112:
113:Body: 
114:
115:  state = 0              /* State variable. 0: Normal text; 1: Inside XML tag */
116:  r = ''                 /* This will hold the accumulated result             */
117:
118:  diff = 0               /* Allow for the first line to be blank, and in..    */
119:  lineno = 1             /* ..this case, ignore it.                           */
120:  if body.1 = '' then do 
121:    lineno = 2 
122:    diff = 1 
123:  End 
124:
125:  /* Main loop                                                                */
126:
127:  Do lineno = lineno to body.0 
128:
129:    l = body.lineno      /* If the last line is blank, ignore it              */
130:    If l = '' & lineno = body.0 Then Leave 
131:
132:    l = change(l,'&','&')                /* Don't mess with '&'           */
133:    l = change(l,'  ','  ')             /* Don't allow blank sequences.. */
134:    l = change(l,'  ','  ')             /* to collapse.                  */
135:
136:    l1 = ''              /* 'll' contains the already processed part of 'l'   */
137:    Do Forever 
138:      If state = 0 & Pos('<',l) > 0 Then Do   /* State change: Normal --> XML */
139:        p = Pos('<',l) 
140:        state = 1 
141:	l1 = l1||Left(l,p-1)'<font color="#0000ff"><b><'
142:	l = Substr(l,p+1) 
143:	End 
144:      Else If state = 1 & Pos('>',l) > 0 Then Do   /* XML --> Normal text     */
145:        p = Pos('>',l) 
146:        state = 0 
147:	l1 = l1||Left(l,p-1)'></b></font>'
148:	l = Substr(l,p+1) 
149:	End 
150:      Else Leave /* Leave when no more '<' or '>' in line                     */
151:    End 
152:    l = l1||l 
153:    If printlinenos Then l = '<font color="#999999"><font size="1">'Change(Right(lineno-diff,3),' ',' ')'</font>:</font>'l 
154:    If lineno = 1 Then r = '<br />'l 
155:    Else r = r'00'x||'<br />'l 
156:  End 
157:Return '<font face="Courier New,Courier,Arial">'r'</font>'
158:
159:/* The following internal function is from Mike Cowlishaw  */
160:/* (posted in comp.lang.rexx)                              */
161:/* Internal function:  CHANGE(string,old,new)              */
162:/*                                                         */
163:/* (Like XEDIT  "C/old/new/1 *")                           */
164:/*                                                         */
165:/* Changes all occurrences of "old" in "string" to "new".  */
166:/* If "old"=='', then "new" is prefixed to "string".   MFC */
167:Change: procedure expose changed 
168:  parse arg string, old, new 
169:  if old=='' then do; changed=1; return new||string; end 
170:  out=''; changed=0 
171:  do while pos(old,string)\=0 
172:    parse var string prefix (old) string 
173:    out=out||prefix||new 
174:    changed=changed+1 
175:    end 
176:  return out||string 
177:
 
  
    /samples/rexxtags.xmlhighlight.html  
      Last update: 13/12/02 at 16:07
       | 
    
      
     | 
    
      
     |