前菜
jekyll-commonmark-ghpages
の README を見ると以下のような設定を _config.yml
に追加する方法が紹介されています。
commonmark:
options: ["UNSAFE", "SMART", "FOOTNOTES"]
extensions: ["strikethrough", "autolink", "table", "tagfilter"]
しかしこれだと iframe
が正しく表示されなくなるという問題が発生しました。
タグがそのまま表示されてしまいます。
メインディッシュ
これの解決策はシンプルで、tagfilter
を削除します。
commonmark:
options: ["UNSAFE", "SMART", "FOOTNOTES"]
extensions: ["strikethrough", "autolink", "table"]
これで iframe
が表示されるようになりました。
iframe
を表示させる方法
そもそもセキュリティ上の観点から、デフォルトでは Jekyll でビルドした記事の中の iframe
はサニタイズされ表示されません。
それを表示するためのオプションが、Commonmarker では UNSAFE
です。これをつけることで iframe
が表示されるようになります。
commonmark:
options: ["UNSAFE"]
HTML タグをそのまま表示させる方法
一方で、HTML タグをそのまま表示させる拡張も用意されています。これが冒頭で登場した tagfilter
です。
commonmark:
extensions: ["tagfilter"]
これを追加すると、<
が <
に、>
が >
にそれぞれエスケープされるため、たとえば <iframe>
と書いてあると <iframe>
と変換され、ページ上では <iframe>
のようにそのまま文字として表示されることになります。
Disallowed Raw HTML (extension) | GitHub Flavored Markdown Spec
つまり、UNSAFE
と tagfilter
を同時に指定すると、せっかく UNSAFE
で iframe
が表示されるようになったのに、それをただのタグとしてそのまま表示してしまうので冒頭であげたような問題が発生してしまう、というわけです。
だから
commonmark:
options: ["UNSAFE", "SMART", "FOOTNOTES"]
extensions: ["strikethrough", "autolink", "table", "tagfilter"]
のように UNSAFE
と tagfilter
が両方指定されているのはどういう意味があるのか謎なんですよね。まあもちろん UNSAFE
がないとそもそも iframe
タグすら表示されないので挙動の違いはあるのですが、iframe
をページに反映させると同時に HTML タグとしてそのまま表示させる、そんな需要あるのか?という疑問が浮かびました。
デザート
まあ単にぼくがあまり理解せずにそのままコピペしていたのが問題なんですが、意外に調べてもこのことを解説しているサイトは見つからなかったので備忘録として書くことにしました1。
今回この問題をややこしくした(解決までに時間がかかった)のは、github-pages
だとこの問題が発生しないからです。
gem 'github-pages'
ただこれ、考えてみれば当たり前で、github-pages
は Dependency versions に示されたライブラリやプラグインをもとに動作するように設計されていて、この中に Commonmarker は含まれていないんですよね。
つまり、github-pages
を使った場合はこの設定は単に無視されて、代わりに kramdown が使われていたので冒頭のような問題が発生しなかった、ということになります。Jekyll は GitHub Pages のエコシステムと密につながっていて、このへんがちょっとわかりづらいと感じるのはぼくだけですかね 🤔
以上となります。わかっている人にとってはすごく当たり前のことを書きましたが、意外にハマってしまったので記録として残しておくことにしました。参考になれば幸いです。
-
ChatGPT に聞いても意外とドンピシャな答えは返してくれませんでした。結果的には ChatGPT が提示した最小構成のサンプルを試したときに動いたのでその差分で原因にたどり着くことができたので壁打ちにはなりましたが。Jekyll ページネーション問題 ↩