Illustrator で JSX を使って 複数成果物を作成

## 前置き
Illustratorで複数の成果物を製作した時のつまずきメモです。
#### 開発環境
- IllustratorCC2017
- mac Sierra

## やったこと
500枚近い同じレイアウトの成果物を作りました。
テンプレートに入れ込むデータはCSVで読み込む。

## 手順
### イラストレーターでテンプレートを作る
1.テンプレートを作ります。
１つの成果物に対して入れ込む箇所だけ１セットにしてグループ化しておく。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/70116/6b9a7177-1ebf-8eb4-666a-4f474cc3b2a2.png)

2.サポートしてくれる[illustroterの変数](https://helpx.adobe.com/jp/illustrator/using/data-driven-graphics-templates-variables.html)の機能を使います。
変数をセットしておくと、アートボード上の変更可能なオブジェクトをスクリプトで変更できます。
変数の設定は「ウィンドウ」＞「変数」で窓を開いて設定します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/70116/df19b289-9ee2-9317-d279-c4b716569dbc.png)

変数を設定するオブジェクトを選択しての赤枠のアイコンをクリックすると変数がセットされます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/70116/e29fc91d-6162-a5d7-cda7-75ade49ec3cf.png)

こんな感じです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/70116/16897ee5-4fb3-629d-ce8a-53645fbca955.png)
これで設定しておくと、デフォルトでtestFormeに入れた文字を利用してテキストの書き換えができます。

### テンプレートに読み込むデータを作る
エクセルで作成する。
エクセルのエンコードshift-jisでは、文字化けしてしまう場合は、xlsxで作成し、UTF-18のテキストで保存。
テキストエディタで開いてcsvファイルと同じカンマ区切りのデータにします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/70116/43c699ea-18d4-f90e-8b83-ee442c36856a.png)
今回は上記のようなデータ参照。
一行目のタイトルはtextframeにデフォルトで入れておく文字とレイアウトの位置を同じにしておくこと。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/70116/93532b33-573f-124e-42c8-1d6d90cff6b3.png)

### JSXを書く
先に、書くときにちょっとクセがあります。
console.log()がありません。代わりに\$.write()または\$.writeln()を使います。
\$.write() 改行なしのコンソールログ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/70116/511ae3ce-5d24-b0ef-83fa-cdb2b743059d.png)

\$.writeln()　改行ありのコンソールログ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/70116/5618e558-7dbd-5142-37c6-fc7962a9cec8.png)

また、価格などカンマを入れる関数が使えませんでした。
[toLocaleString();](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString)
なので、自力で入れるしかありません。
社内の優秀なエンジニアさんに助けていただきました。
カスタマイズと少しの微調整でバッチリ使えて、感謝感謝。

