コモノExtendScript100本ノック

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

055.【Id】placeMultipagePDF改

メモ

経緯

InDesignのビルトインスクリプトの中にPlaceMultipagePDF.jsxというものがあります。
マルチページPDFを自動で配置してくれる便利なやつなのですが、色々と自分のニーズに合わないところがあったのでカスタマイズしてみました。

PlaceMultipagePDF.jsxの不満点

  • PDFやページのリサイズには対応していない。
  • 既存のドキュメントに配置する場合でも、既にあるページに配置するのではなく自動的にページが追加される。
  • スクリプトで行った配置処理を一括でUndoできない。
  • 不要なアラートが出る(ドキュメントのconstructor.name等)。

PlaceMultipagePDF改.jsxの挙動

  • 新規ドキュメントを対象とする場合:
    • PDFのページ数だけページを作成して配置する。
    • 各ページサイズはPDFのサイズに合わせる。
    • ドキュメントサイズは1ページ目のPDFのサイズに合わせる。
  • 既存ドキュメントを対象とする場合:
    • 対象ドキュメントの指定したページから順にPDFを配置する。
    • PDFのサイズはページサイズに合わせて拡大・縮小する(「内容を縦横比率に応じて合わせる」)。
    • ページが不足している場合は「ページを追加しますか?」というアラートが出るので任意でページを追加する。
    • 追加するページサイズはドキュメントのサイズに合わせる。

積み残し

  • なぜかUndoModes.FAST_ENTIRE_SCRIPTだと上手く行かない。
  • 複数のPDFに対応。指定した順番でリンクできるようにしたい。
  • ページサイズを変更する処理がごちゃごちゃしているので直したい。

コード

※PDFのページ数を取得するgetPageLength関数は手抜きLab@DTPの現場様からお借りしています。

