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を実行してしまっているため,
&が二重にエスケープされていました.
その結果,
<が&gt;になってしまったり問題が生じていました.
かと言ってescapeHtmlを外せば良いというわけではなく,
takeによってHTMLがぶつ切りに切断されているため,
外すと<が途中の;が無く切られてしまい,
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