Markdown プレビュー
開発自己完結型のサニタイズ描画エンジンで Markdown を HTML に変換 — 生 HTML は実行されず、出力は CSP セーフです。
このページの内容
Markdown レンダラーとは?#
Markdown は、開発者がリッチテキストを書くために使うプレーンテキストの短縮記法です — **bold**、# headings、- lists、`code`。レンダラーは、それらの短縮マークをブラウザが実際に表示する HTML に変換するプログラムです。README ファイル、ドキュメントサイト、Issue トラッカーのコメント、チャットアプリ、静的サイトジェネレータはすべて、Markdown をユーザーに見せる前にレンダラーに通します。
本ページは、1 つの特定の設計優先度を持つ Markdown レンダラーです — フィルタではなく、構造によって安全。ほとんどのレンダラーはまず Markdown を HTML に変換し、結果から危険なタグを洗い流そうとします — 見落とした正規表現 1 つが XSS 脆弱性を意味するモデルです。本ツールは逆方向で動きます。ソースのすべての文字はフォーマットが適用される前に HTML エスケープされ、emit するタグは固定のハードコードされた許可リスト(p、h1〜h6、ul、ol、li、blockquote、pre、code、hr、a、img、strong、em、del、br)からのみ来ます。入力から <script> タグを発するコードパスは存在しません。ソースの生の < は、フォーマッタが見る前に < にエスケープされるためです。これが、本サイトのような厳格な CSP の静的サイトに適する理由です。
CommonMark の集中的なサブセットに加え、GitHub-Flavored Markdown の要点(フェンスコードブロック、ATX 見出し、段落、順序付き/順序なしリスト、引用、水平線 ---、インラインコード、太字、斜体、取り消し線、画像、リンク、山括弧オートリンク)を実装します。同じ入力から 2 つの出力が並んで得られます — プレビューと生の HTML — レンダラが何を生成したかを正確に確認できます。
使い方#
- 左ペインに Markdown を入力するか、サンプルでサポートするすべての機能を一通り試す組み込みドキュメントを読み込みます。
- 右ペインの上の 2 つのボタンで出力を切り替えます。
- プレビューは、ウェブページに現れるような整形済み結果を表示します。
- HTML は、レンダラが発行した正確な HTML を表示します。テンプレートに貼り付けたり、サニタイザ監査に渡したりする値です。
- HTML をコピーで、生成された HTML を他で使うために取得します — CMS への貼り付け、テンプレートへの埋め込み、レビューへの通過。
- クリアで両ペインを空にします。
- ステータス行がレンダリング後のバイト長を報告するか、入力が空のときに注記します。
主な機能#
- 構造によって安全。 すべてのソーステキストはフォーマット前に HTML エスケープされ、レンダラは固定の許可リストのタグのみを発行します。「それから危険な部分を剥がす」ステップが間違る余地はありません。
- 危険な URL スキームを破棄。 リンクと画像の URL はスキームチェックされ、
javascript:、vbscript:、data:、file:、about:はブロックされ、問題のテキストは生きたリンクではなくリテラルに表示されます。 - 1 つのソースから 2 つのビュー。 再入力せずにプレビューと生 HTML を切り替えられるため、視覚的結果とそれが生成したマークアップの両方を検証できます。
- GFM の要点を含む。 取り消し線(
~~text~~)、言語ヒント付きのフェンスコードブロック、タスクフレンドリなリストは GitHub-Flavored Markdown と同様に振る舞います。 - 依存ゼロ、100% クライアントサイド。 レンダラは自己実装であり — 同梱の解析ライブラリはなく — 完全にブラウザ内で動きます。何もアップロードされず、注入するバックエンドもありません。
実例#
サンプルをクリックすると、左ペインに基本構文を一通り試すドキュメントが入ります。
# Heading
A paragraph with **bold**, *italic*, ~~strike~~ and `inline code`.
- bullet one
- bullet two
1. first
2. second
> A blockquote.
[a link](https://example.com)
\`\`\`
const x = 42;
console.log(x);
\`\`\`
HTML に切り替えると、レンダラが発行したものが正確に見えます。段落は次になります。
<p>A paragraph with <strong>bold</strong>, <em>italic</em>,
<del>strike</del> and <code>inline code</code>.</p>
リンクは、安全な rel/属性を持つハードターゲットになります。
<a href="https://example.com" rel="noopener noreferrer" target="_blank">a link</a>
フェンスブロックは、ソースを逐語的に保つエスケープされた <pre><code> になります — const x = 42; は実行されたスクリプトではなくテキストとして現れます。この最後の点が、小さな枠に収まったセキュリティの全物語です。ソースに <script>alert(1)</script> を貼り付けても、< がフォーマッタが何がタグかを決める前に < にエスケープされるため、リテラルテキスト <script>alert(1)</script> としてレンダリングされます。
よくある質問#
単に HTML を直接書く代わりにこれを使う理由は?#
Markdown はタイプが速く、ソース形式で読みやすく、HTML に詳しくない寄稿者もコンテンツを書けるためです。本レンダラーは、汎用の解析ライブラリが安全でもあると信じることなく、その利便性が欲しい場合向けです — ここでの安全性は、最後にボルトオンされたサニタイザではなく、アーキテクチャから来ます。
<script> タグを貼ったらテキストとして現れました。バグですか?#
いいえ — それが意図された挙動であり、中核の安全保証です。入力のすべての文字はフォーマット前に HTML エスケープされるため、ソース内のタグらしいテキストはすべて不活性な可視テキストとしてレンダリングされます。このレンダラを通じて生きた <script> を出力に持ち込む方法はありません。
なぜ javascript: リンクがプレーンテキストとして表示されたのですか?#
レンダラはすべてのリンクと画像 URL をスキームチェックします。javascript:、vbscript:、data:、file:、about: のようなスキームは、注入攻撃の古典的なベクトルのためブロックされます。URL がブロックされたとき、レンダラは危険なアンカーを発行するのではなく、元の Markdown ソースをリテラルテキストとして残します。
表、タスクリスト、脚注に対応していますか?#
いいえ — これは CommonMark に GFM の要点(フェンスコード、取り消し線、オートリンク)を加えた、意図的に焦点を絞ったサブセットです。表と脚注はよりリッチなパーサと、更大な攻撃表面の監視を必要とし、ここでは意図的に範囲外です。上記機能にリストされた対応構文に留めてください。