0
0

More than 3 years have passed since last update.

indesign スクリプト ページ番号を取得して属性に書き込む(構造の選択要素のテキストフレームから)

Last updated at Posted at 2021-05-31

構造の選択要素のテキストフレームからページ番号を取得して属性に書き込むスクリプトはこれで良いのかな・・・?

/*
構造の選択された要素のテキストフレームから取得したページ番号を属性に書き込む
更新 2021/06/04
*/

// アプリ指定
#target "indesign";

// スクリプト名
var scriptName = "ページ番号を属性に書き込む(構造の選択された要素のテキストフレームから取得した)";

//スクリプト動作指定(一つのアンドゥ履歴にする及びアンドゥ名の指定)
app.doScript(function () {

    // ダイアログ
    var dialogueFlg = confirm("構造の選択された要素のテキストフレームから取得したページ番号を属性に書き込みます", "", scriptName);

    // Noの場合
    if (dialogueFlg == false) {

        // スクリプトを終了
        exit();
    }

    // ページ番号を書き込む属性名
    var pageNumberAttribute = "pageNumber";

    // 書き込み数
    var writeNumber = 0;

    // 日時の情報
    var unshapedDate = new Date();

    // 日時の情報の整形
    var shapedDate = unshapedDate.getFullYear() + "/" + ("0" + (unshapedDate.getMonth() + 1)).slice(-2) + "/" + unshapedDate.getDate() + " " + unshapedDate.getHours() + ":" + ("0" + unshapedDate.getMinutes()).slice(-2);

    // ダイアログ、重複するページ番号を削除するか
    var removeDuplicatesFlg = confirm("重複するページ番号を削除しますか?", "", scriptName);

    // 選択の数だけ繰り返す
    for (var i = 0; i < app.activeDocument.selection.length; i++) {

        // ページ番号配列
        var pageNumberArray = [];

        // 選択がXML要素の場合
        if (app.activeDocument.selection[i].constructor.name == "XMLElement") {

            // ストーリーのコンストラクタ名を取得する関数を使い戻値がストーリーの(Xmlストーリーの場合はページアイテムがない)場合
            if(getStoryConstructorName(app.activeDocument.selection[i]) == "Story"){

                /* ページ番号の取得 */
                // XML要素の参照がストーリーの場合
                if (app.activeDocument.selection[i].xmlContent.constructor.name == "Story") {

                    // ストーリーのテキストコンテナの数だけ繰り返す
                    for(var ii = 0; ii < app.activeDocument.selection[i].xmlContent.textContainers.length; ii++){

                        // ページ番号を取得する関数を使用してページ番号配列に追加
                        pageNumberArray.push(getPageNumber(app.activeDocument.selection[i].xmlContent.textContainers[ii]));
                    }

                // XML要素の参照がテキストの場合
                } else if (app.activeDocument.selection[i].xmlContent.constructor.name == "Text") {

                    // テキストのフレームの数だけ繰り返す
                    for(var ii = 0; ii < app.activeDocument.selection[i].xmlContent.parentTextFrames.length; ii++){

                        // ページ番号を取得する関数を使用してページ番号配列に追加
                        pageNumberArray.push(getPageNumber(app.activeDocument.selection[i].xmlContent.parentTextFrames[ii]));
                    }

                // XML要素の参照がテーブルの場合
                // テーブルが複数のフレームにまたがっている場合はその分だけテーブルの最上部が存在するフレームのラインが増える(見た目よりラインの数が多くなる)
                // テーブルがあふれている場合はラインはあるがラインの親フレームは無い
                } else if (app.activeDocument.selection[i].xmlContent.constructor.name == "Table") {

                    // テーブルの親がストーリーではない(テーブルが表示されている)場合
                    if(app.activeDocument.selection[i].xmlContent.parent.constructor.name != "Story"){

                        // オブジェクトのあるラインのIndexを求める関数を使用してオブジェクトのあるラインのIndexに入れる
                        objectInLineIndex = objectInLineSeach(app.activeDocument.selection[i].xmlContent,app.activeDocument.selection[i].xmlContent.parent.lines,"tables");

                        // 前のラインのテキストフレームのId
                        var previousLineTextFrameId;

                        // 検索対象のあるラインから最後のラインまで繰り返す
                        for(var ii = objectInLineIndex; ii < app.activeDocument.selection[i].xmlContent.parent.lines.length; ii++){

                            // ラインにフレームが無い場合
                            if(app.activeDocument.selection[i].xmlContent.parent.lines[ii].parentTextFrames.length ==0){

                            // 繰り返しから抜ける
                            break;
                        }

                        // ラインのフレームのIdと前のラインのフレームのIdが同じ(テーブルの含まれているラインが終わった)場合
                        if(app.activeDocument.selection[i].xmlContent.parent.lines[ii].parentTextFrames[0].id == previousLineTextFrameId){

                            // 繰り返しから抜ける
                            break;
                        }

                        // ページ番号を取得する関数を(テーブルのあるラインのフレームを引数に)使用してページ番号配列に追加
                        pageNumberArray.push(getPageNumber(app.activeDocument.selection[i].xmlContent.parent.lines[ii].parentTextFrames[0]));

                        // 前のラインのテキストフレームのIdに今のラインのテキストフレームのIdを入れる
                        previousTextFrameId = app.activeDocument.selection[i].xmlContent.parent.lines[ii].parentTextFrames[0].id;
                        }
                    }

                // 以外の場合
                }else{

                    // 次の繰り返しへ
                    continue;
                }
                /* ページ番号の取得終了 */

                /* ページ番号の属性への書き込み */
                // ページ番号配列の長さが1より多い場合
                if(pageNumberArray.length > 1){

                    // 昇順に並び替え
                    pageNumberArray.sort();

                    // 番号の重複を無くすフラグが選択されている場合
                    if (removeDuplicatesFlg == true) {

                        // 配列の値の重複を無くす関数を使いページ番号配列に入れる
                        pageNumberArray = repeatNoneArray(pageNumberArray);
                    }
                }

                // ページ番号配列の長さが0より多い場合
                if(pageNumberArray.length > 0){

                    // ページ番号配列の長さの数だけ繰り返す
                    for(var ii = 0; ii < pageNumberArray.length; ii++){

                        // ページ番号配列の配列の内容が無い場合
                        if(!pageNumberArray[ii]){

                            // ページ番号配列の配列に「-」を入れる(ペーストボードにあるか、あふれていて全く表示されていない)
                            pageNumberArray[ii] = "-";
                        }
                    }

                // 以外の場合
                }else{

                    // ページ番号配列の配列に「-」を入れる(ペーストボードにあるか、あふれていて全く表示されていない)
                    pageNumberArray = ["-"];
                }

                // ページ番号配列を「,」を挟み結合したのちページ番号(文字列)に入れる
                var pageNumberString = pageNumberArray.join(",") + " 検索 " + shapedDate;

                // 番号の重複を無くすフラグが選択されている場合
                if (removeDuplicatesFlg == true) {

                    // ページ番号に追加
                    pageNumberString += " 重複削除処理有";

                // 番号の重複を無くすフラグが選択されていない場合 
                } else {

                    // ページ番号に追加
                    pageNumberString += " 重複削除処理無";
                }

                // ページ番号を書き込む属性が存在する場合
                if (app.activeDocument.selection[i].xmlAttributes.itemByName(pageNumberAttribute).isValid == true) {

                    // ページ番号を属性に書き込み
                    app.activeDocument.selection[i].xmlAttributes.itemByName(pageNumberAttribute).value = pageNumberString;

                // 存在しない場合
                } else {

                    // 属性を追加してページ番号を属性に書き込み
                    app.activeDocument.selection[i].xmlAttributes.add(pageNumberAttribute, pageNumberString);
                }

                // 書き込み数追加
                writeNumber++;
                /* ページ番号の属性への書き込み終了 */
            }
        }
    }

    // 結果表示
    alert("書き込み数 " + writeNumber, scriptName);

// スクリプト動作指定(一つのアンドゥ履歴にする及びアンドゥ名の指定)の続き
}, ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, scriptName);

