Speee DEVELOPER BLOG

Speee開発陣による技術情報発信ブログです。 メディア開発・運用、スマートフォンアプリ開発、Webマーケティング、アドテクなどで培った技術ノウハウを発信していきます!

The story of Marp Next: 次世代の Marp への取り組み

プロジェクト推進室の服部 (@yhatt) です。

この記事は Marp 公式ブログ の記事 "The story of Marp Next" をベースに、意訳と一部加筆・修正を行ったものです。現在オープンソースで開発に取り組んでいる、次世代の Marp(通称 Marp Next)への取り組みについて、現在の状況をお伝えできればと思います。

Marp: The ecosystem to write your presentation with plain Markdown

marp.app

はじめに

tech.speee.jp

Marp の最初のバージョンは、およそ 3 年前に個人開発の成果として公開されました。プレゼンテーションスライドライターとしての価値が認知され、 GitHub では ⭐️ 8000 over のツールに成長し、スライド作成のためのオープンソースアプリケーションとして、一定の成功を収めることができました。

多くの要望やフィードバックを Marp に頂きましたが、Marp は開発のメンテナビリティが低く、自分の JavaScript のスキルも追いついていなかったため、継続的な開発を一度断念せざるを得ませんでした。快適なスライド執筆環境を実現できるように Marp を進化させるためには、これらの克服が絶対条件であり、約2年間、フロントエンド修行を重ねました。1

その成果として、0 から完全に書き直された新しい Marp Next は、複数のモジュールで構成されたエコシステムとして生まれ変わり、様々なユースケースで Marp が利用できるようになりました。JavaScript / TypeScript で開発を進めており、化石のような開発アセットを使っていた旧 Marp と比べても、格段にメンテナビリティが向上しています。

Marp Next

Marp Next には、Marpit フレームワークMarp Core の 2 つの核となるモジュールがあります。Marp エコシステムで提供されるツールは、基本的にこれらのコアモジュールに基づいています。

Marpit

Marpit

Marpit (マーピット) は、Markdown から HTML スライドを作成するためのシンプルなフレームワークで、スライドとして成立する "最小限の" 静的な HTML / CSS を生成することに特化しています。Marpit で生成された HTML は、Google Chrome (Chromium) の印刷機能を使い、PDF に変換することができます。

Marpit は Marp エコシステムと密に連携していますが、基本的には "独立した" 汎用的な Markdown 変換フレームワークです。そのため、カスタマイズによって reveal.jsWebSlides など、他の著名なスライドフレームワークと共に使うこともできます。

Marpit + reveal.js

Marpit + WebSlides

Marpit の機能

Marpit Markdown

旧 Marp には、より便利に Markdown スライドを書くため、追加の構文に対する多くの要望が Issue に寄せられましたが、その一方で "基本的な Markdown 構文を厳守すべき" という要望も挙げられており、一見相反する Issue をどう処理するかが課題でした。Marpit が、それらに対する答えを提示します。

Marpit は CommonMark を遵守し、Marpit に新たに追加した Markdown 構文 (画像に関する構文など) は、CommonMark の仕様を壊しません。また、Marpit にそのような構文を新たに追加するつもりもありません。よって、Marpit 用に書いた Markdown をそのまま普通の Markdown エディタでレンダリングしても、ドキュメントとしての Markdown の見栄えが保たれます。

また、追加の構文については、markdown-it プラグイン を使用・作成することで、ユーザーが自由に拡張することができるため、拡張性もちゃんと確保しています。

テーマCSS

Marpit では正式に、スライドテーマ CSS の仕組みを整備しました。

旧 Marp にもテーマはありましたが、独自のテーマの追加には対応しておらず、テーマ作成には苦労が必要でした。2 そのため、一般的な CSS の知識だけでカスタマイズが可能な、新しいテーマシステムを構築する必要がありました。

