Photoshop Generatorでテキストレイヤーの文字列を取得し、Jadeに出力する


PSDファイル上のデータをHTMLに移すのが面倒

ビジュアルデザイナーが作成したPSDファイルを元に、マークアップエンジニアがHTMLを作成することがあるかと思います。その際、Photoshop上のデータをHTMLに反映させるのが面倒だと思いました。

テキストレイヤーの文字列を反映させる場合

例えばテキストレイヤーで定義された文字列をコピーして、HTMLにペーストすることを考えます。

問題点

コピペに失敗するリスク

正しくコピペできたと思っていても、一部分抜けていることがあるかもしれません。

修正があった時の手間

修正があった時は、またコピペをする必要があります。

解決策

プログラミングを用いて、テキストレイヤーの文字列を取り出せないかと考えました。

Photoshop Generator

Photoshop CCではGeneratorが使えます。これはGeneratorはNode.jsサーバであり、Photoshopの操作を監視しながら、Photoshopのネイティブ機能にアクセスすることができます。

Generatorを導入

導入の仕方は以下を参照してください。
・参考
Node.js+Photoshop: Generatorの設計と使い方

PSDファイルを用意

レイヤー名 テキスト
layerHoge hoge
layerFuga fuga
layerPiyo piyo

上のようなPSDファイルを用意してみました。
今回はグループを使った入れ子構造には対応していませんwグループを作ったら動かないです。

TextLayerを探す

Generatorを使って、テキストレイヤーを探してみましょう。

参考資料

まず以下の参考ページで、「generator-getting-started-master」をgitもしくはzipでダウンロードし、プラグインの使い方をざっくり理解してみてください。
Script Your First Adobe Generator Plugin For Photoshop

全てのレイヤー情報を取得

main.js
function requestEntireDocument(documentId) {
    if (!documentId) {
        console.log("Determining the current document ID");
    }

    _generator.getDocumentInfo(documentId).then(
        function (document) {
            // console.log("Received complete document:", stringify(document));
            jsonParse(stringify(document));
        },
        function (err) {
            console.error("[Tutorial] Error in getDocumentInfo:", err);
        }
    ).done();
}

「generator-getting-started-master」を見ると「_generator.getDocumentInfo」のところで全てのレイヤー情報をJSONで出力していることがわかります。それを自分で定義した関数jsonParseに渡します。

json作成

function jsonParse(jsonString){
    var obj = JSON.parse(jsonString);
    var layers = obj.layers;
    var textLayers = {};
    var textLayerData = {};
    var fs = require("fs");

    for(var i = 0;i < layers.length;i++){
        var layer = layers[i];
        //find textLayer
        if(layer.type == "textLayer"){
            //set textLayer name and textKey
            var textObj = {};
            textObj["text"] = layer.text.textKey; 
            textLayers[layer.name] = textObj;
        }
    }

    textLayerData["textLayerData"] = textLayers;

    fs.writeFile("./test/plugins/naoyaTest/config.json", JSON.stringify(textLayerData, null, '    '));
}

「./test/plugins/naoyaTest/config.json」ひとまず、プラグイン直下にjsonを保存してみます。

・全ソース
https://gist.github.com/naoyashiga/118efc572122eb51b462

{
    "textLayerData": {
        "layerHoge": {
            "text": "hoge"
        },
        "layerFuga": {
            "text": "fuga"
        },
        "layerPiyo": {
            "text": "piyo"
        }
    }
}

上のようなjsonが保存できました。

Jadeでjsonを使用

今回はテンプレートエンジンJadeを用いて、得られたJSONデータを出力してみます。

gulpfile.jsの設定

gulpfile.js
var gulp = require('gulp');
var jadeTest = require('jade');
var jade = require('gulp-jade');
var data = require("gulp-data");

var paths = {
    jadeFile:"./app/jade/*.jade",
    json:"./app/config/test.json"
};

gulp.task('jade', function() {
  return gulp.src(paths.jadeFile)
    .pipe(data(function(file) {
      return require(paths.json);
    }))
    .pipe(
        jade({
            pretty: true//not minifiy
        })
    )
    .pipe(gulp.dest('app'));
});

gulp.task('watch', function() {
  gulp.watch(paths.jadeFile, ['jade']);
});

gulp.task('default', ['watch']);

gulp-dataを使って、jsonを取得して、jadeに渡しています。

・参考
https://www.npmjs.com/package/gulp-jade

jadeでjsonデータを出力

index.jade
p #{textLayerData.layerHoge.text}
p #{textLayerData.layerFuga.text}
p #{textLayerData.layerPiyo.text}

jadeではそのままjsonにアクセスできる状態になっているので、ドットで繋げて出力します。

index.html
<p>hoge</p>
<p>fuga</p>
<p>piyo</p>

テキストレイヤーの文字列を出力することができました。

まとめ

作成し終えて所感を述べます。メリット、デメリットをあげてみます。

メリット

コピペミスを解決

jsでテキストレイヤーの中身を取得するので、コピペミスがなくなりました。

ファイル更新が楽

ビジュアルデザイナーがPSDファイルを編集したら、Generatorを使って、jsonを更新してもらいます。それをgitにpushしてもらい、マークアップエンジニアがpullすれば、テキストが更新されます。

デメリット

レイヤーに命名規則が必要

ビジュアルデザイナーに事前にレイヤー名の規則を伝える必要が有ります。例えば日本語ではなく、英語で命名する必要があったりします。

入れ子構造に対応していない

サンプルのPSDファイルはグループを使った入れ子に対応できてません。致命的ですw 実践にはまだ使えそうにないです。。。。