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
|
|
|