Markdown と HTML を相互変換するときの注意点(GFM、サニタイズ、属性保持)

約7分

「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. 復元できない要素

HTMLMarkdown
<style> のインライン CSS表現不可
<script>表現不可
<iframe>通常は表現不可(埋め込みショートコード経由)
<form>表現不可
クラス名・ID表現不可(一部のツールが拡張で対応)
<table>colspan rowspanGFM テーブルでは表現不可

2. 部分的に保持される

HTMLMarkdown 変換後
<strong> <b>**太字**
<em> <i>*斜体*
<a href="...">[テキスト](URL)
<img src="...">![alt](URL)
<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 拡張に対応し、ブラウザ内で完結するため、社内コンテンツでも安心して試せます。