ファイルから索引を作成するスクリプトは、これで良いのかな・・・?
/*
このスクリプトを利用して起こった不具合の責任は取れません。
ご了承下さい。
更新 2021/11/12
*/
// アプリ指定
#target "indesign";
// スクリプト名
var scriptName = "ファイルから索引";
//スクリプトの動作指定(一つのアンドゥ履歴にする、及び、アンドゥ名)
app.doScript(function(){
// 分割文字
var splitText = ",";
// ダイアログ
var dialogueFlg = confirm("アクティブドキュメントにテキストまたはCSVのファイルから索引の見出しと参照を作成します。" + "\r\r"
+ "参照の検索文字列(正規表現)は「"+ splitText + "」で区切られた9番目になります。" + "\r"
+ "9番目が空白の場合は最下層の項目が参照の検索文字列になります。" + "\r\r"
+ "「検索と置換」の 『正規表現』 での検索の「検索形式」の入力での検索も可能です。"+ "\r\r"
+ "追加する参照が既存の参照と重複する場合は追加しません。" + "\r\r"
+ "ファイルの例(一行目は利用しません)" + "\r"
+ "項目1,読み,項目2,読み,項目3,読み,項目4,読み,参照の検索文字列" +"\r"
+ "動物,どうぶつ,猫,ねこ,三毛(日本固有種),みけ(にほんこゆうしゅ),,,三毛" +"\r"
+ "Id,インデザイン" +"\r"
+ "adobe"
,"", scriptName);
// Noの場合
if(dialogueFlg == false){
// 終了
exit();
}
/* 検索文字列以外を使う場合の処理 */
// 正規表現の検索プロパティのフラグ
var findGrepPreferencesPropertyFlg = false;
// 検索形式一覧
var findFormatList = [];
// 正規表現の検索のプロパティ名の数だけ変数に入れて繰り返す
for(var findGrepPreferencesProperty in app.findGrepPreferences.properties){
// プロパティ名が「findWhat」、「parent」、「bulletChar」、「numberingRestartPolicies」では無い場合
if(findGrepPreferencesProperty != "findWhat" && findGrepPreferencesProperty != "parent" && findGrepPreferencesProperty != "bulletChar" && findGrepPreferencesProperty != "numberingRestartPolicies"){
// プロパティの内容が「NothingEnum.NOTHING」、「」、「null」ではない場合
if(app.findGrepPreferences[findGrepPreferencesProperty] != NothingEnum.NOTHING && app.findGrepPreferences[findGrepPreferencesProperty] != "" && app.findGrepPreferences[findGrepPreferencesProperty] != null){
findGrepPreferencesPropertyFlg = true;
// 検索形式を集める
findFormatList.push(findGrepPreferencesProperty + ":" + app.findGrepPreferences[findGrepPreferencesProperty]);
}
}
}
/* ここまで */
// 索引が無い場合
if(app.activeDocument.indexes.count() == 0){
// 索引を作成
app.activeDocument.indexes.add();
}
// テキスト検索の初期化
app.findTextPreferences = NothingEnum.NOTHING;
// 見出しの最初の数
var firstTopicNumber = searchTopicNumber(app.activeDocument.indexes.firstItem(),0);
// テキストファイル読み込みダイアログ
var openFile = File.openDialog("索引を作成する為のテキストファイルを指定して下さい。","*.txt,*.csv");
// 読み込むファイルの確認
if(openFile){
// ファイルオブジェクト作成
fileObject = new File(openFile);
// 読み込み
var openFlg = fileObject.open("r");
// 進行状況のパレット
var processingPalette = new Window("palette", "進行状況", undefined, {closeButton: false});
processingPalette.orientation = "column";
processingPalette.alignChildren = ["left","top"];
processingPalette.spacing = 5;
processingPalette.margins = 10;
// 子階層のパネル
var processingPanel = processingPalette.add("panel", undefined, undefined,);
processingPanel.text = "参照検索(正規表現)";
processingPanel.preferredSize.height = 80;
processingPanel.orientation = "column";
processingPanel.alignChildren = ["left","top"];
processingPanel.spacing = 5;
processingPanel.margins = 10;
// パネルの文章
var paletteSearchText = processingPanel.add("statictext", [0, 0, 570, 15], undefined);
processingPanel.add("statictext", undefined, "検索形式 : " + findFormatList.join(" + "));
var paletteProcessingText = processingPanel.add("statictext", [0, 0, 570, 15], undefined);
// パレットの文章
processingPalette.add("statictext", [0, 0, 0, 5], undefined);
processingPalette.add("statictext", undefined, "「Esc」キーでスクリプトを取消し出来ます(Macは不明)。");
processingPalette.add("statictext", [0, 0, 0, 5], undefined);
processingPalette.add("statictext", [0, 0, 595, 55], "処理で文字を選択します。" + "\r"
+ "ドキュメントウィンドウの最小化(「ウィンドウメニュー」>「アレンジ」>「ウィンドウを分離」の後、「ウィンドウメニュー」>「アレンジ」>「最小化」)や各種パネルを閉じておくのをおすすめします。"
,{multiline: true});
// 表示
processingPalette.show();
// ファイルが開けた場合
if (openFlg == true){
// 検索結果
var grepResult;
// 一行分の文字
var lineText = "";
// 検索文字
var searchText = "";
// 分割後の文字配列
var splitTextArray;
// 新規見出し
var newTopic;
// 見出し階層数
var topicHierarchyNumber = 0;
// 新規参照
var newReference;
// 参照追加数
var referenceNumber = 0;
// 行数
var lineNumber = 0;
// 新規の参照が作成される前の検索結果の最初の挿入点のIndex
var previousReferenceFirstInsertionPointsIndex;
// 対象の文字
var targetCharacter;
// 対象のIndex
var targetIndex;
// 項目数
var topicNmuber = 0;
// 検索結果数
var searchNumber = 0;
// 最後の行まで繰り返す
while (!fileObject.eof){
// 初期化
topicHierarchyNumber = 0;
// 一行読み込み
lineText = fileObject.readln();
// 増やす
lineNumber++;
// 一行目の場合
if(lineNumber == 1){
// 次の繰り返しへ
continue;
}
// 分割文字で分割
splitTextArray = lineText.split(splitText);
// 項目1が空白で無い、かつ、分割の数が9以下の場合
if(splitTextArray[0] != "" && splitTextArray.length <= 9){
// 増やす
topicNmuber++;
// 初期化
newTopic = app.activeDocument.indexes.firstItem();
// 項目の数だけ繰り返す
for(var i = 0; i <= splitTextArray.length - 1 && i < 8; i += 2){
// 初期化
searchText = "";
// 索引項目(見出し)が空白で無い場合
if(splitTextArray[i] != ""){
// 入れる
topicReading = splitTextArray[i + 1];
// エラー処理
try{
// 見出し作成
newTopic = newTopic.topics.add(splitTextArray[i],splitTextArray[i + 1]);
// エラーの場合
}catch(e){
// 警告
alert("見出しが作成出来ませんでした。" + "\r" + "「索引」ウィンドウの「ソートオプション...」メニューを確認して下さい。");
// 繰り返しから抜ける
break;
}
// 見出しの階層数を増やす
topicHierarchyNumber++;
}
}
// 分割が9つ有る場合
if(splitTextArray.length == 9){
// 入れる
searchText = splitTextArray[8];
// 以外の場合
}else{
// 最下層の項目部分の分割を入れる
searchText = splitTextArray[topicHierarchyNumber * 2 - 2];
}
// 検索文字文字列、もしくは、検索形式が有る場合
if(searchText != "" || findGrepPreferencesPropertyFlg == true){
// 検索文字列
app.findGrepPreferences.findWhat = searchText;
// 処理中表示
paletteSearchText.text = "検索文字列 : " + searchText;
paletteProcessingText.text = "進行状況 : 項目:" + topicNmuber + " 検索結果:0";
// ドキュメント全体から検索
grepResult = app.activeDocument.findGrep();
// 検索結果の数だけ繰り返す
grepResultLabel:
for(var i = 0; i < grepResult.length; i++){
// 入れる
searchNumber = i + 1;
// 処理中表示
paletteProcessingText.text = "進行状況 : 項目:" + topicNmuber + " 検索結果:" + searchNumber;
// 検索結果を選択
grepResult[i].select();
// 選択の最初の挿入点のIndexを入れる(参照を作成するとIndexが変化するので)
previousReferenceFirstInsertionPointsIndex = app.activeDocument.selection[0].insertionPoints.firstItem().index;
// 参照形式を指定して参照作成
newReference = newTopic.pageReferences.add(grepResult[i],PageReferenceType.CURRENT_PAGE);
// 参照の位置がずれる場合(バグ?)
if(previousReferenceFirstInsertionPointsIndex != newReference.sourceText.index){
// 参照の挿入点を移動させる
newReference.sourceText.parent.characters.item(newReference.sourceText.index)
.move(LocationOptions.BEFORE,newReference.sourceText.parent.characters
.item(newReference.sourceText.index + previousReferenceFirstInsertionPointsIndex - newReference.sourceText.index));
}
// 追加
referenceNumber++;
/* 重複しているか */
// 対象のIndex
targetIndex = newReference.sourceText.index;
// 最初の挿入点では無い場合
if(targetIndex != 0){
// 前に調べていく
while(targetIndex >= 0){
// 減らす
targetIndex--;
// 対象の文字
targetCharacter =newReference.sourceText.parent.characters.item(targetIndex);
// 検索文字列
app.findTextPreferences.findWhat = "^I";
// 索引マーカーが検索された場合
if(targetCharacter.findText().length > 0){
// 追加した参照のひとつ前から前に繰り返す
for(var ii = newReference.parent.pageReferences.count() - 2; ii >= 0; ii--){
// 対象のマーカーの挿入点が新規追加した参照の目次の参照の挿入点と同じ場合
if(targetCharacter.insertionPoints.firstItem() == newReference.parent.pageReferences.item(ii).sourceText){
// 参照を削除
newReference.remove();
// 減らす
referenceNumber--;
// ラベルの次の繰り返しへ
continue grepResultLabel;
}
}
}
// 検索文字列
app.findTextPreferences.findWhat = "^a";
// アンカー付きオブジェクトマーカーが検索された場合
if(targetCharacter.findText().length > 0){
// 次の繰り返しへ
continue;
}
// 抜ける
break;
}
}
/* ここまで */
}
}
}
}
// ファイルを閉じる
fileObject.close();
// 開けなかった場合
}else{
// 警告
alert("ファイルが開けませんでした。");
}
// キャンセルの場合
}else{
// 終了
exit();
}
// 索引の更新
app.activeDocument.indexes.firstItem().update();
// 初期化
app.findTextPreferences = NothingEnum.NOTHING;
app.findGrepPreferences.findWhat = NothingEnum.NOTHING;
// 選択の解除
app.activeDocument.selection = NothingEnum.NOTHING;
// 見出しの追加数
var additionalTopicNumber = searchTopicNumber(app.activeDocument.indexes.firstItem(),0) - firstTopicNumber;
// 結果
alert("見出し追加数:" + additionalTopicNumber + "\r"
+ "参照追加数:" + referenceNumber);
//スクリプトの動作指定の続き
}, ScriptLanguage.JAVASCRIPT, [scriptName], UndoModes.ENTIRE_SCRIPT, scriptName);
// 見出しの数検索用
function searchTopicNumber(targetTopic,topicNumber){
// 見出しの数だけ繰り返す
for(var i = 0; i < targetTopic.topics.count(); i++){
// 数を追加
topicNumber++;
// 循環
topicNumber = searchTopicNumber(targetTopic.topics.item(i),topicNumber);
}
// 数を返す
return topicNumber;
}