ReactでJupyter Notebookを表示する一番簡単な方法
結論から言うと react-ipynb-renderer を使います。(v2.2.1を使ってください)
サンプルとコードは以下のコードを見てください。
今回はこのライブラリを作った経緯など、聞かれていないですが勝手に書いていこうと思います。
ライブラリを作った経緯
少し前に Nikola というPython製の静的サイトジェネレータを使ってブログを運営していました。
そのブログではJupyter Notebookの結果を表示するために以下のプラグインを使用していました。
これは notebook_shortcode
というプラグインを一部書き換えただけなので自慢できるような代物ではありませんが、記事ファイルを基点としたパスから参照できることが個人的に好都合だったのです。
で、しばらくはNikolaで十分でしたが、案件でNext.jsに出会い、SSGが流行ったことでブログを引っ越すモチベになりました。大半の記事は書き換えが大変だったものの単純に移行できました。
しかし Jupyter Notebookを表示している記事に問題がありました。当時これを表示するためのReactライブラリを探しましたが、目ぼしいものがなかったため自作することを決意します。正確には保守されていなかったりデザインが気に食わなかったり、一部表示できなかったりという感じで界隈で標準的に使われているようなものが見つからなかったというよくある理由です。
実装について
一般的にJupyterファイルからHTMLを生成する際には nbconvertというものを使います。なのでこの表示に合わせて実装し動くところまではすぐできました。当初これは自身のブログ内だけで動かす予定のプライベートなコードでしたが、他の誰かの役立つかもしれないので公開することにしました。
さて、私は明るいスクリーンを見続けていると目がチカチカするので基本的にダークモードにできる場合は積極的に使っています。(Zennもダークモードほしいですお願いします)
Jupyterには様々なテーマがあり、ダークモード系でもかっこいいものは結構あります。
始めてみたときおしゃれな人のデスクトップ画面を見たときのような感動がありました。
上のExampleは dorkula
という赤と黒をベースとした中二心をくすぐるテーマとなっております。
以前のブログでは個人的に気に入ったテーマのCSSを少しカスタマイズして適用していたのですが、ライブラリとして提供するにあたり、利用者にもテーマを自由に選ばせてあげたいと思いました。
幸いなことにこれらテーマは LESS として提供されていたことと、nbconvertで出力されたHTMLの形式に適合していたため、サブモジュールとして取り込んでビルドすることでライブラリとしてテーマを提供できるようになりました。天才か?(気のせい)
テーマは圧縮したCSSとして提供されるためimportすることで適用されます。もちろん用意されたテーマを使わずに自作してもOKです。
また、数式(Latex)の表示は意外と苦労したポイントです。Markdownの一部として数式のレンダリングを行うことでMarkdown中の数式表示と実行結果としての数式表示を実現しています。
数式表示に用いる描画エンジンは一般的にMathjax、Katexがありますが当ライブラリではどちらを使うかによってライブラリを分けています。前者がMathjax、後者がKatexを使うバージョンです。
KatexはMathjaxより軽量ですが一部表示できない形式があるため Mathjax を使うことを推奨しています。
このライブラリのサイズが結構大きいのは概ねこれが原因です。
Markdownパーサについては、最初 markdown-it を使っていましたが、プラグインの柔軟性に不満があったため Remarkに乗り換えました。 基本的にはあまり変わらないですが、ライブラリからMarkdownコンポーネントに引き渡すpropsの形式に変化があり、メジャーバージョンを上げました。
HTML出力の際には DOMPurifyを噛ませているので今はセキュリティ的に問題はないと思います。
最後に
自己満足で雑に作って公開していたライブラリですが、使ってくれている方もいるようで嬉しい限りです。そもそもライブラリ自体が少ないので消去法的に選ばれているだけだと思いますが利用者がいるうちは保守していくつもりです。
あなたが興味を持ってくれたら嬉しいです。
他のサンプルを見たいという方はブログ記事をご覧ください。実はバージョン上げてない🤫
Discussion