ADR-0041: スライドのエディタは Marp で作り、テーマの CSS からトークンの CSS 変数を参照する¶
Status¶
承認
Context¶
プレイグラウンドに、訪問者と運営者が Markdown からスライドを作るエディタを追加する。
スライドの方式、テーマとトークンの関係、書き出すファイルの形式を決める必要がある。
- プレイグラウンドの全てのツールを、1 つのサブドメインに置き、ツールごとにパスとページを分ける。訪問者が作ったスライドは、訪問者のブラウザに保存する。
- トークンは、プリミティブトークン、セマンティックトークン、テーマ変数の 3 つの層で、CSS 変数として配る。ライトとダークは、セマンティックトークンの値で切り替える。
- コードの色は、セマンティックトークンから配る。
- Marp の
@marp-team/marp-coreと Marpit は MIT である。marp-core の安定版は 4.4.0 で、README は v5 を release candidate と書いている。 - marp-core は、コードの色付けに highlight.js(BSD-3-Clause)を、数式に MathJax(Apache-2.0)と KaTeX(MIT)を使う。
- marp-cli は、PDF、PPTX、画像への変換にブラウザを使う。
- 「You have to install any one of Google Chrome, Microsoft Edge, or Mozilla Firefox to convert slide deck into PDF, …」
- 出典: marp-cli の README
Decision¶
1. 方式とバージョン¶
スライドは Marp で作る。
エディタは、ブラウザの中で marp-core を動かし、入力のたびにプレビューを描き直す。
marp-core は、安定版を使う。v5 に上げるかは、v5 が安定版になった後に決める。
- エディタは、
play.fukuemon.devの、isolation のヘッダを返さないパスに置く。 - プレビューは Shadow DOM に入れる。Marp の CSS を、ページに適用させないためである。
2. テーマとテンプレート¶
テーマは、トークンの CSS 変数を参照する CSS として書く。
トークンからテーマの CSS を生成する処理は持たない。
- ライトとダークは、トークンの値の切り替えだけで追従させる。
- コードの色は、highlight.js のクラスに、コードの色のトークンを対応させる。
- テーマは、2 つ以上を用意する。
- テンプレートは、表紙、目次、コードのページのような Markdown の断片にする。ページの種類は、Marp のクラスの指定で表す。
3. 書き出すファイルの形式¶
書き出しは、Markdown、単独の HTML、印刷での PDF の 3 つにする。
- 単独の HTML には、Marp の HTML と CSS に加えて、トークンの CSS を埋め込む。埋め込まないと、変数の値が無く、色が出ないためである。
- PDF は、単独の HTML と同じ中身を、ブラウザの印刷に渡して作る。
- PPTX は書き出さない。ブラウザの中だけでは作れないためである。
4. 数式と絵文字¶
最初の公開では、数式の記法を無効にする。
絵文字は、OS の絵文字のまま出し、絵文字の画像を外部の CDN から読み込まない。
marp-core のデフォルトでは、絵文字の画像を cdn.jsdelivr.net から読み込むためである。
Verification¶
端末は Apple M2、ブラウザは Playwright 1.65.0 の Chromium 158、WebKit 27.2、Firefox 159(headless)、配信は localhost である。
バージョンは、@marp-team/marp-core 4.4.0、esbuild 0.28.2、Node 24.21.0 である。
実機のブラウザは未確認である。
- 40 枚のスライドで、入力 1 回あたりのスクリプトの時間の中央値は、Chromium 4.5 ミリ秒、WebKit 6 ミリ秒、Firefox 6 ミリ秒だった。
marp.render()とプレビューへの差し込みの時間で、ブラウザのレイアウトと描画は含まない。 - プレビューを Shadow DOM に入れると、ページの側の文字の大きさは変わらず、ページのトークンの変数はプレビューに届いた。
- ページの
data-themeを切り替えると、スライドの背景の色が、ライトとダークのトークンの値に変わった。コードのキーワード、文字列、コメントの色は、ライトとダークの両方で、トークンの値と一致した。 - エディタは、自分のページのほかへリクエストを出さなかった。
emoji: { shortcode: false, unicode: false }を渡したときの結果である。数式は、デフォルトの設定でも、外部へのリクエストを出さなかった。 - エディタの JavaScript は、非圧縮で 3.86 MB、brotli で 936 KB だった。
mathjax-fullが 1.79 MB、highlight.jsが 1.08 MB を占める(非圧縮)。 math: falseを渡しても、MathJax はバンドルに入った。数式のライブラリをバンドルから外せるかは未確認である。- 単独の HTML は、6 枚で 41.8 KB だった。
file://で開いて、外部へのリクエストは 0 件で、OS の設定がダークのときはダークの色で出た。 - Chromium の
page.pdf()で、6 枚のスライドが 6 ページの PDF になった。ページの大きさは、スライドと同じ 1280×720 px だった。 - 訪問者が印刷のダイアログから PDF に保存する操作と、WebKit と Firefox の印刷は未確認である。
- サイトの書体を、単独の HTML にどう持たせるかは未確認である。
Considered Options¶
| 選択肢 | 強み | 弱み |
|---|---|---|
| 採用: Marp の安定版を使い、テーマの CSS からトークンの CSS 変数を参照する | テーマを生成する処理が要らない。ライトとダークが、トークンの値の切り替えだけで追従する | 単独の HTML に、トークンの CSS を埋め込む。エディタの JavaScript が、brotli で 936 KB ある |
| トークンから、テーマの CSS を生成する | 書き出したファイルが、トークンの CSS を持たなくて済む | 生成の処理を持つ。試作では、生成しなくても色が揃った |
| トークンと独立したテーマにする | テーマを、サイトの見た目と別に作れる | スライドの色が、サイトのトークンと揃わない |
| marp-core の v5(release candidate)を使う | 後でバージョンを上げる作業が要らない | 安定版でない。試作していない |
| 書き出しに PPTX を足す | 訪問者が、スライドをほかのツールで編集できる | marp-cli の変換はブラウザを使う。ブラウザの中だけでは作れない |
| 数式の記法を有効にする | 数式を書ける | 数式のライブラリが、エディタの JavaScript の非圧縮の大きさの約半分を占める |
| reveal.js の Markdown を使う | 未確認 | 試作していない。Marp が、ライセンスと動きの両方で要求を満たした |
Consequences¶
Positive¶
- 訪問者と運営者は、ブラウザの中だけで、Markdown からスライドを作れる。
- スライドの色とコードの色が、サイトのトークンと揃う。トークンの値を変えると、テーマも変わる。
- 訪問者が作ったスライドは、fukuemon.dev のサーバーにも、外部の CDN にも送られない。
Negative¶
- エディタの JavaScript が大きい。数式のライブラリをバンドルから外せるかを、実装のときに確認する。
- 数式を使うスライドを作れない。
- 絵文字の見た目が、OS ごとに違う。
- PDF は、ブラウザの印刷の機能に依る。ブラウザごとの結果を、実装のときに確認する。
- marp-core の v5 が安定版になったときに、バージョンを上げるかを決め直す。