DTPab

DTPにまつわるあれこれ

もくもく会#2レジュメ 解答編3「すべてのドキュメントで実行」

改めて元の設問はこちら
機能1機能2・3は前回・前々回の記事を参照してください。

さて、機能4です。
4.開いているすべてのドキュメントで実行する

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++){
                if (!myCel[m].diagonalLineStrokeOverprint &&
                    myCel[m].diagonalLineStrokeColor == tgtBlack){
                    myCel[m].diagonalLineStrokeOverprint = true;
                    }
                if (!myCel[m].diagonalLineStrokeGapOverprint &&
                    myCel[m].diagonalLineStrokeGapColor == tgtBlack){
                    myCel[m].diagonalLineStrokeGapOverprint = true;
                    }
                }
            }
        }
    }

まず新たに変数allDocsを用意し、app.documentsというドキュメントのコレクションを格納しました。そのコレクションに対してfor文を用い、ドキュメントひとつずつに対してこれまでの処理を実行するだけです。myDocの内容を変えるだけなので、以降については手を触れる必要がありません。
ただ流石にこれでは芸がないので、増えすぎたネスト({ }の入れ子)を調整してみました。

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]);
                }
            }
        }
    }

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

というわけで、メインのオーバープリントを処理する部分を関数化してみました。結果的にはネストがひとつ減っただけですが…^^;;
以上、機能4の追加でした。

余談です。
本家JSではどうか知りませんが、関数を定義する際の引数を「仮引数」、実際に関数を呼び出す際に渡す引数を「実引数」とPythonでは呼ぶらしいです。この呼称は割と好きなので普段でも使ったりします。

もくもく会#2レジュメ 解答編2

解説らしい解説がないので、機能2と3は抱き合わせました。
さっそく以下からどうぞ。

2.[黒]スウォッチだけでなく,色成分がK100のみの場合もすべてオーバープリントにする

var myDoc = app.activeDocument;
var myTxf = myDoc.textFrames;
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.colorValue.join(',') == "0,0,0,100"){
                myCel[m].diagonalLineStrokeOverprint = true;
                }
            if (!myCel[m].diagonalLineStrokeGapOverprint &&
                myCel[m].diagonalLineStrokeGapColor.colorValue.join(',') == "0,0,0,100"){
                myCel[m].diagonalLineStrokeGapOverprint = true;
                }
            }
        }
    }

元のコードと比較してもらうと、3行目のtgtBlackという変数を削除し、if文の条件を変更しています。

if (!myCel[m].diagonalLineStrokeOverprint &&
    myCel[m].diagonalLineStrokeColor.colorValue.join(',') == "0,0,0,100"){

それがこの部分の2つめの条件です。
「線の色がK100(他は0なら)」という条件ですが、もともとcolorValueは4つの要素を持った配列です(順にC、M、Y、Kの値が入っています)。したがって、正攻法では下記のようにします。

if (!myCel[m].diagonalLineStrokeOverprint &&
    myCel[m].diagonalLineStrokeColor.colorValue[0] === 0 &&
    myCel[m].diagonalLineStrokeColor.colorValue[1] === 0 &&
    myCel[m].diagonalLineStrokeColor.colorValue[2] === 0 &&
    myCel[m].diagonalLineStrokeColor.colorValue[3] === 100 &&){

ただこれだと冗長で面倒くさい(と僕は思いました)。
そこでjoinメソッドを使ってひとつづきのStringにして、それを文字列として比較させました。この辺は書き方の好みでもあるので、どちらの方法を採ってもらっても構いません。あくまでも後者の方がベーシックな書き方ですが、前者のように書くこともできて、同じ結果が得られます、という例です。

3.スクリプトで修正した個数をカウントして表示

var myDoc = app.activeDocument;
var myTxf = myDoc.textFrames;
var tgtBlack = myDoc.swatches.item('Black');
var resultCount = {'strokes': 0, 'gaps': 0}
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;
                resultCount.strokes ++;
                }
            if (!myCel[m].diagonalLineStrokeGapOverprint &&
                myCel[m].diagonalLineStrokeGapColor == tgtBlack){
                myCel[m].diagonalLineStrokeGapOverprint = true;
                resultCount.gaps ++;
                }
            }
        }
    }
alert ("結果は以下の通りです\n斜線のノセ変更:"+resultCount.strokes+"\n斜線の間隔のノセ変更:"+resultCount.gaps);

結果を表示させるため、処理した数をカウントして代入するresultCountという変数を用意しました。JSON*1で記述してひとつの変数(というかオブジェクトに2つの変数を用意)としましたが、わかりにくければ2つの変数を別々に作ってOKです。

//var resultCount = {'strokes': 0, 'gaps': 0}
var result_strokes = 0;
var result_gaps = 0;

もしこうやって変数を2つに分ける場合は、後に出てくる2箇所のインクリメント*2で変数を参照しているのでそこを書き換えます。

//resultCount.strokes ++;
result_strokes ++;
//resultCount.gaps ++;
result_gaps ++;

という感じですね。
最後に、結果を表示するalertメソッド内でも参照するので、そこを書き換えたら変数の書き換えは完了です。

//alert ("結果は以下の通りです\n斜線のノセ変更:"+resultCount.strokes+"\n斜線の間隔のノセ変更:"+resultCount.gaps);
alert ("結果は以下の通りです\n斜線のノセ変更:"+result_strokes+"\n斜線の間隔のノセ変更:"+result_gaps);


以上です。機能2、機能3については知ってさえいればそんなに難しくなかったと思いますが、どうだったでしょうか。
また、他所からもらってきたスクリプトに手を加える場合は、どこに手を加えたのかが後から分かるように、こうやってコメントアウトしながら書き換えていくのがいいと思います。

*1:JSONについては過去の記事で少し触れています。書き方については僕のブログを参照してもらってもOKですが、JSONってそもそも何?という方はMDN等のちゃんとしたリファレンスをご参照ください。
また、このスクリプトを書いたときはまだJSONの詳しい仕様を理解しておらず、keyの指定にシングルクォートを使っています。本来はダブルクォートを使うべきなのですが、一応そのままにしています。

*2:++をインクリメント、–はデクリメントと呼びます。

もくもく会#2レジュメ 解答編1

先日のもくもく会#2に合わせて作ったレジュメですが、ボチボチ解答例を上げていきます。興味のある方はトライしてみてください。

というわけで、まずは機能1「動作するInDesignのバージョンを指定する」です。

続きを読む