/* ストーリーのコンストラクタ名を取得する関数、引数(オブジェクト)の宣言 */
function getStoryConstructorName(anyObject) {

    // parentStoryプロパティが存在する場合
    if (anyObject.hasOwnProperty("parentStory") == true) {

        // parentStoryがある場合
        if (anyObject.parentStory) {

            // ストーリーのコンストラクタ名を戻す
            return anyObject.parentStory.constructor.name;
        }

    // スプレッドの場合
    } else if (anyObject.constructor.name == "Spread") {

        // 抜ける
        return;
    }

    // オブジェクトの階層を一つ上げて再帰関数
    return getStoryConstructorName(anyObject.parent);
}
/* ストーリーのコンストラクタ名を取得する関数の宣言終了 */

/* オブジェクトのあるラインのIndexを求める関数、引数(検索オブジェクト、検索ライン、検索オブジェクトのプロパティ)の宣言*/
function objectInLineSeach(searchObject,seachLines,objectProperty){

    // 検索ラインの数だけ繰り返す
    for(var i = 0; i < seachLines.length; i++){

        // 検索ラインに検索オブジェクトのプロパティがある場合
        if(seachLines[i][objectProperty].length > 0){

            // プロパティのオブジェクトの数だけ繰り返す
            for(var ii = 0;ii < seachLines[i][objectProperty].length; ii++){

                // 検索オブジェクトのIdとラインのオブジェクトのIdが同じ場合
                if(searchObject.id == seachLines[i][objectProperty][ii].id){

                    // ラインのIndexを戻す
                    return i;
                }
            }
        }
    }
}
/* オブジェクトのあるラインのIndexを求める関数の宣言終了*/

/* ページ番号を取得する関数、引数(オブジェクト)の宣言 */
function getPageNumber(anyObject) {

    // parentPageプロパティが存在する場合
    if (anyObject.hasOwnProperty("parentPage") == true) {

        // parentPageがある場合
        if (anyObject.parentPage) {

            // ページ番号の値を戻す
            return anyObject.parentPage.name;
        }

    // スプレッドの場合
    } else if (anyObject.constructor.name == "Spread") {

        // 抜ける
        return;
    }

    // オブジェクトの階層を一つ上げて再帰関数
    return getPageNumber(anyObject.parent);
}
/* ページ番号取得用関数の宣言終了 */

/* 配列の値の重複を無くす関数、引数(配列)の宣言*/
function repeatNoneArray(anyArray) {

    // 重複の無い配列
    var repeatNoneArray = [];

    // 配列の数だけ繰り返す甲
    for (var i = 0; i < anyArray.length; i++) {

        // 配列の数だけ繰り返す乙
        for (var ii = 0; ii < anyArray.length; ii++) {

            // 甲と乙の内容が同じ場合
            if (anyArray[i] == anyArray[ii]) {

                // 甲と乙のindex(配列の順番)が同じ場合
                if (i == ii) {

                    // 重複の無い配列に値を追加
                    repeatNoneArray.push(anyArray[i]);
                }

                // 乙のループから抜ける
                break;
            }
        }
    }

    // 重複の無い値を戻す
    return repeatNoneArray;
}
/* 配列の値の重複を無くす関数の宣言終了*/
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0