マルチカーソルに連番を入力

提供: MeryWiki
ナビゲーションに移動 検索に移動

概要[編集]

Mery Ver.3 で搭載されたマルチカーソル機能を利用している状態で実行することで各カーソル箇所に連番を入力します。

実行時に表示されるポップアップにて、入力する連番の

  • 開始値
  • 増分値
  • ゼロパディング桁数
  • 書式 (数字のあとに . (ドット) を付けるなど)

の指定が可能です。

ソースコード[編集]

#title = "マルチカーソルに連番を入力";
BeginUndoGroup();
Redraw = false;

var doc = document;
var sel = document.selection;

main();

function main() {
    if (sel.Mode !== meModeMulti) {
        return;
    }

    // オプションと書式を指定
    var option = Prompt(
        "書式を指定してください",
        "開始値=1|増分値=1|ゼロパディング桁=0|書式={num}");
    if (!option) {
        return;
    }
    // オプションをパース
    try {
        var start_num = option.match(/開始値=(\d+)/)[1];
        if (!start_num || isNaN(start_num)) {
            throw new Error();
        }
        start_num = Number(start_num);

        var increment = option.match(/増分値=(\d+)/)[1];
        if (!increment || isNaN(increment)) {
            throw new Error();
        }
        increment = Number(increment);

        var zero_padding = option.match(/ゼロパディング桁=(\d+)/)[1];
        if (!zero_padding || isNaN(zero_padding)) {
            throw new Error();
        }
        zero_padding = Number(zero_padding);

        var format = option.match(/書式=(.+)/)[1];
        if (!format) {
            throw new Error();
        }
    } catch (e) {
        alert("書式が不正です。")
        return;
    }

    doMultiAction(countupFunction(start_num, increment, zero_padding, format));
}

function countupFunction(start_num, increment, zero_padding, format) {
    // クロージャで変数を保持
    var count = start_num;

    var padZero = function (num) {
        var zero = "";
        for (var i = 0; i < zero_padding; i++) {
            zero += "0";
        }
        // 桁数より大きい場合はそのまま返す
        if (num.toString().length > zero_padding) {
            return String(num);
        } else {
            return (zero + num).slice(-zero_padding);
        }
    }

    return function () {
        sel.Text = format.replace(/{num}/g, padZero(count));
        count = count + increment;
    }
}

function doMultiAction(fn) {
    sel.Mode = meModeMulti;
    // ① まず、GetActivePos と GetAnchorPos で複数選択のリストを作成します
    var selections = [{ s: sel.GetAnchorPos(), e: sel.GetActivePos() }];
    if (sel.Count > 0) {
        selections = [];
        for (var i = 0; i < sel.Count; i++)
            selections.push({ s: sel.GetAnchorPos(i), e: sel.GetActivePos(i) });
    }
    var p = 0;
    var q = 0;
    for (var i = 0; i < selections.length; i++) {
        // ② そのリストを上から順に SetActivePos で、「シングルカーソル」で範囲選択します。この段階で複数選択は解除され、通常のマクロ操作が可能となります
        sel.SetActivePos(selections[i].s + p);
        sel.SetActivePos(selections[i].e + p, true);
        q = doc.TextLength;
        // ③ <ここで通常のマクロの機能を使って普通に編集などを行います>
        fn();
        p += doc.TextLength - q;
        // ④ 処理を行った後の選択範囲をリストに反映し、これをリストの最後まで繰り返します
        selections[i] = { s: sel.GetAnchorPos(), e: sel.GetActivePos() };
    }
    // ⑤ そのリストを上から順に document.selection.AddPos(StartPos, EndPos) で複数選択として復元します
    for (var i = 0; i < selections.length; i++)
        sel.AddPos(selections[i].s, selections[i].e);
}
スポンサーリンク