polidog lab++

Blog

tssを書くのがだるいのでyamlを使って書いたというお話

Aug 28, 2013 | tech | alloy titanium

alloyを使った開発をする際にtss書くのは正直面倒です。
そこでstylusを使って書くという選択をした僕ですが、どうもfontの設定とかネストされているtssがうまくstylusでは書けなくて悩んでいました。

例えば

たとえばこういうstylファイル

"Label": {
  font: {
    fontSize: 16,
    fontWeight: "bold"
  },
  textAlign: "left",
  color: "#333333",
  width: Ti.UI.SIZE,
  height: Ti.UI.SIZE,
  top: 11,
  bottom: 11,
  left: 11
}

これを普通にstylusで書くと以下のようになります。

Label
  font
    fontSite 19
    fontWegith "bold"
  textAlign "left"
  color "#333333"
  width "Ti.UI.SIZE"
  height "Ti.UI.SIZE"
  top 11
  bottom 11
  left 11

で、こいつをコンパイルすると、以下のようになってしまいます。。。

"Label": {
  textAlign: "left",
  color: "#333333",
  width: Ti.UI.SIZE,
  height: Ti.UI.SIZE,
  top: 11,
  bottom: 11,
  left: 11
},
"Label font": {
  fontSite: 19,
  fontWegith: "bold"
}

このように非常に残念な結果になってしまいます。
まあcssってネストしない構造だし仕方ないようね。ってことであきらめました。
なんかtylusなんてものもあるけど、まあtss変換にはつかえないかなぁーと。。。

でもまあ普通にtss使うとか負けた気がしたのでyamlを使ってみる事にしました。
ということで、tssをyamlで書く手順をご紹介します。

  1. yamlのライブラリを用意
  2. alloy.jmkにコードを追加
  3. yamlファイルの用意

yamlのライブラリを用意

js-yamlというライブラリを今回はしようしています

npm install js-yaml -g

alloy.jmkにコードを追加

次にalloy.jmkを以下のように記載します

task("pre:compile", function(event,logger) {
  var wrench = require("wrench"),
      fs = require("fs"),
      path = require("path"),
      js_yaml = require("js-yaml");

  event.alloyConfig.tss = [];




  var compileYAMLtoTSS = function(root,target) {
    var replaceVal = function(target,value,object) {
      for ( var key in object) {
        if (object.hasOwnProperty(key)) {
          if (typeof(object[key]) !== "object") {
            if (object[key] === target) {
              object[key] = value;
            }
          } else {
            replaceVal(target,value,object[key]);
          }
        }
      }
    }
    var yaml = fs.readFileSync(path.join(root,target), 'utf-8'),
        tss;
    var object = js_yaml.load(yaml);
    if (typeof(object.parameters) === "object") {
      var param = object.parameters;
      delete object.parameters;
      for (var key in param) {
        if (param.hasOwnProperty(key) && typeof(param[key]) !== "object") {
          replaceVal('%'+key+'%',param[key],object);
        }
      }
    }

    var json = JSON.stringify(object,null, "  ");
    json = json.replace(/['"]expr(.+?)['"]/gi, "expr$1");
    json = json.replace(/['"]Ti(.+?)['"]/gi, "Ti$1");
    json = json.replace(/['"]Titanium(.+?)['"]/gi, "Titanium$1");

    return json;
  }


  // yml
  wrench.readdirSyncRecursive(event.dir.styles).forEach(function(target){
    if (target.match(/\.yml$/)) {
      event.alloyConfig.tss.push(target.replace(/\.yml$/, ".tss"));
      logger.debug("-----polidog ------");
      fs.writeFileSync(
        path.join(event.dir.styles,target.replace(/\.yml/, ".tss")),
        compileYAMLtoTSS(event.dir.styles, target)
      );
    }
  });

});

task("post:compile",function(event,logger){
  var fs = require("fs"),
      path = require("path");

  if (event.alloyConfig.deploytype != 'development') {
    event.alloyConfig.tss.forEach(function(target){
      fs.unlinkSync(event.dir.styles + "/" + target);
    });
  }
});

yamlファイルの用意

あとはstylesディレクトリの適当にyamlを用意すればいいです。
ちなみに今回は拡張子を「yml」としているのでその辺は注意してください。

parameters:
  var1: 12
  var2: "bold"
"#addWin[platform=ios]":
  backgroundColor: "#FFFFFF"
Label:
  font:
    fontSite: "%var1%"
    fontWeight: "%var2%"
  textAlign: "left"
  color: "#FF0000"
  width: Ti.UI.SIZE
  height: Ti.UI.SIZE
  top: 11
  bottom: 11
  left: 11

これでストレス無くtssを書く事が出来るかと思います。

ちなみに気づいたかもしれませんが、ymlで変数的な物を持たせる事が可能です。
まったくもってphpのsymfony2で使ってるyamlの変数的な使い方と一緒です。
parametersの中に定義した項目に%をつけた形を変数として認識してくれるので、parametersに定義しとけばいいというお話です。
上のyamlでいうところの「%var1%」がvar1の内容に置き換わるという感じです。

ちなみにちゃんとバグとかチェックしてないので使用する際は気をつけてくださいねw

comments powered by Disqus

関連記事

© 2017 polidog lab++