2008年02月13日

item()とitemByRange()の謎

InDesign Hacking with JavaScriptのほうはぼちぼちとライブラリを追加/リファクタリングを進めています。今のところはまだ安定期ではないため、関数引数もわりあい頻繁に変わってたりします。

最近は側注対応(libSidenote)やツメ見出し対応(libSidemarker。本当は英語では何ていうんですかね。手近な洋書にはそもそもそういうデザインのがないんですが)を行い、そこそこ実用になっています。

さて、CS3ではすでに修正が行われていそうなことですが、少なくともCS2ではitem()とitemByRange()の挙動が妙に使いにくくて困ったものです。どちらもあるラベルまたはXML要素(属性)を検索してヒットしたものを返すのですが、

  • xmlAttributes.item("id")としたとき、idという属性がある場合にはその属性のXMLAttributeオブジェクトが返る。idという属性がなくてもXMLAttributeオブジェクトが返る。でもそのXMLAttributeオブジェクトが使える(プロパティを取れる)かどうかは調べることができない。アクセスして例外が起きて初めてわかるので、えらく使いにくい。
  • itemByRangeは2つの引数を取る。ある1つのものを探したいときには同じものを指定する。つまり、xmlAttributes.itemByRange("id", "id")という感じ。取れなかったときにはnullが返る。取れたときには、XMLAttributeの微妙な配列が返る。微妙というのは、たとえばこれをvar a = xmlAttributes...で取っても、aは配列ではなくてXMLAttributeオブジェクトになる。パラメータを取りたければa.name[0]とかする。テキストフレームのgeometricBoundsを取りたいというときも、textFrames.itemByRange("main", "main")[0].geometricBoundsのようにしたいんだけど駄目で、textFrames.itemByRange("main", "main").geometricBounds[0]。

まぁこういうのはInDesignのオブジェクト構成ではままあるようです。そういえば、スタイルのオーバーライドを解除するのをスクリプトからできないんですかね。placeXMLするとスタイルがオーバーライドされてしまうので、現状ではオブジェクトスタイルプロパティ経由で1つずつ適用し直すという不格好な方法をとっています。