コモノExtendScript100本ノック

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

071.【Id】ブックから指定したドキュメントを書き出し

ブック内のドキュメントを指定してPDFを書き出すスクリプト
例えば、書籍の途中に挟まる折り込みページだけPDFを分けたいときなどに使うつもりで作成しました。
f:id:haraguai_is_bad:20200508115805p:plain:w300
(↑「02-02_2章-2_折込」だけ別PDFにしたい)

挙動

  1. 以下のような指示書(テキストファイル)を作成する。
    f:id:haraguai_is_bad:20200508115823p:plain:w300
  2. ブックを一つ開いた状態で実行する。
  3. 1で作成した指示書を指定する。
  4. PDFの書き出しプリセットを指定する。
  5. ブックと同階層にPDFが書き出される。

コード

以前の記事のコメントでご紹介いただいた、UskeSさんによるArray.some()のポリフィル(InDesign-Scripts/array_some.jsxinc at master · UskeS/InDesign-Scripts · GitHub)をお借りしています。

//@targetengine "exportPdfFromBook"
//@include "./arraysome.jsxinc"
var main = function () {
    var myList = fileReadIn("tgtIndd", "pdfName");
    // ウィンドウを作成
    var dialog = new Window("dialog");
    dialog.text = "ブックPDF書き出し";
    dialog.orientation = "column";
    dialog.alignChildren = ["center", "top"];

    var dropdown1 = dialog.add("dropdownlist", undefined, app.pdfExportPresets.everyItem().name);
    dropdown1.preferredSize.width = 300;

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

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

    // ファイル名の重複チェック
    if (chkDuplicates(myList, "pdfName").length > 0) {
        alert("ファイル名が重複しているため中断しました");
        exit();
    }


    // ファイル名に使用できない文字チェック
    var checkName = function (tgt) {
        if (/[*?"<>\\|]/g.test(tgt.pname)) {
            alert("ファイル名に使用できない文字が含まれているため中断しました");
            exit();
        }
    }
    myList.some(checkName);

    if (!dropdown1.selection) {
        alert("書き出しプリセットが選択されていないため中断しました");
        exit();
    }

    var myBook = app.books[0];
    var pPreset = app.pdfExportPresets.itemByName(dropdown1.selection.text);
    for (var i = 0; i < myList.length; i++) {
        var tmpIndds = [];
        var s = myList[i]['tgtIndd'].split(",")
        for (var j = 0; j < s.length; j++) {
            tmpIndds.push(myBook.bookContents[s[j] - 1]);
        }
        var tmpPath = new File(app.books[0].filePath + "/" + myList[i]['pdfName'] + ".pdf");
        myBook.exportFile(ExportFormat.PDF_TYPE, tmpPath, false, pPreset, tmpIndds);
    }

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

        try {
            while (!tgtFile.eof) {
                var ln = tgtFile.readln().split(/\t/);
                var item = {};
                item[value0] = ln[0];
                item[value1] = ln[1];
                res.push(item);
            }
            fileReadFlag = true;
        } catch (e) {
            alert(e);
            fileReadFlag = false;
        } finally {
            tgtFile.close()
        }
        if (!fileReadFlag || res.length === 0) {
            alert("ファイルを読み込めませんでした");
            exit();
        }
        return res;
    }

    // 配列内で同じプロパティを持つオブジェクトを抽出
    function chkDuplicates(objArr, prop) {
        var exist = {};
        var result = [];
        for (var i = 0, l = objArr.length; i < l; i++) {
            if (typeof objArr[i] !== "object") {
                continue;
            }
            var tmp = objArr[i][prop];
            if (!exist[tmp]) {
                exist[tmp] = 1;
            } else if (exist[tmp] === 1) {
                exist[tmp]++;
                result.push(objArr[i]);
            } else {
                exist[tmp]++;
            }
        }
        return result;
    }
}

app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.FAST_ENTIRE_SCRIPT, "exportPdfFromBook.jsx");
alert("完了しました")

メモ

積み残し

  • 対象となるinddの指定の仕方。「1,2,3,4」ではなく「1-4」と書いても通るようにしたい。
  • PDFごとに見開きか単ページかを指定できるようにしたい。