Adobe ExtendScriptのプリプロセッサディレクティブ

ExtendScriptって名前、検索しづらいにもほどがあると思います。どうもこんばんは。

スクリプトをいくつかのファイルに分割したり、単機能のライブラリとして読み込んだりしたいとき、#includeディレクティブ(指示文)を記述するとインクルードすることができます。
他にも#targetとか#targetengineだとかあって、使うたびに調べてて面倒になったのでまとめておこうと思いました。

元ネタは「JavaScriptToolsGuideCC.pdf」。Mac 10.9 + ExtendScript Toolkit CCでの実験結果を含みます。

書き方

#include "file1.jsxinc;folder/file2.jsxinc"

Cとかに似てるそうですね、知らんけど。

ポイントは以下の通り。

  • 先頭に#、続けてディレクティブ名、スペース、引数。
  • 末尾にセミコロンはつけない。
  • 引数に複数の値を指定するときはセミコロンで区切る。
  • 引数の引用符は必須ではないけど、英数字以外を含む場合や、複数指定する場合は必要。'でも"でもOK。

各ディレクティブ説明

指定できるディレクティブは以下の6つ。

  • #include
  • #includepath
  • #script
  • #strict
  • #target
  • #targetengine

順番にいきましょう。

#include
#include "../folder/file1.jsxinc"

他のスクリプトファイルをインクルード(読み込んで実行)します。相対パス絶対パスどちらも使えるっぽいです。

ちなみに.jsxincというのは普通の.jsxファイルの拡張子を変えただけのファイルです。インクルード専用のファイルだということを明示するために付ける拡張子。InDesignスクリプトパネルなどから直接実行できなくなります。

ディレクティブは複数書いても大丈夫みたいですね。その場合は上から順に読み込まれます。

#includepath
#includepath "folder1;../folder2"

インクルードするファイル(#includeで記述)のパスを指定します。相対パス絶対パスどちらも使えます。引数は複数指定可能。

これがなかなかややこしいというか、下手に使うと失敗しそうです。例を挙げると、

#includepath "../lib/folder1;../lib/folder2"
#includepath "../lib"
#include "multi.jsxinc"

こんなふうに記述した場合、インクルードされるファイルは以下の4つ。(数字)は読み込み順です。

  • ../lib/folder1/multi.jsxinc (3)
  • ../lib/folder2/multi.jsxinc (2)
  • ../lib/multi.jsxinc (1)
  • ./multi.jsxinc (4)

最後のは、実行中のスクリプトと同じ階層にあるファイルです。
確かに#include自体相対パスとみなせるので理解はできるんだけど……ちょっと怖いのは私だけですか。主に順番とか。

面倒なので実験はしてないけど、これで#includeが複数あるともっとややこしくなりそうです。
ファイル名をユニークにすること、グローバル変数を最低限にすることが大事っぽい。

#script
#script "Script Name"

スクリプトの名前を指定します。
「The name value is displayed in the Toolkit Editor tab.」って書いてあるんだけど、どこで使われるんだかよくわからない。知ってる人いたら教えてください。

#strict
#strict on

エラーチェックをstrict(厳密)モードにします。
オブジェクトのプロパティがreadonly(読み込み専用)に設定されているとき、通常はスクリプトで上書きしようとしても無視されてそのまま進むだけなんだけど、strictモードがonだとエラーで止まるようになるみたいです。

#target
#target "indesign"

スクリプトが動作するアプリケーションを指定します。
ここで指定しておくと、.jsxファイルをダブルクリックしたとき、アプリケーションを起動して実行するかどうかのダイアログが出ます。指定しない場合はESTKで開くだけで、実行はされません。

#targetengine
#targetengine "session"

スクリプトが動作するJavaScriptエンジンを指定します。
通常、スクリプトで使用したグローバル変数は実行後に破棄されるんだけど、ここでmain以外を指定しておくと、スクリプトが動作したアプリケーションが起動している間はずっと変数が保持され、同じエンジンを指定したスクリプトから参照できるようになります。
ScriptUIを使ってウィンドウやらパレットやらを作りたいときには指定必須です。

おしまい

正直#includepathのとこが書きたかっただけです。