用Javascript replace方法完成代码高亮插件——支持JS\CSS\HTML(支持html里面的JS,CSS)
2012-11-22 20:30 VVG 阅读(2995) 评论(3) 编辑 收藏 举报看到语法高亮的帖子,然后下班路上想了一下,有一个具体的思路,但是不知道别人如何实现,总觉得自己想法会太复杂,
主要就是用到Javascript的字符串的处理方法replace,然后利用正则表达式替换包裹HTML标签,全程都是字符串的处理,
输出的也是字符串。先把自己实现的发上来,只是简单的字符串替换,复杂的情况还满足不了,特别是特殊的注释与正则表达式不能够很好的识别
演示如下:
语法高亮
在这里输入代码:
代码高亮用到的CSS:
/* 代码高亮CSS start */ .codePre{width: 900px; margin-top: 5px;} .codePre { background: #282525; color: #fff; font: 14px/1.5em "Consolas", "Bitstream Vera Sans Mono", "Courier New", 'microsoft Yaheis'; border-radius: 8px; padding: 10px; } .codePre ol li { word-break: break-all; } .codePre ol li:nth-child(odd){background-color:#282828;} .codePre span.keyWords { color: #99ffdd; font-weight: bold; } .codePre span.string { color: #75c894; font-weight: bold; } .codePre span.string span { color: #75c894 !important; font-weight: bold; } .codePre span.string span.string { color: #3adf3a !important; font-weight: bold; } .codePre span.lineComment { color: #808080; } .codePre span.lineComment span { color: #808080 !important; } .codePre span.blockComment { color: #808080; font-style: italic; } .codePre span.blockComment span { color: #808080 !important; } .codePre span.blockComment span.attribute { color: #808080 !important; } .codePre span.blockComment span.string { color: #808080 !important; } .codePre span.nummber { color: red; } .codePre span.reg { background: #ccc; } .codePre span.attribute { color: #75c894; font-weight: normal; font-style: italic; } .codePre span.attribute span.string { color: #3adf3a; font-weight: bold; } .codePre span.class { color: #99cc00; } .codePre span.styleName { color: #ccffff } .codePre span.styleValue { color:#5bc5c9} /* 代码高亮CSS end */
代码高亮JS:
var heighLight = function () { /* 高亮正则*/ var heighLightWords = { 'javascript':{ keywords :/\b(break|delete|function|return|typeof|case|do|if|switch|var|catch|else|in|this|void|continue|false|instanceof|throw|while|debugger|finally|new|true|with|default|for|null|try)\b/g, lineComment :/([^\\:])(\/\/.*$)/g, blockComment:/\/\*.*?\*\//g, string :/('[^']*?')/g, string2 :/("[^"]*?")/g, nummber :/\b([0-9]+)\b/g }, 'html' :{ string :/(".*?")/g, attribute :/(<[a-z]+ )(.+?)(\/?>)/ig, blockComment:/(<!--.*?-->)/g, js :/(<script(?: .*?)?>)(.+?)(<\/script>)/ig, css :/(<style .*?>)(.+?)(<\/style>)/ig }, 'css' :{ cssCut :/((?:[-a-z.:\(\)_#]| )+?)({)(.*?)(})/ig, blockComment:/\/\*.*?\*\//g, } }; // 转义字符串 var htmlEncode = function (html) { return html.replace(/</g, '<').replace(/>/g, '>').replace(/\n|\r/g, '<br/>') .replace(/\s/g, ' ').replace(/"/g, '"').replace(/\t/g, ' '); }; // 处理多行注释 var filterBlockComment = function (str, type) { return str.replace(heighLightWords[type].blockComment, function (a) { var str = '<span class="blockComment">'; if (a.indexOf('<br/>') > -1) { var arr = a.split('<br/>'); str += arr.join('</span><br/><span class="blockComment">'); } else { str += a; } str += '</span>'; return str; }) }; //处理HTML里面的JS var filterHtmlJs = function (str) { return str.replace(heighLightWords.html.js, function (a, b, c, d) { //var myStr = b + javascriptReplace(c) + d; // return myStr; var arr = []; c = filterBlockComment(c, 'javascript'); // 拆分成单行处理 arr = c.split('<br/>'); for (var i = 0, n = arr.length; i < n; i++) { arr[i] = javascriptReplace(arr[i]); } c = arr.join('<br/>'); return b + c + d; }) }; // 处理HTML里面的CSS var filterHtmlCss = function (str) { return str.replace(heighLightWords.html.css, function (a, b, c, d) { var arr = []; c = filterBlockComment(c, 'css'); c = filterCss(c); return b + c + d; }) } // 处理纯CSS var filterCss = function (str) { return str.replace(heighLightWords.css.cssCut, function (a, b, c, d, e) { var arr, arr2; if (b.indexOf('<br/>') > -1) { b.replace(/<br\/>/g, ''); } b = '<span class="class">' + b + '</span>'; // 替换掉特殊字符,避免里面的分号影响分组 d = d.replace(/ /g, '$'); d = d.replace(/"/g, '@'); arr = d.split(';'); for (var i = 0; i < arr.length; i++) { if (!/^(<br\/>|\$)*$/.test(arr[i])) { arr2 = arr[i].split(':'); // 如果含有<br/>,不能用span包裹,因为后面以BR来添加OL LI if (arr2[0].indexOf('<br/>') > -1) { // 查找<br/>最后出现的位置 var index = arr2[0].lastIndexOf('<br/>'); // 加上<br/> 自己的长度 index = index + 5; var len = arr2[0].length; arr2[0] = arr2[0].slice(0, index) + '<span class="styleName">' + arr2[0].slice(index, len) + '</span>'; } else { arr2[0] = '<span class="styleName">' + arr2[0] + '</span>'; } arr2[1] = '<span class="styleValue">' + arr2[1] + '</span>'; arr[i] = arr2.join(':'); } } d = arr.join(';'); d = d.replace(/@/g, '"'); d = d.replace(/\$/g, ' '); return b + c + d + e; }) } // replace替换操作 var javascriptReplace = function (str) { // 关键字高亮 str = str.replace(heighLightWords.javascript.keywords, '<span class="keyWords">$1</span>'); // 单行注释 str = str.replace(heighLightWords.javascript.lineComment, '$1<span class="lineComment">$2</span>'); // 单引号字符串 str = str.replace(heighLightWords.javascript.string, '<span class="string">$1</span>'); // 双引号字符串 str = str.replace(heighLightWords.javascript.string2, '<span class="string">$1</span>'); // 数字 str = str.replace(heighLightWords.javascript.nummber, '<span class="nummber">$1</span>'); return str; } // jsArrayReplace JS文件分成行处理,返回字符串 var jsArrayReplace = function (str) { var arr = []; str = filterBlockComment(str, 'javascript'); // 拆分成单行处理 arr = str.split('<br/>'); for (var i = 0, n = arr.length; i < n; i++) { arr[i] = javascriptReplace(arr[i]); } str = arr.join('<br/>'); return str; } var htmlReplace = function (str) { // 标签属性 《img .... /》 str = str.replace(heighLightWords.html.attribute, '$1<span class="attribute">$2</span>$3'); // 双引号里面 str = str.replace(heighLightWords.html.string, '<span class="string">$1</span>'); return str; } var cssReplace = function (str) { str = str.replace(); } // 处理html js 成最后输出的<ol><li></li></ol>格式 var addOlli = function (str) { var arr = []; str = str + '<br/>'; var str2 = '<ol><li>'; arr = str.split('<br/>'); // 去除空行 for(var i=0;i<arr.length;i++){ if(/^\s*$/.test(arr[i])){ arr.splice(i,1); i--; } } str2 += arr.join('</li><li>'); str2 += '</li></ol>'; return str2; } /* 高亮实现方法 */ var heighLightO = { lightJs :function (str) { // 先转义 str = htmlEncode(str); // 在处理替换关键字等项 str = jsArrayReplace(str); // 隔行处理 str = addOlli(str); return str; }, lightHtml:function (str) { // HTML转义 str = htmlEncode(str); // 先处理html多行注释 str = filterBlockComment(str, 'html'); // 再处理HTML页内的JS str = filterHtmlJs(str); // todo 处理HTML页内的css str = filterHtmlCss(str); // 在处理HTML标签的着色 str = htmlReplace(str); // 隔行处理 str = addOlli(str); return str; }, lightCss :function (str) { str = htmlEncode(str); str = filterBlockComment(str, 'css'); str = filterCss(str); str = addOlli(str); return str; } }; return heighLightO; }(); document.getElementById('go').onclick = function () { var type = document.getElementById('choose').value; document.getElementById('heighLightCode').innerHTML = heighLight['light' + type](document.getElementById('code').value); };
转载请注明出处:http://www.cnblogs.com/NNUF/