Home About
UXP , InDesign , Spreadsheet

UXP InDesign Hello, World!

Node.js による InDesign ExtendScript モダン開発入門」というキンドル書籍を一年前くらいに書いたのですが、 とうとう、InDesign が最新バージョン(18.0)から UXP に対応しました。 つまり、小細工しなくても普通にいわゆるモダンなJavaScript (ES6) で InDesign 用の Script を書くことができるようになった。

なお、InDesign の UXP は Plugin にはまだ対応していないそうです。 UXP Scripting と呼ばれるスクリプト実行だけ対応した段階。 そのうち Plugin に対応するようです。 https://developer.adobe.com/indesign/uxp/plugins/ に Comming Soon って書いてあります。

ExtendScript で面倒だったことの一つに https の外部リソースを取得できなかったことがあります。 UXP ではこの問題が解決されているのか関心があったので調べました。 fetch が使える、と書いてあったので、いけるか!と思って調べたところ問題なく使えたので、UXPのスクリプトとともに得たことを簡単にシェアします。

mac price list

なお、このエントリーでは InDesign 2023 (version 18.1)と UDT version 1.7.0.13 を使用しています。

fetch JSON

まずは一番簡単な wttr.in を使ったサンプルコードです。

wttr.in についてはこのエントリーを参照のこと。

// fetchjson.idjs

const url = 'https://wttr.in/nagoya?format=j1';

const res = await fetch(url);
if(res.ok) {
    const obj = await res.json();
    const text = JSON.stringify(obj);
    console.log(`@ ${text}`);
}

wttr.in に format=j1 指定すると JSON がダウンロードできるのですが、 これを UXP InDesign で取得できるか調べました。

なお、console に結果を出力するだけなので、このスクリプトで作動を確認するには UDT が必要です。

console log

await を使って同期で記述しています。もし非同期のお作法でコードを書くと動きません。 UXP Script は InDesign 文書に対してスクリプト処理するものなので、非同期で処理されたら困るのでしょう、たぶん。

fetch image

ここにネット上の画像をInDesign 文書に place するサンプルコードがあります。

fetch Google Spread Sheet data

Google Docs の Spread Sheet のデータ(CSV)をダウンロードして、InDesign 文書にするコードです。

事前準備として、以下のような Google Docs のSpread Sheet ドキュメントを作成して、URLを知っている人が誰でもアクセスできる状態にしておきます。

mac price list google spreadsheet document

// fetch-mac-price-list-csv.idjs

// FILE-ID, SHEET-ID はあなたの用意したドキュメントのものに差し替えること!
const csvURL = "https://docs.google.com/spreadsheets/d/FILE-ID/export?format=csv&gid=SHEET-ID"

const res = await fetch(csvURL);
if(res.ok) {
    const text = await res.text()
    console.log(text);

    const params = {};
    params.documentPreferences = {
        pageWidth   : "210mm",
        pageHeight  : "297mm",
        facingPages : false};

    const doc = app.documents.add(params);

    const page = doc.pages.item(0);
    page.marginPreferences.properties = {
        top    : "10mm",
        left   : "10mm",
        bottom : "10mm",
        right  : "10mm"};
    
    const textFrame = page.textFrames.add({
        geometricBounds : ["10mm","10mm","287mm","200mm"] // top,left,bottom,right
    });

    const rows = text.split(/\r\n/);
    rows.forEach((row)=> {
        console.log(`- ${row}`);
    });

    const headerValues = rows[0].split(/,/);
    const tableColumnCount = headerValues.length;
    const tableBodyRowCount = rows.length-1;

    const table = textFrame.tables.add({
        headerRowCount : 1,
        bodyRowCount   : tableBodyRowCount,
        columnCount    : tableColumnCount,
        width          : "120mm",
        height         : "60mm"});

    const headerRow = table.rows.item(0);
    headerRow.fillColor = doc.colors.item("Black");
    headerRow.fillTint = 30;
    
    for(let i=0; i<tableColumnCount; i++){
        headerRow.cells.item(i).contents = headerValues[i];
    }

    for(let j=0; j<tableBodyRowCount; j++){
        const rowIndex = j+1;
        const bodyRow = table.rows.item(rowIndex);
        const cellValues = rows[rowIndex].split(/,/);

        for(let i=0; i<tableColumnCount; i++){
            const columnIndex = i;
            const cell = bodyRow.cells.item(columnIndex);
            cell.contents = cellValues[columnIndex]; 
        }
    }
}

実行すると以下のような InDesign 文書が生成されます。

mac price list

以上です。

Liked some of this entry? Buy me a coffee, please.