📄 syntax-parser.js
字号:
var ie5 = "test".replace(/\w+/, "$&") == "$&";function SyntaxParser(source) {this.initialize(source);}function cloneObject(src) {var dest = {};for (var n in src) {dest[n] = src[n];}return dest;}SyntaxParser.prototype.initialize = function (source) {this.source = source;this.depths = [];this.anchors = [];this.partitionerMap = cloneObject(this.partitionerMap);this.rendererMap = cloneObject(this.rendererMap);this.depVisitorMap = cloneObject(this.depVisitorMap);};SyntaxParser.prototype.setRendererMap = function (group) {this.rendererMap = {};for (var n in group) {n = n || this.defaultType;var v = group[n];if (v instanceof Function) {this.rendererMap[n] = v;} else {if (v instanceof Array) {v = "(\\b" + v.join("\\b|\\b") + "\\b)";}var reg = new RegExp(v, "g");this.rendererMap[n] = this.buildRenderer(reg, "<b class='xidea--syntax-keyword xidea--syntax-$1'>$1</b>");}}};SyntaxParser.prototype.buildRenderer = function (regexp, str) {return function (text) {return text.replace(regexp, str);};};SyntaxParser.prototype.setPartitionerMap = function (group) {this.partitionerMap = {};function build(ps) {if (ps.exec) {return ps;} else {if (ps instanceof Array) {var ps = ps.join("|");}return new RegExp(ps, "gm");}}for (var n in group) {this.partitionerMap[n || this.defaultType] = build(group[n]);}};SyntaxParser.prototype.parse = function () {if (!this.lines) {this.lines = [];var lreg = new RegExp("\\r\\n|\\n|\\r", "g");var begin = 0, lm;while (lm = lreg.exec(this.source)) {this.lines.push({begin:begin, end:lm.index});begin = lm.index + lm[0].length;}if (begin < this.source.length) {this.lines.push({begin:begin, end:this.source.length});}this.partitions = this.buildPartitions();}};SyntaxParser.prototype.defaultType = "code";SyntaxParser.prototype.guessType = function () {for (var n in this.partitionerMap) {if (this.partitionerMap[n].test(p)) {return n;}}return this.defaultType;};function Partition(value, type, begin, end) {this.value = value;this.type = type;this.begin = begin;this.end = end;}Partition.prototype.toString = function () {return "{value:" + this.value + ",type:" + this.type + ",begin:" + this.begin + ",end:" + this.end + "}\n";};SyntaxParser.prototype.parsePartitions = function () {var exp = [];for (var n in this.partitionerMap) {exp.push(this.partitionerMap[n].source);}exp = new RegExp(exp.join("|"), "gm");var match, ps = [], s = this.source;while (match = exp.exec(s)) {var token = match[0];var type = this.guessType(token);ps.push(new Partition(token, type, match.index, match.index + token.length));}return ps;};SyntaxParser.prototype.buildPartitions = function () {var nps = [], pos = 0, dep = 0, ps = this.parsePartitions();for (var i = 0; i < ps.length; i++) {var p = ps[i];if (p.begin > pos) {var bp = new Partition(this.source.substring(pos, p.begin), this.defaultType, pos, p.begin);dep = this.computeDepth(bp, dep);nps.push(bp);}dep = this.computeDepth(p, dep);nps.push(p);pos = p.end;}if (pos < this.source.length) {var p = new Partition(this.source.substr(pos), this.defaultType, pos, this.source.length);dep = this.computeDepth(p, dep);nps.push(p);}return nps;};SyntaxParser.prototype.computeDepth = function (p, dep) {switch (p.type) {case "code":var reg = new RegExp("{|}", "g");var match, code = p.value;while (match = reg.exec(code)) {if (match[0] == "{") {this.depths.push({position:p.begin + match.index, preDepth:dep, minDepth:dep++, nextDepth:dep, type:"open"});} else {this.depths.push({position:p.begin + match.index, preDepth:dep, minDepth:--dep, nextDepth:dep, type:"close"});}}break;case "muti-comment":case "document":this.depths.push({position:p.begin, preDepth:dep, minDepth:dep++, nextDepth:dep, type:"open"});this.depths.push({position:p.end - 1, preDepth:dep, minDepth:--dep, nextDepth:dep, type:"close"});break;}return dep;};SyntaxParser.prototype.buildLineIterator = function () {if (this.partitions.length == 0) {this.parse();}return new LineIterator(this);};function LineIterator(sourceParser) {this.parser = sourceParser;this.source = sourceParser.source;this.partitions = sourceParser.partitions;this.lines = sourceParser.lines;this.depths = sourceParser.depths;this.anchors = sourceParser.anchors;this.depth = 0;this.nextDepth = 0;this.depthStack = [-1];this.depthStart = -1;this.partitionIndex = 0;this.lineIndex = 0;this.depthIndex = 0;this.anchorsIndex = 0;}LineIterator.prototype.hasNext = function () {return (this.partitions[this.partitionIndex] && this.lines[this.lineIndex]);};LineIterator.prototype.next = function () {var p = this.partitions[this.partitionIndex];var l = this.lines[this.lineIndex];if (!p || !l) {return null;}try {var d = this.depths[this.depthIndex];if (d != null) {if (d.position < l.end) {this.depth = d.minDepth;while (d = this.depths[++this.depthIndex]) {if (d.position < l.end) {this.depth = Math.min(this.depth, d.minDepth);} else {break;}}if (d) {this.nextDepth = d.preDepth;} else {this.nextDepth = 0;this.depth = 0;this.depthStack.length = 0;this.depthStart = -2;}} else {this.nextDepth = this.depth = d.preDepth;}}var i = this.depth - this.depthStack.length + 1;if (i > 0) {while (i-- > 0) {this.depthStack.push(this.lineIndex);this.depthStart = this.lineIndex;}} else {if (i < 0) {this.depthStack.length = this.depth + 1;this.depthStart = this.depthStack[this.depth];}}var a = this.anchors[this.anchorsIndex];this.anchor = "";if (a && a.position < l.end) {this.anchor = "";do {this.anchor += "<a name=\"" + a.name + "\" />";a = this.anchors[++this.anchorsIndex];} while (a && a.position < l.end);}if (p.end >= l.end) {return this.render(l.begin, l.end, p.type);} else {var buf = [];var i = l.begin;while (p.end < l.end) {buf.push(this.render(i, i = p.end, p.type));p = this.partitions[++this.partitionIndex];}buf.push(this.render(i, l.end, p.type));return buf.join("");}}finally {this.lineIndex++;}};LineIterator.prototype.render = function (b, e, type) {if (e > b) {var text = this.source.substring(b, e);text = this.encodeText(text);var renderer = this.parser.rendererMap[type];if (renderer) {text = renderer.call(this.parser, text);}return "<span class='xidea--syntax-" + type + "'>" + text + "</span>";} else {return "";}};LineIterator.prototype.encodeText = function (str) {if (str) {return str.replace(/[\r\n]/g, "").replace(/&/g, "&").replace(/>/g, ">").replace(/</g, "<");}return str;};function ECMAParser(source) {this.initialize(source);}$JSI.extend(ECMAParser, SyntaxParser);ECMAParser.prototype.setRendererMap({"code":["abstract", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "debugger", "default", "delete", "do", "double", "else", "enum", "export", "extends", "false", "final", "finally", "float", "for", "function", "goto", "if", "implements", "import", "in", "instanceof", "int", "interface", "long", "native", "new", "null", "package", "private", "protected", "prototype", "public", "return", "short", "static", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "typeof", "var", "void", "volatile", "while", "with"], "document":ECMAParser.prototype.buildRenderer(/@([\w-_\.\d]+)/g, "<b class='xidea--syntax-tag xidea--syntax-$1'>@$1</b>")});ECMAParser.prototype.setPartitionerMap({"document":"/\\*\\*(?:[^\\*]|\\*[^/])*\\*/", "muti-comment":"/\\*(?:[^\\*]|\\*[^/])*\\*/", "comment":"//.*$", "regexp":"/(?:\\\\.|[^/\\n\\r])+/", "string":["\"(?:\\\\.|[^\"\\n\\r])*\"", "'(?:\\\\.|[^'\\n\\r])*'"], "preprocessor":"^\\s*#.*"});ECMAParser.prototype.guessType = function (p) {var type = "";switch (p.charAt(0)) {case "/":var c = p.charAt(1);if (c == "/") {type = "comment";} else {if (c == "*") {if (p.charAt(2) == "*" && p.charAt(3) != "/") {type = "document";} else {type = "muti-comment";}} else {type = "regexp";}}break;case "'":case "\"":type = "string";break;case " ":case "#":type = "preprocessor";break;}return type;};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -