/* 縦位置揃え 複数列対応&デリミタ自動選択 デリミタは事前に設定したものの中から自動判別します PukiWikiのテーブルや、複数行にわたる配列の初期化子などに、幅広く使えます written by Nickle 2007/4/21- 動作例 |a|bbb|c|h |a |bbb |c |h |aaa| bb|ccc| --> |aaa| bb|ccc| |aaa|b|cc| |aaa|b |cc | a ,bb,cccc a ,bb ,cccc aa,b,c --> aa ,b ,c a,bbb,cc a ,bbb,cc const char* array[] = { const char* array[] = { "a", "b", "c", "a" , "b" , "c" , "aaa", "b", "cc", --> "aaa", "b" , "cc", "aa", "bbbb", "c", "aa" , "bbbb", "c" , }; }; // 各要素の先頭・末尾の空白を削除すると、こういう場合に綺麗にいかない int i = 0; int i = 0; int abc = 1; --> int abc = 1; int longlonglong = 2; int longlonglong = 2; 仕様 ・矩形選択は非対応です ・デリミタは、delimitersの中から最初に現れたものを選択します ・タブは考慮しません。必要なら空白<->タブ変換と組み合わせて使うと吉です */ // 設定 -------------------------------------------------------------- // デリミタ候補。優先度の高い順に並べてください var delimiters = [ "|", ",", "=" ]; // 各要素の先頭・末尾の空白を削除するかどうか // (有効にするなら、インデントなど意図して入れてある場合に注意) var removeLeadingSpace = false; var removeTrailingSpace = false; // ここまで ---------------------------------------------------------- var delimiter = ""; main(); function main() { if(Editor.IsTextSelected() == 0) return; var lines = getSelectedLines(); // デリミタ決定 outer: for(i in delimiters) { for(j in lines) { if(lines[j].indexOf(delimiters[i]) != -1) { delimiter = delimiters[i]; break outer; } } } if(delimiter == "") return; // Editor.InsText(delimiter); // 各列の最大幅取得 var maxWidth = new Array; for(i in lines) { var cols = getCols(lines[i]); // デリミタがひとつもない行 if(cols.length == 1) continue; for(j in cols) { if(maxWidth[j] == null) maxWidth[j] = bytes(cols[j]); else maxWidth[j] = Math.max(maxWidth[j], bytes(cols[j])); } } // Editor.InsText(maxWidth.join(",")); // 最大幅に合わせて整形 var out = new Array; for(i in lines) { var cols = getCols(lines[i]); // デリミタがひとつもない行 if(cols.length == 1) { out.push(lines[i]); continue; } // 各列に空白を入れる var newCols = new Array; for(j in cols) { var s = cols[j]; assert(bytes(s) <= maxWidth[j]); newCols[j] = s; for(var i=0;i<maxWidth[j] - bytes(s); i++) newCols[j] += " "; } // 行全体を生成 out.push(newCols.join(delimiter).replace(/\s+$/, "")); /* "|a|b|c|".split("|") => ("", a, b, c, "") ("", a, b, c, "").join("|") => |a|b|c| ということで、先頭や末尾のデリミタも気にしなくてOK。幸せだ */ } Editor.InsText(out.join(newLine())); } function assert(cond) { if(!cond) throw new Error("assertion failed!", cond); } function newLine() { switch(Editor.GetLineCode()) { case 0: return "\r\n"; case 1: return "\r"; case 2: return "\n"; } } function getSelectedLines() { var lines = Editor.GetSelectedString(0).split(newLine()); return lines; } // thx to Macro-BBS[341] function isWide(charCode) { return 0x80 <= charCode && (charCode <= 0xff60 || 0xffa0 <= charCode); } // Shift-JIS換算のバイト数(=画面上の表示桁数)を返す function bytes(str) { var bytes = 0; for (var i=0;i<str.length;i++) { var ch = str.charCodeAt(i); if (isWide(ch)) bytes += 2; else bytes += 1; } return bytes; } function getCols(line) { var cols = line.split(delimiter); // 各列になにか操作したければここで for(i in cols) { if(removeLeadingSpace) cols[i] = cols[i].replace(/^\s+/, ""); if(removeTrailingSpace) cols[i] = cols[i].replace(/\s+$/, ""); } return cols; } |