構造の選択要素のテキストフレームからページ番号を取得して属性に書き込むスクリプトはこれで良いのかな・・・?
/*
構造の選択された要素のテキストフレームから取得したページ番号を属性に書き込む
更新 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;
}
/* 配列の値の重複を無くす関数の宣言終了*/