経緯
- HTML文字列をフォーマットしてくれる、最近もメンテナンスされてるgemがなかったため作った
- 特に下記の点を重視した
- 何回もかけても同じ結果になること (span や p や インデントが増えないこと)
できたもの
- hitomalu_formatter | RubyGems.org | your community gem host
- GitHub - t-hazawa/hitomalu_formatter: Format Html String
似たライブラリ
- GitHub - akicho8/html_formatter: HTML自動整形ライブラリ (最終コミット7年前)
このようなフォーマットができます
主なルール
- タグの中身の整形について
- 開始タグから 非空白文字が始まるまでの 空白文字は削除
- 行中(= 行の中で非空白文字で囲まれたところ)にある半角スペースは保持 (ただし、2つ以上連続していたら1つにする)
- 改行や行頭 or 行末の空白文字は、改行前後の行に非空白文字があるなら、半角スペース1つに置換 (非空白文字がない行は削除)
- 最後の非空白文字から閉じタグまでの空白文字は削除
- pre 要素の中は整形しない
- インライン要素の後は 「改行(スペース混じりでも)があれば改行1個にする」「改行がなく、スペースがあればスペース1個にする」(何もなければそのまま)
- インデントはしない
- (これ以外にもルールはあります)
例
- hitomalu_formatter/formatter_spec.rb at master · t-hazawa/hitomalu_formatter · GitHub より抜粋
- (しかしテストコードは expected が改行コードなのでわかりにくい)
例1
<div> <p id="kore_id" hgeg2> nakami </p><span>2つ目</span></div><a href="hoge">fuga</a> <pre> (スペース4つ) (a c) || 人 ←全角スペース </pre> <!-- コメントしてみた --> <saigo>aaaa</saigo>
↓
<div> <p id=\"kore_id\" hgeg2>nakami</p> <span>2つ目</span> </div> <a href=\"hoge\">fuga</a> <pre> (スペース4つ) (a c) || 人 ←全角スペース </pre> <!-- コメントしてみた --> <saigo>aaaa</saigo>
使い方
gem install hitomalu_formatter require "hitomalu_formatter" Hitomalu::Formatter.format('<DIV id=aaa>content</div>') => "<div id=\"aaa\">content</div>"
ポイント
- Nokogiri利用
- なので Nokogiri に似た感じのgem名にしました
- テストケースが44種類あって安心
- すっかりテストありきの人間になりました
- 100万文字で20000ノード程度のHTMLの場合、2分前後、メモリ5GB程度使います。
詳細 (ここから技術勉強ブログ的内容)
やったこと
フォーマッターを作るにあたって
- MacやLinuxの改行コード(\n) と Windowsの改行コード (\r\n) をあわせるのが大事
- シェルで使えるコマンドは速い
- sed の例
- 100万文字から 20000箇所置換するのが 20ミリ秒くらい
- sed の例
- paiza の ブラウザで Ruby を実行できるものは便利
- Online PHP/Java/C++... editor and compiler | paiza.IO
- 試すのも共有も簡単。Nokogiri も require 'Nokogiri' だけで使える
高速化で参考にした記事
Nokogiri の挙動などフォーマッターつくりについて
- 勝手に wbr に閉じタグをつける (wbr は閉じタグを伴わない要素)
- HTML5からは閉じタグを p や li などメジャーな要素で省略できるようになったが、Nokogiri は 中身がないと積極的に省略しがち (なので、中身がない場合は中にダミー文字列を入れて閉じタグをつけさせて、最後に空文字列に置換)
- Nokogiri は 閉じタグと閉じタグの間の \n を消すようなので、一旦 ダミー文字列にして後で置換
- Ruby では "\n" と '\n' では意味が違う (前者が今回必要なもの)
gem にするにあたって
- はじめての自作Gem - シンプルなGemを作成して公開する - Qiita を参考にしました
- git add しないと rake build の対象にならないのがムズい
- git ありきの仕組み
- 作成したgemを扱う際の注意点 - Qiita (神Qiita)
- .gem/credentials を作るには Gem パッケージを作成する (3) パッケージを公開する - まくまくRubyノート。 curl -u するとパスワードを入力できる
感想など
- gemは公開すると、それだけでかなりDLされる (数時間で100など)