共计 6149 个字符,预计需要花费 16 分钟才能阅读完成。
这是对 SQL 实现语法高亮的局部:
// 可用的语法着色数据
var Colors = {
//Sql 暗
SqlDark: {
"language": "Sql",
"theme": "dark",
"objectColor": "#8BC96C",
"operatorColor": "#A7A7A7",
"annotationColor": "#3E983E",
"annotationsColor": "#3E983E",
"stringColor": "#FF9393",
"constantColor": "#B5CEA8",
"keywordsInfo": [{
"color": "#7C9DED",
"keywords": ["USE", "GO", "SET", "ANSI_NULLS", "OFF", "ALTER", "TABLE", "UPDATE", "ORDER", "BY", "DESC", "ASC", "PROCEDURE", "QUOTED_IDENTIFIER", "IDENTITY_INSERT", "OUTPUT", "INT", "BIGINT", "NCHAR", "VARCHAR", "NTEXT", "VARBINARY", "BINARY", "SYSNAME", "AS", "NOCOUNT", "ON", "DECLARE", "IF", "ELSE", "BEGIN", "END", "WHILE", "CASE", "WHEN", "THEN", "RAISERROR", "RETURN", "SELECT", "TOP", "DELETE", "EXEC", "FROM", "WHERE", "TRAN", "SAVE", "INSERT", "INTO", "VALUES", "TYPE", "GOTO", "COMMIT", "UNDO:", "ROLLBACK", "TRANSACTION", "NVARCHAR", "SYSNAME", "UNIQUEIDENTIFIER", "BIT", "TINYINT", "DATETIME", "MASTER", "VERSION", "EXECUTE", "DBCC", "SYSTEM", "PRINT"]
}, {
"color": "#A7A7A7",
"keywords": ["NULL", "AND", "IS", "OR", "NOT", "IN", "EXISTS", "BETWEEN", "LEFT", "RIGHT", "JOIN"]
}, {
"color": "#C940C9",
"keywords": ["COLLATE"]
}],
"functionsInfo": [{
"color": "#C940C9",
"keywords": ["CONVERT", "ISNULL", "IS_SRVROLEMEMBER", "ROW_NUMBER", "MAX", "MIN", "COUNT", "UPPER", "LOWER", "SUBSTRING", "REPLACE", "LEN", "IDENT_CURRENT", "QUOTENAME", "RTRIM", "LTRIM", "SUM", "DB_ID", "DB_NAME", "CAST", "PLATFORM", "SERVERPROPERTY", "NEWID", "DATALENGTH", "OBJECT_ID"]
}]
}
};
// 应用某一种色彩数据对指定的文本进行语法着色(主入口)function StainColor(text, colorObj) {if (colorObj.language == "Sql") {return StainGrammerSql(text, colorObj);
}
}
//Sql 语法着色
function StainGrammerSql(text, colorObj) {text = text.replace(/&/g, "&");
text = text.replace(/\</g, "<").replace(/\>/g, ">");
var t_regex = null;
// 临时排除单引号模式的字符串
var chars = new Array();
var tchar = null;
while (tchar = text.match(/N?'(?:(?:'')|[^'\r\n]|)*'/)) {text = text.replace(/N?'(?:(?:'')|[^'\r\n]|)*'/, "###char_{" + chars.length + "}###");
chars.push(tchar[0]);
}
// 临时排除多行正文
var comments = new Array();
var tcomment = null;
while (tcomment = text.match(/\/\*(?:.|\s)*?\*\//)) {text = text.replace(/\/\*(?:.|\s)*?\*\//, "###comment_{" + comments.length + "}###");
comments.push(tcomment[0]);
}
// 临时排除单行正文
var annotations = new Array();
var tannotation = null;
while (tannotation = text.match(/\-\-.*/)) {text = text.replace(/\-\-.*/, "###annotation_{" + annotations.length + "}###");
annotations.push(tannotation[0]);
}
// 临时排除标量变量
var vars = new Array();
var tvar = null;
while (tvar = text.match(/@[\d\w$#@]*/)) {text = text.replace(/@[\d\w$#@]*/, "###var_{" + vars.length + "}###");
vars.push(tvar[0]);
}
// 临时排除运算符
var operators = new Array();
var toperator = null;
while (toperator = text.match(/(?:<)|(?:>)|(?:&)|[\(\),=\+\-\*\/!&~\.%]/)) {text = text.replace(/(?:<)|(?:>)|(?:&)|[\(\),=\+\-\*\/!&~\.%]/, "###operator_{" + operators.length + "}###");
operators.push(toperator[0]);
}
// 临时排除常数
var constants = new Array();
var tconstant = null;
while (tconstant = text.match(/\b\d+(?!\}#)\b/)) {text = text.replace(/\b\d+(?!\}#)\b/, "###constant_{" + constants.length + "}###");
constants.push(tconstant[0]);
}
// 临时排除对象标识符
var objects = new Array();
while (text.indexOf("[") >= 0) {var charStart = pCrt = text.indexOf("[");
var cCrt = '';
while (cCrt = text[pCrt]) {if (cCrt == "[") {charStart = pCrt;}
else if (cCrt == "]") {var center = text.substring(charStart, pCrt + 1);
var left = text.substr(0, charStart);
var right = text.substr(pCrt + 1);
var replaced = "###object_{" + objects.length + "}###";
objects.push(center);
text = left + replaced + right;
break;
}
pCrt += 1;
}
}
// 关键字着色
for (var i = 0; i < colorObj.keywordsInfo.length; i++) {for (var j = 0; j < colorObj.keywordsInfo[i].keywords.length; j++) {t_regex = new RegExp("\\b" + colorObj.keywordsInfo[i].keywords[j] + "\\b", "gi");
var coloredText = "<strong style=\"color:"+ colorObj.keywordsInfo[i].color +";\">" + colorObj.keywordsInfo[i].keywords[j] + "</strong>";
text = text.replace(t_regex, coloredText);
}
}
// 函数着色
for (var i = 0; i < colorObj.functionsInfo.length; i++) {for (var j = 0; j < colorObj.functionsInfo[i].keywords.length; j++) {t_regex = new RegExp(colorObj.functionsInfo[i].keywords[j] + "(?= *###operator_)", "gi");
var coloredText = "<strong style=\"color:"+ colorObj.functionsInfo[i].color +";\">" + colorObj.functionsInfo[i].keywords[j] + "</strong>";
text = text.replace(t_regex, coloredText);
}
}
// 还原并着色对象标识符
for (var i = 0; i < objects.length; i++) {var coloredText = "<strong style=\"color:"+ colorObj.objectColor +";\">" + objects[i] + "</strong>";
t_regex = new RegExp("###object_\\{" + i + "\\}###");
text = text.replace(t_regex, coloredText);
}
// 还原并着色常数
for (var i = 0; i < constants.length; i++) {var coloredText = "<strong style=\"color:"+ colorObj.constantColor +";\">" + constants[i] + "</strong>";
t_regex = new RegExp("###constant_\\{" + i + "\\}###");
text = text.replace(t_regex, coloredText);
}
// 还原并着色运算符
for (var i = 0; i < operators.length; i++) {var coloredText = "<strong style=\"color:"+ colorObj.operatorColor +";\">" + operators[i] + "</strong>";
t_regex = new RegExp("###operator_\\{" + i + "\\}###");
text = text.replace(t_regex, coloredText);
}
// 还原并着色标量变量
for (var i = 0; i < vars.length; i++) {var coloredText = "<strong style=\"color:"+ colorObj.objectColor +";\">" + vars[i] + "</strong>";
t_regex = new RegExp("###var_\\{" + i + "\\}###");
text = text.replace(t_regex, coloredText);
}
// 还原并着色非空单引号模式的字符串
for (var i = 0; i < chars.length; i++) {var coloredText = "<strong style=\"color:"+ colorObj.stringColor +";\">" + chars[i] + "</strong>";
t_regex = new RegExp("###char_\\{" + i + "\\}###");
text = text.replace(t_regex, coloredText);
}
// 还原并着色单行正文
for (var i = 0; i < annotations.length; i++) {
// 还原单行正文中单引号模式的字符串
var t_char = null;
while (t_char = annotations[i].match(/###char_\{(\d+)\}###/)) {annotations[i] = annotations[i].replace(/###char_\{(\d+)\}###/, chars[t_char[1]]);
}
// 还原单行正文中的多行正文
var t_comment = null;
while (t_comment = annotations[i].match(/###comment_\{(\d+)\}###/)) {annotations[i] = annotations[i].replace(/###comment_\{(\d+)\}###/, comments[t_comment[1]]);
}
var coloredText = "<strong style=\"color:"+ colorObj.annotationColor +";\">" + annotations[i] + "</strong>";
t_regex = new RegExp("###annotation_\\{" + i + "\\}###");
text = text.replace(t_regex, coloredText);
}
// 还原并着色多行正文
for (var i = 0; i < comments.length; i++) {
// 还原正文中单引号模式的字符串
var t_char = null;
while (t_char = comments[i].match(/###char_\{(\d+)\}###/)) {comments[i] = comments[i].replace(/###char_\{(\d+)\}###/, chars[t_char[1]]);
}
var coloredText = "<strong style=\"color:"+ colorObj.annotationsColor +";\">" + comments[i] + "</strong>";
t_regex = new RegExp("###comment_\\{" + i + "\\}###");
text = text.replace(t_regex, coloredText);
}
return text;
}
SQL 的高亮相对来讲并不是很简单,因为大小写不敏感和语法不够谨严的关系,这里次要是采取的关键字高亮的办法,只是用到了不同色彩的关键字,成果如下图:
正文完
发表至: javascript
2021-04-17