//JavaScript整形マクロ ver 2010/5/22 Array.prototype.peek = function() { return this.length == 0 ? null : this[this.length-1]; }; String.prototype.trim = function() { return this.replace(/(^\s*|\s*$)/g, ""); }; //設定変数 var CRLF = "\r\n"; //改行コード var INDENT_BY_TAB = true; //TABインデントかどうか true:TAB, false:SPACE var SUPPORT_ONELINE_INDENT = false; //if文などで { を省略されている場合、インデントする機能。(未完成) true:有効 false:無効 var s = Editor.GetSelectedString(0); var literals = []; //コメント・正規表現リテラル・文字リテラルの退避 s = s.replace(/(\/\/[^\r\n]*|\/\*(.|\n)*?\*\/|\/(\\.|.)*?\/|"(\\.|.)*?"|'(\\.|.)*?')/g, function(m) { literals.push(m); return "##$$s" + (literals.length-1).toString() + "$$##"; }); //無駄な空白の削除 s = s.replace(/[\r\n]+/, ""); s = s.replace(/\s+/g, " "); //整形 var indent_level = 0; var indent_width; var indent_base = ""; if (INDENT_BY_TAB) { indent_width = 1; for (var i=0; i<40; i++) { indent_base += "\t"; } } else { indent_width = Editor.ChangeTabWidth(0); for (var i=0; i<40*indent_width; i++) { indent_base += " "; } } var paren_stack = []; var statement_stack_length = 0; s = s.replace(/ *(\bif\b|\bfor\b|[{}();,]) */g, function(match) { var m = match.trim(); var index = arguments[arguments.length - 2]; if (m == "{") { paren_stack.push("{"); indent_level++; return " {" + CRLF + indent_base.substr(0, indent_level * indent_width); } else if (m == "}") { while (paren_stack.length > 0) { if (paren_stack.pop() == "{") break; } if(indent_level > 0) indent_level--; return CRLF + indent_base.substr(0, indent_level * indent_width) + "}" + CRLF + indent_base.substr(0, indent_level * indent_width); } else if (m == "(") { paren_stack.push("("); } else if (m == ")") { while (paren_stack.length > 0) { if (paren_stack.pop() == "(") break; } if (paren_stack.length <= statement_stack_length) { statement_stack_length = 0; if (SUPPORT_ONELINE_INDENT) { // { 省略対応 for (var i=1, next = s.charAt(index + i); " \t".indexOf(next) >= 0; i++) { next = s.charAt(index + i); } if (/[a-zA-Z_$]/.test(next)) { return ")" + CRLF + indent_base.substr(0, (indent_level+1) * indent_width); } } } } else if (m == ";" || m == ",") { if (paren_stack.peek() == "(") { return m + " "; } else { return m + CRLF + indent_base.substr(0, indent_level * indent_width); } } else if (m == "if" || m == "for") { // { 省略対応 statement_stack_length = paren_stack.length; if (index > 0 && s.charAt(index - 1) == "e") { m = " " + m; //else if →elseif にならないようスペースを入れる } } return m; }); //無駄な空白の削除 s = s.replace(/[\r\n]\s+[\r\n]/g, CRLF); s = s.replace(/\}\s*\b(else|catch|finally)\b/g, "} $1"); s = s.replace(/\(\s*\{/g, "({"); s = s.replace(/\}\s*([,;)])/g, "}$1"); s = s.replace(/{\s*}/g, "{}"); //微整形 s = s.replace(/ ?(=+|!=+|[><+\-*\/%]=|[><*\/%]|\+\+?|--?|\|\||&&|\?|:) ?/g, " $1 "); s = s.replace(/([ \t])?\b(if|else|do|while|for|try|catch|finally|return|in)\b ?/g, "$1$2 "); s = s.replace(/ +([\r\n])/g, "$1"); //コメント・正規表現リテラル・文字リテラルの復元 s = s.replace(/([ \t]*)##\$\$s[0-9]+\$\$##/g, function(m, preSpace) { var lit = literals[ parseInt(m.replace(/[#$s]+/g, "")) ]; if (/^\/(\/|\*)/.test(lit)) { return preSpace + lit + CRLF + preSpace; } else { return preSpace + lit; } }); Editor.InsText(s);