Syntax Highlighter 代码研究
始终对代码恢复后的样式不是很满意于是对纯js实现的Syntax Highlighter作了一番研究,并根据自己的喜好改写和增加了一些功能
突然又发现这里评论中的代码高亮样式我比较喜欢,于是看了下发现都定义好了的。。。我的努力白费了。。不过还是很有收获的...
1,首先看下该写后的效果,也可参照这里
js代码:
c#代码:
2,关于改写的Syntax Highlighter
调用就这2句:
一下是其代码:
然后是Highlight,这个方法比较繁琐
其中创建第一行的div时的tools工具条是在上面的SwitchToList中完成,我加了一个参数_isJavaScript,目的是如果代码是js的话在tools栏上增加一个run code的button SwitchToList内有codeHighLight.Toolbar.Create的调用创建,一下是修改后的方法
同时当然需要在codeHighLight.Toolbar.Commands中添加runCode的实现代码部分
突然又发现这里评论中的代码高亮样式我比较喜欢,于是看了下发现都定义好了的。。。我的努力白费了。。不过还是很有收获的...
1,首先看下该写后的效果,也可参照这里
js代码:
c#代码:
2,关于改写的Syntax Highlighter
调用就这2句:
1 <script type="text/javascript">
2 codeHighLight.ClipboardSwf = 'Scripts/clipboard.swf';
3 codeHighLight.HighlighterAll('code', true, true, true, false);
4 </script>
看字面意思就知道HighlightAll在给所有需要高亮的代码高亮显示,这里我去掉了一个显示列数的参数2 codeHighLight.ClipboardSwf = 'Scripts/clipboard.swf';
3 codeHighLight.HighlighterAll('code', true, true, true, false);
4 </script>
一下是其代码:
codeHighLight.HighlighterAll = function(tagName, _60, _61, _62, _64) { function FindValue() { ... } function IsOptionSet(_67, _68) { ... } function GetOptionValue(_6a, _6b, _6c) { ... } function FindTagsByName(_70, _71, _72) { ... } var _75 = []; //tag list (need to high light) var _76 = null; //codeHighLight.Brushes var _77 = {}; //aliases FindTagsByName(_75, tagName, "pre"); FindTagsByName(_75, tagName, "textarea"); if (_75.length == 0) { return; } for (var _79 in codeHighLight.Brushes) { var _7a = codeHighLight.Brushes[_79].Aliases; if (_7a == null) { continue; } for (var i = 0; i < _7a.length; i++) { _77[_7a[i]] = _79; } } for (var i = 0; i < _75.length; i++) { var _7d = _75[i]; var _7e = FindValue(_7d.attributes["class"], _7d.className, _7d.attributes["language"], _7d.language); var _7f = ""; if (_7e == null) { continue; } _7e = _7e.split(":"); _7f = _7e[0].toLowerCase(); if (_77[_7f] == null) { continue; } _76 = new codeHighLight.Brushes[_77[_7f]](); _7d.style.display = "none"; //check function arguments and set the currect settings _76.noGutter = (_60 == null) ? IsOptionSet("nogutter", _7e) : !_60; _76.addControls = (_61 == null) ? !IsOptionSet("nocontrols", _7e) : _61; _76.collapse = (_62 == null) ? IsOptionSet("collapse", _7e) : _62; _76.showColumns = (_64 == null) ? IsOptionSet("showcolumns", _7e) : _64; if (_76.Style) { document.write(""); } //_76.firstLine = (_63 == null) ? parseInt(GetOptionValue("firstline", _7e, 1)) : _63; _76.Highlight(_7d["innerHTML"]); //高亮这个new codeHighLight.Brushes[_77[_7f]](); _76.source = _7d; _7d.parentNode.insertBefore(_76.div, _7d); } };
然后是Highlight,这个方法比较繁琐
codeHighLight.Highlighter.prototype.Highlight = function(_4c) { function Trim(str) { return str.replace(/^\s*(.*?)[\s\n]*$/g, "$1"); } function Chop(str) { return str.replace(/\n*$/, "").replace(/^\n*/, ""); } function Unindent(str) { ... } var _55 = _52.exec(_50[i]); if (_55 != null && _55.length > 0) { min = Math.min(_55[0].length, min); } } if (min > 0) { for (var i = 0; i < _50.length; i++) { _50[i] = _50[i].substr(min); } } return _50.join("\n"); } function Copy(_57, _58, _59) { return _57.substr(_58, _59 - _58); } var pos = 0; if (_4c == null) { _4c = ""; } this.originalCode = _4c; this.code = Chop(Unindent(_4c)); this.div = this.CreateElement("DIV"); this.bar = this.CreateElement("DIV"); this.ol = this.CreateElement("OL"); this.matches = new Array(); this.div.className = "dp-highlighter"; this.div.highlighter = this; this.bar.className = "bar"; this.ol.start = this.firstLine; if (this.CssClass != null) { this.ol.className = this.CssClass; } if (this.collapse) { this.div.className += " collapsed"; } if (this.noGutter) { this.div.className += " nogutter"; } if (this.tabsToSpaces == true) { this.code = this.ProcessSmartTabs(this.code); } this.ProcessRegexList(); if (this.matches.length == 0) { this.AddBit(this.code, null); this.SwitchToList(this.isJavaScript); this.div.appendChild(this.ol); return; } this.matches = this.matches.sort(codeHighLight.Highlighter.SortCallback); for (var i = 0; i < this.matches.length; i++) { if (this.IsInside(this.matches[i])) { this.matches[i] = null; } } for (var i = 0; i < this.matches.length; i++) { var _5d = this.matches[i]; if (_5d == null || _5d.length == 0) { continue; } this.AddBit(Copy(this.code, pos, _5d.index), null); this.AddBit(_5d.value, _5d.css); pos = _5d.index + _5d.length; } this.AddBit(this.code.substr(pos), null); this.SwitchToList(this.isJavaScript); this.div.appendChild(this.bar); this.div.appendChild(this.ol); };
其中创建第一行的div时的tools工具条是在上面的SwitchToList中完成,我加了一个参数_isJavaScript,目的是如果代码是js的话在tools栏上增加一个run code的button SwitchToList内有codeHighLight.Toolbar.Create的调用创建,一下是修改后的方法
codeHighLight.Toolbar.Create = function(_8, _isJavaScript) { var div = document.createElement("div"); div.classname = "tools"; for (var i in codeHighLight.Toolbar.Commands) { var cmd = codeHighLight.Toolbar.Commands[i]; if (cmd.check != null && !cmd.check(_8)) { continue; } if (cmd.label == "RunCode " && !_isJavaScript) { continue; } div.innerHTML += "" + cmd.label + ""; } return div; }
同时当然需要在codeHighLight.Toolbar.Commands中添加runCode的实现代码部分
var newWin1 = window; var newWin = newWin1.open('', "_blank", ''); newWin.document.open('text/html', 'replace'); newWin.opener = null var testCode = _runCode.originalCode.replace(/</g, "<"); var testCode = testCode.replace(/>/g, ">"); newWin.document.write(testCode); newWin.document.close();