REXXTAGS.org :: | Samples: REXX highlighter tag |
Home Samples
File: rexxtags.rexxhighlight.tag [download (.tag file, 10Kb)]
Author: José María
Blasco<jm@jmblasco.com>
Contributed on: 2002-12-04
Description: This REXX tag allows for a simple form of REXX code highlighting. You can
insert REXX code into your XML page, and, by surrounding it with this tag, the code
will be highlighted (with optional line-numbering). This is the same REXX tag used in
the REXXTAGS tutorial.
Example: Here's the XML code,
1:<rexxtags:rexxhighlight lineno="yes">
2: Parse var line 'option='option
3: /* This is a comment to show highlighting */
4: If Left(option,3) = 'yes' Then Say 'OK'
5: Else Say 'Invalid option: 'option
6:</rexxtags:rexxhighlight>
7:
and here's the generated output:
1: Parse var line 'option='option
2: /* This is a comment to show highlighting */
3: If Left(option,3) = 'yes' Then Say 'OK'
4: Else Say 'Invalid option: 'option
5:
Program code:
1:/* <rexxtags:rexxhighlight>: a quick and dirty REXX tag to highlight REXX code*/
2:/* */
3:/* Parameters: lineno=[YES|1|NO|0] */
4:/* */
5:/* Version: 1.0 */
6:/* */
7:/* Author: (c) Jose Maria Blasco <jm@jmblasco.com> */
8:/* */
9:/* This software is subject to the terms of the Common Public License. You */
10:/* must accept the terms of this license to use this software. Refer to */
11:/* the license at the following URL for more information: */
12:/* http://oss.software.ibm.com/developerworks/opensource/CPLv1.0.htm */
13:/* */
14:/* Description: A quick-and-dirty REXX code highlighter which is used */
15:/* in the REXXTAGS tutorial (and elsewhere on the REXXTAGS site, */
16:/* http://www.rexxtags.org ). I wrote it in 30 minutes to test code */
17:/* highlighting, and invested later some more time so that the code is */
18:/* readable and has some documentation */
19:/* */
20:/* Disclaimer: I wrote this program for my own needs (mainly, for the */
21:/* REXXTAGS tutorial). It is NOT a complete REXX highlighter, nor does it */
22:/* handle all syntactical cases, stop words or BIFs. Use at your own risk. */
23:/* */
24:/* Modifications: */
25:/* */
26:/* Date Author Description */
27:/* ---------- ----------- --------------------------------------------------- */
28:/* 2002/12/04 J.M.Blasco v1.0 Initial release */
29:
30:
31:Parse arg verb, parms, body /* Standard 'parse' for tags */
32:
33:If verb == 'QUERY BODY CONTENT' Then
34: Return 'TAGDEPENDENT' /* Process tag body ourselves */
35:If verb == 'START' then Return '' /* No output at start tag */
36:If verb == 'BODY' Then Do /* Standard body processing */
37: Interpret body /* Get the tag body into.. */
38: Signal Body /* ..the 'body.' stem */
39: End /* */
40:If verb == 'END' then Return '' /* Nothing output at end tag */
41:
42:Return 0 /* Return 0 for all other calls */
43:
44:/*----------------------------------------------------------------------------*/
45:/* Body processing routine. Here we do the actual parsing */
46:/*----------------------------------------------------------------------------*/
47:Body:
48:
49: /* We first fill the 'res.' and 'fun.' stems with reserved words and BIF.. */
50: /* ..names. */
51:
52: Call SetReserved
53: Call SetFunctions
54:
55: /* We now parse the parameter string and check for the presence of a.. */
56: /* ..'lineno' parameter. Note that we do little actual verification of.. */
57: /* ..correctness of the parameter. */
58:
59: Parse var parms 'lineno="'lineno'"'
60: If Translate(lineno) == "YES" Then lineno = 1
61: If lineno \= 1 Then lineno = 0
62: printlinenos = lineno
63:
64: /* Variable 'r' will hold the constructed return value (i.e. the.. */
65: /* ..highlighted, parsed program). */
66: r = ''
67:
68: lineno = 1 /* For line number counting */
69: diff = 0 /* The following code allows.. */
70: If body.1 = '' Then Do /* ..for the first line to be.. */
71: lineno = 2 /* ..a blank line. */
72: diff = 1 /* 'diff' will be subtracted.. */
73: End /* ..from 'lineno' below. */
74:
75: /*--------------------------------------------------------------------------*/
76: /* We iterate over all body lines, with a few tricks */
77: /*--------------------------------------------------------------------------*/
78:
79: Do lineno = lineno To body.0 /* We parse all 'body.' lines. */
80: l = body.lineno /* Get the line in 'l'. Don't.. */
81: If l = '' & lineno = body.0 Then Leave /* print the last line if blank */
82:
83: /*------------------------------------------------------------------------*/
84: /* Main loop. Parse one line; parsed results will go into 'lr' */
85: /*------------------------------------------------------------------------*/
86:
87: l = change(l,'&','&') /* Don't mess with <, > and & .. */
88: l = change(l,'<','<') /* in HTML code. */
89: l = change(l,'>','>')
90: l = change(l,' ',' ')
91: l = change(l,' ',' ')
92:
93: lr = '' /* 'lr' gets the parsed part. */
94: Do while l <> '' /* Loop until the line is parsed.*/
95:
96: /* First take care of starting blanks */
97: nb = Verify(l,' ')
98: If nb > 0 & left(l,1) == ' ' Then Do
99: lr = lr||Copies(' ',nb-1)
100: l = Strip(l,'L')
101: End
102:
103: /* Get a token (word) from the (rest of the) line */
104: Parse var l w' 'l
105:
106: /* Built-in Functions */
107: If pos('(',w) > 1 Then Do
108: Parse var w fn'('rest
109: ufn = Translate(fn)
110: If fun.ufn Then Do
111: lr = lr'<b><font color="#990099">'fn'</font></b>('
112: l = rest' 'l
113: Iterate
114: End
115: End
116:
117: /* 'Reserved' words */
118: uw = Translate(w)
119: If res.uw Then Do
120: lr = lr'<b>'w'</b> '
121: Iterate
122: End
123:
124: /* Comments */
125: If left(w,2) == '/*' Then Do
126: If Pos('*/',SubStr(w,3)' 'l) > 0 Then Do
127: Parse Value SubStr(w,3)' 'l With b'*/'l
128: lr = lr'<i><font color="#006600">/*'||b'*/</font></i>'
129: Iterate
130: End
131: End
132:
133: /* This code is to separate expressions from abuttal strings */
134: p1 = Pos('"',w)
135: p2 = Pos("'",w)
136: If p1 > 1 | p2 > 1 Then Do
137: If p1 = 0 | (p2 > 0 & p2 < p1) Then Do
138: lr = lr||Left(w,p2-1)
139: w = Substr(w,p2)
140: End
141: Else Do
142: lr = lr||Left(w,p1-1)
143: w = Substr(w,p1)
144: End
145: End
146:
147: /* Handle strings */
148: c = left(w,1)
149: If c = '"' | c = "'" Then Do
150: start = 2
151: w = w' 'l
152: l = ''
153: Do Forever
154: p = Pos(c,w,start)
155: If p = 0 Then p = Length(w) /* Unended string */
156: If SubStr(w,p+1,1) = c Then start = p+2
157: Else Leave
158: End
159: l = Substr(w,p+1)
160: lr = lr'<font color="#0000ff">'left(w,p)'</font>'
161: Iterate
162: End
163: lr = lr||w' '
164: End
165: If printlinenos Then lr = '<font color="#999999"><font size="1">'Change(Right(lineno-diff,3),' ',' ')'</font>:</font>'lr
166: If r = '' then r = '<br />'lr
167: Else r = r'00'x'<br />'lr
168:
169: End
170:Return '<font face="Courier New,Courier,Arial">'r'</font>'
171:
172:
173:/* This is the list of 'reserved' words. Extend as needed */
174:SetReserved:
175: res. = 0
176: res.if = 1
177: res.then = 1
178: res.else = 1
179: res.do = 1
180: res.to = 1
181: res.end = 1
182: res.leave = 1
183: res.iterate = 1
184: res.say = 1
185: res.parse = 1
186: res.with = 1
187: res.select = 1
188: res.when = 1
189: res.otherwise = 1
190: res.call = 1
191: res.signal = 1
192: res.arg = 1
193: res.return = 1
194: res.procedure = 1
195: res.expose = 1
196: res.var = 1
197: res.value = 1
198:Return
199:
200:/* This is the list of built-in functions. Extend as needed */
201:SetFunctions:
202: fun. = 0
203: fun.substr = 1
204: fun.left = 1
205: fun.right = 1
206: fun.arg = 1
207: fun.reverse = 1
208: fun.pos = 1
209: fun.translate = 1
210: fun.word = 1
211: fun.length = 1
212: fun.date = 1
213:Return
214:
215:/* The following internal function is from Mike Cowlishaw */
216:/* (posted in comp.lang.rexx) */
217:/* Internal function: CHANGE(string,old,new) */
218:/* */
219:/* (Like XEDIT "C/old/new/1 *") */
220:/* */
221:/* Changes all occurrences of "old" in "string" to "new". */
222:/* If "old"=='', then "new" is prefixed to "string". MFC */
223:Change: procedure expose changed
224: parse arg string, old, new
225: if old=='' then do; changed=1; return new||string; end
226: out=''; changed=0
227: do while pos(old,string)\=0
228: parse var string prefix (old) string
229: out=out||prefix||new
230: changed=changed+1
231: end
232: return out||string
233:
/samples/rexxtags.rexxhighlight.html
Last update: 29/05/03 at 01:34
|
|
|