こちらの記事、参考になりました。ありがとうございます。
[数値をカンマ区切りにする](http://qiita.com/zawascript/items/922b5db574ef2b126069)

```
(function() {
  //CSVを読み込む関数を定義。
  var CSVConverter = function() {
    //csvの中身を一度格納しておく配列を作成
    this.lines = [];
    this.textGroups = [];
    this.pathGroups = [];
    this.textWords = null;
    //現在開いているドキュメントを指定
    this.variables = app.activeDocument.variables;
    this.path = String(app.documents[0].fullName).replace(app.documents[0].name, "");

    for (var i = 0, n = this.variables.length; i < n; i++) {
      //開いているドキュメントの変数の数ぶん、一度、groupに格納
      var group = this.variables[i].pageItems[0];
      //文字の数が０でないのならば
      //this.textGroupsにpush()
      if (group.textFrames.length != 0) {
        this.textGroups.push(group);
      }
    }

  };

  function add_comma(str){
      $.writeln("add_comma----->" + str);
      //空の箱を用意
      var new_str = '';
      //実際の数字の文字列を入れる
      var old_str = str;
      //文字数を数える
      var len = old_str.length;

      //3より大きい
      //文字数が３で割り切れないかつ、３より多い場合は
      if(len > 3){

          //3ずつ足してゆく
          for(cnt = 3 ; cnt < len ;cnt+=3) {
            if(cnt < len + 3) {
                //後ろから３っつ切り抜く
                new_str = old_str.substr(-cnt,3) + new_str;
                new_str = "," + new_str;
                $.writeln("if(cnt < len + 3) new_str----->" + new_str);
              }
            }
        //0,len%3 前から０番目で全ての文字数を３で割ったあまりの数の個数の数字を抽出。
        var num = len%3;
        new_str=old_str.substr(0,(3-num))+new_str;
        $.writeln("if(cnt < len + 3) new_str22222----->" + new_str);
        //3以下
        }else{
          //3以下はなにもしない
          new_str = textFrame.contents;
        };
        $.writeln("function add_comma return new_str----->" + new_str);
        return new_str;
      }

  CSVConverter.prototype = {
    read: function() {
      var path = File.openDialog("CSVファイルを選択してください。");
      if (! path) {
        return;
      }
      /*---------------------------------
      Fileオブジェクト生成して、CSVを読み込みモードに設定
       w:書き込みモード r:読み込みモード e:編集モード
       ---------------------------------*/
      var csv = new File(path);
      if (! csv.open("r", "", "")) {
        return;
      }

      this.lines = [];
      // CSVを読み込む。全ての内容をtextに格納
      var text = csv.read();
      /*---------------------------------
      var LF = String.fromCharCode(10); 
      読み込んだ全ての文字列を改行コードで配列に変換
      1行ずつの２次元配列
      ---------------------------------*/
      var lines = text.split(String.fromCharCode(10));
      $.writeln("lines" + lines);

      //読み込んだ行数を数えてline配列に格納
      for (var i = 0, n = lines.length; i < n; i++) {
        var line = lines[i];

        if (! line) {
          // 読み込めるlineがもし無くなったら、現在のfor文の現在反復中の文の実行を終了して、次の反復でループの実行を続ける
          continue;
        }

        // 最初の行はインデックスなので"textWords"へ
        if (i == 0) {
          this.textWords = line.split(",");
        // ２行目以降はデータの中身なので"line配列"へ格納
        } else {
          this.lines.push(line.split(","));
        }
      }
      /*---------------------------------
        ここまでのfor文を通ると２次元配列ができます。
        textWords[name1.name2,name3,name4];
        lines[
        　　　　[おにぎり,しゃけとタラコと梅で美味しいです,1000,1080]
        　　　　[卵焼き,だし巻き卵の味がついた感じでふわふわ,400,432]
        　　　　[お刺身,お寿司用で手巻きにも使えます,20000,20800]
        　　　];
      -----------------------------------*/

      // 開いた文章は閉じます
      csv.close();
      $.writeln("よみおわり");

    },
    writeText: function() {
      $.writeln("よみはじめ");

      for (var i = 0, n = this.textGroups.length; i < n; i++) {
        var textFrames = this.textGroups[i].textFrames;
            $.writeln("textFrames----->" + textFrames);


        for (var j = 0, o = textFrames.length; j < o; j++) {
          try {
            var textFrame = textFrames[j];
            var text = textFrame.contents;

            for (var key in this.textWords) {

              if (text.indexOf(this.textWords[key]) != -1) {
                textFrame.contents = this.lines[i][key];
                $.writeln("this.textWords----->" + this.textWords[key]);

                switch (this.textWords[key]){
                    //税抜き
                    case 'taxfree':
                          $.writeln('税抜き：textFrame.contents----->' + textFrame.contents);
                          textFrame.contents = "¥ " + add_comma(textFrame.contents);

                          break;

                    //税込
                    case 'tax':
                          $.writeln('税込：textFrame.contents----->' + textFrame.contents);
                          textFrame.contents = "¥ " + add_comma(textFrame.contents) + "税込";

                          break;

                    //デフォルト
                    default:
                          $.writeln('商品名と注釈');
                          textFrame.contents = textFrame.contents.replace( "||" , "\n\n" );
                          textFrame.contents = textFrame.contents.replace( "|||" , "\n" );
                          break;
                }

                $.writeln("-----------------------------------");
              }
            }
          } catch (e) {}
        }
      }
    }
  };

  var converter = new CSVConverter();
  converter.read();
  converter.writeText();
})();
```
### 最終確認
入れ込んだ文字に損失がないか目視確認は必ず。
想定外のことってありますので、必ず確認します。
スクリプトを過信（？）してはいけません。

## まとめ
JSX使えない関数はある程度知っておくこと。
あと、adobeのScriptガイドも書く時には手元に置きたい。