一个 JavaScript 代码语法高亮类
JavaScript October 11th, 2006
放出个 JavaScript 代码语法高亮类, 是根据 Unnamed Blog 上的修改的(原文提供的下载后有不少错误…), 效率比我原来写的高了不少. 当然, 我自己最后估计还是拿 Lex 来做…
主要修改的地方首先是让整个 js 可运行(-_-!)…然后完善了一些功能, 比如对 & 和 < 的处理, 还有把其它语言的支持分离开来.
首先是 cpp 高亮的支持 js 文件
?Download brushCpp.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | sh.Brushes.Cpp = function() {} sh.Brushes.Cpp.aliases = 'cpp'; sh.Brushes.Cpp.regexList = [ {regex: new RegExp('//.*$', 'gm'), css: 'comment'}, // one line comments {regex: new RegExp('/\\*[\\s\\S]*?\\*/', 'g'), css: 'comment'}, // multi line comments {regex: new RegExp("\'(?:[^\\\\']|\\\\.)*\'|" + "\"(?:[^\\\\\"]|\\\\.)*\"", 'g'), css: 'string'}, // string literals {regex: new RegExp('^\\s*#.*', 'gm'), css: 'preprocessor'}, // preprocessor directives {regex: new RegExp('\\b(?:auto|break|case|char|const|continue|default|do' + 'double|else|enum|extern|float|for|goto|if|int|long|register' + 'return|short|signed|sizeof|static|struct|switch|typedef|union' + 'unsigned|void|volatile|while)\\b', 'gm'), css: 'keyword'} // keyword ]; |
然后是关于着色的 css 文件
?Download brushColor.js
1 2 3 4 | .cpp .comment { color: gray; } .cpp .string { color: red; } .cpp .preprocessor { color: green; } .cpp .keyword { color: blue; } |
最后是主程序文件…
?Download highLight.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 | // create namespaces var sh = { Brushes : {} } // Match object sh.Match = function(regex, css) { this.regex = regex; // regeax to match this.css = css; // color the matches this.match = null; // match result, return of re.exec(str) this.index = 0; } sh.Parser = function(lang) { this.minIndex = -1; this.matches = new Array(); this.style = null; this.InitMatches(lang); } // Init match regex list sh.Parser.prototype.InitMatches = function(lang) { var brush; for(brush in sh.Brushes) if(sh.Brushes[brush].aliases == lang) break; // If lang can be found, set matches and style if(sh.Brushes[brush].aliases == lang) { this.matches = sh.Brushes[brush].regexList; this.style = sh.Brushes[brush].aliases; } } // Compare this.matches[i].match.index and store min i into this.minIndex, skip null sh.Parser.prototype.RefreshMin = function() { var i; // get the first not null in this.matchers[i].match for(i=0; i<this.matches.length; i++) { if(this.matches[i].match != null) { this.minIndex = i; break; } } // get min and store into this.minIndex for(; i<this.matches.length; i++) { if(this.matches[i].match != null && this.matches[i].match.index < this.matches[this.minIndex].match.index) { this.minIndex = i; } } } // Do first match, refresh this.minIndex sh.Parser.prototype.PrepareMatch = function(str) { var i; for(i=0; i<this.matches.length; i++) this.matches[i].match = this.matches[i].regex.exec(str); this.RefreshMin(); } // Find a match, begins at the last matched index, and refresh this.minIndex // returns found or not(true/false) sh.Parser.prototype.MatchOnce = function(str) { var index = this.matches[this.minIndex].regex.lastIndex; var i; for(i=0; i<this.matches.length; i++) { if(this.matches[i].match && this.matches[i].match.index < index) { if(this.matches[i].regex.lastIndex < index) { this.matches[i].regex.lastIndex = index; } this.matches[i].match = this.matches[i].regex.exec(str); } } this.RefreshMin(); return (this.matches[this.minIndex].match != null); } // Main parser sh.Parser.prototype.HighLight = function(str) { // If no lang matched, return str if(this.style == null) { str = str.replace(/&/g, '&'); // Replace & whith & str = str.replace(/</g, '<'); // Replace < whith < return "<pre>" + str + "< /pre>"; } var gIndex = 0; var buf = new Array(); this.PrepareMatch(str); buf.push("<pre class=\"" + this.style + "\">") if(this.minIndex == -1) buf.push(str); do { var i = this.minIndex; // push not matched buf.push(str.substring(gIndex, this.matches[i].match.index)); // push matched in color var matched = "" + this.matches[i].match; matched = matched.replace(/&/g, '&'); // Replace & whith & matched = matched.replace(/</g, '<'); // Replace < whith < buf.push("<span class=\"" + this.matches[i].css + "\">" + matched + "</span>"); gIndex = this.matches[i].regex.lastIndex; } while(this.MatchOnce(str)) buf.push(str.substr(gIndex)); buf.push("< /pre>") return buf.join(""); } |
调用也很简单
?Download highLight.js
1 2 3 4 5 6 7 8 | <script class="javascript" src="test.js"></script> <script class="javascript" src="brushCpp.js"></script> <link type="text/css" rel="stylesheet" href="brushColor.css"></link> <script class="javascript"> var input_code = "/* int x = 5; // test */"; var parser = new sh.Parser('cpp'); var highlighted_code = parser.HighLight(input_code); </script> |
给这个类添加其它语言的高亮支持也很简单, 只要仿照 brushCpp.js 写一个对应语言的 js 文件, 然后在 brushColor.css 添加相应的颜色配置方案就可以了.
Related posts:
Tags: Hihglight, JavaScript