2012年09月12日
_ [indesign] 索引をスクリプトからなんとかして埋め込む
弊社の作業では(さまざまな事故が起き得ることから)InDesignのデータの中に索引を入れるということはまずない(別ファイルで管理)のだけれども、まれに入れざるを得ない案件もある。
手作業で選択→ヨミ入力→選択→ヨミ入力 とやっているとアホになる。スクリプトプログラマとしてはそんなの自動化だろということで、kakasiなりYahoo!なりを使って形態素解析するわけだ。
さてここまではたいして難しい話ではなく、pageReferences.addを使ってめでたく索引埋め込みスクリプトは動作するわけだが、どうも奇妙な現象にぶつかることになるだろう。
というのも、表が途中に存在すると、登録しようとした位置からその行数の累積の文字数分、実際に配置される索引位置がずれるのだ。これはひどい。表が実装されたCS2以来、CS6でも未だ直ってない。表の実装はややこしく、いくらでも不具合はある(たとえば未だに脚注ができずにだまって消えるとか…)のだが、ともかくこのままだと表が登場するたびにどんどんずれていって使い物にならないし、ドキュメント末尾にさしかかると今度はドキュメント先頭やら表の中やらおもしろすぎる場所に索引が入るというオマケ付きだ。
1つの作戦としては表が登場するたびに行数を数えて処理するという手があるが、これは検査が面倒で時間がかかりすぎる。
そこで、前置きが長くなったが、「コピペ」作戦である(正確にはカット&ペーストだが)。「スクリプトだとどうにもだめなのに手作業だとなぜかできる」という処理がInDesignにはよくある。今回も手作業をエミュレートすると、バグを回避して索引を埋め込めた。
埋め込み処理のメソッド実装は次のとおり。
function embedIndex(document, sel, ins, item1, yomi1, item2, yomi2) { var tf = document.pages[0].textFrames.add(); // ダミーのテキストフレーム tf.geometricBounds = [0, 0, 30, 30]; tf.contents = "♦"; if (item2 != "") { var topic1 = document.indexes[0].topics.add(item2, yomi2); var topic2 = topic1.topics.add(item1, yomi1); topic2.pageReferences.add(tf.characters[-1], PageReferenceType.CURRENT_PAGE); } else { var topic = document.indexes[0].topics.add(item1, yomi1); topic.pageReferences.add(tf.characters[-1], PageReferenceType.CURRENT_PAGE); } tf.characters[0].select(); app.cut(); ins[-1].select(); app.paste(); tf.remove(); }
selが索引用選択中のテキスト系オブジェクト、insがsel.InsertionPoints(ということはinsは実はリファクタリングできるな…)。item1/yomi1がレベル1索引のペア、item2/yomi2がレベル2索引のペアの文字列。
ポイントとしては、ダミーのテキストフレームをかなり適当に作り、索引をまずそちらに貼り付けるというところ。それをカットして、あるべき箇所にペーストし、ダミーは削除する。
この時点では索引参照ページを見ると空になっているので、すべての索引登録作業を終えたら索引ウィンドウで「プレビューを更新」をすればよい。
あ、topics.addについて重複検査とかしていない(笑)。まぁ基本はできたので、もうちょっとマジメに直そう。