構成が複雑なPSDファイルからテキスト情報

# はじめに
PhotoShopCCに気がつくとアートボードがデフォルトで設定されていたりして
アートボードになっててもなってなくても動くjsxがあるといいかなと。

フォント情報やサイズを、当該レイヤーをクリックして取得するにあたって
レイヤーセット、グループ化された状態でPSDに入っているTextレイヤーの情報を抜き出す、となると割とアナログな作業で
営業職も、デザイナーも、PG的にも比較的嫌な作業です。（少なくとも私は）
Textレイヤーが2つか3つでも嫌、と思ったらコードを書くしかない。

# PSDからの抽出

## PSD

<img width="1077" alt="スクリーンショット 2016-03-21 7.34.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/12362/b99d2ce0-f0af-738b-871e-6266667e5c6d.png">

## JSX

```js:textinfo.jsx

#target "Photoshop"

var CR = String.fromCharCode(13);

function findLayersText (layers) {
    for (var i = 0; i < layers.length; i++) {
        if (layers[i].kind == "LayerKind.TEXT") {
		
			var layerName = layers[i].name;		
			var contentsText = layers[i].textItem.contents;
			var textFont = layers[i].textItem.font;
			var textSize = layers[i].textItem.size;
			
			fileObj.write( layerName+','+ contentsText+','+ textFont+','+ textSize + CR);
        }
    }
}

//check all art layers then
//check if there are any inner layer sets
function browseLayerSets (sets) {
    for (var i = 0; i < sets.length; i++) {
        findLayersText(sets[i].artLayers);

        if(sets[i].layerSets.length > 0){
            browseLayerSets(sets[i].layerSets);
        }
    }
}

var savename = File.saveDialog("csvを保存する");
if (savename) {
    var fileObj = new File(savename);
	if (fileObj.open("w") == true) {
		fileObj.write('レイヤー名,テキスト,フォント,フォントサイズ' + CR);

		findLayersText(app.activeDocument.artLayers);
		browseLayerSets(app.activeDocument.layerSets);

		fileObj.close();
		alert("テキストの抽出が完了しました");
	}
}

```

## 手順

`ファイル > スクリプト > 参照` からjsxを指定して実行。
出力するCSVを指定し

<img width="597" alt="スクリーンショット 2016-03-21 7.48.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/12362/746945b3-2b3a-06b2-cb79-34410dfc1f96.png">

# テキストレイヤーに含まれる文字
テキストにカンマが含まれる場合はTSVにすればいい？と考えていたところ
PhotoShopでテキストに使える文字の自由度は高く
改行、タブが使えてしまいます。

 - 運用ルールで区切り文字に当たるもの、改行を使わないようにする

これも一つの方法ながら

JSXで読み込むことを前提の方法をもうちょっと考えてみます。

タブを含み、改行を含む場合です。
"(ダブルクオート)もいれたかったのですが、微妙に文字種が変わってしまった。
<img width="1030" alt="スクリーンショット 2016-03-25 8.52.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/12362/90d2fb52-ffae-ca2f-282d-99bac4c90ed3.png">

## JSX

```js:textExport.js

#target "Photoshop"

var CR = String.fromCharCode(13);
var TAB = String.fromCharCode(9);

var CR_TAG = '<CR>';
var LF_TAG = '<LF>';
var TAB_TAG = '<TAB>';

function findLayersText (layers) {
    for (var i = 0; i < layers.length; i++) {
        var txtArray =[];
        if (layers[i].kind == "LayerKind.TEXT") {
		
			var layerName = replaceCRTAB(layers[i].name);
			var contentsText = replaceCRTAB(layers[i].textItem.contents);
			var textFont = layers[i].textItem.font;
			var textSize = layers[i].textItem.size;
            
            txtArray.push(layerName);
            txtArray.push(contentsText);
            txtArray.push(textFont);
            txtArray.push(textSize);
			
			fileObj.write( txtArray.join (TAB) + CR);
        }
    }
}

//check all art layers then
//check if there are any inner layer sets
function browseLayerSets (sets) {
    for (var i = 0, len = sets.length; i < len; i++) {
        findLayersText(sets[i].artLayers);

        if(sets[i].layerSets.length > 0){
            browseLayerSets(sets[i].layerSets);
        }
    }
}

function replaceCRTAB (txt){
    return txt.replace(/\t/g, TAB_TAG).replace(/\r/g, CR_TAG).replace(/\n/g, LF_TAG);
}

var savename = File.saveDialog("tsvを保存する");
if (savename) {
    var fileObj = new File(savename);
	if (fileObj.open("w") == true) {
        var  headerArray =[];
        headerArray.push('レイヤー名');
        headerArray.push('テキスト');
        headerArray.push('フォント');
        headerArray.push('フォントサイズ');
        
        
		fileObj.write(headerArray.join (TAB) + CR);

		findLayersText(app.activeDocument.artLayers);
		browseLayerSets(app.activeDocument.layerSets);

		fileObj.close();
		alert("テキストの抽出が完了しました");
	}
}
```


## 手順

`ファイル > スクリプト > 参照` からjsxを指定して実行。
出力するTSVを指定し

<img width="597" alt="スクリーンショット 2016-03-21 7.48.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/12362/746945b3-2b3a-06b2-cb79-34410dfc1f96.png">

## TSV
<img width="404" alt="スクリーンショット 2016-03-25 9.07.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/12362/ca048f54-7a80-8210-d21f-808f70e672fb.png">

Excelでは通常通り、セルが分かれた状態で表示できました。

## TSVにしてどうする
書き出したものは読み込みに使ってみましょうか。
もうちょっと続く・・・

# 参考
http://stackoverflow.com/questions/34473365/photoshop-script-remove-all-text-layer
http://www.programing-style.com/android/android-api/android-image-text-button/

https://codezine.jp/article/detail/2364

http://geckotang.tumblr.com/post/47689882849/jsx-テキストレイヤーの文字をcsvを基に置き換える未完成

# さいごに
exportした情報からPSDに書き戻せば、多言語対応などで画像のレイアウトに反映が可能。
Androidアプリの場合は、xmlでdrawableを定義し、ボタンのテキストはstring.xmlでまとめていればコードベースで置換作業にかかれそうです。