function main() {
  var mu = app.scriptPreferences.measurementUnit;
  app.scriptPreferences.measurementUnit=MeasurementUnits.POINTS;
    //Make certain that user interaction (display of dialogs, etc.) is turned on.
    app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
    //Display a standard Open File dialog box.
    var myPDFFile = File.openDialog("Choose a PDF File");
    if ((myPDFFile != "") && (myPDFFile != null)) {
        var myDocument, myPage;
        if (app.documents.length != 0) {
            var myTemp = myChooseDocument();
            myDocument = myTemp[0];
            myNewDocument = myTemp[1];
        } else {
            myDocument = app.documents.add();
            myNewDocument = true;
        }
        if (myNewDocument == false) {
            myPage = myChoosePage(myDocument);
        } else {
            myPage = myDocument.pages.item(0);
        }
        myPlacePDF2(myDocument, myPage, myPDFFile, myNewDocument);
    }

    function myChooseDocument() {
        var myDocumentNames = new Array;
        myDocumentNames.push("New Document");
        //Get the names of the documents
        for (var myDocumentCounter = 0; myDocumentCounter < app.documents.length; myDocumentCounter++) {
            myDocumentNames.push(app.documents.item(myDocumentCounter).name);
        }
        var myChooseDocumentDialog = app.dialogs.add({
            name: "Choose a Document",
            canCancel: false
        });
        with(myChooseDocumentDialog.dialogColumns.add()) {
            with(dialogRows.add()) {
                with(dialogColumns.add()) {
                    staticTexts.add({
                        staticLabel: "Place PDF in:"
                    });
                }
                with(dialogColumns.add()) {
                    var myChooseDocumentDropdown = dropdowns.add({
                        stringList: myDocumentNames,
                        selectedIndex: 0
                    });
                }
            }
        }
        var myResult = myChooseDocumentDialog.show();
        if (myResult == true) {
            if (myChooseDocumentDropdown.selectedIndex == 0) {
                myDocument = app.documents.add();
                myNewDocument = true;
            } else {
                myDocument = app.documents.item(myChooseDocumentDropdown.selectedIndex - 1);
                myNewDocument = false;
            }
            myChooseDocumentDialog.destroy();
        } else {
            myDocument = "";
            myNewDocument = "";
            myChooseDocumentDialog.destroy();
        }
        return [myDocument, myNewDocument];
    }

    function myChoosePage(myDocument) {
        var myPageNames = new Array;
        //Get the names of the pages in the document
        for (var myCounter = 0; myCounter < myDocument.pages.length; myCounter++) {
            myPageNames.push(myDocument.pages.item(myCounter).name);
        }
        var myChoosePageDialog = app.dialogs.add({
            name: "Choose a Page",
            canCancel: false
        });
        with(myChoosePageDialog.dialogColumns.add()) {
            with(dialogRows.add()) {
                with(dialogColumns.add()) {
                    staticTexts.add({
                        staticLabel: "Place PDF on:"
                    });
                }
                with(dialogColumns.add()) {
                    var myChoosePageDropdown = dropdowns.add({
                        stringList: myPageNames,
                        selectedIndex: 0
                    });
                }
            }
        }
        myChoosePageDialog.show();
        var myPage = myDocument.pages.item(myChoosePageDropdown.selectedIndex);
        myChoosePageDialog.destroy();
        return myPage;
    }

    function myPlacePDF2(myDocument, myPage, myPDFFile, newDoc /*boolean*/ ) {
        var pdfPageLen = getPageLength(myPDFFile);
        var myPDFPage;
        app.pdfPlacePreferences.pdfCrop = PDFCrop.cropMedia;
        var strt = myPage.documentOffset;
        for (var i = 0; i < pdfPageLen; i++) {
            var tgtPage = myDocument.pages[strt + i];
            // もしページが無かったらページ追加。既存のページに追加する場合は一度だけ確認メッセージを出す。
            if (!tgtPage.isValid) {
                if (newDoc) {
                    var addPage = true;
                } else if (newDoc === false && addPage === undefined) {
                    var addPage = false;
                    var addPage = confirm("ページを追加しますか?");
                }
                if (addPage) {
                    tgtPage = myDocument.pages.add(LocationOptions.AT_END);
                    var docSize = [myDocument.documentPreferences.pageWidth, myDocument.documentPreferences.pageHeight]
                    tgtPage.resize(CoordinateSpaces.INNER_COORDINATES,
                        AnchorPoint.TOP_LEFT_ANCHOR,
                        ResizeMethods.REPLACING_CURRENT_DIMENSIONS_WITH,
                        docSize)
                } else if (addPage === false) {
                    break;
                }
            }
            app.pdfPlacePreferences.pageNumber = i + 1;
            myPDFPage = tgtPage.place(File(myPDFFile), [0, 0])[0];
            if (newDoc) {
                var top_left = myPDFPage.resolve([
                    [0, 0], BoundingBoxLimits.outerStrokeBounds, CoordinateSpaces.spreadCoordinates
                ], CoordinateSpaces.spreadCoordinates)[0];
                var bot_right = myPDFPage.resolve([
                    [1, 1], BoundingBoxLimits.outerStrokeBounds, CoordinateSpaces.spreadCoordinates
                ], CoordinateSpaces.spreadCoordinates)[0];
                myPDFPage.parent.parentPage.reframe(CoordinateSpaces.spreadCoordinates, [
                    [top_left[0], top_left[1]],
                    [bot_right[0], bot_right[1]]
                ]);
            } else {
                myPDFPage.parent.geometricBounds = myPDFPage.parent.parentPage.bounds;
                myPDFPage.fit(FitOptions.PROPORTIONALLY)
            }
        }
        alert("終了しました");
    }

    function getPageLength(f) {
        var tg = /<<\/Count\s(\d+)/;
        var count = /<<\/Type\/Page\/Parent/;
        var count_2 = /\/Type\s\/Page\s/;
        var count_3 = /\/StructParents\s\d+.*\/Type\/Page>>/;
        var tg2 = /<<\/Linearized\s.+\/N\s(\d+)\/T\s.+>>/;
        var tg3 = /\/Type\/Pages/;
        var tg4 = /\/Count\s(\d+)/;
        var len = 0;
        var num = 0;

        if (f.open('r')) {
            while (!f.eof) {
                wd = f.readln();
                if (tg.test(wd)) return RegExp.$1 - 0;
                if (tg2.test(wd)) return RegExp.$1 - 0;
                if (count.test(wd)) len++;
                if (count_2.test(wd)) len++;
                if (count_3.test(wd)) len++;
                if (tg3.test(wd)) {
                    wd = f.readln();
                    if (tg4.test(wd)) {
                        num = RegExp.$1 - 0;
                        if (len < num) len = num;
                    }
                }
            }
        }
        if (len > 0) return len;
        return null;
    }
  app.scriptPreferences.measurementUnit=mu;
}

//~ app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.FAST_ENTIRE_SCRIPT, "PDF配置スクリプト");
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.SCRIPT_REQUEST, "PDF配置スクリプト");

参考