InDesignスクリプトアイコン

jsxでもお世話になった取り消し一発「doScript」!をUXPスクリプトでも使ってみる、もちろんインデザインのみ有効。

jsxスクリプト時代にもお世話になった「doScript」。UXPスクリプトにもあるようなので使ってみました。jsx版はコチラ→スクリプト取り消し一発!インデザインスクリプト実行後のundo(取り消し)のためのdoScript


まずは公式を紐解いてみる

まずは公式リファレンスのdoScriptを紐解きます。下記画像がdoScriptの項目です

基本的にjsxと一緒なのですが復習がてら、ひとつひとつ引数を見ていきます。

  • script
  • これが引き渡すスクリプト実行コードですね。ファイル・直打ち・functionの3通りの方法で実行できます。今回はfunctionを使います。

  • language
  • スクリプト言語を指定できます。

    上記のように「VBScript・「UxpScript」・「JavaScript」を実行できます。「UxpScript」が追加されました!しかし「AppleScript」が削除されてます…。

  • withArguments
  • 翻訳しました「スクリプトに渡される引数の配列」だそーです。functionの引数を書くみたいです。

  • undoMode
  • スクリプト実行するモードです。下記参照

    今回は早さと取り消しを兼ね備えた「FAST_ENTIRE_SCRIPT」を使用します。

  • undoName
  • 取り消しする時の名前です。メニューに「●●●を取り消し」などと表示されます。

早速使ってみる

まずテキトーなスクリプトをfunctionで書いてみました。

async function textFrameMake(strings){
  const myDoc=app.activeDocument;
  var textFrame=myDoc.textFrames.add();
  textFrame.geometricBounds=[20,20,30,80];
  textFrame.contents=strings[0];
  var textFrame2=myDoc.textFrames.add();
  textFrame2.geometricBounds=[70,20,80,80];
  textFrame2.contents=strings[1];
};

アクティブドキュメントにテキストフレームを2つ作成して引数のテキストを挿入します。doScriptの引数は必ず配列なので「strings[int]」というカタチにしています。

ちなみにこのスクリプト取り消そうと思うと

  1. テキストの挿入を取り消し
  2. サイズ変更を取り消し
  3. テキストフレームの作成を取り消し
  4. テキストの挿入を取り消し
  5. サイズ変更を取り消し
  6. テキストフレームの作成を取り消し

と6回も取り消しが必要になります。

さてこのfunction、フツーに使うなら

let {app}=require("indesign");
const musules=["マッスルインフェルノ","マッスルリベンジャー"];
textFrameMake(musules);

こんな感じですが、、、doScriptは

const musules=["マッスルインフェルノ","マッスルリベンジャー"];
let {app,ScriptLanguage,UndoModes}=require("indesign");
app.doScript(textFrameMake,ScriptLanguage.UXPSCRIPT,musules,UndoModes.FAST_ENTIRE_SCRIPT,"doScript.idjs");

となります。では解説

const musules=["マッスルインフェルノ","マッスルリベンジャー"];

まずは引数を配列(Array)で定義

let {app,ScriptLanguage,UndoModes}=require("indesign");

次にapp等の必要なクラス(?)って言ったらよいのか、それらを定義します。{}を使うことによって1行で定義できます。よーするに下記と同じ意味です。

let app=require("indesign").app;
let ScriptLanguage=require("indesign").ScriptLanguage;
let UndoModes=require("indesign").UndoModes;

jsx時代は定義する必要がなかったんですがね…。

app.doScript(textFrameMake,ScriptLanguage.UXPSCRIPT,musules,UndoModes.FAST_ENTIRE_SCRIPT,"doScript.idjs");

やっとスクリプトを実行します。jsxと使い方は同じです。っていうかずっと「withArguments」を無視して「script」を直打ちにして無理やり引数持たせてました、スイマセン…。で、実行すると

こんな感じで一発取り消しが効きます。

前回の「linkedText」に適用

早速、前回の「linkedText」に適用!しかし何故か、一発取り消しが出来ない。なぜ…?

いろいろやってるとメインfunction内でfunctonを使うとダメみたいです。上記テキトーなスクリプトを例にとると下記のようにfunction「textFrameMake」内にfunction「textFrameAdd」を使用するとイカンようです。

