デザイン自動化メモ（スクリプト実行内容をアンドゥスタック１回にまとめる）

スクリプト全体を１つのUndo/Redo処理にする。

**効果**
スクリプトの実行内容を１回のUndoで取り消せるようになる。
アンドゥスタックも逐次ではなく、１つだけになるので、スクリプトの実行速度が上がる。

**やり方**
doMain関数を追加して、main関数内でapp.doScriptを使ってdoMain関数を実行。
この時、末尾の引数にUndoModes.EntireScriptを指定する。

**書き方**

```js
function doMain() {
   //スクリプト実行内容
   app.doScript("doMain()",ScriptLanguage.JAVASCRIPT,[],UndoModes.fastEntireScript);
}

function main() {

}
```

**サンプル（テキストフレームの背景色をグレースケールにする）**

```js

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 cmyk2L(c,m,y,k) {
    
     // InDesignのCMYKは0% - 100%になるので、0-255にスケール変換
      var c255 = c*2.55;
      var m255 = m*2.55;
      var y255 = y*2.55;
      var k255 = k*2.55;
            
      // なんちゃってRGB
      var r = Math.max(0,255- c255 - k255);
      var g = Math.max(0,255- m255 - k255);
      var b = Math.max(0,255- y255 - k255);
            
      // 輝度を出す
      var luminance = Math.round(0.2990 * r  + 0.5870 * g + 0.1140 * b);
            
      // スケールを 0% - 100%に戻す
       var retk = 100 - Math.round(luminance / 2.55);
       
       return retk;
}

function backgroundColor2Grayscale_for_TextFrame(pageItem) {

    // 設定されている背景色を取得する。
    var col = pageItem.fillColor;
    var cs = col.space;
    
    // カラーモデルがCMYKなのを確認し、CMYK以外なら処理しない。
    // 実際に使う場合はエラーにします。
    if (cs!=ColorSpace.CMYK) {
        
        return;
    }

    var c = col.colorValue[0];
    var m = col.colorValue[1];
    var y = col.colorValue[2];
    var k = col.colorValue[3];
    
    var retK = cmyk2L(c,m,y,k)
    
    // スォッチを追加
    var sname = "K" + retK;
    var colorObj = addSwatch(0,0,0,retK,sname)        
    
    // 背景色を反映
    pageItem.fillColor = colorObj;
 }

function doMain() {
 
    pageObj = app.activeDocument.pages[0];
    total = pageObj.allPageItems.length;
    
    var i = 0;
    
    for (i=0;i<total;i++) {
       var label = "";
       var typeName = "";
       var pageItem;
        
       pageItem = pageObj.allPageItems[i];
 
       var typeName = pageItem.constructor.name;
       label = pageItem.label; 
 
        // 特定のテキストフレームは処理をしない。ここではスクリプトラベルで判断する。
        if (label=="hoge") {
                   
            continue;
        } 
       
       // テキストフレームのときの背景色を変更する。
       if (typeName=="TextFrame") {
 
            backgroundColor2Grayscale_for_TextFrame(pageItem);
       }
    }
}

function main() {

      app.doScript("doMain()",ScriptLanguage.JAVASCRIPT,[],UndoModes.fastEntireScript);
 }

main();
```

**実行結果**

実行前
![スクリーンショット 2018-07-01 5.17.53.png](https://qiita-image-store.s3.amazonaws.com/0/139650/f242a6e9-88d8-4b7a-3bb5-b899cfa3a442.png)

実行後
![スクリーンショット 2018-07-01 5.19.33.png](https://qiita-image-store.s3.amazonaws.com/0/139650/63ead629-b08d-3bf8-3c19-aa1c9c71965e.png)

アンドゥ１回で全部のオブジェクトが元に戻る。
![スクリーンショット 2018-07-01 5.17.53.png](https://qiita-image-store.s3.amazonaws.com/0/139650/0aced3a6-c478-0bc7-ed33-98e2f7353517.png)