DTPab

DTPにまつわるあれこれ

もくもく会#2レジュメ 解答編5「doScriptによる実行」

元の設問はこちら

今回はdoScriptを使った処理です。doScript自体はCS3から実装されていますが、いろいろ含めてCS4からが本格仕様です。ちなみにIllustratorのそれとは違い、InDesigndoScriptは文字通りスクリプトを(言語を指定して)実行できます。
この機能、とっても便利なので覚えておくといいです。UndoModesの設定次第では、Undoの履歴を残さないので処理させることができます。そうすると圧倒的に処理が早くなるのと、スクリプトを実行した後でも一度のUndoでスクリプト実行前に戻ることができます。
6.スクリプトによる修正を一度のUndoで戻れるようにdoScriptで実行する

app.doScript (main, ScriptLanguage.JAVASCRIPT, [], UndoModes.FAST_ENTIRE_SCRIPT);

function main (){
    var myDoc = app.activeDocument;
    var myTxf = myDoc.textFrames;
    var tgtBlack = myDoc.swatches.item('Black');
    for (var i=0; i<myTxf.length; i++){
        var myTab = myTxf[i].tables;
        for (var k=0; k<myTab.length; k++){
            var myCel = myTab[k].cells;
            for (var m=0; m<myCel.length; m++){
                if (!myCel[m].diagonalLineStrokeOverprint &&
                    myCel[m].diagonalLineStrokeColor == tgtBlack){
                    myCel[m].diagonalLineStrokeOverprint = true;
                    }
                if (!myCel[m].diagonalLineStrokeGapOverprint &&
                    myCel[m].diagonalLineStrokeGapColor == tgtBlack){
                    myCel[m].diagonalLineStrokeGapOverprint = true;
                    }
                }
            }
        }
    }

doScriptは、引数に「関数、または文字列」「スクリプト言語」「第一引数の関数に渡す引数(配列)」「UndoModes」という順序で指定します。今回は引数のない関数(main)を指定しているので、doScriptの第三引数は空の配列([ ])です。
もし引数がうまく渡せない場合は、第一引数に関数を文字列型として記述するという方法もあります。仮引数hogeを指定するなら

app.doScript ("main(hoge)", ScriptLanguage.JAVASCRIPT, [], UndoModes.FAST_ENTIRE_SCRIPT);

こんな感じです。まぁこの辺はフレキシブルでいいと思います。
ScriptLanguageの指定、UndoModesの指定は、お〜まちさんのディザInDesignドキュメントオブジェクトモデル図*1を見ていただくとよいです。特にScriptLanguageは、OSによってドキュメントオブジェクトビューワーに表示される言語が決まってしまいます。つまりMacではAppleScriptJavaScriptは見つかりますが、VisualBasicは参照できません。WindowsではAppleScriptの指定の仕方が参照できません。 ちなみに、前々回の記事(機能3)で斜線のオーバープリント処理を関数化しました。その場合はこんな感じになります。

app.doScript (main, ScriptLanguage.JAVASCRIPT, [], UndoModes.FAST_ENTIRE_SCRIPT);

function main (){
    var allDocs = app.documents;
    for (var x=0; x<allDocs.length; x++){
        //var myDoc = app.activeDocument;
        var myDoc = allDocs[x];
        var myTxf = myDoc.textFrames;
        var tgtBlack = myDoc.swatches.item('Black');
        for (var i=0; i<myTxf.length; i++){
            var myTab = myTxf[i].tables;
            for (var k=0; k<myTab.length; k++){
                var myCel = myTab[k].cells;
                for (var m=0; m<myCel.length; m++){
                    refineDiagonalLineOP (myCel[m], tgtBlack);
                    }
                }
            }
        }
    }

function refineDiagonalLineOP (tgtCell, tgtSwatch){
    if (!tgtCell.diagonalLineStrokeOverprint &&
        tgtCell.diagonalLineStrokeColor == tgtSwatch){
        tgtCell.diagonalLineStrokeOverprint = true;
        }
    if (!tgtCell.diagonalLineStrokeGapOverprint &&
        tgtCell.diagonalLineStrokeGapColor == tgtSwatch){
        tgtCell.diagonalLineStrokeGapOverprint = true;
        }
    }

関数の中で関数を呼び出すため、スコープ*2に注意してください。今回のケースでいうと、refineDiagonalLineOP関数からtgtBlack変数を参照できないため、第二引数にして渡しています。
以上がdoScriptを使った記述です。処理の高速化とUndoのコントロールができるので、使い勝手のいいスクリプトになります。ぜひ自分で作ったほかのスクリプトでも試してみてください。

*1:ページ内を「doscript」で検索すれば見つかります。まだ英語表記のままですが、そんなに難しくないでしょう…^^;

*2:JavaScriptの変数のスコープについては、MDNなどをご参照ください。なかなか簡単には説明しにくいので、もし分かりにくければ「関数の中から変数が見に行けない状態」という大雑把な感じで理解しておいてください。いずれ関数をたくさん書くようになると、スコープが煩わしいものからありがたいものになるはずですw