语法高亮显示问题。
程序代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www. xmlns="http://www. http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>jslib测试</title> <style type="text/css"> pre { color:black; } span.hl_js_kw { color: blue; font-weight:bold;} span.hl_js_mcm { color:green; } span.hl_js_scm { color:gray; } span.hl_js_s { color:green; } span.hl_js_reg { color: red; } span.hl_js_num { color: red; } span.hl_js_typ { color: #9900CC; } </style> <script type="text/javascript"> function $(id) { return document.getElementById(id); }; function btn_click() { var pre = $("codePre"); var area = $("codeArea"); var code = area.value.replace(/</g, "<").replace(/>/g, ">"); var dt = new Date(); str = jsEngine.parseSyntax(code, formats,'js'); $("msg").innerHTML = "共有" + code.length + "个字符, 解析花时" + (new Date().getTime() - dt.getTime()) + "ms"; str = str.replace(/^(\t+)/gm, function(m) { return (new Array(m.length + 1)).join(" "); }); str = str.replace(/^( +)/gm, function(m) { return (new Array(m.length + 1)).join(" "); }); str = str.replace(/\r?\n/g, "<br/>"); pre.innerHTML = str; } window.onload = function() { $("btn").onclick = btn_click; } var languages = { 'js': { keyword: "Array|arguments|Boolean|Date|Enumerator|Error|Function|Global|Math|Number|Object|RegExp|String|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|abstract|double|goto|native|static|boolean|enum|implements|package|super|byte|export|import|private|synchronized|char|extends|int|protected|throws|class|final|interface|public|transient|const|float|long|short|volatile", types: "Anchor|Applet|Area|Arguments|Array|Boolean|Button|Checkbox|Collection|Crypto|Date|Dictionary|Document|Drive|Drives|Element|Enumerator|Event|File|FileObject|FileSystemObject|FileUpload|Folder|Folders|Form|Frame|Function|Global|Hidden|History|HTMLElement|Image|Infinity|Input|JavaArray|JavaClass|JavaObject|JavaPackage|JSObject|Layer|Link|Math|MimeType|Navigator|Number|Object|Option|Packages|Password|Plugin|PrivilegeManager|Random|RegExp|Screen|Select|String|Submit|Text|Textarea|URL|VBArray|Window|WScript|window", regexpLiteral:true } }; var jsEngine = {}; jsEngine.TYPE_KEYWORD = 0; jsEngine.TYPE_MUTILCOMMENT = 1; jsEngine.TYPE_SINGLECOMMENT = 2; jsEngine.TYPE_STRING = 3; jsEngine.TYPE_REGEXP = 4; jsEngine.TYPE_NUMBER = 5; jsEngine.TYPE_TYPES = 6; var formats = []; formats[jsEngine.TYPE_KEYWORD] = { "start": "<span class=\"hl_js_kw\">", "end": "</span>" }; formats[jsEngine.TYPE_MUTILCOMMENT] = { "start": "<span class=\"hl_js_mcm\">", "end": "</span>" }; formats[jsEngine.TYPE_SINGLECOMMENT] = { "start": "<span class=\"hl_js_scm\">", "end": "</span>" }; formats[jsEngine.TYPE_STRING] = { "start": "<span class=\"hl_js_s\">", "end": "</span>" }; formats[jsEngine.TYPE_REGEXP] = { "start": "<span class=\"hl_js_reg\">", "end": "</span>" }; formats[jsEngine.TYPE_NUMBER] = { "start": "<span class=\"hl_js_num\">", "end": "</span>" }; formats[jsEngine.TYPE_TYPES] = { "start": "<span class=\"hl_js_typ\">", "end": "</span>" }; jsEngine.parseSyntax = function(code, formats, lang) { var buff = [], codeBuff = code, codeLen = code.length, sIdx = 0, buffIdx = 0, objBuff = []; var stopIdx = codeLen, searchResult = null, result = null, len = 0; var flgs = {string1: true, string2: true, mutilcm: true, singlecm: true, regcm: !!languages[lang].regexpLiteral }; while (flgs.string1 || flgs.string2 || flgs.mutilcm || flgs.singlecm || flgs.regcm) { searchResult = null; codeLen = code.length; stopIdx = codeLen; if (flgs.string1) { result = searchString(code, codeLen, sIdx, stopIdx, "\""); switch (result) { case null: flgs.string1 = false; break; case -1: break; default: { searchResult = result; searchResult[3] = jsEngine.TYPE_STRING; stopIdx = result[0]; break; } } } if (flgs.string2) { result = searchString(code, codeLen, sIdx, stopIdx, "\'"); switch (result) { case null: flgs.string2 = false; break; case -1: break; default: { searchResult = result; searchResult[3] = jsEngine.TYPE_STRING; stopIdx = result[0]; break; } } } if (flgs.mutilcm) { result = searchMutilComments(code, codeLen, sIdx, stopIdx); switch (result) { case null: flgs.mutilcm = false; break; case -1: break; default: { searchResult = result; searchResult[3] = jsEngine.TYPE_MUTILCOMMENT; stopIdx = result[0]; break; } } } if (flgs.singlecm) { result = searchSingleComments(code, codeLen, sIdx, stopIdx); switch (result) { case null: flgs.singlecm = false; break; case -1: break; default: { searchResult = result; searchResult[3] = jsEngine.TYPE_SINGLECOMMENT; stopIdx = result[0]; break; } } } if (flgs.regcm) { result = searchRegexp(code, codeLen, sIdx, stopIdx); switch (result) { case null: flgs.regcm = false; break; case -1: break; default: { searchResult = result; searchResult[3] = jsEngine.TYPE_REGEXP; break; } } } if (searchResult == null) { buff.push(code); break; } else { /* len = searchResult[1] - searchResult[0] + searchResult[2]; if (searchResult[0] != ŀ) { buff.push(code.substring(sIdx, searchResult[0])) } buff.push([code.substring(searchResult[0], searchResult[1] + searchResult[2]), searchResult[3]]); sIdx = searchResult[1] + searchResult[2]; code = code.substr(sIdx); sIdx = 0;*/ len = searchResult[1] - searchResult[0] + searchResult[2]; if (searchResult[0] != 0) { buff.push(code.substring(sIdx, searchResult[0])) } objBuff.push([code.substring(searchResult[0], searchResult[1] + searchResult[2]), searchResult[3]]); buff.push("<_" + (objBuff.length - 1) + "_>"); sIdx = searchResult[1] + searchResult[2]; code = code.substr(sIdx); sIdx = 0; } } //dt = new Date(); /* for (i = 0, len = buff.length; i < len; i++) { if (typeof(buff[i]) == "string") { reg = new RegExp("\\b(" + keywords + ")\\b", "gm"); result = formats[jsEngine.TYPE_KEYWORD].start + "$1" + formats[jsEngine.TYPE_KEYWORD].end; buff[i] = buff[i].replace(reg, result); reg = new RegExp("\\b(" + types + ")\\b", "gm"); result = formats[jsEngine.TYPE_TYPES].start + "$1" + formats[jsEngine.TYPE_TYPES].end; buff[i] = buff[i].replace(reg, result); reg = /\b([+-]?(?:\d+(?:\.\d*)?(?:e[+-]?\d+)?|0x[\dA-F]+))\b/gim; result = formats[jsEngine.TYPE_NUMBER].start + "$1" + formats[jsEngine.TYPE_NUMBER].end; buff[i] = buff[i].replace(reg, result); } else { buff[i] = ([formats[buff[i][1]].start, buff[i][0], formats[buff[i][1]].end]).join(""); } }*/ //alert(new Date().getTime() - dt.getTime()); buff = buff.join(""); reg = new RegExp("\\b(" + languages[lang].keyword + ")\\b", "g"); result = formats[jsEngine.TYPE_KEYWORD].start + "$1" + formats[jsEngine.TYPE_KEYWORD].end; buff = buff.replace(reg, result); reg = new RegExp("\\b(" + languages[lang].type + ")\\b", "g"); result = formats[jsEngine.TYPE_TYPES].start + "$1" + formats[jsEngine.TYPE_TYPES].end; buff = buff.replace(reg, result); reg = /\b([+-]?(?:\d+(?:\.\d*)?(?:e[+-]?\d+)?|0x[\dA-F]+))\b/gim; result = formats[jsEngine.TYPE_NUMBER].start + "$1" + formats[jsEngine.TYPE_NUMBER].end; buff = buff.replace(reg, result); buff = buff.replace(/<_(\d+)_>/g, function(m, n) { return formats[objBuff[n][1]].start + objBuff[n][0] + formats[objBuff[n][1]].end; }); //return buff.join(""); return buff; } function searchMutilComments(code, codeLen, sIdx, stopIdx) { var startIdx = -1, endIdx = -1; if (codeLen < 4) return null; startIdx = code.indexOf("/*", sIdx); if (startIdx == -1) return null; if (startIdx > stopIdx) return -1; endIdx = code.indexOf("*/", startIdx + 2); if (endIdx == -1) return null; return [startIdx, endIdx, 2]; } function searchString(code, codeLen, sIdx, stopIdx, ch) { var at = sIdx, i = 0, isEscape = false, startIdx = -1, endIdx = -1, len = 0; var isMutilLine = false, fragments = null, isContinueSearch = false, tCh = null, fragm = null, fragmLen = 0; if (codeLen < 2) return null; while(true) { startIdx = code.indexOf(ch, at); if (startIdx == -1) return null; if (startIdx > stopIdx) return -1; if (startIdx > at) { i = startIdx, isEscape = false; while(code.charAt(--i) == "\\") isEscape = !isEscape; if (isEscape) { at = startIdx + 1; if ((at + 2) > stopIdx) return -1; continue; } } break; } if (startIdx > stopIdx) return -1; at = startIdx + 1; lab_searchString: while(true) { while(true) { endIdx = code.indexOf(ch, at); if (endIdx == -1) return null; if (endIdx > at) { i = endIdx, isEscape = false; while(code.charAt(--i) == "\\") isEscape = !isEscape; if (isEscape) { at = endIdx + 1; continue; } } break; } isMutilLine = code.indexOf("\n", startIdx + 1); if (isMutilLine != -1 && isMutilLine < endIdx) { fragments = code.substring(startIdx + 1, endIdx).split("\n"); len = fragments.length - 1; for (i = 0; i < len; i++) { fragm = fragments[i]; fragmLen = fragm.length; tCh = fragm.charCodeAt(fragmLen - 1) == 13 ? fragm.charAt(fragmLen - 2) : fragm.charAt(fragmLen - 1); if (tCh != "\\") { if (endIdx > stopIdx) return -1; if ((endIdx + 1) == stopIdx) return -1; startIdx = endIdx; at = startIdx + 1; continue lab_searchString; } } } break; } return [startIdx, endIdx, 1]; }; function searchSingleComments(code, codeLen, sIdx, stopIdx) { var at = sIdx, i = 0, isEscape = false, startIdx = -1, endIdx = -1; if (codeLen < 2) return null; while(true) { startIdx = code.indexOf("//", at); if (startIdx == -1) return null; if (startIdx > stopIdx) return -1; if (startIdx > at) { i = startIdx, isEscape = false; while(code.charAt(--i) == "\\") isEscape = !isEscape; if (isEscape) { at = startIdx + 2; if ((at + 3) > stopIdx) return -1; continue; } } break; } endIdx = code.indexOf("\n", startIdx + 2); return [startIdx, endIdx == -1 ? code.length : endIdx, 0]; }; function searchRegexp(code, codeLen, sIdx, stopIdx) { var at = sIdx, i = 0, isEscape = false, tmpResult = null, ch = null, endAt = 0, tmpStr = null; var startIdx = -1, tSIdx = -1, eStopIdx = -1, endIdx = -1, escapeFlg = "\\", bIdx = -1, eIdx = -1, bAt = -1, eAt = -1; function sEnd(code, startIdx) { var endIdx = -1, endAt = startIdx, i = 0, isEscape = false; while(true) { endIdx = code.indexOf("/", endAt); if (endIdx == -1) return -1; i = endIdx, isEscape = false; while(code.charAt(--i) == "\\") isEscape = !isEscape; if (isEscape) { endAt = endIdx + 2; continue; } else { return endIdx; } } } if (codeLen < 2) return null; while(true) { startIdx = code.indexOf("/", at); if (startIdx == -1) return null; if (startIdx > stopIdx) return -1; switch(code.charAt(startIdx + 1)) { case null : case "\r": case "\n": case "*": case "/": { at = startIdx + 2; if ((at + 2) > stopIdx) return -1; continue; } } if (startIdx > at) { i = startIdx, isEscape = false; while(code.charAt(--i) == "\\") isEscape = !isEscape; if (isEscape) { at = startIdx + 2; if ((at + 3) > stopIdx) return -1; continue; } } tmpResult = code.indexOf("\n", startIdx + 1); //不允许在不同行 eStopIdx = tmpResult == -1 ? codeLen : tmpResult; tmpStr = code.substring(0, startIdx); if(!/(?:[!=(,:+\-*%&|!~\[\/\n;{}?\r\n]|\btypeof|\bin|\binstanceof|\bvoid|\bnew|\breturn|\bdo|\belse|\bthrow|^)[ \t]*$/.test(tmpStr)) { //LZ写的比我还夸张 at = startIdx + 1; continue; } endAt = (code.charAt(startIdx + 1) == "[" ? 1 : 2) + startIdx; endIdx = sEnd(code, endAt); if (endIdx == -1) return null; bAt = startIdx + 1; while(true) { bIdx = code.indexOf("[", bAt); if (bIdx == -1) break; i = bIdx, isEscape = false; while(code.charAt(--i) == "\\") isEscape = !isEscape; if (isEscape) { bAt = bIdx + 1; continue; } if (bIdx > endIdx) break; eAt = bIdx + 2; while(true) { eIdx = code.indexOf("]", eAt); if (eIdx == -1) break; i = eIdx, isEscape = false; while(code.charAt(--i) == "\\") isEscape = !isEscape; if (isEscape) { eAt = eIdx + 1; continue; } if (eIdx > endIdx) { endAt = eIdx + 1; endIdx = sEnd(code, endAt); if (endIdx == -1) return null; } bAt = eIdx + 1; break; } } if (endIdx > eStopIdx) { at += 1; continue; } break; } return [startIdx, endIdx, 1]; } </script> </head> <body> <p id="msg">请输入代码测试一下,如果是PHP输出,请使用htmlspecialchars对其编码</p> <textarea id="codeArea" style="width:1000px;height:300px;"> // test 1 function myfun(id) { /* this is mutilcomments "string" keyword: function */ var str = "this is a string, /*fasasdf*/ //fdsasdf /^reg/"; var reg = /^fdadfasdf$/ig; return "myvalue"; // hahah } //test 2 if(str.match(/(?:(?:[!=(,:]|\[|\n)[ \t]*\/$)|^\n?[\t ]*\/$/)){} //test 3 a = 1 b = 2 g = {test:function(){return 1}} c = a// /* */ /b/g.test(); alert(c); // test 4 function t4(test) { return (test/* /* // ' " { ; \*/ && // /* // " ' { ; \ test && " /* // \ \" ' \ { ;" && ' /* // \ " \' \ { ;' && test); } // test 5 var rexT5 = /[/][+]([\S\s]*?)(?:[+][/]|$)|[/][/](.*)|"((?:\\"|[^"])*)"|'((?:\\'|[^'])*)'/g; //正则 var nu = 1/2/3 //这是除法 var str = "123//456".replace(/[/]/g,'')+1/2/3; //comment var o=[/re/,(/re/),typeof /re/,function(){return /re/},'o' in /re/,1 / /re/,!/re/]; var m = ereturn/2/3; </textarea> <input type="button" id="btn" value="上色" /> <pre id="codePre"> </pre> </body> </html>请问这个js语法高亮显示的。是51js写的。。针对的js。。
如果要增加其它语言的,例如:
asp/php/c#的。。
应该如何修改啊?