t_hazawaの日記

株式投資とWebエンジニアリングのブログです。株式投資の目次は→です。 https://t-hazawa.hatenablog.com/entry/2021/02/12/220933

HTMLフォーマッターgemを作った (hitomalu_formatter)

経緯

  • HTML文字列をフォーマットしてくれる、最近もメンテナンスされてるgemがなかったため作った
  • 特に下記の点を重視した
    • 何回もかけても同じ結果になること (span や p や インデントが増えないこと)

できたもの

似たライブラリ

このようなフォーマットができます

主なルール

  • タグの中身の整形について
    • 開始タグから 非空白文字が始まるまでの 空白文字は削除
    • 行中(= 行の中で非空白文字で囲まれたところ)にある半角スペースは保持 (ただし、2つ以上連続していたら1つにする)
    • 改行や行頭 or 行末の空白文字は、改行前後の行に非空白文字があるなら、半角スペース1つに置換 (非空白文字がない行は削除)
    • 最後の非空白文字から閉じタグまでの空白文字は削除
  • pre 要素の中は整形しない
  • インライン要素の後は 「改行(スペース混じりでも)があれば改行1個にする」「改行がなく、スペースがあればスペース1個にする」(何もなければそのまま)
  • インデントはしない
  • (これ以外にもルールはあります)

例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程度使います。

詳細 (ここから技術勉強ブログ的内容)

やったこと

フォーマッターを作るにあたって

  • MacLinuxの改行コード(\n) と Windowsの改行コード (\r\n) をあわせるのが大事
  • シェルで使えるコマンドは速い
    • sed の例
      • 100万文字から 20000箇所置換するのが 20ミリ秒くらい
  • paiza の ブラウザで Ruby を実行できるものは便利

高速化で参考にした記事

Nokogiri の挙動などフォーマッターつくりについて

gem にするにあたって

感想など

  • gemは公開すると、それだけでかなりDLされる (数時間で100など)