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 ""