InDesignをJavaScriptで制御する際に基本になる詰まりどころをまとめていきます。
※ちょっとずつ追記していく予定です。
開発環境(ExtendScript Toolkitを使います)
注意点。
起動後にソースコードを実行する対象アプリケーションを選択する必要があります。
JAVASCRIPTコンソールに文字を出力する。
プログラムの試行錯誤時にコンソールに変数情報を出力すると何かと便利です。
//改行なし
$.write("Hello World!!!!!");
//改行あり
$.writeln("Hello World!!!!!");
JAVASCRIPTコンソールの表示内容をクリアしたり、文字の大きさを変更するには右上のプルダウンを選択します。
下図の赤枠で囲った部分です。
フォルダー操作の基本
フォルダー選択画面を表示してフォルダーを選ぶ
var folderObj = Folder.selectDialog ();
$.writeln(folderObj.fsName);
備考:InDesignで定義されているFileオブジェクトやFolderオブジェクトはフォルダーの区切り文字がWindowsとmacOS両方で/(スラッシュ)で統一されているようです(macOS 10.13 InDesignCS5、Windows10 InDesign CCで確認)。
サブフォルダ/サブファイルを取得する
var folderObj = Folder.selectDialog ();
var subFolderObjList = folderObj.getFiles();
for (var i = 0; i < subFolderObjList.length; i++) {
$.writeln(subFolderObjList[i].fsName);
}
テキストファイル処理
テキストファイルを読み込む
function main() {
var text_content = "";
f = new File("/Users/efla/Desktop/test/test.xml");
if (fh = f.open("r")) {
text_content = f.read();
f.close();
}
$.writeln(text_content);
}
main();
XMLファイルの操作
XMLファイルの中身を取り出す。
色々な文法でXMLのパースができます。
ソースコードにXML構造をゴリゴリ書く。
function main() {
var text_content = "";
f = new File("/Users/efla/Desktop/test/test.xml");
if (fh = f.open("r")) {
text_content = f.read();
f.close();
}
$.writeln(text_content);
var xml_contents = new XML(text_content);
for (i=0;i<xml_contents.Text.length();i++) {
$.writeln(xml_contents.Text[i]);
}
}
main();
XPathを使う
function main() {
var text_content = "";
f = new File("/Users/efla/Desktop/test/test.xml");
if (fh = f.open("r")) {
text_content = f.read();
f.close();
}
$.writeln(text_content);
var xml_contents = new XML(text_content);
for (i=0;i<xml_contents.xpath ("/Text").length();i++) {
$.writeln(xml_contents.xpath ("Text")[i]);
}
}
main();
属性値を取り出す
メソッドattributeでノードの属性値を取得できます。
function main() {
var text_content = "";
f = new File("/Users/efla/Desktop/test/test.xml");
if (fh = f.open("r")) {
text_content = f.read();
f.close();
}
$.writeln(text_content);
var xml_contents = new XML(text_content);
for (i=0;i<xml_contents.Text.length();i++) {
$.writeln(xml_contents.Text[i]);
$.writeln(xml_contents.Text[i].attribute("color"));
}
}
main();
実行結果
InDesignドキュメントとファイル操作
ファイパスを指定してInDesignファイルを開く
function main() {
// ドキュメントを開く
f = new File("/Users/efla/Desktop/test.indd");
doc = app.open(f);
$.writeln(doc);
}
main();
新規InDesignドキュメントを作成・保存・閉じる
function main() {
// 新規ドキュメントを作成する
doc = app.documents.add();
$.writeln(doc);
// 新規ドキュメントを保存する
doc.save("/Users/efla/Desktop/hoge.indd");
// 新規ドキュメントを閉じる
doc.close();
}
main();
PDF出力
アクティブドキュメントをPDFファイルに書き出しする。
既定のプリセットで書き出す。
function main() {
app.activeDocument.exportFile(ExportFormat.pdfType, "/Users/efla/Desktop/hoge.pdf", false);
}
main();
プリセットを指定して書き出す。
function main() {
presetName = "[PDF/X-1a:2001 (日本)]";
app.activeDocument.exportFile(ExportFormat.pdfType, "/Users/efla/Desktop/hoge.pdf", false,presetName);
}
main();
文字列操作
正規表現と完全一致するか調べる。
function main() {
Str = “0987”
if (/^[0-9][0-9][0-9][0-9]$/.test(Str)) {
alert(“correct”);
}
}
main();
画像操作
画像をドキュメントに配置する。
function main() {
pageObj = app.activeDocument.pages[0];
var imageObj = pageObj.textFrames.add();
imageObj.visibleBounds = ["10mm","10mm","30mm","30mm"];
imageObj.contentType = ContentType.graphicType;
imageObj.place(new File("/Users/efla/Desktop/IMG_1453.png"));
imageObj.fit(FitOptions.fillProportionally);
}
main();
画像のリンク情報を取得する
function main() {
pageObj = app.activeDocument.pages[0];
var imageObj = pageObj.textFrames.add();
imageObj.visibleBounds = ["10mm","10mm","30mm","30mm"];
imageObj.contentType = ContentType.graphicType;
imageObj.place(new File("/Users/efla/Desktop/IMG_1453.png"));
imageObj.fit(FitOptions.fillProportionally);
var glist = imageObj.allGraphics;
for (i=0;i<glist.length;i++) {
g = glist[i];
l = g.itemLink;
$.writeln(g.itemLink.name); // リンク先のファイル名取得
$.writeln(l.filePath); // リンク先のファイルパスを取得
}
}
main();
画像のメタ情報・位置情報を取得する
function main() {
pageObj = app.activeDocument.pages[0];
var glist = pageObj.allGraphics;
for (i=0;i<glist.length;i++) {
var g = glist[i]; // Imageオブジェクト
var l = g.itemLink; // Linkオブジェクト
$.writeln(g);
$.writeln(l);
$.writeln(g.itemLink.name); // リンク先のファイル名取得
$.writeln(l.filePath); // リンク先のファイルパスを取得
$.writeln(g.imageTypeName); // リンクファイルの形式を取得
$.writeln(g.absoluteHorizontalScale);
$.writeln(g.absoluteVerticalScale);
$.writeln(g.absoluteRotationAngle);
$.writeln(g.absoluteShearAngle);
$.writeln(g.horizontalScale);
$.writeln(g.verticalScale);
$.writeln(g.rotationAngle);
$.writeln(g.shearAngle);
$.writeln(g.visibleBounds);
$.writeln(g.actualPpi);
$.writeln(g.clippingPath);
}
}
main();
文字組処理
テキストフレームを作成
function addSwatch(c,m,y,k,name) {
var i=0;
for (i=0;i<app.activeDocument.colors.length;i++) {
if (app.activeDocument.colors[i].name==name) {
app.activeDocument.colors[i].remove();
}
}
colorOption = {colorValue:[c,m,y,k],model:ColorModel.process,space:ColorSpace.cmyk,name:name}
colorObj = app.activeDocument.colors.add(colorOption);
return colorObj;
}
function main() {
// 新しいテキストフレームを追加する。
var tf = app.activeDocument.pages[0].textFrames.add();
// テキストフレームの位置と大きさをページの左上を原点とする絶対座標で指定する。
tf.visibleBounds = ["0mm","0mm","10mm","30mm"];
// テキストフレームを移動させる(ページの左上を原点とする絶対座標)
tf.move(["5mm","5mm"]);
// テキストフレームを移動させる(今の位置から移動距離を指定)
tf.move(undefined,["2mm","2mm"]);
// テキストフレームに文字列を設定する。
tf.contents = "みすずちんにはは";
// 文字のQ数を指定する
tf.paragraphs[0].characters[0].pointSize = "24Q";
//テキストフレームを黒で塗りつぶす
var s1 = addSwatch (0, 0, 0, 100, "黒");
tf.fillColor = s1;
// 文字の色とフォントを変更
var s2 = addSwatch (0, 0, 0, 0, "白");
var s3 = addSwatch (100,0,0,0, "C100");
for (i = 0; i < tf.paragraphs[0].characters.length;i++) {
tf.paragraphs[0].characters[i].strokeColor = s2;
tf.paragraphs[0].characters[i].fillColor = s3;
}
// 文字のフォントを変更
var f = app.fonts.item("ヒラギノ丸ゴ Pro");
tf.paragraphs[0].appliedFont = f;
}
main();
結果(画像は別記画像処理で追加)
選択
スクリプトを作るときに、選択の解除や吟味をする処理を入れておかないと、トラブルの元になりやすい。
現在の選択をクリアする
function main() {
app.select(NothingEnum.nothing);
}
main();
全てのオブジェクトを選択する
function main() {
// 必要に応じて、ロックオブジェクトやロックレイヤーの状態を調整する
app.select(SelectAll.all); // 全てのオブジェクトを選択する
}
main();
現在の選択で、テキストフレーム以外の選択を解除する。
function main() {
var sel = app.activeDocument.selection;
for (i=0;i<sel.length;i++) {
if ( sel[i].contentType!=ContentType.textType ) {
sel[i].select(SelectionOptions.removeFrom);
}
}
}
main();
コピー&ペースト
選択しているオブジェクトをコピーペーストする
function main() {
try {
app.copy();
app.paste();
} catch(e) {
alert(e);
}
}
main();
結果(オブジェクトを選択している時)
結果(オブジェクトを選択していない時)
選択しているオブジェクトを同じ位置にペーストする
function main() {
try {
app.copy();
app.pasteInPlace();
} catch(e) {
alert(e);
}
}
main();
結果
レイヤー操作
レイヤー情報を取得する
function main () {
var lList = app.activeDocument.layers;
for (i = 0; i < lList.length;i++) {
$.writeln(lList[i].name); // レイヤー名
$.writeln(lList[i].locked); // レイヤーロック状態
$.writeln(lList[i].visible); // レイヤー表示非表示状態
}
}
main();
実行結果
線を扱う
線に矢印があるかどうか確認する
function main() {
var pageObj = app.activeDocument.pages[0];
var total = pageObj.allPageItems.length;
var i = 0;
for (i=0;i<total;i++) {
var pageItem;
pageItem = pageObj.allPageItems[i];
var typeName = pageItem.constructor.name;
if (typeName=="GraphicLine") {
$.writeln(typeName);
$.writeln(pageItem.leftLineEnd.constructor.name);
$.writeln(isDoubleHeadArrow (pageItem));
$.writeln(isArrow(pageItem));
//ArrowHead.NONE
//ArrowHead.SIMPLE_ARROW_HEAD
//ArrowHead.SIMPLE_WIDE_ARROW_HEAD
//ArrowHead.TRIANGLE_ARROW_HEAD
//ArrowHead.TRIANGLE_WIDE_ARROW_HEAD
//ArrowHead.BARBED_ARROW_HEAD
//ArrowHead.CURVED_ARROW_HEAD
//ArrowHead.CIRCLE_ARROW_HEAD
//ArrowHead.CIRCLE_SOLID_ARROW_HEAD
//ArrowHead.SQUARE_ARROW_HEAD
//ArrowHead.SQUARE_SOLID_ARROW_HEAD
//ArrowHead.BAR_ARROW_HEAD
}
}
}
function isDoubleHeadArrow( item ) {
var typeName = item.constructor.name;
if (typeName != "GraphicLine") {
return false;1
}
if (item.leftLineEnd!=ArrowHead.NONE && item.rightLineEnd != ArrowHead.NONE) {
return true;
}
return false;
}
function isArrow( item ) {
var typeName = item.constructor.name;
if (typeName != "GraphicLine") {
return false;1
}
if (item.leftLineEnd != ArrowHead.NONE || item.rightLineEnd != ArrowHead.NONE) {
return true;
}
return false;
}
main();
矢印の対比
