eEhdsa

Syntax Highlighter 代码研究

      始终对代码恢复后的样式不是很满意于是对纯js实现的Syntax Highlighter作了一番研究,并根据自己的喜好改写和增加了一些功能
      突然又发现这里评论中的代码高亮样式我比较喜欢,于是看了下发现都定义好了的。。。我的努力白费了。。不过还是很有收获的...

1,首先看下该写后的效果,也可参照这里
js代码:

c#代码:

2,关于改写的Syntax Highlighter
调用就这2句:
1    <script type="text/javascript">
2        codeHighLight.ClipboardSwf = 'Scripts/clipboard.swf';
3        codeHighLight.HighlighterAll('code'truetruetruefalse);
4    
</script>
看字面意思就知道HighlightAll在给所有需要高亮的代码高亮显示,这里我去掉了一个显示列数的参数
一下是其代码:

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();

posted on 2009-09-23 13:28  eEhdsa  阅读(485)  评论(0编辑  收藏  举报

导航