マークダウンプレビュー

左にMarkdownを入力すると、右に変換結果がすぐ表示されます。生成されたHTMLソースの確認とコピーもできます。変換はすべてブラウザ内で行われ、入力内容は送信されません。

文字数: 0行数: 0見出し: 0リンク: 0ブロックしたURL: 0

マークダウンとは

マークダウン(Markdown)は、記号を使って書式を指定する軽量マークアップの書き方で、2004年にジョン・グルーバー(John Gruber)がアーロン・スワーツの協力も得て考案しました。変換する前の原文そのものが読みやすいことを目標に設計されており、行頭の#は見出し、アスタリスク2つで囲んだ語は太字、行頭のハイフンは箇条書きになります。ただのテキストなので、どのエディターでも書け、バージョン管理で差分を取りやすく、チャットに貼っても崩れません。そのため、READMEや開発ドキュメント、ブログ、ノートアプリ、Wikiなどで広く使われています。

このページは、専用に書いた小さな変換処理でMarkdownをHTMLに変えます。結果欄はプレビューとHTMLソースを切り替えられ、文字数・行数・見出し数・リンク数と、危険として無効化したURLの数も確認できます。

この変換ツールが扱う文法

下の表の各行は、このページの変換処理で実際に確認した内容です。入力例の列をそのままエディターに貼って結果を見比べられます。

文法入力例HTML備考
見出し# 見出し1 ~ ###### 見出し6h1-h6#の後に空白が必要。下線形式(=== / ---)も可
太字・斜体**太字** *斜体*strong, em__太字__ や _斜体_ も可(単語の途中のアンダースコアは無視)
取り消し線~~削除~~delGFMの拡張
リスト- 項目 / 1. 項目ul, ol空白2つ以上で入れ子。番号付きは開始番号を保持
チェックリスト- [x] 完了 / - [ ] 未完了input[type=checkbox]GFMの拡張。プレビュー上では操作不可
表| 列1 | 列2 | + |:--|--:|tableGFMの拡張。コロンで列の揃えを指定
引用> 引用文blockquote中にリストや見出しを入れ子にできる
コード`code` / ```言語 ... ```code, pre~~~ のフェンスも可。中身は変換せずそのまま表示
リンク・画像[文字](URL) / ![説明](URL)a, imghttp・https・mailto・tel・相対パスのみ許可。引用符のタイトルも解釈
自動リンクhttps://example.com / <https://...>ahttp・httpsのみ
区切り線・改行--- / 行末に空白2つhr, br段落の直下の --- は見出しの下線として解釈される

バックスラッシュによるエスケープにも対応しており、\*と書くとアスタリスクがそのまま表示されます。入れ子は8階層までで、それより深い部分は変換せず文字として表示します。表は、見出し行と区切り行の列数が同じときだけ表として認識されます。

非対応なのは、参照形式のリンク([文字][1])、脚注、定義リスト、数式、Mermaid図、インデントによるコードブロック(フェンスを使ってください)、生のHTMLブロックです。いずれも処理系ごとに挙動が分かれる領域なので、推測で変換すると公開先とずれたプレビューになってしまうためです。

CommonMark・GFM・元のMarkdown

元のMarkdownの説明は曖昧な部分が多く、同じ入力でも実装によって出力が違いました。その曖昧さをなくすために作られた仕様がCommonMarkで、この記事の執筆時点の最新版は2024年1月28日付の0.31.2です。GFM(GitHub Flavored Markdown)はCommonMarkに次の拡張を加えたものです。

このツールは表・チェックリスト・取り消し線・自動リンクに対応しています。タグのフィルタリングは、そもそも生のHTMLを一切通さない作りなので不要です(下の安全性の節を参照)。

同じMarkdownでも表示が変わるところ

実際の出力で確認した例

例1: 列揃えのある表 見出し2列、区切り行に:--(左)と--:(右)、データ2行を入力しました。表はスクロール用のコンテナで包まれ、各見出しセルとデータセルにtext-alignが付きます。

| 名前 | 点数 |
|:--|--:|
| 佐藤 | 90 |
| 鈴木 | 85 |
<div class="md-table-wrap"><table>
<thead><tr><th style="text-align:left">名前</th><th style="text-align:right">点数</th></tr></thead>
<tbody>
<tr><td style="text-align:left">佐藤</td><td style="text-align:right">90</td></tr>
<tr><td style="text-align:left">鈴木</td><td style="text-align:right">85</td></tr>
</tbody></table></div>

例2: 入れ子のリスト 「りんご」「なし」を2スペース字下げすると、「果物」項目の中の子リストになります。最上位は2項目、入れ子は2項目です。

- 果物
  - りんご
  - なし
