Home About Contact
UXP , InDesign

InDesign 18.4 の変更点と UXP InDesign Script を deno_emit でバンドルする

Hello, World!

InDesign 18.4 から require() API を使って InDesign DOM を取得するように変わったそうです。 詳しくはこのページ https://developer.adobe.com/indesign/uxp/recipes/dom-versioning/ をご覧ください。

18.4 以前は、app などが予めグロバール変数として存在していたが、これを以下のように取得する。

let myInDesign = require("indesign");
let app = myInDesign.app;

さらにこのように、明示的にバージョンを指定して取得することもできる。

let myInDesign = require("indesign-16.1");

Hello, World!

それでは、InDesign 18.4 に対応した Hello, World! を書きます。 以前書いたこのコードをベースとして使いました。

使用する deno のバージョン

$ deno --version
deno 1.35.3 (release, x86_64-unknown-linux-gnu)
v8 11.6.189.12
typescript 5.1.6

今回作成する Hello, World! 文字列をテキストフレームに入れた InDesign 文書を生成する UXP InDesign スクリプトは、 ごく簡単なものですが、モジュールにして deno bundle する形でつくります。

まず InDesign の ドキュメント・ページ・テキストフレームを生成する関数 ind.createDocObject を定義した ind.js を用意.

const ind = {};

ind.createDocObject = (app, params)=>{
    const pageWidth = params.pageWidth;
    const pageHeight = params.pageHeight;
    const margin = params.margin;

    const docParams = {
        documentPreferences : {
            pageWidth   : `${pageWidth}mm`,
            pageHeight  : `${pageHeight}mm`,
            facingPages : false
        },
        cjkGridPreferences : {
            showAllLayoutGrids : false
        }
    };
    const doc = app.documents.add(docParams);

    const page = doc.pages.item(0);
    page.marginPreferences.properties = {
        top    : `${margin.top}mm`,
        left   : `${margin.left}mm`,
        bottom : `${margin.bottom}mm`,
        right  : `${margin.right}mm`
    };

    const textFrameParams = {
        geometricBounds: [
            `${margin.top}mm`, // top
            `${margin.left}mm`, // left
            `${pageHeight - margin.bottom}mm`, // bottom
            `${pageWidth - margin.right}mm` // right
        ]
    };
    const textFrame = page.textFrames.add(textFrameParams);

    return {
        doc: doc,
        page: page,
        textFrame: textFrame
    };
};

export { ind };

この ind.js モジュールをつかう main.js を書きます。

import { ind } from "./ind.js"

const myInDesign = require("indesign");

const params = {
    pageWidth: 50,
    pageHeight: 50,
    margin: {
        top: 5,
        left: 5,
        bottom: 5,
        right: 5
    }
};

const obj = ind.createDocObject(myInDesign.app, params);
obj.textFrame.contents = 'Hello, World!';

生成するドキュメントのページサイズやテキストフレームのマージンを params で指定して ind.createDocObject に渡します。

最後にこれをバンドルして、一つのファイルにまとめ UXP InDesign Script として作動するようにします。

$ deno bundle main.js > hello-world.idjs

警告が出ます。今はそのまま進みます。あとで対処します。

あとは、出来上がった hello-world.idjs を InDesign のスクリプトフォルダにコピーして InDesign のスクリプトパネルから実行します。

今使用している環境は M1 Macbook Air の InDesign 18.4 ですが、該当のスクリプトフォルダは /Applications/Adobe InDesign 2023/Scripts/Scripts Panel です。そこにコピーします。

$ cp hello-world.idjs /Applications/Adobe\ InDesign\ 2023/Scripts/Scripts\ Panel/

InDesign のスクリプトパネルを見ると、hello-world.idjs が存在しているのがわかります。

InDesign Script Panel

それでは、該当スクリプトをダブルクリックして実行します。実行結果は以下の通り。

Hello, World!

バンドル時の警告に対処する

先程、deno bundle したときに警告が出ました。

Warning "deno bundle" is deprecated and will be removed in the future.
Use alternative bundlers like "deno_emit", "esbuild" or "rollup" instead.

deno bundle は deprecated になり将来削除される機能とのこと。 deno_emitesbuildrollup を代わりに使ってと言われたので、 素直に最初に提案された deno_emit を使います。

詳細はこちら

今回はローカルにある main.js をバンドルしたいので、以下の bundle.js を書きます。

import { bundle } from "https://deno.land/x/emit/mod.ts";

const result = await bundle(
    new URL("./main.js", import.meta.url),
);

const { code } = result;
console.log(code);

バンドルするためのビルドツールもただの JavaScript であるという単純さ。

このスクリプトを実行するには以下のようにします。

$ deno run --allow-read --allow-env --allow-write --allow-net bundle.js > hello-world.idjs

main.js をバンドルして hell-world.idjs にするのですが、main.js を引数で与えたほうが都合がよいので bundle.js を修正します。

import { bundle } from "https://deno.land/x/emit/mod.ts";

const targetFilename = Deno.args[0];

const result = await bundle(
    new URL(targetFilename, import.meta.url),
);

const { code } = result;
console.log(code);

これで、以下のようにバンドルターゲットとなる JSファイルを指定してバンドルできるようになりました。

$ deno run --allow-read --allow-env --allow-write --allow-net bundle.js main.js > hello-world.idjs

Makefile を書いておきます。

hello_idjs:=hello-world.idjs

$(hello_idjs) : main.js
	deno run --allow-read --allow-env --allow-write --allow-net bundle.js $< > $@

clean:
	rm -f $(hello_idjs)

最後に今回のプロジェクトのファイル構成を確認しておきます。

$ tree .
.
├── Makefile
├── bundle.js
├── ind.js
└── main.js

以上です。