HTMLのインデントを綺麗にするサービス、「Ham Cutlet」を公開しました! | FJORD, LLC(合同会社フィヨルド)

Help me, hackers!に続くフィヨルドのサービス第二弾をリリース!今回はちょっとした便利ツールHTMLのインデントを美しくするサービス、その名も「Ham Cutlet(通称ハムカツ)」です。

HTMLのインデントを綺麗にするサービスHam Cutletを作りました。

中身はHaml::HTMLでHTMLをHamlにして、Haml::EngineでHamlをHTMLに戻すだけです。

で、Haml::Engineはメインなので問題無いんですが、Haml::HTMLはおまけ的な感じなのと、仕様的には問題のあるHTMLでもある程度許容しないと使えないのでちょっと弄る必要がありました。

http://gist.github.com/426798

class Hpricot::Comment
  def to_haml(tabs, options)
    content = self.content
    if content =~ /\A(\[[^\]]+\])>(.*)<!\[endif\]\z/m
      condition = $1
      content = $2
    end
    if content.include?("\n")
      "#{tabulate(tabs)}/#{condition}\n#{parse_text(content, tabs + 1)}"
    else
      "#{tabulate(tabs)}/#{condition} #{content.strip}\n"
    end
  end   
end     
        
class Hpricot::Elem       
  def to_haml_filter(filter, tabs, options)
    content =
      if children.first.is_a?(::Hpricot::CData)
        children.first.content
      elsif children.first.is_a?(::Hpricot::Comment)
        children.first.content.gsub(/\/\/$/, '')
      else
        CGI.unescapeHTML(self.innerText)
      end
        
    content = erb_to_interpolation(content, options)
    content.gsub!(/\A\s*\n(\s*)/, '\1')    original_indent = content[/\A(\s*)/, 1]
    if content.split("\n").all? {|l| l.strip.empty? || l =~ /^#{original_indent}/}     
      content.gsub!(/^#{original_indent}/, tabulate(tabs + 1))
    end
    
    "#{tabulate(tabs)}:#{filter}\n#{content}"
  end
end

一つは単一行のコメントに改行が付かないところ。これは単なるバグだと思います。

もう一つはHamlのせいというかHTMLの仕様的にOKかどうかわからないんですが、

<script type="text/javascript"><!--
function foo() {}
//--></script>

よくあるこういう書き方への対応部分です。HTML -> Hamlの変換時に、Javascriptの部分は:javascript haml_filterに、HTMLコメントはHpricot::Commentとして処理されます。

上記はscriptタグ -> HTMLコメント -> Javascript(+Javascriptのコメント)という構造になっています。

Haml::HTMLでは、scriptタグの中はjavascriptかCDataしかないと思って油断しているのでHTMLコメントが処理できません。さらにHTMLコメントの中のJavascriptは本来HTMLでは中がどうなってようが大した問題じゃないんですが、Javascript的には大問題。最後にあるJavascriptコメントも処理出来てないので修正。

CSSのtypeタグも似たような感じで修正。

お陰でこんな感じで綺麗になりました。

<script type="text/javascript">
//<![CDATA[
function foo() {}
//]]>
</script>

Yahoo JAPAN!のHTMLを食べさせたらInternal Server Errorになってしまう - Help me, hackers!

Yahoo! JAPANトップページのHTMLを貼り付けてみたところ、Internal Server Errorとなってしまいました。不味いものを食べさせてしまったみたいで申し訳ないですが、サーバー側でログを調べてもらえると解決も早そうです。

Yahoo! JAPANのHTMLを読めるように対応していたら他のページの対応率もグッと上がって良かったです。

Comments


Option