2010年9月3日金曜日

InDesign CS5 の pageItems の並びが CS4 以前までと違っている件

昨日、今まで作ったスクリプトのCS5での動作検証をしていて、あることに気づいた。
下のようなInDesignドキュメントを用意する。



レイヤーは3つ、下から順番にテキストフレームに数字を入れ、ところどころグループしてある。
このドキュメントに対し、InDesignCS4で以下のスクリプトを実行する。
var doc = app.activeDocument;
for(var l=0,lLength=doc.layers.length;l<lLength;l++){
var layer = doc.layers[l];
$.writeln('----↓Layer '+layer.name);
var items = layer.pageItems.everyItem().getElements();
(function(items){
for(var i=0,iLength=items.length;i<iLength;i++){
var item=items[i];
if(item.constructor.name==='Group'){
$.writeln('--↓Group '+item.id);
arguments.callee(item.pageItems.everyItem().getElements());
$.writeln('--↑Group '+item.id);
}else{
$.writeln(item.contents);
}
};
})(items);
$.writeln('----↑Layer '+layer.name);
};

すると、結果はこう出る。
----↓Layer レイヤー 3
12
11
10
----↑Layer レイヤー 3
----↓Layer レイヤー 2
--↓Group 986
9
--↓Group 985
8
7
--↑Group 985
--↑Group 986
----↑Layer レイヤー 2
----↓Layer レイヤー 1
--↓Group 987
6
5
--↑Group 987
4
--↓Group 976
3
2
--↑Group 976
1
----↑Layer レイヤー 1

これが今までの動き。pageItemsは、レイヤーごとに上から順に、グループ以下を含まずに「PageItem」オブジェクトを返す。
それらはTextFrameやGroupではなく、一枚皮をかぶった状態なので、everyItem().getElements()で、PageItemの皮を剝いた配列を拾っていた。これは今まで自分が結構使っている手だった。

さて、このスクリプトをCS5で走らせてみると、こうなった。
----↓Layer レイヤー 3
12
11
10
----↑Layer レイヤー 3
----↓Layer レイヤー 2
--↓Group 986
9
--↓Group 985
8
7
--↑Group 985
--↑Group 986
----↑Layer レイヤー 2
----↓Layer レイヤー 1
4
1
--↓Group 987
6
5
--↑Group 987
--↓Group 976
3
2
--↑Group 976
----↑Layer レイヤー 1

並び順が変わってしまっている!わかりにくいので、レイヤーを結合して、もう一度実行してみる。
----↓Layer レイヤー 1
12
11
10
4
1
--↓Group 986
9
--↓Group 985
8
7
--↑Group 985
--↑Group 986
--↓Group 987
6
5
--↑Group 987
--↓Group 976
3
2
--↑Group 976
----↑Layer レイヤー 1

再帰するのをやめて、contentsじゃなくそのまま出してみる。
var doc = app.activeDocument;
for(var l=0,lLength=doc.layers.length;l<lLength;l++){
var layer = doc.layers[l];
var items = layer.pageItems.everyItem().getElements();
for(var i=0,iLength=items.length;i<iLength;i++){
$.writeln(items[i]);
};
};

結果は?こうなった。
[object TextFrame]
[object TextFrame]
[object TextFrame]
[object TextFrame]
[object TextFrame]
[object Group]
[object Group]
[object Group]

要するに、CS5のpageItemsは、上から順にアイテムを並べるのではなく、「テキストフレームのまとまり(textFrames)」、「グループのまとまり(groups)」といったまとまりごとに並べて来るようだ。
ちなみに順番は、
Oval→Rectangle→GraphicLine→Polygon→TextFrame→Group
の順に来るみたい。

これは……地味に困る。前後関係を取りたいスクリプトがいくつかあるんだ。
pageItemsでは前後関係が正しく来ないものの、allPageItemsでは正しい前後関係で取れる(ただしグループ以下のアイテムもまとめて来てしまう)のを確認したので、以下のようなfunctionを書いてpageItems.everyItem().getElements()と置き換えることにした。
var getChildItems=function(item){
var allItems = item.allPageItems;
var max = allItems.length, i = 0, children = [];
while(i < max){
var child = allItems[i];
children.push(child);
i++;
if(child.constructor.name==='Group'){
i += child.allPageItems.length;
}
};
return children;
};
とりあえずこれで何とか……。まいったよもう。

0 件のコメント: