コンテンツにスキップ

ADR-0041: スライドのエディタは Marp で作り、テーマの CSS からトークンの CSS 変数を参照する

Status

承認

Context

プレイグラウンドに、訪問者と運営者が Markdown からスライドを作るエディタを追加する。
スライドの方式、テーマとトークンの関係、書き出すファイルの形式を決める必要がある。

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 が安定版になったときに、バージョンを上げるかを決め直す。