ガイド · HTML → Markdown

HTML から Markdown へ

HTML は Markdown よりずっと多くを書き表せます。だからこの変換は、ほとんど「対応物がないものをどうするか」という話です。

答えはタグによって三つ。対応させる、タグだけ外して文字を残す、両方消す。どれになるかは許可リストが決めていて、そこに何が入っているかは知っておく価値があります。

変換ツールを開く

禁止リストではなく許可リスト

最初の通過で生き残るのは、Markdown で意味を持つタグだけです。見出し、段落、リスト、リンク、画像、強調、引用、コード、表、そしてその周りにある少数のインラインタグ。それ以外は文字を残してタグを消します。

許可リストにしている理由は、禁止リストは危険なタグを一つずつ言い当てなければならず、HTML には新しいタグが増え続けるからです。抜けた一項目がそのまま穴になります。だから未知のものへの既定の答えは「いいえ」です。

スクリプト、イベント属性、javascript: のリンクは消えます。script、style、iframe、object、embed は中身も一緒に消します。<script> の文字を残せば、そのコードが目に見える文章として文書に貼り込まれてしまいます。

属性も同じく許可リストで、href、src、alt、title、colspan、rowspan、start だけ。class、id、style は出力に届きません。安全のためだけでもなく、Markdown にはそれらを置く場所もありません。

何も表示しないのにサニタイズする理由

このページはあなたの HTML を一度も表示しません。だからここで実行されるものはありません。サニタイザーがあるのは、その後に起きることのためです。

[click me](javascript:alert(1)) と書かれたリンクは、どの Markdown 変換ツールもそのまま写します。そしてその Markdown を誰かが表示するサイトに公開した瞬間、動く攻撃になります。リスクは私たちのものではなく、出力を使う人に渡されます。

だから URL はプロトコルの許可リスト —— http、https、mailto、ftp、相対パス —— と照らし合わせ、それ以外は捨てます。何かを消したときは、それが何だったかを出力に書きます。黙って入力を掃除するのではなく。

表:残すか、潰すか

既定では表は Markdown のパイプ表になります。セル内の縦棒はエスケープされ、セル内の空白は単一の空白にまとめられ、短い行は一番幅の広い行に合わせて埋められて、表は長方形のままです。

潰す方は代替で、もともと表ではなかった表のためにあります。位置合わせのために表で組まれたページは、パイプ表にすると空セルだらけになります。潰せば各行が中黒でつながった 1 行のテキストになり、ずっと読みやすくなります。

どちらの道でも残らないものが二つ。<caption> は捨てられます。パイプ表に置き場がないからです。必要なら表の上の 1 行として自分で写してください。それとセル内のブロック要素は潰れます。セルの中のリストは項目がつながって出ます。パイプ表の行は 1 行でなければならないからです。

HTML
<table><tr><th>Part</th><th>Qty</th></tr>
<tr><td>Bolt | M6</td><td>12</td></tr></table>
Markdown
| Part | Qty |
| --- | --- |
| Bolt \| M6 | 12 |

HTML のまま残るタグ

上付きと下付きは <sup> と <sub> のまま残ります。Markdown に構文がなく、x² が x2 になると数式の意味が変わるからです。生の HTML は Markdown として正しく、この二つはどの表示系でも扱えます。

下線はその扱いを受けません。保つべき意味を持っていないからです。ウェブでの下線はリンクなので、残せばはっきり誤解を招きます。下線付きのテキストは普通のテキストとして出ます。

取り消し線は ~~ になります。これは元の仕様ではなく GitHub の Markdown ですが、いまでは十分に共通なので、外すほうが不自然です。

リスト、コードブロック、そして設定

リスト項目は「- item」と、空白 1 つで書きます。ほとんどの Markdown ツールチェーンがこう書きますし、よくあるもう一つの流儀 —— 記号の後に空白 3 つ —— は、両方で編集されるファイルで差分をうるさくします。

入れ子のリストは記号の幅までインデントし、リスト項目の中で続く段落は、リストから抜けるのではなく上のテキストに揃うところまでインデントします。start 属性の付いた <ol> は番号を保ちます。

行頭記号は -、*、+ から、コードフェンスは ``` か ~~~ から選べます。ファイルの行き先に合わせて選んでください。機能的な違いはありません。見出しを下線スタイルにもできますが、下線があるのは上位 2 レベルだけです。3 番目以降はどうしても # 記号のままなので、選ぶ前に知っておくとよいところです。

HTML
<ol><li><p>First para</p>
<p>Still item one</p></li></ol>
Markdown
1. First para

   Still item one

入口は二つ、道は一つ

枠に HTML を貼ってもいいし、.html ファイルを置いてもいいです。どちらも同じに扱われます。コードから見れば同じもの —— 信用できない HTML の文字列 —— だからです。

25 MB の上限は入力ごとで、どんなページのソースよりずっと大きい値です。何も送られません。解析もサニタイズも変換も、全部このタブの中で起きます。

結果が空で返ってきたら、出力がそう言います。たいていは入力がマークアップだけで文字がなかった場合です。ページの <head> だとか、スタイルだけの断片だとか。

ソースを貼るかファイルを置いて、表を表のままにするか決めて、Markdown をコピーする。全部ブラウザの中で動きます。

HTML → MD