const musules=["マッスルインフェルノ","マッスルリベンジャー"];
let {app,ScriptLanguage,UndoModes}=require("indesign");
app.doScript(textFrameMake,ScriptLanguage.UXPSCRIPT,musules,UndoModes.FAST_ENTIRE_SCRIPT,"doScript.idjs");
async function textFrameMake(strings){
  await textFrameAdd(strings[0],[20,20,30,80]);
  await textFrameAdd(strings[1],[70,20,80,80]);
};
//指定のテキスト内容とサイズでテキストフレームを作成
async function textFrameAdd(content,XTWH){
  var textFrame=app.activeDocument.textFrames.add();
  textFrame.geometricBounds=XTWH;
  textFrame.contents=content;
}

そんな!ソレ結構不便だぜ!

この問題、誰か答え持ってますかね?

promptだけjsxにしてみる

で、思いついたんですが前回作ったUXPスクリプトのpromp部分だけjsxにしてそれを利用してはどうだろうか?つまり

const XYWH=app.doScript("prompt('X,Y,W,H?\\n(ex.20,30,200,20)','')",ScriptLanguage.JAVASCRIPT,[],UndoModes.FAST_ENTIRE_SCRIPT);

「ScriptLanguage.JAVASCRIPT」にしてjsxスクリプトを呼び出してpromptを実行し文字列を「XYWH」に格納させてます。

前項のfunctio内function問題を解決した全文は

let {app,ScriptLanguage,UndoModes}=require("indesign");
app.doScript(linkedText,ScriptLanguage.UXPSCRIPT,[],UndoModes.FAST_ENTIRE_SCRIPT,"[linkedText.idjs]");
async function linkedText(){
  try{
    const myDoc=app.activeDocument;
    const XYWH=app.doScript("prompt('X,Y,W,H?\\n(ex.20,30,200,20)','')",ScriptLanguage.JAVASCRIPT,[],UndoModes.FAST_ENTIRE_SCRIPT);
    const [x,y,width,height]=XYWH.split(",").map((value)=>parseInt(value));
    if(!isNaN(x)&&!isNaN(y)&&!isNaN(width)&&!isNaN(height)){
      var pushTextFrames=[];
      for(let p=0;p<myDoc.pages.count();p++){
        var textFrame=myDoc.pages.item(p).textFrames.add();
        textFrame.geometricBounds=[y,x,y+height,x+width];
        pushTextFrames.push(textFrame);
      };
      for(let t=0;t<pushTextFrames.length-1;t++){
        pushTextFrames[t].nextTextFrame=pushTextFrames[t+1];
      };
    }else{
      alert("Error: 数値入力が不正です。\nInvalid numerical value input.");
    };
  }catch(e){
    alert(e);
  };
};

こーなります。UXPにprompt実装されるまでのつなぎとして使えそうですね。

おまけで実行速度計測してみた

上記スクリプトをドキュメント内1000ページに適用させました。エントリーは4種類、驚きの結果は以下

UndoModes 実行速度(単位:ミリ秒 ※1000ミリ秒で1秒)
1 UXPスクリプト FAST_ENTIRE_SCRIPT 60934
2 UXPスクリプト 22785
3 JSXスクリプト fastEntireScript 26773
4 JSXスクリプト 24792

と何故か、FAST_ENTIRE_SCRIPTのUXPスクリプトが一番遅いという結果に!しかもぶっちぎりの最下位。

っていうか早いと思ってたfastEntireScriptのJSXスクリプトも通常より遅いやんけ。ショック!UXPスクリプトの通常版が一番早くUXPの面目躍如といったところだが思ってもみない結果に。

ダウンロードは「あどびのすくりぷと」ページ

早いと思ったら衝撃的に遅くてまぁまぁショックを抱えておりますが、もちろん実行状況にもよるよね?偶然偶然。そんなUXP版doScriptを使用した「linkedText.idjs」興味ある方は下記リンクからダウンロードして下さい。

→web site:shock tm 「あどびのすくりぷと」ページ

便利だと思う度 ★★★☆☆
遅い… ★☆☆☆☆

スポンサーリンク

スポンサーリンク

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です