すがブロ

sugamasaoのhatenablogだよ

html2hamlで

html2haml で変換する場合の挙動について

環境は

という環境で、以下のHTMLを変換したとする

<!DOCTYPE HTML>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	</head>
	<body>
		<h1>テスト</h1>
		<input type="button" value='テスト' />
	</body>

</html>

これを html2haml で変換すると

!!!
%html
  %head
    %meta{:content => "text/html; charset=utf-8", "http-equiv" => "Content-Type"}/
  %body
    %h1 テスト
    %input{:type => "button", :value => "\xE3\x83\x86\xE3\x82\xB9\xE3\x83\x88"}/

てなるんだけど

input タグの value がおかしくてレンダリングできない

このままの状態で haml を使ってレンダリングしようとすると

Encoding::CompatibilityError at /
incompatible character encodings: UTF-8 and ASCII-8BIT

って言われる。

value の値がおかしい

該当行消すとうまくいくので、原因はそこっぽい。
で、じゃあ

"\xE3\x83\x86\xE3\x82\xB9\xE3\x83\x88"

の encoding ってどうなってるの、っていうと UTF8 になってる。
.to_s ってすると、レンダリングもうまくいって、きちんと日本語で表示されるのだけど、そういう手順を踏まないとダメなのかな。

そもそも変換の時に日本語にして欲しいのだけど、そうじゃなければ to_s を明示しなくてもうまくレンダリングしてくれる何かが欲しいんだけどなぁ。

ちなみに

ここで Haml3.0.11 で試したけど、同じ変換結果だった。うーん、Ruby1.9.2で Haml 大好きで html2haml 使ってる人で対応した猛者はいないものか。。。

変換の該当箇所を見つけた

gems/haml-3.0.21/lib/haml/html.rb

の一番最後のメソッド

      # Returns a string representation of an attributes hash
      # that's prettier than that produced by Hash#inspect
      def haml_attributes(options)
        attrs = attr_hash.sort.map do |name, value|
          value = dynamic_attribute?(name, options) ? dynamic_attributes[name] : value.inspect
          name = name.index(/\W/) ? name.inspect : ":#{name}"
          "#{name} => #{value}"
        end
        "{#{attrs.join(', ')}}"
      end

の value.inspect の .inspect を取ればそのまま出力されるというのは確認した。
ただ、それがどこまで影響があるのか、なんの意図で .inspect しているのかがよくわかっていないのでアドホック過ぎるな。。。