イラストレーター用スクリプトの謎

イラストレーターでドキュメント内のオブジェクトを操作したいのですが。

まずは、ドキュメント全て、要は開いているファイル全て取得。どちらでも良い(結果は同じ)模様。

$.writeln(documents);
$.writeln(app.documents);

で、appって何。色々検索したけど、日本語の説明を見つけられない。なお、英語では見つけたけど、読んでもよくわからない。

次に、アクティブドキュメント、要は今操作しているファイルの取得。どちらでも良い(結果は同じ)模様。

$.writeln(activeDocument);
$.writeln(app.activeDocument);

で、app(以下略

ここからが本題。動かない理由がわからなくて、ちょっと気持ち悪い。コードを一気に書きます。

// ローカル(グローバル)
$.writeln(documents);
$.writeln(app.documents);	
$.writeln(activeDocument);
$.writeln(app.activeDocument);

// 関数
function hoge() {
	$.writeln(documents);
	$.writeln(app.documents);	
	$.writeln(activeDocument);
	$.writeln(app.activeDocument);	
}
hoge();

// ウィンドウからのイベント
var win = new Window('palette', '窓');
var btn = win.add('button', undefined, '釦');
btn.onClick = function() {
	$.writeln(documents);
	$.writeln(app.documents);
	$.writeln(activeDocument); // ここでコケる
	$.writeln(app.activeDocument);
}
win.show();

明確な答えが見つからないけど、イラストレーターは自分を呼ぶ出すのにBridgeTalkクラス経由で実行する必要があるとのこと。なるほど…って、なんでやねん?!

var win = new Window('palette', '窓');
var btn = win.add('button',undefined,'釦');
btn.onClick = function() {
	var bt = new BridgeTalk();
	bt.target="illustrator";
	bt.body = 'hoge();';
	bt.send();
};
function hoge() {
	$.writeln(documents);
	$.writeln(app.documents);
	$.writeln(activeDocument);
	$.writeln(app.activeDocument);
}
win.show();

これで動くのはわかったけど、正直なところ気持ち悪い。Windowクラスがローカルを汚染、ここではactiveDocumentを削除してしまうのか?しかしdefined関数がないので定義判定が出来ないため確認できず。そもそもBridgeTalkクラスを呼ぶとactiveDocumentが復活するのは、BridgeTalkクラスがグローバルを汚染していることになるのでは?

activeDocuemtを使うためだけにBridgeTalkクラスを呼ぶのは気持ちが悪いから、activeDocumentを再定義すれば良いのかもしれない。と思ってactiveDocuent関数を書いたら、そこでイラストレータがフリーズする。これはダメみたい。

それならばgetActiveDocument関数を書けばいいと思ったけど、documentがアクティブかどうかの判定方法がわからない。document(s)のプロパティ一覧を調べても、アクティブかどうかを取得する方法がない感じ。そもそもアクティブかどうかはアプリケーションの状態なので判定できないのだろう。なるほど、それでBridgeTalkクラスが必要なのか。って思ったけど、だったらWindowクラスからのイベントで呼ばれない場合に動くのが説明つかない。やはりグローバルかどうかが鍵なのか?

Illustrator CS5で文字を置換するスクリプト

イラレCS5での話ですが、置換ダイアログを出すところまでははアクションに登録できるものの、置換する文字の組み合わせは記録されません。
常に同じ文字を置換したくても、アクションでは対応できないのです。

仕方がないのでスクリプトをおさらいすることに。
検索するといろいろ出てくるのですが、文字を操作するスクリプトは大抵
activeDocument.selection
を使用しており、文字を選択していることが前提となっているので使いにくいことこの上ないです。
そこで、ドキュメント内全てのオブジェクトからテキストかどうかを判定して、置換に掛けるように組み直してみました。
ファイル名を「relpacement.jsx」とでもして保存すれば使えます。

var data = {src:"あ", dst:"い"};
var targetObj = [];

// ドキュメント内からテキストのみを取り出す
var docObj = activeDocument;
for(var i=0; i<docObj.pageItems.length; i++){
	typ = docObj.pageItems[i].typename;
	if (typ != "TextFrame") continue; // テキスト以外は無視
	targetObj.push(docObj.pageItems[i]); // 対象を格納
}

// テキストの該当文字を置換
for(var i=0; i<targetObj.length; i++){
	var regSrc = new RegExp(data.src, "gm");
	targetObj[i].contents = targetObj[i].contents.replace(regSrc, data.dst);
}


CS5では正常に動いていますが、CCはでは不明です。
そもそもアクションに記録できるようになっているのかな?
CS6以降なら、スクリプトの実行もアクションに登録できるらしいので、さらに楽になりますね。
CS5ではいちいちファイルを指定しないとだめです。