/************************************************************
*
* JavaScript の構文色分け表示
*
* ソースがC言語風なのは仕方ないなぁ
*
* Copyright (c) 2005, 2006, 2009 AOK. All Rights Reserved.
*
************************************************************/
function JSParser() {
//////////////////////////////////////////////////////////
this.color_keyword = "<span style='color:blue'>";
this.color_comment = "<span style='color:#C00000'>";
this.color_string = "<span style='color:teal'>";
this.color_end = "</span>";
var __keys = new Array(
"abstract","assert","boolean","break","byte","case","catch","char","class",
"const","continue","debugger","decimal","default","delete","do","double","else",
"ensure","enum","event","export","extends","false","final","finally","float",
"for","function","get","goto","if","implements","import","in","instanceof","int",
"interface","internal","invariant","long","namespace","native","new","null",
"package","private","protected","protected","public","require","return","sbyte",
"set","short","static","super","switch","synchronized","this","throw","throws",
"transient","true","try","typeof","uint","ulong","use","ushort","var","void",
"volatile","while","with"
);
var src, dest, chbuf;
var pos, error;
var cl_key, cl_com, cl_str, cl_end;
/* 1文字取ってくる */
var getnext = function() {
if (pos >= src.length) {
error++;
return false;
}
chbuf = src.charAt(pos++);
return true;
};
/* 1文字戻す */
var ungetnext = function() {
if (--pos < 0) error++;
};
/* 予約語の連想配列を作成 */
var keys = new Object();
(function() {
for (var i = 0; i < __keys.length; i++)
keys['_' + __keys[i]] = true;
})();
/* 標準の書き出し */
var normal = function() {
if (chbuf == ">") dest += ">";
else if (chbuf == "<") dest += "<";
else if (chbuf == "&") dest += "&";
else if (chbuf == "\"") dest += """;
else dest += chbuf;
};
/* コメント文 (C Style) */
var comment = function() {
dest += cl_com + "/*";
while (getnext()) {
if (chbuf == "*") {
dest += chbuf;
if (!getnext()) return;
if (chbuf == "/") {
dest += chbuf + cl_end;
return;
} else if (chbuf == "*") {
ungetnext();
} else normal();
} else normal();
}
dest += cl_end;
};
/* コメント文 (C++ Style) */
var comment_line = function() {
dest += cl_com + "//";
while (getnext()) {
if (chbuf == "\n") {
dest += cl_end + "\n";
return;
} else normal();
}
dest += cl_end;
};
/* 文字列定数 */
var string = function(c) {
var escape = false;
if (c == "\"")
dest += cl_str + """;
else
dest += cl_str + c;
while (getnext()) {
if (escape == 0 && chbuf == c) {
if (c == "\"")
dest += """ + cl_end;
else
dest += c + cl_end;
return;
} else if (chbuf == "\\") {
escape = !escape;
dest += chbuf;
} else {
escape = false;
normal();
}
}
dest += cl_end;
};
/* 予約語を探す */
var symbol = function() {
var buf = "";
buf += chbuf;
if (!getnext()) {
dest += buf;
return;
}
while (chbuf.match(/[\w]/)) {
buf += chbuf;
if (!getnext()) break;
}
if (keys['_' + buf])
dest += cl_key + buf + cl_end;
else
dest += buf;
if (!error) ungetnext();
};
/* 最初の文字を判定して処理を分岐する */
var getsym = function() {
if (!getnext()) return;
if (chbuf == "/") {
if (!getnext()) {
dest += "/";
return;
}
if (chbuf == "*")
comment();
else if (chbuf == "/")
comment_line();
else {
dest += "/";
ungetnext();
}
} else if (chbuf == "\"" || chbuf == "'") {
string(chbuf);
} else if (chbuf.match(/[\w]/)) {
symbol();
} else if (chbuf == "=" || chbuf == "(") {
normal();
while (getnext()) {
if (chbuf.match(/\s/)) {
normal();
} else if (chbuf == "/") {
string(chbuf);
break;
} else {
ungetnext();
break;
}
}
} else {
normal();
}
};
/* 解析 */
this.parse = function(str) {
cl_key = this.color_keyword;
cl_com = this.color_comment;
cl_str = this.color_string;
cl_end = this.color_end;
src = str.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
dest = "<pre>";
pos = error = 0;
while (!error) getsym();
return dest + "</pre>";
};
//////////////////////////////////////////////////////////
} |