DTPab

印刷やデザイン、アドビ製アプリやスクリプトなど、雑多な技術ブログ

【InDesign】ExtendScriptで相互参照を操作する

趣味で作っていたスクリプトで躓いて、自己解決に至るまでにだいぶかかりました。
今後のために記しておきます。

やりたいこと

ExtendScriptを利用し、任意の場所(テキストの挿入点)に、相互参照で参照した段落のテキストを丸ごと挿入したい

図に表すと、こう。

相互参照を利用して…

ある段落のテキストを任意の場所に挿入

相互参照形式はこんなものが既にある、という仮定。

先に作っておいた相互参照形式

呼称の整理

今回大きく混乱したいちばんの理由が、ExtendScript上での用語がうまく理解できなかったから、でした。
InDesignの相互参照(Cross Reference)は、ハイパーリンク(Hyperlink)と密接に関わっています。別々の機能としてパネルがそれぞれに存在しますが、前掲の相互参照のパネルメニューを見ていただいてもわかる通り、相互参照パネルからハイパーリンクの設定もできるようになっています。

ということで、ExtendScript上での呼称を整理しましょう。

必要な役者は4人

部品 UI上の名称 ExtendScriptの名称
A 相互参照/リンク先 ParagraphDestination
B 相互参照/ソース CrossReferenceSource
C 相互参照形式 CrossReferenceFormat
D 相互参照 Hyperlink

相互参照パネルにアイテムを追加するには、ExtendScript上ではHyperlinkオブジェクトの追加になるわけで、ここが混乱の原因となった本懐かもしれない。

実装

では、サンプルコードを示します。

var doc = app.activeDocument;
var parDest = doc.paragraphDestinations.add(doc.textFrames.item("HOGE").paragraphs[0]);
var xRefFrm = doc.crossReferenceFormats.item("paraTexts");
var xRefSrc = doc.crossReferenceSources.add(doc.selection[0], xRefFrm);
var myLink = doc.hyperlinks.add(xRefSrc, parDest);

コードとしては、テキストフレーム名"HOGE"の最初の段落を相互参照先(リンク先)として、カーソルの挿入点の位置に相互参照元(ソース)を挿入します(こうやって言葉にすること自体が混乱の元なのでは、という気すらしますね)

parDest変数は、ParagraphDestinationオブジェクトです(前掲画像A)。今回はわかりやすくテキストフレームに"HOGE"という名前をつけたので、それを参照させました。ParagraphDestinations.add()メソッドの引数はTextオブジェクトです*1

レイヤーに名前をつけるには、レイヤーをゆっくり2回クリック

xRefFrm変数には、もともと定義しておいた相互参照形式Document.crossReferenceFormat(前掲画像C)を代入しています。

xRefSrc変数は、CrossReferenceSourceオブジェクトです(前掲画像B)。CrossReferenceSources.add()メソッドの第一引数が相互参照元(ソース)の挿入先、第二引数が利用する相互参照形式です*2

最後のmyLink変数の行が、相互参照(前掲画像D)の挿入になります。Hyperlinks.add()メソッドの第一引数がCrossReferenceSourceオブジェクト、第二引数がParagraphDestinationオブジェクトです*3

ということで、やっていることは大したことないんですが、ここにたどり着くまでになかなかの時間をかけてしまいました。
この記事が相互参照で悩めるスクリプターを救ってくれることを期待します…。

*1:ParagraphDestinations.add()メソッド。第二引数は省略しています。

*2:CrossReferenceSources.add()メソッド。第三引数は省略しています。

*3:Hyperlinks.add()メソッド。第三引数は省略しています。