コモノExtendScript100本ノック

超初心者のDTPオペレーターが週にひとつスクリプトを書くブログ

063.【Id】マスターページ一括割り当て

挙動

  1. 起動するとダイアログが立ち上がる
    f:id:haraguai_is_bad:20200215102353p:plain:w300
  2. ダイアログに表示されたレイヤー名を元に、以下のようなテキストデータを作成する
    ページ範囲 [タブ] マスター名1
    ページ範囲 [タブ] マスター名2
    (ページの指定は名前か絶対ページ番号で行う。どちらも「-」での範囲指定可)
  3. ページ名と絶対ページ番号のどちらで指示するか、ラジオボタンで指定する
  4. 実行を押すと指示書の通りにマスターを宛がう

コード

//@targetengine "setMaster"
/* 
あらかじめ以下のようなテキストデータを作成する。
ページ範囲 [タブ] マスター名1
ページ範囲 [タブ] マスター名2
*/
var main = function() {
    app.scriptPreferences.enableRedraw = false;

    var doc = app.activeDocument;
    var mstNames = [];
    for (var i = 0, mst = doc.masterSpreads; i < mst.length; i++) {
        mstNames.push(mst[i].name);
    }
    if (app.documents.length === 0) {
        alert("開いているドキュメントがないため中断します");
        exitFlag = true;
        exit();
    }
    // ウィンドウを作成
    var dialog = new Window("dialog");
    dialog.text = "マスターページ一括指定";
    dialog.orientation = "column";
    dialog.alignChildren = ["center", "top"];

    var statictext2 = dialog.add("statictext");
    statictext2.text = "マスターページ一覧";

    var edittext2 = dialog.add('edittext {properties: {multiline: true, scrollable: true}}');
    edittext2.text = mstNames.join("\n");
    edittext2.preferredSize.width = 200;
    edittext2.preferredSize.height = 300;
    edittext2.multiline = true;

    var group1 = dialog.add("group");
    group1.orientation = "row";

    var radiobutton1 = group1.add("radiobutton");
    radiobutton1.text = "ページ名で指定";
    var radiobutton2 = group1.add("radiobutton");
    radiobutton2.text = "絶対ページ番号で指定";

    var button1 = dialog.add("button");
    button1.text = "実行";

    button1.onClick = function() {
        dialog.close(1);
    }
    var dlgResult = dialog.show();
    if (dlgResult !== 1) {
        alert("中断しました");
        exitFlag = true;
        exit();
    }

    if (radiobutton1.value === false && radiobutton2.value === false) {
        alert("ページ指定の種類が選択されていないため中断しました。");
        exitFlag = true;
        exit();
    }
    var myList = fileRead("page", "master");
    var cnt = myList.length;

    for (var i = 0; i < cnt; i++) {
        try {

            if (radiobutton1.value) {
                // ページ名で指定した場合
                var tmp = myList[i]['page'].split("-");
                if (tmp[0] === "") {
                    tmp[0] = doc.pages[0].name
                }
                if (tmp[1] === "") {
                    tmp[1] = doc.pages.lastItem().name
                }
                if (tmp[1] === undefined) { // 範囲指定では無い場合
                    myList[i]['pageObjs'] = doc.pages.itemByName(tmp[0]);
                } else {
                    myList[i]['pageObjs'] = doc.pages.itemByRange(doc.pages.itemByName(tmp[0]), doc.pages.itemByName(tmp[1]));
                }
            } else {
                // 絶対ページ番号で指定した場合
                var tmp = myList[i]['page'].replace("+", "").split("-");
                if (tmp[0] === "") {
                    tmp[0] = 1;
                }
                if (tmp[1] === "") {
                    tmp[1] = doc.pages.length;
                }
                if (tmp[1] === undefined) { // 範囲指定では無い場合
                    myList[i]['pageObjs'] = doc.pages[parseInt(tmp[0], 10) - 1];
                } else {
                    myList[i]['pageObjs'] = doc.pages.itemByRange(parseInt(tmp[0], 10) - 1, parseInt(tmp[1], 10) - 1);
                }
            }
            myList[i]['pageObjs'].appliedMaster = doc.masterSpreads.itemByName(myList[i]['master']);
        } catch (e) {
            alert("指定のページあるいはマスターが存在しないため中断しました");
            exitFlag = true;
            exit();
        }
    }

    function fileRead(value /*string*/ ) {
        var tgtFile = File.openDialog("ファイルを選んでください", "*.txt");
        if (!tgtFile || !tgtFile.exists) {
            alert("中断しました");
            exitFlag = true;
            exit();
        }
        var res = [];
        var fileReadFlag;
        tgtFile.open("r");
        tgtFile.encoding = "UTF-8";

        try {
            while (!tgtFile.eof) {
                var args = arguments;
                var ln = tgtFile.readln().split(/\t/);
                if (ln.length !== args.length) {
                    alert("読み込みテキストに不備があるため中断します。");
                    exit();
                    exitFlag = true;
                }
                var item = {};
                for (var i = 0; i < args.length; i++) {
                    item[args[i]] = ln[i];
                }
                res.push(item);
            }
            fileReadFlag = true;
        } catch (e) {
            alert(e);
            fileReadFlag = false;
        } finally {
            tgtFile.close();
        }
        if (!fileReadFlag || res.length === 0) {
            alert("ファイルを読み込めませんでした");
            exit();
            exitFlag = true;
        }
        return res;
    }
}

var exitFlag = false; // main内で中断した場合に完了アラートを出さないようにするため
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.FAST_ENTIRE_SCRIPT, "setMaster.jsx");
if (!exitFlag) {
    app.undo(); // dialogの段階で中断している場合はundoできない
    alert("完了しました");
}

メモ

split()について

var test1 = "001"
var result1 = test1.split("-"); 
// result1[0]は"001"、result1[1]はundefined

var test2 = "001-"
var result2 = test2.split("-"); 
// result1[0]は001、result1[1]は""

var test3 = "-001"
var result3 = test3.split("-"); 
// result1[0]は""、result1[1]は"001"

Falsyな値

0、−0、undefined、空文字、null、false、NaN
つまり if(!result1[0]) では空文字かundefinedか区別できない。

page.index

page.indexは親スプレッドに対するインデックスを意味する。
あるふぁ(仮)さんに教えていただきました。いつもありがとうございます!)

積み残し

  • セクション名を含んだページ指定にも対応