サクラエディタでJSON整形
サクラエディタ v2.4.1.2849
はじめに
例によって、サクラエディタで動かせるJSON整形用のJscriptマクロ作る。
始めに言っとくと、JSON整形機能なんてエディタや他のツールに標準で備わってることも珍しくないです。
なので正直、一々コード書くほどのものじゃない。
でも何か宗教上の理由とかでVSCodeやPostmanが使えないなんて場合に整形用のマクロ持ってると、役立つ場面が万一であるかもね。
ただ、標準のJSONライブラリなんて立派なモノJscriptにはありませんからね。
ゴリゴリ書いてくしかないんです。
経緯
サクラエディタが提供しているBracketPair();は対括弧の検索ができるのだが、
これ使ってjson整形できないかと思い立ったのが始まり。
アルゴリズムを組んでAI君に精査してもらおう。
…
……
すると文字列リテラル内の波括弧{}とかどうすんのと突っ込みが入る。
確かに。
しょうがないので、一文字ずつ走査する方針に決定。
方針決めたら後はAI君に手動かしてもらいますよ。
整形用コード
// JSON整形マクロ for サクラエディタ
// 選択範囲のJSON文字列を整形する
var tabChar = "\t"; // インデントに使う文字("\t" または " ")
var jsonText = Editor.GetSelectedString(0); // 選択範囲の文字列を取得
var result = "";
var depth = 0;
var inString = false;
var prevChar = "";
var i;
// 文字列を1文字ずつ走査
for (i = 0; i < jsonText.length; i++) {
var c = jsonText.charAt(i);
// 文字列リテラル内かどうかを判定
if (c === '"' && prevChar !== '\\') {
inString = !inString;
result += c;
} else if (!inString) {
switch (c) {
case '{':
case '[':
result += c + "\r\n";
depth++;
result += repeatIndent(depth, tabChar);
break;
case '}':
case ']':
result += "\r\n";
depth--;
result += repeatIndent(depth, tabChar) + c;
break;
case ',':
result += c + "\r\n" + repeatIndent(depth, tabChar);
break;
case ':':
result += c + " ";
break;
default:
result += c;
}
} else {
result += c;
}
prevChar = c;
}
// インデント文字列を生成する関数
function repeatIndent(count, char) {
var s = "";
for (var j = 0; j < count; j++) {
s += char;
}
return s;
}
// 整形済みJSONを挿入
Editor.InsText(result);
お、ちゃんとインデント生成のお仕事を外出ししてるね。
関心関心。
で、これよりもっとスマートに書けないものかね、とAI君に質問すると、
JSON.parse()とかの標準ライブラリ使えば10行程度で書けまっせと返ってきた。
。。
。。。
だからそれが使えないから色々やっとんねんって話。
我、JScriptぞ?
その旨伝えると、古いwindows環境ではこの方法無理だったかもですね(意訳)と煽られる始末。
間違いを認められないの良くないよAI君。
ただ、AI君もレガシーな言語でコード書けなんて言われてイライラしとったんやな。
まま、こっちが大人になろうや。
でも最後にはちゃんとコード出してくれるAI君はやっぱりできる子だね。
// サクラエディタ用:簡易JSON整形マクロ(JScript)
var json = Editor.GetSelectedString(0);
var out = "", depth = 0, inStr = false, prev = "";
for (var i = 0; i < json.length; i++) {
var c = json.charAt(i);
if (c === '"' && prev !== '\\') inStr = !inStr;
if (!inStr) {
if (c === '{' || c === '[') {
out += c + "\r\n" + indent(++depth);
} else if (c === '}' || c === ']') {
out += "\r\n" + indent(--depth) + c;
} else if (c === ',') {
out += c + "\r\n" + indent(depth);
} else if (c === ':') {
out += ": ";
} else if (c === ' ' || c === '\t' || c === '\r' || c === '\n') {
// skip whitespace outside strings
} else {
out += c;
}
} else {
out += c;
}
prev = c;
}
function indent(n) {
return Array(n + 1).join("\t");
}
Editor.InsText(out);
やってることはあんま変わりませんな。
trimなんて便利なモノ使えないこともちゃんと分かってるね。
じゃあJSON用メソッド使えないこと知ってても良くない?とは思ったけど。
最後に
こっちの遊びに付き合ってくれるAI君は偉いという話。
でもこれ、今を時めくAI君にレガシー言語使わせるって何かのハラスメントにあたりませんかね?
Java6で書かれたきったないJSPの改修振られたとき同じようなこと思いながら仕事してましたよ、これ絶対何かのハラスメントだろって。
その前にハイパーモダンな環境でJava17辺り使って開発してたから、上昇不可で死にそうだったなー
thanks for reading!