Tbpgr Blog

元エンジニア 人事 tbpgr(てぃーびー) のブログ

RubyでCSS3のベンダープリフィックス付与スクリプトを作成する

概要

CSS3の草案段階の機能に対してはベンダープリフィックスをつけることになっています。
例えば、CSS3の中でもサンプルで目にすることの多い角丸の指定を行う

border-radius:15px;

というプロパティですが、現状記述する場合はベンダーごとに複数の記述を行う必要があります。

/* W3Cの仕様。最終的にはこの記述で統一される */
border-radius:15px;
/* Firefox用 */
 -moz-border-radius:15px;
/* Webkit用(Google Chrome、Safari)用 */
 -webkit-border-radius:15px;
/* Opera用 */
 -o-border-radius:15px;
/* Internet Explorer用 */
 -ms-border-radius:15px;

ここで、Rubyの勉強がてらW3Cの記述だけしておけば
各ベンダープリフィックス付きのプロパティを生成できるようなスクリプト
作成しようと思います。

実装内容

ベンダープリフィックス付与スクリプト仕様

前提としてyamlで記述された以下のファイルを用意する

vendor-prefix.yml

置換ルールを記載するファイル。形式はRubyで良く利用されるYAML
置換対象となるCSS3のプロパティ名称と
置換時に追加するベンダープリフィックスを記載します。

# 複製が必要となる個社別ベンダープリフィックス
vendor:
  - -ms-
  - -webkit-
  - -o-
  - -moz-
# 置換対象となるキーワード
css_properties:
  - linear-gradient
  - border-radius
  - box-shadow
test-css3.css

置換対象のCSSファイル。

h4 {
	/* 文字サイズを16pxに */
	font-size:16px;
	/* 文字の太さを通常に */
	font-weight:normal;
	/* 文字色を黄色に */
	color:yellow;
	/* 背景色をグレーに */
	background-color:gray;
	
	/* W3C */
	border-radius:15px;

	/* W3C */
	box-shadow: 0px 0px 6px #333;
	/* textに影設定 */
	text-shadow: 4px 4px 4px #335;
}
Rubyの変換処理(vendor-prefix-generator.rb)
require 'yaml'

class VendorPrefixGenerator
#出力ファイルサフィックス
SUFIX = '_vendor'

#置換ルール設定ファイル
CONFIG = 'vendor-prefix.yml'

=begin rdoc
==ベンダープリフィックスを付与した行を追加する
css_pathで取得したファイルに対して、
vendor-prefix.ymlに設定してあるCSS3のプロパティ名で検索を行う。
一致する行に関してはベンダー数分コピーし、ベンダープリフィックスを付与する。
===Param css_path cssファイルのパス
===Return なし
===Contract vendor-prefix.ymlに設定したプロパティが存在する場合はベンダー数分行が追加される
===Contract 出力ファイル名は元ファイル名+_vendor.cssとする
=end
  def self.append_vendor_prefix(css_path)
    config = get_config
    vendors = config["vendors"]
    css_properties = config["css_properties"]
    
    output = ""
    File.open(css_path).each{|line|
      output << line
      for css_property in css_properties
        if line.index(css_property)
          for vendor in vendors
            output << line.gsub(css_property,vendor + css_property)
          end
        end
      end
    }
    
    File.open(css_path + SUFIX + ".css",'w'){|output_file|
      output_file.write output
    }

    puts "ファイルの変換が完了しました。"
  end
  

=begin
yaml形式のconfig.ymlファイルを読み込む
===Return Configの内容(ベンダー情報と、置換対象のCSS3プロパティ名)
=end
  def self.get_config()
    YAML.load_file(CONFIG)
  end
  
  private_class_method :get_config
end

VendorPrefixGenerator.append_vendor_prefix "test-css3.css"
置換処理後のCSS(test-css3.css_vendor.css
h4 {
	/* 文字サイズを16pxに */
	font-size:16px;
	/* 文字の太さを通常に */
	font-weight:normal;
	/* 文字色を黄色に */
	color:yellow;
	/* 背景色をグレーに */
	background-color:gray;
	
	/* W3C */
	border-radius:15px;
	-ms-border-radius:15px;
	-webkit-border-radius:15px;
	-o-border-radius:15px;
	-moz-border-radius:15px;

	/* W3C */
	box-shadow: 0px 0px 6px #333;
	-ms-box-shadow: 0px 0px 6px #333;
	-webkit-box-shadow: 0px 0px 6px #333;
	-o-box-shadow: 0px 0px 6px #333;
	-moz-box-shadow: 0px 0px 6px #333;
	/* textに影設定 */
	text-shadow: 4px 4px 4px #335;
}

ポイント

規約

今回からRubyの一般的な規約をちょっと調べてから書いた。
ここまでの記事についてはJava風味になってる。

ファイル名:全部小文字のハイフン区切り
クラス名:Javaと一緒。各単語の頭だけ英大文字。
メソッド名:全部小文字のアンダースコア区切り
変数名:全部小文字のアンダースコア区切り

プライベートクラスメソッド

private_class_method :メソッド

YAMLファイルの読取

require 'yaml'
YAML.load_file(ファイル名)

オブジェクトの各要素に対する処理

オブジェクト.each{|変数|
実行する処理1
実行する処理2
}