Playground
Playground は go-slides v0.18.0 そのものを WebAssembly にコンパイルし、 ブラウザー内で動かしたものです。左側にスライドデッキを入力すると、右側にスライドが追従して表示されます。 スライドデッキも共有リンクも、サーバーには何も送信されません。
Playground 自体の画面(リボン、ヘルプ、メッセージ)は、ページの言語で表示されます。
日本語なら /ja/playground/ を開いてください。このサイトの 12 言語すべて同じです。
ページの言語セレクターで切り替えられ、選択はこのブラウザーに保存されます。言語を指定したリンクが
常に優先されます。サンプルのデッキは英語のままです。ウクライナ語、ロシア語、中国語、日本語、韓国語は、
その言語のときだけページがダウンロードする Noto Sans のサブセット(0.06〜2.3 MiB)で描画されます。
主な機能
各スライドの ライブプレビュー。ページのスレッドとは別(Web Worker)でレンダリングされるので、入力が待たされることはありません。スライドをクリックすると、エディターが その行に移動します。キャレットを動かすと、プレビューがそのスライドまでスクロールします。
スライドショー:キーボード操作、画面上のコントローラー、トランジションを備えた、 プレゼンテーションそのものです。
発表者ビュー:Present(スライドショーでは
p)を押すと、2 つ目のウィンドウで開きます。 現在のスライド、次のステップ、スピーカーノート(スライドデッキの<!-- comments -->)、時計、タイマーが表示されます。矢印キー、Space、 Home、End はどちらのウィンドウでも使え、互いに連動します。スライドデッキを編集したときも 連動します。ウィンドウが開かない場合は、このサイトのポップアップを許可してください。 一覧表示(o)は、ダウンロードしたページでのみ使えます。入力中の 補完:ディレクティブのキー(コメント内ではスポットディレクティブの
_付きのものも)、kind、theme、size、paginateの値、そして{{ }}内のテンプレート関数と データのフィールド。キャレット位置にあるものの ヘルプ:ディレクティブ、kind(スライドの種類。何を設定するか)、 テンプレート関数。ヘルプペインからは、このドキュメントの各ページにもリンクしています。 v0.16.0 以降、ディレクティブのヘルプは画面の言語に従い、11 言語に対応しています。
該当行に表示される 問題:テンプレート、YAML、HCL のエラーはエディター内でハイライトされ、 エディターの下に一覧表示されます。プレビューには、最後に正しくレンダリングできたスライドデッキが 表示されたままになります。
サンプル:ウェルカム用のスライドデッキ、スライドを生成するテンプレート、スライドの kind、 HCL のフロントマター、テーマとスポットディレクティブ、そして数式、画像、 背景(
![bg]、分割背景の![bg left:40%]、フィルター)。ファイル:エディターの左にあるパネルはスライドデッキのプロジェクトで、 コマンド や VS Code 拡張機能 が読み込むのと同じ構成になっています:
deck.md、slides.yaml、themes/、kinds/、media/。- ファイルをクリックすると編集できます。エディターは言語 (Markdown、YAML、HCL、JSON、CSS)に応じて色付けし、問題箇所に印を付けます。
- 右クリック(または Shift+F10)で、New File、New Folder、Rename(F2)、 Delete(確認あり)、New theme / New kind を使えます。ファイルをフォルダーにドラッグすると 移動できます。キーボード操作は WAI-ARIA のツリーパターンに従い、先行入力による検索にも 対応しています。
- Project ▸ New theme は
themes/my-gaia.css(または default、 uncover をもとにしたもの)を作成します。内容は組み込みテーマの@importと、追加したルールです。 作成したテーマは Theme の一覧に加わります。New kind と New data file も テンプレートから始まります。いずれもslides.yamlに登録されるので、slides build deck.mdで見つかります。 - Project ▸ Download project (.zip) ですべてを保存できます。展開すれば、
slides build deck.mdでビルドできます。Open project では.zipまたは フォルダーを読み込めます。フォルダーの外に出るアーカイブ(..、絶対パス)、 256 個を超えるファイルや 8 MiB を超えるファイルを含むアーカイブ、展開後のサイズが 100 倍を超えるアーカイブは拒否されます。 - すべては下書きと一緒に、このブラウザー内に保存されます。プロジェクトの容量は 最大 64 MiB で、ファイル一覧の下の行に使用量が表示されます。
メディア:画像、動画、音声をエディターにドロップまたは貼り付けると、
media/に保存され、スライドデッキにその参照が書き込まれます:。パネルのフォルダーに ファイルをドロップすると、そのフォルダーに保存されます。スライドデッキは小さく読みやすいままで、 何もアップロードされません。プレビューのサンドボックスは、制限を緩めることなくメディアを読み込みます (ページがバイト列を渡します)。Save as ▸ HTML page では、メディアがページに埋め込まれます。https:の画像も使えますが、ブラウザーが そのサーバーから取得するため、サーバー側にはあなたのアドレスが伝わります。 プレビューはリファラーを送信しません。サイズ変更可能なペイン:ファイルパネル、エディター、スライドのサムネイル、 プレビュー、ヘルプは、ドラッグできるバーで区切られています(バーの上ではポインターが サイズ変更カーソルになります)。バーの隣のペインが広さを取り、 ほかのペインはサイズを保ちます。バーをダブルクリックするか、バー上で Enter を押すと、 ペインを閉じたり元に戻したりできます。キーボードでは、F6 でバー間を移動し、 矢印キーで 16 px ずつ動かし、Home と End でバーの前のペインを最小・最大にし、Escape でエディターに戻ります。 View タブではこれまでどおりペインを非表示にできます。設定したサイズは下書きと一緒に このブラウザーに保存されます。デフォルトのサイズ(190、168、280 px で、残りをエディターと プレビューが 6 対 5 で分け合う)は保存されません。
書式:Format タブで Markdown を編集でき、1 回押すごとに 元に戻す(Undo)の 1 ステップになります。
- テキスト:Bold、Italic、Strikethrough、Inline code は、選択範囲
またはキャレット位置の単語に適用され、オン・オフが切り替わります(Ctrl+B、Ctrl+I、Ctrl+Shift+X、
Ctrl+E。Mac では Cmd)。キャレットが書式の記号の内側にあると、ボタンが押された状態で表示されます。
Markdown には下線がないため、Underline(Ctrl+U)はテキストを
<u>…</u>で囲みます。このタグは Marp のデフォルトの HTML 許可リストで残されるので、 生の HTML がオフでも機能します。 - 段落:見出し 1〜3(Ctrl+Alt+1..3)、箇条書き(Ctrl+Shift+8)、
番号付きリスト(Ctrl+Shift+7)、引用は、選択した行に適用され、オン・オフが切り替わります。
水平線は
<hr>タグです:---、***、___は、Marp ではいずれも 新しいスライドの開始になってしまうためです。 - 表:グリッドで列数と行数を選びます。表の中にキャレットがあるときは、
行や列を追加・削除したり、列の配置(
:--、:-:、--:)を設定したりできます。編集のたびに、表は整形し直されます。 - スライドのテキスト の左揃え、中央揃え、右揃えは、現在のスライドに
<style scoped>ブロックを 書き込みます。Marp には配置の構文がなく、style属性はデフォルトの HTML 許可リストを 通りませんが、scoped ブロックは通ります。そのため、生の HTML がオフでも機能し、 プレビュー、HTML ページ、PDF に反映されます。 - リンク(Ctrl+K)は、url を選択した状態で
[text](url)を書き込みます。
- テキスト:Bold、Italic、Strikethrough、Inline code は、選択範囲
またはキャレット位置の単語に適用され、オン・オフが切り替わります(Ctrl+B、Ctrl+I、Ctrl+Shift+X、
Ctrl+E。Mac では Cmd)。キャレットが書式の記号の内側にあると、ボタンが押された状態で表示されます。
Markdown には下線がないため、Underline(Ctrl+U)はテキストを
フロントマターのキーを、どの深さでも ハイライト します。YAML(
{a: 1}形式のマッピングも含む)と HCL に対応しています。テーマ の選択:default、gaia、uncover、プロジェクトのテーマ (
themes/*.css)、スライドデッキ内で定義したテーマ(<style>内の/* @theme name */)から選べます。選択すると、YAML または HCL のフロントマターにtheme:が 書き込まれるので、共有リンクにも反映されます。フロントマターを編集すると、 選択もそれに追従します。入力中もプレビューは 表示位置を保ちます:変更されたスライドだけが置き換えられ、 テーマを変更してもプレビューは同じスライドで開き直されます。
共有リンク:スライドデッキはリンク自体(
#以降の部分に 圧縮して)に含まれるので、リンクを開けばスライドデッキが開きます。リンクで運べるのは 圧縮後 64 KiB までで、スライドデッキだけです。プロジェクトにほかのもの (テーマ、kind、メディア)が含まれる場合は、Share がその旨を伝え、.zipを提案します。Save as:
- HTML ページ(
slides deck.mdが書き出すものと同じ) - PDF(ベクター、テキスト選択可、アウトライン付き)
- 編集可能な PowerPoint または OpenDocument のスライドデッキ
これらは、
slides --pdf、--pptx、--odpと同じコードによってブラウザー内で作成されます。100 枚のベンチマーク用スライドデッキの PDF は、 コマンドで作成したものとバイト単位で同一です。最初のエクスポート時には、エクスポート エンジン(約 5 MiB。一度だけで、次の更新までブラウザーに保持されます)が、 進捗表示付きでダウンロードされ、届きながらコンパイルされます。その後は、スライドが使うフォントだけを ダウンロードします。3 MB/s の回線では、ウェルカムデッキの最初の PDF が 3 秒未満で仕上がります。その後、100 枚のスライドデッキは約 3 秒で書き出せます。https:の画像は、そのサーバーが許可している場合(CORS)にだけ含まれます。data:の 画像は常に含まれます。- HTML ページ(
下書きは保持されます:
- スライドデッキは入力に合わせてこのブラウザーに保存され(IndexedDB、このサイト専用)、
再読み込みしても戻ってきます。どこにも何も送信されません。
プロジェクトのテキストファイル(テーマ、kind、データ、
slides.yaml)も同じように保存され、 入力直後にタブを閉じても失われません。メディアはドロップした時点で保存されます。 - 共有リンクを開くとそのスライドデッキが開きますが、あなたの下書きは保持されます:Draft ▸ Restore my draft で元に戻せます。
- サンプルを開いても、Draft ▸ Reset to the example(確認あり)を実行しても、 別のタブで作業しても、下書きは消えません:Draft ▸ Restore replaced で 元に戻せます。
- Draft ▸ Forget my drafts は、保存されているものをすべて消去します。
- スライドデッキは入力に合わせてこのブラウザーに保存され(IndexedDB、このサイト専用)、
再読み込みしても戻ってきます。どこにも何も送信されません。
プロジェクトのテキストファイル(テーマ、kind、データ、
どのエクスポートも、プレビューに表示されているプロジェクト(slides.yaml、
テーマ、kind、データファイル、メディア)をレンダリングし、メディアはドキュメント内に埋め込まれます。
ファイルとしての画像(slides の --images)はブラウザーでは作成できません。
コマンド または
VS Code 拡張機能 を使ってください。
元に戻す、やり直し、バージョン
Undo(元に戻す)と Redo(やり直し)は Home タブにあり、Ctrl+Z、 Ctrl+Shift+Z、Ctrl+Y(Mac では Cmd)でも使えます。まず表示中のファイルの直前の編集を取り消し (ファイルごとに独自の履歴があります)、その後はプロジェクト全体への直前の操作を取り消します。 選んだサンプル、Reset、開いた .zip やフォルダー、復元した下書き、削除または名前変更した ファイルやフォルダー、復元したバージョンが対象です。Redo は、Undo を押した時点の状態にすべてを戻します。
バージョンは、プロジェクト全体をこのブラウザーに保存します。どこにも送信されません。 バージョンは、入力をやめてから少し後(最短 2 分間隔)、プロジェクト全体への各操作の前、 エクスポートと共有リンクのたびに保存されます。Save version… は名前を付けて 1 つ保存します。 Home ▸ Versions で Versions ペインが開きます。
- Preview はバージョンをプレビューに表示します。
- Compare with now は各ファイルの変更を行単位で、インラインまたは左右に並べて表示します。 F7 と Shift+F7 で変更箇所の間を移動できます。
- Restore はバージョンを元に戻します。Undo で復元を取り消せます。
- Delete はバージョンを削除します。
保存される内容:最新の自動バージョン 20 件、その後は 1 日分を 1 時間に 1 件、1 か月分を 1 日に 1 件。 名前付きバージョンは削除するまで残ります(最大 50 件)。すべてのバージョンの合計は最大 96 MiB で、 変更のないファイルは 1 回だけ保存されます。ブラウザーのストレージがいっぱいになると、 古い自動バージョンから消えます。
GitHub
Home ▸ History ▸ GitHub で、GitHub リポジトリからスライドのフォルダーを読み込み、 変更をプルリクエストとして提案するペインが開きます。次を入力します。
- リポジトリ(所有者/名前)
- ブランチ(空欄:既定)
- フォルダー(空欄:ルート):フォルダーに
deck.mdが必要です - トークン(マスク表示)
- このデバイスに記憶する
トークンはきめ細かい個人用アクセストークン (作成はこちら)で、 選んだリポジトリに限定し、権限は Contents の読み取りと書き込み、Pull requests の 読み取りと書き込みです(Metadata の読み取りは暗黙に含まれます)。続けて次の操作ができます。
- 接続 はトークンとリポジトリを確認し、切断 はトークンを忘れます。
- 読み込む はプロジェクトを GitHub のフォルダーに置き換えます。Undo で元に戻せ、 元のプロジェクトは「GitHub から」のバージョンとして残ります。
- 変更を提案… はタイトルを尋ね、新しいブランチ
slides/<タイトル>-<日付-時刻>を作成してプルリクエストを開きます。既存のブランチにも既定のブランチにも 書き込みません。プルリクエストを開く でそこへ移動します。 - 変更を確認 は GitHub 上の新しいバージョンを自分のものと Compare ビューで比較します。 向こうを採用 で読み込みます。
GitHub にはプロキシを使いません。playground が直接通信します。
トークンはタブのメモリにだけ置かれ、送信先は api.github.com だけです。ページの
Content Security Policy は他のホストを許可しません。下書き、バージョン、共有リンク、
エクスポートには保存されず、スライドのプレビューやレンダリング worker にも届きません。
このデバイスに記憶する を選ぶと、切断(または Forget my drafts)までこのブラウザーの
localStorage に保存されます。リスクが一つ残ります。playground ページ自体に注入された
スクリプトがトークンを読める点です。必要なリポジトリに限定したトークンを使ってください。
チームには、トークンをサーバー側に置くセルフホストのサーバーモード(近日公開)があります。
GitLab.com
ペインには forge の一覧があり、GitHub と GitLab.com から選べます。GitLab では、
スコープ api の個人アクセストークンを入力するか、GitLab でサインイン
(PKCE 付き OAuth 認可コード、シークレットなし)を押します。サインインではページが
gitlab.com へ移動して戻り、アドレスはすぐに消去されます。そのトークンはこのタブの
メモリーにだけ置かれ(このデバイスに記憶する を選んでも記憶されません)、期限前に
自動で更新され、切断 で GitLab 側で取り消されます。別のタブで始めたサインインや
再利用されたリンクは拒否されます。サインインはサイトの GitLab アプリケーションが
登録されてから使えます。それまでは個人アクセストークンを使ってください。
リクエストの送信先は api.github.com と gitlab.com だけです。ページの Content Security
Policy は他のホストを許可せず、ページは referrer を送りません。
なぜ api が必要か。GitLab のスコープ表は
write_repository を “Does not support API authentication” としています。これは HTTP 経由の git
専用で、GitLab は CORS なしで提供するため、ブラウザーからは使えません。変更の提案は REST API を
使い、そこでは api(“complete read and write access to the API”)が必要です。盗まれた api
トークンは、そのユーザーが API でできることをすべて、そのユーザーが届くすべてのプロジェクトで
行えます。スライドのリポジトリに限定したプロジェクトまたはグループのアクセストークン、
あるいはスライドのプロジェクトのメンバーにだけなっている専用の GitLab アカウントを使ってください。
セキュリティ
スライドデッキは、ページのオリジンを持たないサンドボックス化された iframe に表示されます。
iframe からは Playground にもそのストレージにもアクセスできず、フォームの送信もナビゲーションもできません。
そのページには、自身のスクリプトだけを実行する Content Security Policy が設定されています。
スライドデッキ内の生の HTML は、slides のデフォルトと同じく Marp の許可リストに従います。
5 秒を超えて実行されるレンダリング(ループするテンプレートなど)は
停止されます。
発表者ウィンドウも同じサンドボックスを保ちます。このウィンドウは Playground 自身が開き、 同じようにサンドボックス化された iframe にスライドデッキを表示します。2 つの iframe はストレージを共有できないので、Playground がメッセージでスライド番号を 中継します。スライドデッキを実行するフレームが Playground の オリジンを得ることはありません。
プロジェクトのメディアは、メッセージ内のバイト列としてサンドボックス化されたフレームに渡され、
各フレームは自身のオリジンで、それぞれ独自の blob: URL を作成します。Playground が作成した blob:
URL はそこでは読み込まれず、フレームのポリシーに追加されるのは、メディアとフォント向けの blob: だけです。
Playground は、サインインを必須にしたうえで、自分のマシンから配信することもできます。詳しくは セルフホスティングを参照してください。
サイズと速度
モジュールは、GitHub Pages が配信する状態で 8.8 MiB です(gzip。Pages は brotli で配信しません)。進捗バー付きで一度だけダウンロードされ、その後は次のデプロイまで ブラウザーにキャッシュされます。Apple M4 Max と Chrome 155 で公開中のページを 計測したところ、エディターはページを開いてから 2.1 s で使えるようになり、そのうち 1.5 s はダウンロードで、最初のスライドは 2.4 s で表示されました。100 枚のベンチマーク用スライドデッキへの変更は、 約 30 ms でプレビューに反映されます:go-slides は変更されたスライドだけを レンダリングし、プレビューでもそのスライドだけが置き換えられます。
Created on by tannevaled
Modified on by tannevaled