Markdown と HTML を相互変換するときの注意点(GFM、サニタイズ、属性保持)
「Markdown で書いてブログ HTML を生成」「既存の HTML 記事を Markdown 化したい」など、Markdown と HTML の相互変換は日常的に発生します。両方向の変換で気をつけるべき点を整理します。
Markdown → HTML:基本は loseless でない
Markdown を HTML に変換すると、Markdown では表現できない HTML 機能が落ちる可能性があります。逆に、Markdown の構文ルールが厳しいツールでは、エッジケースの HTML が想定通りにならないこともあります。
1. 改行の扱い
1 行目
2 行目 - CommonMark:
<p>1 行目\n2 行目</p>(改行は単なる空白として扱われる) - GFM(GitHub Flavored Markdown):オプションで
<p>1 行目<br>2 行目</p>のように<br>に変換
意図的に改行を強制したい場合は 行末に半角スペース 2 つ か <br> を直接書く。
2. テーブル(GFM 専用)
| 列 1 | 列 2 |
| ---- | ---- |
| a | b | CommonMark の純粋仕様にはテーブル記法がなく、GFM 等の拡張機能を有効にしないと変換されません。レンダラーが GFM 互換かを確認する必要があります。
3. 生 HTML の埋め込み
Markdown 内に HTML を直接書けます:
これは **太字** で <span style="color: red">赤字</span> - 多くのツール:
<span>タグはそのまま HTML 出力に含まれる - サニタイズが厳しいツール(CMS の投稿欄など):HTML タグを削除またはエスケープする
- 静的サイトジェネレータ:通常はそのまま通す
4. リンクの自動化
https://example.com ← GFM では自動でリンクに
[テキスト](https://example.com) ← 明示的なリンク GFM は素の URL を <a href="..."> に変換しますが、CommonMark では文字列のまま扱われます。
5. 数式・図(拡張依存)
LaTeX 数式($E = mc^2$)や Mermaid 図はそれぞれ拡張機能で、レンダラー(GitHub、Notion、独自サイト)が対応しているかで結果が変わります。
HTML → Markdown:情報量が減る
逆方向はより多くの情報が失われます。HTML は Markdown より表現力があるため:
1. 復元できない要素
| HTML | Markdown |
|---|---|
<style> のインライン CSS | 表現不可 |
<script> | 表現不可 |
<iframe> | 通常は表現不可(埋め込みショートコード経由) |
<form> | 表現不可 |
| クラス名・ID | 表現不可(一部のツールが拡張で対応) |
<table> の colspan rowspan | GFM テーブルでは表現不可 |
2. 部分的に保持される
| HTML | Markdown 変換後 |
|---|---|
<strong> <b> | **太字** |
<em> <i> | *斜体* |
<a href="..."> | [テキスト](URL) |
<img src="..."> |  |
<code> | `code` |
<pre><code> | フェンスコードブロック |
<ul> <ol> | - 1. |
<blockquote> | > |
<h1>〜<h6> | # 〜 ###### |
3. 完全に失われる属性
リンクの target="_blank" や、画像の width height はほとんどの Markdown 変換ツールで失われます。必要なら HTML を残すしかない。
サニタイズ:信頼できない Markdown の扱い
ユーザー投稿可能なシステムで Markdown を受け取る場合、生 HTML 埋め込みが許されていると XSS の危険があります:
これは <script>alert('XSS')</script> 攻撃 対策:
- サニタイザを必ず通す(DOMPurify、sanitize-html など)
- 生 HTML を禁止する Markdown レンダラーを選ぶ(marked の
mangle: true等) - 画像 URL をホワイトリスト化(
data:を許すと SVG XSS の可能性) - リンクは
noopener noreferrerを自動付与する
GitHub、Reddit、Stack Overflow 等の多くのサービスはサーバー側でサニタイズしてから保存しています。
ツールごとの動作差
| ツール | GFM 対応 | 生 HTML | サニタイズ | 数式 |
|---|---|---|---|---|
| GitHub | ✅ | △(一部 OK) | 内部で実施 | KaTeX 対応 |
| Notion | ✅ | × | 自動 | LaTeX 対応 |
| Obsidian | ✅ | ✅ | しない(ローカル前提) | KaTeX |
| Hugo / Jekyll | ✅ | ✅ | デフォルトしない | プラグイン |
| marked.js | ✅ | 設定次第 | 別途 | 別途 |
| markdown-it | ✅ | 設定次第 | 別途 | プラグイン |
実用上の判断軸
Markdown → HTML
- 「書きやすい原稿」が目的なら Markdown が圧倒的に楽
- 「ピクセル単位のコントロール」が必要なら最初から HTML
HTML → Markdown
- ブログ移行(WordPress → Hugo など)で頻繁に発生
- 完全自動化は不可、最終的に手動チェック必要
turndownなどのライブラリで概ね 80% は自動化可能
まとめ
- Markdown と HTML は情報量に非対称性がある(HTML が広い)
- GFM 拡張対応の有無で変換結果が変わる
- 信頼できない Markdown は必ずサニタイズ
- HTML → Markdown は情報損失が前提、自動化 + 手動補正
Markdown を HTML に、または HTML を Markdown に変換したい場面では、本サイトの Markdown ↔ HTML 変換ツールが使えます。GFM 拡張に対応し、ブラウザ内で完結するため、社内コンテンツでも安心して試せます。