Marpit のテーマは非常にシンプルで、 『普通の CSS と同じく、Markdown に対応するセマンティック HTML 要素にスタイルを充てていくだけ』 です。Marpit に固有の知識(独自のクラスや mixin など)はできる限り排除しているのが、他のスライドフレームワークと異なる点です。

また、Marpit のスライドは、 PowerPoint や Keynote のように、画面サイズに関わらず縦横比が固定の「ピクセルパーフェクトスライド」を採用しています。テーマ作者はレスポンシブレイアウトを考慮しなくて良いので、環境に依るデザイン崩れを心配する必要もありません。

インライン SVG スライド (Experimental)

珍しい機能として、各スライドページのコンテナとして、インライン SVG を使用する機能があり、以下のような利点があります。

  • Marpit を Web アプリに組み込む際、各スライドを画像のように扱えるので、取り回しがシンプルになる
  • HTML の拡大縮小が CSS だけで可能で、『表示時に一切 JavaScript を使わないプレゼン HTML』を実現 (Zero-JS slide deck)
  • SVG の中に複数の HTML コンテナをレイヤー構造的に注入できるため、背景画像などの追加機能を Markdown の DOM 構造を壊さずに提供できる(例: テーマ CSS で隣接セレクタを使ってもデザインが崩れない)

特に Zero-JS slide deck は、パフォーマンスやシンプルさの観点でも強く意識している部分です。後述の Marp CLI でも、実際に一切 JS を使わない HTML を作成できます。

これにより、Marpit は『Markdown の変換処理』だけにフォーカスできる (KISS 原則) ため、メンテナビリティの確保に大きく貢献しています。

Marp Core

Marp Core は、Marpit を拡張した Marp エコシステムのためのコアコンバーターです。

Marpit は汎用的な機能にフォーカスしており、実際にスライドを作るにあたっては少し力不足な部分もあります。そこで Marp Core では、 Marpit を拡張し、より実用的な構文・追加機能・公式テーマを提供します。

拡張された機能の多くは、旧 Marp アプリに基づくものですが、Marpit に沿ったものに改良されているほか、新テーマ、新機能も追加されています。

  • 公式テーマ(Default、Gaia、Uncover [NEW]
  • スライドサイズの切り替え (size ディレクティブ)
  • 絵文字サポート (twemoji)
  • 数式サポート (KaTeX)
  • オートスケーリング [NEW]
    • <!-- fit --> コメントによるフィッティングヘッダー
    • はみ出る可能性のあるコードブロック・数式の自動縮小

Marp アプリケーション

Marp CLI

Marp CLI は、Marpit / Marp Core の CLI インターフェースです。

もし Node.js がインストールされていれば、npx @marp-team/marp-cli を叩けばすぐに使えますし、従来と同様の 実行可能ファイルDocker イメージ も提供しています。

機能

  • HTML、PDF、PPTX、画像へのエクスポート
  • ウォッチモード (--watch) で Markdown・テーマの変更を反映
  • サーバーモード (--server) によるオンデマンド変換
  • プレビューウィンドウ (--preview)
  • 変換エンジン (Marpit / Marp Core) のフルカスタマイズ

旧 Marp ではエディタが統合されていましたが、『好きなエディタでスライドを書きたい』という声が多く寄せられていました(Vim のキーバインドを使いたいなど)。Marp CLI のウォッチモードで、この問題が解消されます。

また、Bespoke.js をベースエンジンに採用したスライド HTML を生成できるようになり、ブラウザを使ったプレゼンテーション 3 や、Web ページの公開も容易になりました。

NetlifyNow で Marp CLI を使えば、Marp のスライドを GitPitch 風に Git で管理し、Web サイトにホスティングすることもできます。サンプルリポジトリ yhatt/marp-cli-example をベースすれば、 Marp のスライドを 簡単に Web にホスティングすることができます。 (リポジトリにある "Deploy to Netlify" ボタン を使えば数秒で構築できますので、ぜひお試しください)

Marp Web (技術デモ)

Marp Web は、その名の通り Web 上で動作する Marp です。 現時点ではあくまで技術デモであり、将来的には諸々再設計する予定です。

PWA (Progressive Web App)

約 2 年前、旧 Marp アプリの開発継続を断念していた頃に、Web 版への移行のアイデアが出されましたが、オフラインで Marp を使いたいというユーザーからの否定的な反応が多くありました。 PWA はそれを解決する技術のはずですが、当時はその考え方が一般に浸透していないこともあり、採用に舵を切れない状態が続いていました。

時が経つに連れて状況も大きく変わり、PWA も浸透しつつあるため、Marp Web への移行を決断しました。Marp Web は従来のアプリに近い操作感を目的とした 2 ペインエディターですが、Marp Web のリソースがブラウザにキャッシュされるため、オンラインでもオフラインでも動作するのが特徴です。アプリをインストールすれば、旧 Marp アプリに近い感覚で使えます。

Android / iOS 端末での利用

Web ベースアプリケーションへの移行による大きな利点が、Android や iOS 端末でも利用できるようになることです。特に iPad のようなタブレット端末には非常にマッチします。

現在の Marp Web はあくまで技術デモなので、iOS 端末では PDF への変換ができないなど、まだ実用向きではありません。

リアルタイム・ライブプレビュー

Web 版の作成にあたり、旧 Marp の特徴でもある、リアルタイムなライブプレビューの実現を特に意識して作成しています。

現在公開されているデモは、その試行錯誤の成果であり、可能な限り即座に Markdown をレンダリングします。Web Worker を採用し、たとえ 100 ページ超の Markdown スライドでも、タイピングがフリーズしたりすることはありません。

Marp for VS Code

実際のところ、現時点では「新しいエディタを作る」ことにはあまり注力していません。4 優秀な Markdown エディターの力を借り、Marp の機能を統合したほうが現時点ではハッピーだろうと考えています。そしてその 1 つとして、Marp for VS Code を公式の拡張機能として提供します。

VS Code 上で Marp スライドをプレビューしながら書くことができ、組み込みの Marp CLI を介して PDF・HTML・PPTX へのエクスポートも可能です。カスタムテーマ CSS もサポートしており、この拡張で新しい Marp の機能をフル活用できます。

この拡張機能は、VS Code で使われている Markdown エンジンと Marp で使われているエンジンが共通している (markdown-it) ことで実現しました。

Marp React & Marp Vue (開発中)

Marp は Web の基礎技術 (HTML + SVG / CSS) しか使用しないので、フレームワークに縛られません。React でも Vue でも、同じように Marp を使えます。

開発中の Marp React および Marp Vue は、Marp を活かしたツールを作りたいユーザーのために開発・提供しているコンポーネントです。主な機能は、以下で共通しています。

  • 各フレームワークの仮想 DOM によるスライドの差分更新
  • スライド表示の細かな制御(カスタムレンダラー)
  • Web Worker を用いたレンダリングプロセスの分離

Marp のスライドを React / Vue アプリに簡単に組み込めるので、独自のプレゼンシステムを DIY で構築したり 5、自身の開発するエディターに組み込んだりすることができます。将来的には、Marp Web の基盤として Marp React が採用される予定です。

旧 Marp からの移行について

もしまだ 古い Marp のデスクトップアプリを使用している場合は、Marp Next で提供されているツールを使用するように移行する必要があります。 (前述の通り Marp for VS Code をオススメします)

古い Marp は 3 年も前にメンテナンスを中止しており、セキュリティに関する懸念も度々報告されています。古い Marp は決して使うべきではありません。

移行計画

将来的には、Marp Web が Marp アプリケーションのメインインターフェースになる予定です。デスクトップアプリは、将来単なる Marp Web のラッパーとして提供されるようになる予定ですが、現時点でどうなるかはまだ未定です。

旧 Marp を置き換えられるレベルの機能が Marp Web に揃った時点で、旧 Marp の公開は終了する予定です。

主な構文の変更点

新しい Marp エコシステムでは、旧 Marp で得られたフィードバックに基づき、 Markdown の構文を検討し直しました。その結果、一部の古い構文で書かれた Marp Markdown とは互換性が失われていることに注意してください。

Markdown

  • Marp Core では旧 Marp で指摘されたセキュリティ対策として、HTML ホワイトリストを導入しています。ほとんどの HTML 要素は原則使用できません(Marpit が認識できるコメントや、<style><br> タグが例外です)。いくつかのツールでは HTML を有効にする設定が提供されていますが、信頼できない Markdown の表示においてはセキュリティリスクになり得るため、使用には十分注意してください。

ディレクティブ

  • 新しい Marp エコシステムでは YAML パーサーを使用するため、スポットディレクティブ(単一ページにのみ適用するディレクティブ)を指定するための接頭辞が * から、YAML のキー名として valid な _ (アンダースコア) を使うように変わりました。
  • size ディレクティブは Marp Core 限定の機能になりました。もし Marpit を使用している場合は、代わりにテーマ CSS でカスタムサイズを定義してください。
  • page_number ディレクティブの名前が paginate に変わりました。
  • template ディレクティブは廃止され、代わりに section HTML 要素のクラスを定義できる class ディレクティブを使うようになりました。
  • prerender ディレクティブは削除されました。PDF 生成時のバグを避けるため、スライドを画像に変換するためのディレクティブですが、ユーザーに混乱を招くだけの機能になっていました。

画像

  • ![bg]() による背景画像には、透明度フィルタが適用されなくなります。今までと同じ表示にする場合は ![bg opacity]() を使い、CSS フィルタを定義します。
  • 画像のパーセンテージによる拡大/縮小ができなくなりました(Marp CLI でエクスポートした HTML が Firefox で使用できなくなるため)。代わりに、CSS の width (w) および height (h) を定義するためのキーワードを用意しています。
  • center キーワードが削除されました。画像のセンタリングには暗黙的な CSS ブロック要素への変換が必要であり、テーマ作者が意図した通りにデザインを表示できなくなる可能性があります。もし center キーワードが必要なら、<style> タグでスタイルを微調整することができます。
<style>
img[alt~='center'] {
  display: block;
  margin-left: auto;
  margin-right: auto;
}
</style>

おわりに

Marp

本記事では、次世代の Marp である Marp Next への取り組みについてご紹介しました。

すでに多くの支持をいただいている Marp をより進化させ、普遍的なスライドフレームワークに成長させるため、コミュニティと共にエコシステムを拡大・拡張していきたいと考えています。

そのためには、まだまだ未成熟な部分がありますので、フィードバックや開発などにおけるプロジェクトへの貢献 をいただけると、私としても大変励みになります。もし興味があれば、ぜひともよろしくお願いします。


  1. 当時は Ruby や Rails が中心でしたが、この1件で完全に JavaScript 使いにピボットしました。

  2. Marp を 1 からビルドする必要があるほか、内部的に使われているクラスや Sass mixin の役割を読み解かないといけません。私は決して望んでいませんが、それがカスタマイズのベストプラクティスであるかのように旧 Marp が紹介されるケースが多く、心苦しい思いで一杯でした。

  3. 旧 Marp ではプレゼンモードの要望を本当に多く頂いており、存在意義も充分に理解していますが、Marp Next は プレゼンツールの DIY を前提としているため、統合環境での本格的な対応は未だ消極的です。

  4. 旧 Marp に寄せられた Issue のうち、約半数はテキストエディタとしての機能への要望で、Marp の本質である「スライドの生成」にフォーカスできなくなってしまい、結果として開発が止まってしまったという経緯があるためです。

  5. marp-vue-slide は、実際に Marp Vue を使用して発表者ツールを組み込んだボイラープレートです。