Practice makes Perfect !

ExtendedScript素人です。同じ境遇の方、一緒に脱素人を目指しましょう!

関数

関数は汎用的に利用できる処理をまとめたものです。箱のような入れ物に機能をまとめておくと考えるとわかりやすいと思います。

関数は定義する場合はfuncution( )を使います。

function 関数名 ( 引数 ){
命令文;
}

引数が複数ある場合はカンマで区切ります。

また関数で処理した結果を戻り値として返したい場合はreturnを使います。

function 関数名 ( 引数 ){
命令文;
return 戻り値;
}

例えば以下にnumという関数を定義します。

function num(n1, n2){
	// 引数n1とn2で渡された数値を合計し、結果を返す
	return n1 + n2;
}
// num という関数を実行する。(引数n1に 3、引数n2に 8 を指定し結果を得る)
var total = num(3, 8);

// コンソール出力
$.writeln(total); // 11


下の例では、main()という関数を定義して、最後に実行しています。
関数の中身は①新規ドキュメントの作成、②保存先の指定、③指定したフォルダにsample.inddというファイル名で保存、④ドキュメントを閉じるという処理を行っています。

function main() {

//新規ドキュメントを作成
var docObj= app.documents.add( );

//保存先を選択するダイアログを表示
var sDir= Folder.selectDialog('保存するフォルダを選択');

//sample.inddという名前で先に指定したフォルダに保存
var fObj= new File(sDir.getRelativeURI("/")+'/sample.indd');
docObj.save(fObj);

//ドキュメントを閉じる
docObj.close();
}

// main という関数を実行する
main();

関数は次のような書き方をすることもあります。

(function(){
命令文;
})();

この場合の処理はすぐに実行されます。即時関数と呼ばれることもあるそうです。

繰り返し

繰り返しの処理を行うには、for( )またはWhile( )を使います。for文は繰り返しの回数が決まっている場合に、while文は、条件を満たしている限り処理を繰り返したい場合によく用いられます。

for文

for文は次のように書きます。

for (変数名=最初の値; 変数名<繰り返し回数; 変数名++){
繰り返したい処理
}

たとえば、ドキュメントに長方形を5つ作成したい場合。

for (var i=0; i<5; i++){
app.activeDocument.rectangles.add();
}

反対に、数を減らすような処理をしたい場合には次のような書き方をします。

var doc = app.activeDocument;
var cnt = doc.rectangles.length;
//ドキュメントの長方形が1つになるまで削除を続けます
for (var i=cnt-1; i>0; i--){
doc.rectangles[i].remove();
}

繰り返しで使われる変数名はi, j, kが多く使われますが特に決まりはありません。

while文

条件文がtrueの間は処理を繰り返し、falseになれば処理を終了する構文です。
条件を判断してから処理をするwhile文と、一度処理をしてから条件を判断するdo/whille文があります。

while文は次のように書きます。
while (条件文) 条件文がtureになる場合に実行する命令

do/while文は次のように書きます。
do 条件がtrueの場合に実行する命令 while (条件文);

例えば1から10までアラート表示する場合。

var n = 1;
while (n < 11) {
alert(n);
n++; 
}
n = 0;
do
{
n++;
alert(n);
}while(n<10);

条件判断

条件判断はif( )を使います。
( )の中に条件文を書いて、条件文の結果が真(true)の場合に実行します。
if文を使うことで、「もし(true)ならこの処理」「そうでなければ(false)この処理」というように条件によって処理を分けることができます。

書式は次のようになります。

if ( 条件文 ) 条件文が真の場合に実行する命令
if (app.activeDocument.textFrames.length < 1){
	alert("テキストフレームがありません");
}

アクティブドキュメントにテキストフレームがひとつもない場合に「テキストフレームがありません」と表示します。

条件を満たさない場合も併せて書くときにはelseを使います。

if (app.activeDocument.textFrames.length < 1){
	alert("テキストフレームがありません");
}else{
	alert("テキストフレームがあります");
}

else ifを使うと、2つ目以降の条件文を追加できます。else ifはいくつでも使えます。

var doc = app.activeDocument;
var txtObj = doc.textFrames;
if (txtObj.length < 1){
	alert("テキストフレームがありません");
}else if (txtObj.length > 1){
	alert("テキストフレームは1つにしてください");
}else{
	txtObj[0].fillColor = doc.swatches.itemByName("Black");
}

アクティブドキュメントにテキストフレームがひとつもない場合に「テキストフレームがありません」と表示します。そうでない場合で、アクティブドキュメントにテキストフレームが2つ以上ある場合は「テキストフレームは1つにしてください」と表示します。
どちらにも当てはまらない場合、つまり、アクティブドキュメントにテキストフレームが1つの場合のみ、そのテキストフレームを黒く塗りつぶします。

if文を入れ子にすることもできます。

var doc = app.activeDocument;
var txtObj = doc.textFrames;
if (txtObj.length < 1){
	alert("テキストフレームがありません");
}else if (txtObj.length > 1){
	alert("テキストフレームは1つにしてください");
}else{
	if (confirm("テキストフレームを削除しますか?")){
		txtObj[0].remove();
	}
}

confirm( )はメッセージと[Yes] [No]のボタンのあるダイア ログを表示します。Yesでtrueを、Noでfalseを返します。
テキストフレームが1つの場合、それを削除するか尋ね、Yesなら削除します。

複合条件を指定することもできます。左辺と右辺の条件を満たした場合のみ処理するには、&&を使います。

var doc = app.activeDocument;
var txtObj = doc.textFrames;
if ((txtObj.length == 1)&&(txtObj[0].fillColor == doc.swatches.itemByName("Black"))){
	txtObj.add({
		geometricBounds:[10, 10, 35, 110],
		fillColor: doc.swatches[6]
	});
}

アクティブドキュメントにテキストフレームが1つのみで、かつ、塗りが黒の場合、Y:10, X:10の位置に H25, W100のスウォッチパネルの7番目の色を塗りに設定したテキストフレームを追加しなさい。

左辺と右辺の条件のうち、どちらかが成立した場合に処理するには、&&ではなく、||を使います。

長方形を描画してみる

ここで実際に新規ドキュメントに長方形を作成してみましょう。

var doc = app.documents.add();
doc.rectangles.add();//長方形はrectangleオブジェクトです

InDesignに新規ドキュメントが追加され、ページの左上に長方形が作成されたはずです。

それでは、作成した長方形のサイズを指定します。
上から10mm、左から10mmの位置に、幅90mm、高さ30mmの長方形を作成します。

var doc = app.documents.add();

//作成した長方形を操作するので、いったん変数rctに代入します。
var rct = doc.rectangles.add();

//座標の値は配列で指定するので[ ]でくくります。ドキュメントの単位が「ミリ」になっている場合は[10, 10, 40, 100]でも可。
rct.geometricBounds = ["10mm", "10mm", "40mm", "100mm"];

座標は「上」「左」「下」「右」の順で指定します。上が10で下を40にしたので高さが30mmとなり、左が10で右が100にしたので幅が90mmとなります。なお、geometricBoundsは線幅を含まないサイズになっています。

次に、作成した長方形を黒く塗りつぶしましょう。

var doc = app.documents.add();
var rct = doc.rectangles.add();
rct.geometricBounds = ["10mm", "10mm", "40mm", "100mm"];

// fillColorは塗りを設定するプロパティで、値はSwatchオブジェクトで指定します。itemByNameはオブジェクトの名前を呼び出します。
rct.fillColor = doc.swatches.itemByName("Black");

塗の指定はスウォッチを使用しますので、例えばスウォッチパネルにある6番目の色を呼び出したい時は

rct.fillColor = doc.swatches[5];

または

rct.fillColor = doc.swatches.item(5);

とします。

また、上記の例のようにitemByNameで指定したい時は、スウォッチパネルの色をダブルクリックすれば、上部に名前が表示されます。
f:id:YustinBieber:20211012164609p:plain

マゼンダなら「C=0 M=100 Y=0 K=0」なので、

rct.fillColor = doc.swatches.itemByName("C=0 M=100 Y=0 K=0");

とします。ちなみに「白」は「Paper」です。

配列

配列は、1つの変数内に複数のデータを持つことができます。変数名の後に[ ]、その中に番号をいれて値にアクセスします。Javascriptでは配列はArrayオブジェクトとなります。空の配列を作成するときは次のように書きます。

var data = newArray(); 

または

var data = [ ]; 


以前も述べましたが、Javascriptではデータの参照番号は「0」から始まるので、配列の要素の1番目にアクセスしたいときは、次のように書きます。

data[0]


また[ ]の中には文字列を書くこともできます。
例としてあげると次のようになります。

var dataA = ["いか", "たこ", "さざえ"];
alert(dataA[0]);  

配列 dataAの1番目にアクセスするので いか と表示されます。


存在しない要素でも追加することが可能です。

var dataB = Array(33, 44, 55, 66);
dataB[4] = 77;
alert(dataB);  

配列dataBの5番目に77を追加するので
33,44,55,66,77 と表示されます。


またpushメソッドを使うと、配列の「末尾」に要素を追加できます。

var dataA = ["いか", "たこ", "さざえ"];
dataA.push("あわび");
alert(dataA);

配列dataAの末尾にあわびを追加するので
いか,たこ,さざえ,あわび と表示されます。

$.writeln();

$オブジェクトはExtendScript の特殊なオブジェクトです。
ESTKではJavascriptコンソールというウィンドウがあって(図の左上部分)、コンソール出力(変数に格納されている値や任意の文字列を出力)するとこができます。

f:id:YustinBieber:20211005151554p:plain
左上の部分に出力される

上記の例では、配列の中身をalertで表示しましたが、いちいちalert表示せずにコンソールに出力することができます。

$.writeln(dataA);
$.writeln(dataB);

といった感じで上記と同じ内容がコンソールウィンドウに出力されます。

コレクション、代入、変数

コレクション

オブジェクトを複数まとめて扱うことができるのがコレクションです。InDesignスウォッチやレイヤーなど、複数のオブジェクトに対して一括で処理ができます。
「何番目のレイヤーを非表示にする」とか「何番目のスウォッチを塗に適用する」といった感じです。

Javascriptでは「0」が1番目

app.activeDocument.layers[0];

または

app.activeDocument.layers.item(0);

で、「アクティブドキュメントの一番上のレイヤー」となります。


また「itemByName」を使えばコレクションの中で「○○という名前のもの」という指定もできます。

app.activeDocument.layers.itemByName("背景");

「アクティブドキュメントの"背景"という名前のレイヤー」となります。

代入「=」って何ですか?

「=」は、代入演算子といって、変数に値を代入するために使用されます。JavaScriptでの「=」は数学での等号とは意味合いが違い、右辺にあるデータを左辺に入れるという意味になります。

num = 2;

「変数numに2を入れる」

app.activeDocument.layers[2].name="背景";

「アクティブドキュメントの上から3番目のレイヤー名を『背景』とする」

変数

変数は、数値や文字列、オブジェクトの場所や配列など、様々なデータを入れておく場所(箱のようなもの)です。
変数を使う場合はvarを使います。varのあとの変数名は好きな名前を付けます。

var num = 123;

「変数numに123を入れる」

var num;

初期値をnullにする場合は、このように宣言だけすれば良いです。
nullは「値が存在しない」という意味です。

var num1, num2, num3;

一度varと書けば続けて複数の変数を宣言することも可能です。


先述の

app.activeDocument.layers[2].name="背景";

を以下のように書くこともできます。

var doc = app.activeDocument;
var lay = doc.layers[2];
lay.name ="背景";

varはどこで宣言するかによって、アクセスできる範囲が変わるそうです。
varをつかわないとどこでも使える状態(グローバル変数)になってしまい、不具合の原因になるとか…。私はvarは必ずつけるようにしています。だって、グローバルとかよくわからないんだもん。

オブジェクト,プロパティ,メソッド

オブジェクト

コンピュータ上で操作や処理の対象となる何らかの実体のことをオブジェクトといいます。
またオブジェクトにはそれぞれ固有のプロパティ(属性)とメソッド(操作)があり、外部からのメッセージを受けてメソッドを実行し、データを操作します。
InDesignでオブジェクトと言えば、テキストフレームや画像などをいいますが、例えばテキストフレームを選択したときに変形パレットに表示される座標はプロパティ、テキストフレームを選択した状態での操作(コピペとか塗りを追加するとか)をメソッドと言います。

プロパティ

オブジェクトのデータや値

メソッド

オブジェクトの操作。メッソッドの( )には必要なデータ(パラメーター、引数)を渡すことができます。
パラメーターは全くない場合や1つの場合、複数の場合があります。

app.activeDocument.close();
app.activeDocument.close(SaveOptions.ask);

など

「.」(ドット)って何ですか?

このオブジェクトとプロパティ、メソッドにアクセスする場合にオブジェクト名とプロパティ名を「.」で区切るのです。
これで何となく「app.documents.add();」の意味が見えてきました。

app.documents.add();
  • appはAppllicationオブジェクトを指す。
  • documentsはApplicationオブジェクトのdocumentsプロパティ。
  • add()は「追加」というメソッド。
  • 行末の「;」は行末であることを示します。

「.」は「~の」とか「~に」とかというニュアンスでとらえてもいいのかなと思います。
つまり、「アプリケーション(InDesign)に新たにドキュメントを追加しなさい」という意味合いになるかと思います。

もうひとつおまけに。

app.activeDocument.close(SaveOptions.ask);

これは「アプリケーション(InDesign)の作業中のドキュメントを閉じなさい(保存するか尋ねなさい)」といった感じかな。