Spaces:
Running
Running
File size: 3,053 Bytes
87b3b3a |
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 |
var Syntax = {
base: "", /* base path */
tab: " ",
_registry: {},
_todo: {},
/* apply to all elements */
all: function() {
var all = document.getElementsByTagName("*");
var todo = [];
for (var i=0;i<all.length;i++) {
var node = all[i];
if (node.getAttribute("data-syntax")) { todo.push(node); }
}
while (todo.length) { this.apply(todo.shift()); }
},
/* apply to one element */
apply: function(node) {
var syntax = node.getAttribute("data-syntax");
if (syntax in this._registry) { /* apply */
this._process(node, syntax);
} else { /* defer */
if (!(this._todo[syntax])) { /* append syntax script */
this._todo[syntax] = [];
this._append(syntax);
}
this._todo[syntax].push(node);
}
},
/* register new patterns */
register: function(name, patterns) {
this._registry[name] = patterns;
},
init: function() {
var scripts = document.getElementsByTagName("script");
for (var i=0;i<scripts.length;i++) {
var s = scripts[i];
var r = s.src.match(/^(.*)syntax\.js$/);
if (r) { this.base = r[1]; }
}
},
/* apply a set of patterns to a node */
_process: function(node, syntax) {
var patterns = this._registry[syntax];
node.className += " syntax-"+syntax;
var code = "";
/* IE normalizes innerHTML; need to get text content via nodeValues */
for (var i=0;i<node.childNodes.length;i++) { code += node.childNodes[i].nodeValue || ""; }
code = code.replace(/</g, "<").replace(/>/g, ">");
for (var i=0;i<patterns.length;i++) {
var pattern = patterns[i];
var index = pattern.index;
var replacement = "";
if (index > 1) {
for (var j=1;j<index;j++) { replacement += "$"+j; }
}
replacement += "<span class='"+pattern.token+"'>$"+index+"</span>";
code = code.replace(pattern.re, replacement);
}
code = code.replace(/\t/g, this.tab);
if (node.outerHTML) { /* IE hack; innerHTML normalizes whitespace */
node.innerHTML = "";
var tmp = document.createElement("div");
tmp.style.display = "none";
document.body.insertBefore(tmp, document.body.firstChild);
var pre = document.createElement("pre");
tmp.appendChild(pre);
pre.outerHTML = "<pre>" + code + "</pre>";
while (tmp.firstChild.firstChild) { node.appendChild(tmp.firstChild.firstChild); }
tmp.parentNode.removeChild(tmp);
} else {
node.innerHTML = code;
}
},
_append: function(syntax) {
var s = document.createElement("script");
s.src = this.base + "syntax-"+syntax+".js";
var thisp = this;
var loaded = function() { thisp._loaded(); }
if (s.addEventListener) {
s.addEventListener("load", loaded, false);
} else {
s.attachEvent("onreadystatechange", loaded);
}
document.body.insertBefore(s, document.body.firstChild);
},
_loaded: function() {
for (var syntax in this._registry) {
if (!(syntax in this._todo)) { continue; }
while (this._todo[syntax].length) {
this._process(this._todo[syntax].shift(), syntax);
}
delete this._todo[syntax];
}
}
};
Syntax.init();
|