このエントリーをはてなブックマークに追加 hatena-bookmark fb-like g-plusone
line-it
pocket
  • 作成日時:
  • 更新日時:

HakyllサイトのHTML特殊文字が二重エスケープされてしまうのを正規表現によって解決

このサイトのdescriptionやteaserといったものは

teaserFieldByResource :: Int -> String -> Snapshot -> Context String
teaserFieldByResource l key snapshot = field key $ \item ->
    escapeHtml . take l . stripTags . itemBody <$> loadSnapshot (itemIdentifier item) snapshot

によって作られているのですが,snapshotが既に特殊文字エスケープされているにもかかわらず,escapeHtmlを実行してしまっているため,&が二重にエスケープされていました.その結果,<&amp;gt;になってしまったり問題が生じていました.

かと言ってescapeHtmlを外せば良いというわけではなく,takeによってHTMLがぶつ切りに切断されているため,外すと&lt;が途中の;が無く切られてしまい,tidy HTMLに怒られることになります.

この問題を解決するために,dropWarningHtmlEntityという関数を書くことにしました.この関数は文字列の最期の&を検索し,それに;が続いていなければ最期の&以下を消去してしまう関数です.これでフィルタリングすればtidy HTMLには怒られなくなるはずです.

正規表現で実装できそうですね.

実装できました.

teaserFieldByResource :: Int -> String -> Snapshot -> Context String
teaserFieldByResource l key snapshot = field key $ \item ->
    dropWarningHtmlEntity . take l . stripTags . itemBody <$>
    loadSnapshot (itemIdentifier item) snapshot

dropWarningHtmlEntity :: String -> String
dropWarningHtmlEntity entity = R.subRegex (R.mkRegex "&[^&;]*$") entity ""
このエントリーをはてなブックマークに追加 hatena-bookmark fb-like g-plusone
line-it
pocket