-
Notifications
You must be signed in to change notification settings - Fork 169
/
all.js
296 lines (265 loc) · 8.19 KB
/
all.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
/* Unobtrustive Code Highlighter By Dan Webb 11/2005
Version: 0.4
Usage:
Add a script tag for this script and any stylesets you need to use
to the page in question, add correct class names to CODE elements,
define CSS styles for elements. That's it!
Known to work on:
IE 5.5+ PC
Firefox/Mozilla PC/Mac
Opera 7.23 + PC
Safari 2
Known to degrade gracefully on:
IE5.0 PC
Note: IE5.0 fails due to the use of lookahead in some stylesets. To avoid script errors
in older browsers use expressions that use lookahead in string format when defining stylesets.
This script is inspired by star-light by entirely cunning Dean Edwards
http://dean.edwards.name/star-light/.
*/
// replace callback support for safari.
if ("a".replace(/a/, function() {return "b"}) != "b") (function(){
var default_replace = String.prototype.replace;
String.prototype.replace = function(search,replace){
// replace is not function
if(typeof replace != "function"){
return default_replace.apply(this,arguments)
}
var str = "" + this;
var callback = replace;
// search string is not RegExp
if(!(search instanceof RegExp)){
var idx = str.indexOf(search);
return (
idx == -1 ? str :
default_replace.apply(str,[search,callback(search, idx, str)])
)
}
var reg = search;
var result = [];
var lastidx = reg.lastIndex;
var re;
while((re = reg.exec(str)) != null){
var idx = re.index;
var args = re.concat(idx, str);
result.push(
str.slice(lastidx,idx),
callback.apply(null,args).toString()
);
if(!reg.global){
lastidx += RegExp.lastMatch.length;
break
}else{
lastidx = reg.lastIndex;
}
}
result.push(str.slice(lastidx));
return result.join("")
}
})();
var CodeHighlighter = { styleSets : new Array };
CodeHighlighter.addStyle = function(name, rules) {
// using push test to disallow older browsers from adding styleSets
if ([].push) this.styleSets.push({
name : name,
rules : rules,
ignoreCase : arguments[2] || false
})
function setEvent() {
// set highlighter to run on load (use LowPro if present)
if (typeof Event != 'undefined' && typeof Event.onReady == 'function')
return Event.onReady(CodeHighlighter.init.bind(CodeHighlighter));
var old = window.onload;
if (typeof window.onload != 'function') {
window.onload = function() { CodeHighlighter.init() };
} else {
window.onload = function() {
old();
CodeHighlighter.init();
}
}
}
// only set the event when the first style is added
if (this.styleSets.length==1) setEvent();
}
CodeHighlighter.init = function() {
if (!document.getElementsByTagName) return;
if ("a".replace(/a/, function() {return "b"}) != "b") return; // throw out Safari versions that don't support replace function
// throw out older browsers
var codeEls = document.getElementsByTagName("CODE");
// collect array of all pre elements
codeEls.filter = function(f) {
var a = new Array;
for (var i = 0; i < this.length; i++) if (f(this[i])) a[a.length] = this[i];
return a;
}
var rules = new Array;
rules.toString = function() {
// joins regexes into one big parallel regex
var exps = new Array;
for (var i = 0; i < this.length; i++) exps.push(this[i].exp);
return exps.join("|");
}
function addRule(className, rule) {
// add a replace rule
var exp = (typeof rule.exp != "string")?String(rule.exp).substr(1, String(rule.exp).length-2):rule.exp;
// converts regex rules to strings and chops of the slashes
rules.push({
className : className,
exp : "(" + exp + ")",
length : (exp.match(/(^|[^\\])\([^?]/g) || "").length + 1, // number of subexps in rule
replacement : rule.replacement || null
});
}
function parse(text, ignoreCase) {
// main text parsing and replacement
return text.replace(new RegExp(rules, (ignoreCase)?"gi":"g"), function() {
var i = 0, j = 1, rule;
while (rule = rules[i++]) {
if (arguments[j]) {
// if no custom replacement defined do the simple replacement
if (!rule.replacement) return "<span class=\"" + rule.className + "\">" + arguments[0] + "</span>";
else {
// replace $0 with the className then do normal replaces
var str = rule.replacement.replace("$0", rule.className);
for (var k = 1; k <= rule.length - 1; k++) str = str.replace("$" + k, arguments[j + k]);
return str;
}
} else j+= rule.length;
}
});
}
function highlightCode(styleSet) {
// clear rules array
var parsed, clsRx = new RegExp("(\\s|^)" + styleSet.name + "(\\s|$)");
rules.length = 0;
// get stylable elements by filtering out all code elements without the correct className
var stylableEls = codeEls.filter(function(item) { return clsRx.test(item.className) });
// add style rules to parser
for (var className in styleSet.rules) addRule(className, styleSet.rules[className]);
// replace for all elements
for (var i = 0; i < stylableEls.length; i++) {
// EVIL hack to fix IE whitespace badness if it's inside a <pre>
if (/MSIE/.test(navigator.appVersion) && stylableEls[i].parentNode.nodeName == 'PRE') {
stylableEls[i] = stylableEls[i].parentNode;
parsed = stylableEls[i].innerHTML.replace(/(<code[^>]*>)([^<]*)<\/code>/i, function() {
return arguments[1] + parse(arguments[2], styleSet.ignoreCase) + "</code>"
});
parsed = parsed.replace(/\n( *)/g, function() {
var spaces = "";
for (var i = 0; i < arguments[1].length; i++) spaces+= " ";
return "\n" + spaces;
});
parsed = parsed.replace(/\t/g, " ");
parsed = parsed.replace(/\n(<\/\w+>)?/g, "<br />$1").replace(/<br \/>[\n\r\s]*<br \/>/g, "<p><br></p>");
} else parsed = parse(stylableEls[i].innerHTML, styleSet.ignoreCase);
stylableEls[i].innerHTML = parsed;
}
}
// run highlighter on all stylesets
for (var i=0; i < this.styleSets.length; i++) {
highlightCode(this.styleSets[i]);
}
}
CodeHighlighter.addStyle("css", {
comments : {
exp : /\/\*[^*]*\*+([^\/][^*]*\*+)*\//
},
keywords : {
exp : /@\w[\w\s]*/
},
selectors : {
exp : "([\\w-:\\[.#\\*][^{};>]*)(?={)"
},
properties : {// + values
exp : "([\\w-]+)(\\s*:\\s*)(.*?)(\\s*;)",
replacement: '<span class="properties">$1</span>$2<span class="values">$3</span>$4'
},
/* units : {
exp : /([0-9])(em|en|px|%|pt)\b/,
replacement : "$1<span class=\"$0\">$2</span>"
},
urls : {
exp : /url\([^\)]*\)/
},*/
curly : {
exp : /\{|\}/
}
});
CodeHighlighter.addStyle("html", {
xml : {
exp : /^\s*<\?xml .*?\?>/
},
doctype : {
exp: /<!DOCTYPE([^&]|&[^g]|&g[^t])*>/
},
comment : {
exp: /<!\s*(--([^-]|[\r\n]|-[^-])*--\s*)>/
},
tag : {
exp: /(<)(\/?)([a-zA-Z0-9]+\s?)/,
replacement: "<span class=\"brackets\">$1</span>$2<span class=\"$0\">$3</span>"
},
brackets : {
exp: />|</
},
/* string : {
exp : /'[^']*'|"[^"]*"/
},*/
attribute : {
exp: /\b([a-zA-Z-:]+)(=)('[^']*'|"[^"]*")/,
replacement: "<span class=\"attribute\">$1</span><span class=\"separator\">$2</span><span class=\"value\">$3</span>"
}
});
CodeHighlighter.addStyle("javascript",{
comment : {
exp : /(\/\/[^\n]*(\n|$))|(\/\*[^*]*\*+([^\/][^*]*\*+)*\/)/
},
brackets : {
exp : /\(|\)/
},
string : {
exp : /'[^']*'|"[^"]*"/
},
keywords : {
exp : /\b(arguments|break|case|continue|default|delete|do|else|false|for|function|if|in|instanceof|new|null|return|switch|this|true|typeof|var|void|while|with)\b/
},
global : {
exp : /\b(toString|valueOf|window|element|prototype|constructor|document|escape|unescape|parseInt|parseFloat|setTimeout|clearTimeout|setInterval|clearInterval|NaN|isNaN|Infinity)\b/
}
});
CodeHighlighter.addStyle("ruby",{
comment : {
exp : /#[^\n]+/
},
parens : {
exp : /\(|\)/
},
brackets : {
exp : /\[|\]/
},
curly : {
exp : /\{|\}/
},
string : {
exp : /'[^']*'|"[^"]*"/
},
keywords : {
exp : /\b(do|end|self|class|def|if|module|yield|then|else|for|until|unless|while|elsif|case|when|break|retry|redo|rescue|require|raise)\b/
},
/* Added by Shelly Fisher (shelly@agileevolved.com) */
symbol : {
exp : /:[A-Za-z0-9_!?]+/
},
instance : {
exp : /[^@]@[a-zA-Z0-9_]+/
},
'class' : {
exp : /@@[a-zA-Z0-9_]+/
},
numbers : {
exp : /[0-9][0-9\._]*/
},
constants : {
exp : /(:{0,2}[A-Z][a-zA-Z]*)+/
}
});