Skip to content

Commit f7d2742

Browse files
committed
CSS and JS tweaks
1 parent 872a7cd commit f7d2742

File tree

1 file changed

+280
-0
lines changed

1 file changed

+280
-0
lines changed

js/SyntaxHighlighting.js

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

0 commit comments

Comments
 (0)