忍者ブログ

ぼんぷろぐ

InDesignとかイラレとかのスクリプトよもやま話

新しいブログに引っ越しました。

こちらのブログはもう更新しませんが、コメント欄は生きてますので疑問、ご指摘などありましたらどうぞ。

[ExtendScript]
ExtendScript Toolkitにコード整形機能をつけてみる

Adobeの英語フォーラムかなんかで見かけたんですけど、ESTKのDOMってそのままだとあんまりいじるところが無いですが、
#target estoolkit#dbg
っていうおまじないを書いておくと編集中のテキストを取得したりとかいろいろできるみたいです。ただしいちいち保存しないと実行させてくれない。

てことでなにかと嫌われがちなESTKですが、アレさえあればもっと愛されるツールになるのにっていうアレを実装してみました。



①コード整形には js-beautify を使わせてもらいます。https://github.com/beautify-web/js-beautify からダウンロードしてbeautify.jsを適当な場所に置きます。
(2019/09/11追記)
【ExtendScript】コード自動整形機能の追加方法について | CGメソッド
こちらのブログによると今のjs-beautifyにはExtendScriptで実行可能なbeautify.jsが含まれてないようです。過去のバージョンがダウンロードできるリンクも貼っていただいてます。ありがたやー。
(追記ここまで)

②以下のコードの6行目をbeautify.jsを置いた場所に応じて書き換え、jsxファイルとして保存します。
#target estoolkit#dbg
var toolMenu = MenuElement.find ("toolA") || new MenuElement("menu", "ツール", "at the end of menubar", "toolA");
var beautifyCommand = MenuElement.find ("toolA/beautify") || new MenuElement("command", "整形", "at the end of toolA", "toolA/beautify");
var js_beautify = (function () {
    var exports = {};
    #include "C:\\lib\\beautify.js"
    return exports;
})();

