ごんれのラボ

iOS、Android、Adobe系ソフトの自動化スクリプトのことを書き連ねています。

テキストフレーム内で適用されている段落および文字スタイルを取得

Adobe USのスクリプトフォーラムを見てたらちょっと面白い質問を見つけたので、私なりの回答を書いてみた。

 

質問はこれ。

JS for all styles within a TextFrame

 

っていまみたらもっといい回答がされていた…。

出オチってことで書くのやめようか。(しょんぼり)

 

まぁ誰かの役に立つかもってことで書いてみます。

選択しているテキストフレームの中で適用されている段落スタイル名と文字スタイル名を重複していないものだけ連想配列に突っ込むというものです。

コードは下記です。

すごく簡単です。

 

main();

//メイン
function main() {
    var selObj = app.selection[0]; //選択しているオブジェクトを変数に
    if (selObj != undefined) { //なにか選択していたら(未選択はundefined)
        var appliedStyleHash = getAppliedStylesInFrame(selObj); //getAppliedStylesInFrameの戻り値を変数に(連想配列で戻る)
    }
    //なんかする
}

//テキストフレームの中の適用されているスタイルを連想配列に入れる関数
function getAppliedStylesInFrame(targetObj) {
    var tempHash = { pstyle: new Array(), cstyle: new Array() }; //連想配列を作成してその中に配列を作る
    if (targetObj.constructor.name == "TextFrame") { //テキストフレームだったら
        for (var i = 0, iLen = targetObj.textStyleRanges.length; i < iLen; i++) {
            var myTextStyleRange = targetObj.textStyleRanges[i];
            tempHash["pstyle"].push(myTextStyleRange.appliedParagraphStyle.name); //適用されている段落スタイル名を配列に入れる
            tempHash["cstyle"].push(myTextStyleRange.appliedCharacterStyle.name); //適用されている文字スタイル名を配列に入れる
        }
    }
    tempHash["pstyle"] = unique(tempHash["pstyle"]); //配列内の重複してない要素のみにする
    tempHash["cstyle"] = unique(tempHash["cstyle"]);
    return tempHash;
}

//配列内の重複していない要素のみを返す関数
function unique(array) {
    var storage = {};
    var uniqueArray = [];
    var i, value;
    for (i = 0; i < array.length; i++) {
        value = array[i];
        if (!(value in storage)) {
            storage[value] = true;
            uniqueArray.push(value);
        }
    }
    return uniqueArray;
}

 

unique()の書き方が違うのはググって拾ってきたものをそのままコピペしてるからです。

InDesignのDOMが絡まないところはWebで使われているコードをそのまま使えるのもJavaScriptの利点ですね。

 

えーと、なにをしているかと言うと。

まずtargetObj.constructor.nameのプロパティを見て、選択しているオブジェクトが何者か判断しています。

そしてTextFrameだったらtextStyleRangesの操作に移ります。

textStyleRangesは「同じ書式設定が適用されている範囲」を示すオブジェクトです。

「同じスタイル」じゃないところがミソで、適用されているスタイルの違いはもちろん、トラッキング、長体などが違っても別のものとして認識されます。

段落スタイルの場合はひとつの段落の中で別の段落スタイルが適用されていることはないんですが、文字スタイルの場合はそういうケースはままあると思います。

んで、characters.lengthでぐるぐる回してappliedCharacterStyleを取得すると効率が悪いので、textStyleRangesを使っています。

そして取得したスタイル名は連想配列に突っ込んでおきます。

最後に配列の中の重複していない要素だけを再抽出してmain()に戻して変数に代入しています。

あとはこの連想配列からなにかすればいいんじゃないでしょうか。

テキストに書き出すとかアラートで表示するとか、そんな感じ?

このままだとスタイルグループを使っていた場合、親グループがわからないので、それを取得するようにしたほうがいいのかも。

ついでにスタイル名はパレットに表示されるような「スタイル名(親:親2)」みたいな形にするといいか。

うん、こないだ書いた。

関数にして再帰処理させるのが楽なんじゃないかな。

 

そんな感じでおしまいです。