【代码分享】一个javascript实现简易的代码高亮模块。

王集鹄 2009-05-18 10:10:11
加精
/*--
标题:代码高亮控件
设计:王集鹄
博客:http://blog.csdn.net/zswang
日期:2009年5月15日
--*/

var Highlight = {
analyze: function(code, lang) {
if (!lang) return null;
var result = [];
var find = true;
var last = "";
while (find && code) {
find = false;
var j;
for (var i = 0; i < lang.syntaxs.length; i++) {
if (lang.syntaxs[i].start) {
var exists = false;
for (j = 0; j < lang.syntaxs[i].start.length; j++) {
if (last == lang.syntaxs[i].start[j]) {
exists = true;
break;
}
}
if (!exists) continue;
}
var match = lang.syntaxs[i].pattren.exec(code);
if (match) {
var methods = lang.syntaxs[i].methods;
if (methods) {
for (j = 0; j < methods.length; j++) {
var method = methods[j];
if (!method) continue;
if (!match[j + 1]) continue;
if (this[method] && this[method].syntaxs) {
var items = this.analyze(match[j + 1], this[method]);
for (var k = 0; k < items.length; k++) {
result.push(items[k]);
}
} else result.push({ name: method, text: match[j + 1] });
}
} else {
if (lang.syntaxs[i].name) {
var item = { name: lang.syntaxs[i].name, text: match[0] };
if (item.name == "Identifier" && lang.identifiers) {
for (j = 0; j < lang.identifiers.length; j++)
if (lang.identifiers[j].pattren.test(item.text))
item.name = lang.identifiers[j].name;
}
if (!/^(Whitespace|LineComment|MultiComment)$/i.test(item.name)
&& !/\)$/.test(item.text)) last = item.name;
result.push(item);
}
}
code = code.substr(match[0].length);
find = true;
break;
}
}
}
if (!find && code) result.push({ name: "Unknown", text: code });
return result;
}
, exportHtml: function(code, lang) {
var items = this.analyze(code, lang);
var html = [];
html.push("<pre class=\"Code\"><code>");
for (var i = 0; i < items.length; i++)
html.push("<span class=\"" + items[i].name + "\">"
+ items[i].text.replace(/</g, "<").replace(/>/g, ">")
+ "</span>");
html.push("</pre></code>");
return html.join("");
}
, attribute: {
syntaxs: [
{ pattren: /^\s+/, name: "Whitespace" }
, { pattren: /^(=|:|;|\/)/, name: "Symbol" }
, { pattren: /^('[^']*'|"[^"]*")/, name: "String" }
, { pattren: /^[\w\/\-_]+/, name: "Variant" }
]
}
, property: {
syntaxs: [
{ pattren: /^\s+/, name: "Whitespace" }
, { pattren: /^\/\*[\s\S]*?\*\//, name: "MultiComment" }
, { pattren: /^([a-zA-Z0-9_\-]+)(\s*)(:)(\s*)([^;]*)(;|$)/, methods: ["Variant", "Whitespace", "Symbol", "Whitespace", "String", "Symbol"] }
]
}
, css: {
syntaxs: [
{ pattren: /^\s+/, name: "Whitespace" }
, { pattren: /^\/\*[\s\S]*?\*\//, name: "MultiComment" }
, { pattren: /^(((\.|#)[a-zA-Z0-9_\-]+[\s,]*)+)(\{)([\s\S]*?)(\})/, methods: ["Function", null, null, "Symbol", "property", "Symbol"] }

]
}
, javascript: {
syntaxs: [
{ pattren: /^\s+/, name: "Whitespace" }
, { pattren: /^\/\/.*/, name: "LineComment" }
, { pattren: /^\/\*[\s\S]*?\*\//, name: "MultiComment" }
, { pattren: /^\/([^\\\/\n\r]*(\\.)*)*\/(i|m|g)*/, name: "Regex", start: ["", "Symbol"] }
, { pattren: /^(~|\+|\-|\*|\(|\)|\[|\]|\{|\}|\||\;|:|=|<|>|\.|\,|\%|\!|&|\?|\^)+/, name: "Symbol" }
, { pattren: /^\//, name: "Symbol" }
, { pattren: /^(\d+(?!\.|x|e|d|m)u?)|^0x([\da-fA-F]+(?!\.|x|m)u?)|^NaN/, name: "Number" }
, { pattren: /^(\d+)?\.\d+((\+|\-)?e\d+)?(m|d|f)?|^\d+((\+|\-)?e(\+|\-)?\d+)?(m|d|f)?/, name: "Float" }
, { pattren: /^"([^\\"]*(\\.)*)*"/, name: "String" }
, { pattren: /^'([^\\']*(\\.)*)*'/, name: "String" }
, { pattren: /^[\w$_]+/, name: "Identifier" }
]
, identifiers: [
{ pattren: /^(break|delete|function|return|typeof|case|do|if|switch|var|catch|else|in|this|void|continue|false|instanceof|throw|while|debugger)$/, name: "Reserved" }
, { pattren: /^(finally|new|true|with|default|for|null|try|abstract|double|goto|native|static|boolean|enum|implements|package|super|byte|prototype)$/, name: "Reserved" }
, { pattren: /^(export|import|private|synchronized|char|extends|int|protected|throws|class|final|interface|public|transient|const|float|long|short|volatile)$/, name: "Reserved" }
, { pattren: /^(Array|String|Boolean|undefined|Object|Enumerator|Error|Math)$/, name: "Type" }
]
}
, xhtml: {
syntaxs: [
{ pattren: /^\s+/, name: "Whitespace" }
, { pattren: /^<!--[\s\S]*?-->/, name: "MultiComment" }
, { pattren: /^(<!)([\s\S]*?)(>)/, methods: ["Symbol", "attribute", "Symbol"] }
, { pattren: /^(<\?)(xml\b)([\s\S]*?)(\?>)/, methods: ["Symbol", "Reserved", "attribute", "Symbol"] }
, { pattren: /^(<\?)(php\b)(.*?)(\?>)/, methods: ["Symbol", "Reserved", "php", "Symbol"] }
, { pattren: /^(<\?)(php\b)([\s\S]*?)(\n\?>|$)/, methods: ["Symbol", "Reserved", "php", "Symbol"] }
, { pattren: /^(<%@)([\s\S]*?)(%>)/, methods: ["Symbol", "attribute", "Symbol"] }
, { pattren: /^(<%)([\s\S]*?)(%>)/, methods: ["Symbol", "Text", "Symbol"] }
, { pattren: /^(<)(style\b)(([^>"']*(".*?"|'.*?')*)*?)(>)([\s\S]*?)(<\/)(style)(>)/i, methods: ["Symbol", "Type", "attribute", null, null, "Symbol", "css", "Symbol", "Type", "Symbol"] }
, { pattren: /^(<)(script\b)(([^>"']*(".*?"|'.*?')*)*?)(>)([\s\S]*?)(<\/)(script)(>)/i, methods: ["Symbol", "Type", "attribute", null, null, "Symbol", "javascript", "Symbol", "Type", "Symbol"] }
, { pattren: /^(<\/?)([\w\-]+)(([^>"']*(".*?"|'.*?')*)*?)(>)/i, methods: ["Symbol", "Type", "attribute", null, null, "Symbol"] }
, { pattren: /^[^<]+/i, name: "Text" }
]
}
, php: {
syntaxs: [
{ pattren: /^\s+/, name: "Whitespace" }
, { pattren: /^(\/\/|#).*/, name: "LineComment" }
, { pattren: /^\/\*[\s\S]*?\*\//, name: "MultiComment" }
, { pattren: /^(~|\+|\-|\*|\(|\)|\[|\]|\{|\}|\||\;|:|=|<|>|\.|\,|\%|\!|&|\?|\^|@)+/, name: "Symbol" }
, { pattren: /^\//, name: "Symbol" }
, { pattren: /^(\d+(?!\.|x|e|d|m)u?)|^0x([\da-fA-F]+(?!\.|x|m)u?)|^NaN/, name: "Number" }
, { pattren: /^(\d+)?\.\d+((\+|\-)?e\d+)?(m|d|f)?|^\d+((\+|\-)?e(\+|\-)?\d+)?(m|d|f)?/, name: "Float" }
, { pattren: /^"([^\\"]*(\\.)*)*"/, name: "String" }
, { pattren: /^'([^\\']*(\\.)*)*'/, name: "String" }
, { pattren: /^\$[\w_]*/, name: "Variant" }
, { pattren: /^[\w_]+/, name: "Identifier" }
]
, identifiers: [
{ pattren: /^(require_once|include|and|or|xor|__FILE__|exception|php_user_filter|__LINE__|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|each|echo|else|elseif|empty)$/, name: "Reserved" }
, { pattren: /^(enddeclare|endfor|endforeach|endif|endswitch|endwhile|eval|exit|extends|for|foreach|function|global|if|isset|list|new|old_function|print|return|static|switch|unset|use|var|while|__FUNCTION__|__CLASS__|__METHOD__)$/, name: "Reserved" }
, { pattren: /^(NULL|FALSE|TRUE)$/, name: "Variant" }
]
}
};


完整演示代码:http://www.renrousousuo.com/scripts/Highlight.html

包括了:html(xml)、javascript、php、css、csharp、delphi

如发现问题和改进意见请通知我一声。
...全文
2483 107 打赏 收藏 转发到动态 举报
写回复
用AI写文章
107 条回复
切换为时间正序
请发表友善的回复…
发表回复
zdbfba739 2011-08-26
  • 打赏
  • 举报
回复
不错!!
yld394774596 2011-08-25
  • 打赏
  • 举报
回复
看了大半天算是大概看懂了。。。
sd468605 2011-08-24
  • 打赏
  • 举报
回复
看晕了
howdy19881314 2010-10-04
  • 打赏
  • 举报
回复
好强大!!!
cuixiping 2010-08-11
  • 打赏
  • 举报
回复
原来是一个老坟贴

匹配“HTML标签”
/^(<\/?)([\w\-]+)(([^>"']*(".*?"|'.*?')*)*?)(>)/i
可能还得加上有XML命名空间的标签
比如vml的<v:rect ....></v:rect>
属性名也可能有名称空间,典型的是从office里面粘贴过来的时候,不清理的话,漫天遍野都是。


匹配正则的
/^\/([^\\\/\n\r]*(\\.)*)*\/(i|m|g)*/
这个是有问题的

假设已经排除了是注释的情况,并且假设排除了空格和TAB的干扰,那么:
第一个/的前面是什么才会是正则呢,我的看法:

如果/的前面是以下情况则是除号:
变量名许可的字符(包括数字、字母、[\x00-\x7f]以外的字符、下划线_、美元符$)
反圆括号)
反方括号]

反之,一般来说是正则,但也有比较变态的例外,那就是--和++的情况了,比如:
var i=1;
i=i++/2+2/i; //哈哈,我不是正则
i=i--/2+2/i; //哈哈,我不是正则
i=i+++/2+2/.test(2); //哈哈,我是正则
i=i---/2+2/.test(2); //哈哈,我是正则

wwfgu00ing 2010-08-11
  • 打赏
  • 举报
回复
很不错
masky5310 2010-04-08
  • 打赏
  • 举报
回复
MARK
諾临風 2010-04-08
  • 打赏
  • 举报
回复
确实不错啊,真牛X
tianqing52 2010-03-04
  • 打赏
  • 举报
回复
js看着就头大,,,先收藏下来。。
ChinaXtHuLang 2009-08-01
  • 打赏
  • 举报
回复
怎么没有VB的?
SongWangchu 2009-05-24
  • 打赏
  • 举报
回复
恩,研究研究了
pstrunner 2009-05-23
  • 打赏
  • 举报
回复
怎么只有前面部分文字有变化,并且如果先Attribute、css、Javascript变化后,再回头选开始选Javascript、css、Attribute,效果都不一样。
iovewdh 2009-05-23
  • 打赏
  • 举报
回复
真的很不错啊,想学啊
veslen 2009-05-23
  • 打赏
  • 举报
回复
要好好研究一下
skyell 2009-05-23
  • 打赏
  • 举报
回复
厉害啊
love1901 2009-05-23
  • 打赏
  • 举报
回复

snailery 2009-05-23
  • 打赏
  • 举报
回复
mark
wbanwashui 2009-05-23
  • 打赏
  • 举报
回复
```````````````````````````````````````````````
boyking_msn 2009-05-23
  • 打赏
  • 举报
回复
收藏了
超维电脑科技 2009-05-23
  • 打赏
  • 举报
回复
收藏了
加载更多回复(85)

87,921

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