beautifyCommand.onSelect = function() {
    try {
        var editor = document.editor;
        var selText=editor.textselection;
        var code=selText.length>0?selText:editor.text;
        code = code.replace(/^\s*#(?=(target|targetengine|include|includepath|script|strict))/mg, "//@");
        if (code.indexOf("\"\"\"") > -1) {
            if(!confirm("\"\"\"が含まれているため正常に整形できない可能性があります.\n続行しますか?")) return;
        }
        code = js_beautify.js_beautify(code);
        if (selText.length>0) document.editor.textselection = code;
        else editor.text = code;
    } catch (e) {
        alert(e);
    }
}

③これを実行すればメニューにツール>整形が追加されるわけですが、起動時に自動実行させるには、こいつをESTKの実行ファイルがあるフォルダの下の"Required"フォルダ内にぶち込んでやります。

これであんなに汚かったコードが…


なんということでしょう こんなに読みやすく…っていうほどでもないな。こりゃ例が悪いわ。1行目のaと2行目のbもちゃんと等幅フォント使ってれば揃います。



細かいこと

  • テキストを範囲選択してる場合はその範囲、してなければファイル全体を整形します。とはいえjs-beautifyは基本的にコードの断片を整形するようなものではないので、選択範囲に適用する場合はその範囲だけでjavascriptのコードとして成立するようにする("{"は含んで"}"を含まないみたいな選択の仕方をしない)というような配慮は要ると思います。
  • #targetとか#includeの#は//@に置き換わります(同じように機能します)

  • javascriptではありえないExtendScript独自の記法が含まれているとうまく動作しない可能性があります。たとえば"""とかXMLリテラルとか(他にあったっけ?)

  • js-beautifyにはいくつかオプションがあります。たとえばインデントのスペースの個数を8個にするなら{"indent_size":8}をjs_beautify()の第2引数に入れてやればいいみたい。

  • 右クリックメニューにもつけたいんだけどやり方が分かりません。というかコード編集のUIは全部Scintilla任せになってていじれないのかな?




ESTKへのメニュー追加については、手抜きLabさんのこちらの記事を参考にしました。
http://chuwa.iobb.net/tech/archive/2017/01/estk-1.html


ここから追記(2017/02/20)

js-beautifyのデフォルトだと、
{a:1,b:2}
なんかは
{
    a: 1,
    b: 2
}
のように改行してくれるんですが、これがありがたいこともあれば、そうでもないこともあるなーと思いまして

たとえばInDesignスクリプトなんかだとちょっとしたオブジェクトをadd()の引数に入れてプロパティを設定することがよくあって、
こういうの↓をいちいち



こう↓されては、やたら行数増えてかえって見にくいなぁと



で、js-beautifyのオプションを見てみたら"brace_style":"collapse,preserve-inline"っていうちょうどいいのがあったのでスクリプトに組み込んでみました。実行するとツールメニューに「整形」と「整形({}内を改行)」の2つができます(「整形」が"brace_style":"collapse,preserve-inline"を使った方です)。


//@target estoolkit#dbg
var toolMenu = MenuElement.find("toolA") || new MenuElement("menu", "ツール", "at the end of menubar", "toolA");
var beautifyCommand = MenuElement.find("toolA/beautify") || new MenuElement("command", "整形", "at the end of toolA", "toolA/beautify");
var beautifyCommand2 = MenuElement.find("toolA/beautify2") || new MenuElement("command", "整形({}内を改行)", "at the end of toolA", "toolA/beautify2");
var js_beautify = (function() {
    var exports = {};
    //@include "C:\\lib\\beautify.js"
    return exports;
})();

beautifyCommand.onSelect = getBeautifyHandler({ "brace_style": "collapse,preserve-inline" });
beautifyCommand2.onSelect = getBeautifyHandler();

function getBeautifyHandler(opt) {
    return function() {
        try {
            var editor = document.editor;
            var selText = editor.textselection;
            var code = selText.length > 0 ? selText : editor.text;
            code = code.replace(/^\s*#(?=(target|targetengine|include|includepath|script|strict))/mg, "//@");
            if (code.indexOf("\"\"\"") > -1) {
                if (!confirm("\"\"\"が含まれているため正常に整形できない可能性があります.\n続行しますか?")) return;
            }
            code = js_beautify.js_beautify(code, opt);
            if (selText.length > 0) document.editor.textselection = code;
            else editor.text = code;
        } catch (e) { alert(e); }
    }
}


ところでESTKをすなお~に使うと、
function f(x) {
    return x * x;
    }
みたいに}が上の行に揃う書き方になると思うのですが、この書き方に合わせるようなオプションは残念ながら無さそうです。うーむ
PR

コメント

お名前
タイトル
文字色
メールアドレス
URL
コメント
パスワード Vodafone絵文字 i-mode絵文字 Ezweb絵文字

無題

ご指摘の通りメニュー項目とコンテキストメニュ―では実行結果は同じでも実行される命令は異なります。
コンテキストメニューはScintillaへ丸投げしています。メニュー項目はExtendscriptの関数が実行されます。
ショートカットなら付加することが出来るかもしれませんw

Re:無題

どうもです。
やっぱりそういうことなんですね~ ESTKがバグって保存できないっってときでも右クリックメニューのコピーだけは生きてて救われることがよくあるのもそのおかげなんでしょうね

  • kawamoto_α
  • 2017/06/07(Wed.)

プロフィール

kawamoto_α
(あるふぁ(仮))


InDesignで新聞組版のようなことをしています。

ツイッタ

※ブラウザによっては当ブログからDLしたzipファイルが拡張子なしになることがあるようですが、.zipを補って開いてください。



イラレ用トーンカーブスクリプト(¥1500)



クロソイド式角丸長方形スクリプト(¥500)
Illustrator用
InDesign用



イラレスクリプトをキーボードショートカットで実行するやつ(Win用)