- 野菜
<ul>
<li>果物
<ul>
<li>りんご</li>
<li>なし</li>
</ul></li>
<li>野菜</li>
</ul>

安全性: 変換後のHTMLをそのまま信用してはいけない理由

Markdownは原文にHTMLを混ぜられるため、利用者が入力したMarkdownをそのままページのHTMLにすると、クロスサイトスクリプティング(XSS)の脆弱性になりがちです。典型的な手口は3つあります。

このツールは3つともコードで対処しています。まず&・<・>と引用符を文字参照に置き換え、入力中の生HTMLが要素にならず文字として表示されるようにします。リンクと画像のURLはhttp・https・mailto・telと相対パス、アンカーだけを許可し、それ以外は#に置き換えます。スキームを隠すために入れた制御文字も判定前に取り除きます。外部リンクにはrel="noopener noreferrer nofollow"を付けて新しいタブで開きます。プレビュー欄には生成したHTMLをそのまま入れているため、この処理が唯一の防御で、別のサニタイズ用ライブラリは使っていません。セキュリティテスト用サンプルでは、javascript:のリンクとdata:の画像が#に置き換わって「ブロックしたURL」が2になり、scriptタグと画像タグは文字として表示されます。

自分の文章を自分で確認するプレビュー用途なら十分ですが、本番コードの手本ではありません。手書きの変換処理は想定外の組み合わせで破られる可能性があります。他人が書いたMarkdownを表示するサービスでは、メンテナンスされているMarkdownライブラリと専用のHTMLサニタイザーを併用し、可能ならコンテンツセキュリティポリシー(CSP)も設定してください。

よくある間違い

限界と、使うべきでない場面

これは基本文法とGFMの一部を扱う簡易変換ツールで、CommonMarkの全テストを通るものではありません。入れ子のリストの中のコードブロックのような複雑な構造は、GitHubやお使いの静的サイトジェネレーターと結果が異なることがあります。外部URLの画像はプレビュー時にそのサーバーへアクセスするため、IPアドレスが相手に伝わる可能性があります。公開前には、GitHubやブログ、ノートアプリなど実際の公開先のプレビューで最終確認してください。パスワードや個人情報は、このツールが送信しなくても、オンラインツールには入力しない習慣をつけておくと安心です。

結果の使い方

  1. 左で書きながら、見出しのレベルが飛んでいないか(h1の次がいきなりh3など)を確認します。
  2. 「HTMLソース」タブで変換結果を確認し、必要なら「HTMLをコピー」で持ち出します。貼り付け先のサービスは独自のサニタイズを行う点に注意してください。
  3. READMEやWikiに載せる文書は、公開先の表示で表・チェックリスト・改行が同じか確認します。
  4. 文字数の確認には文字数カウント、2つの版の比較にはテキスト差分チェッカー、英字の大文字小文字の整形には大文字小文字変換が使えます。
  5. Markdownに載せるJSONのサンプルは、先にJSON整形ツールで整えておくと見やすくなります。

よくある質問

変換したHTMLをコピーできますか?

はい。「HTMLソース」タブで内容を確認でき、「HTMLをコピー」ボタンでコピーできます。ほかのサービスに貼り付けると、そのサービスのサニタイズ規則で残るタグや属性が決まります。

表はどう書きますか?

1行目に| 列1 | 列2 |の形で見出しを書き、2行目に|--|--|のような区切り行、その後にデータ行を続けます。区切り行で:--は左揃え、:-:は中央揃え、--:は右揃えです。どの行も見出しと同じ列数にしてください。

MarkdownにHTMLタグを直接書いてもいいですか?

このツールでは安全のため、HTMLタグは変換せず文字として表示します。GitHubなどでは許可されたタグだけが残りますが、許可の範囲は公開先ごとに違うため、実際の公開先で確認してください。

改行しても1行につながってしまいます。

CommonMarkでは改行1つでは段落内でつながります。行末に空白を2つ入れるか、空行で段落を分けてください。エディター上の「改行をそのまま <br> にする」をオンにすると、改行を反映する環境での見え方を確かめられます。

入力した内容はサーバーに送られますか?

いいえ。変換はブラウザ内のスクリプトだけで行われ、入力内容は送信されません。ただし、Markdownに外部画像のURLを入れると、プレビューがその画像を読み込むためにそのサーバーへアクセスします。

MarkdownとHTMLはどちらで書くべきですか?

READMEやブログ、メモのような文章中心の文書ならMarkdownが手軽です。細かいレイアウトや色、フォームが必要ならHTMLが向いています。Markdownに少しだけHTMLを混ぜる方法もありますが、処理系が許可している場合に限られます。