「Markdown で書いたのに、環境によって表示が変わる」——その原因の多くは、Markdown に"方言"がいくつも存在することにあります。
この記事では、Markdown の歴史的な出発点であるオリジナル Markdownから、事実上の標準仕様である CommonMark、GitHub の GFM、GitLab の GLFM までを、それぞれの関係と違いが分かるように整理します。
そもそも Markdown には「正式な仕様」がなかった
Markdown は 2004 年、John Gruber(ブログ Daring Fireball の著者)が Aaron Swartz の協力を得て作りました。しかし、その定義は散文的な説明と Perl スクリプト 1 本(Markdown.pl)だけでした。
このため、「強調の中に強調を入れたら?」「リストのインデントが半端なときは?」といった細かいケースの挙動が曖昧で、実装するツールごとに解釈が割れてしまいました。同じ Markdown が、環境によって違う HTML になる——この問題を解決するために、後から厳密な共通仕様が作られていきます。
その流れが、次の 4 層です。
オリジナル Markdown(2004・Gruber)… 元祖。基本を定めたが曖昧さが残る
│ 曖昧さを排除し、厳密なテスト付き仕様に
▼
CommonMark … 厳密な共通仕様(基本記法のみ)
│ 表・打ち消し線などの実用拡張を追加
▼
GFM(GitHub Flavored Markdown)… CommonMark + GitHub の拡張
│ さらに GitLab 独自の拡張を追加
▼
GLFM(GitLab Flavored Markdown)… GFM + GitLab の拡張
順番に見ていきましょう。
1. オリジナル Markdown(元祖)
すべての出発点。Gruber が定めた基本的な考え方と記法です。見出し・段落・強調・リスト・リンク・引用・コードといった、いま私たちが使う Markdown の骨格は、ここでほぼ出そろっています。
ただし、曖昧さと独自のクセが残っています。たとえば:
- 見出しの
#の直後にスペースが必須とは書かれていない(#見出しも当時は見出し扱い)。 - 水平線の公式例が
* * *(スペース入り)で、_(アンダースコア)でも引ける。 - 強調のネスト(
***太字斜体***のような重なり)を明確に定義していない。 - 一方で、
<や&を自動でエスケープしてくれる(AT&T→AT&T)など、気の利いた独自機能もある。
「元祖ゆえの緩さ」があり、これが後の厳密化を必要とした理由でもあります。
公式ドキュメント:Daring Fireball の Markdown Syntax が、いまもオリジナルの一次資料です。
2. CommonMark(厳密な共通仕様)
オリジナルの曖昧さをなくすために、John MacFarlane らが中心となって作った厳密な共通仕様が CommonMark です。
CommonMark の狙いは明快で、「同じ Markdown は、どの実装でも同じ HTML になる」を保証すること。そのために、エッジケース(強調の重なり、リストの詰まり/緩み、HTML の混在など)まで細かく定義し、公式のテストケース群を用意しました。
いまや多くの Markdown パーサーが CommonMark に準拠しており、Markdown の"共通の土台"と言える存在です。
- 見出し(
#、および下線形式) - 段落・改行
- 強調(
*_/**__) - リスト(
-+*/1.) - コード(インライン・コードブロック)
- 引用(
>) - リンク・画像
- 水平線
- HTML の直接埋め込み
- エスケープ(
\)
ここで押さえておきたいのは、CommonMark には「表(テーブル)」が含まれないということ。表・打ち消し線・タスクリストといった"実務で欲しい記法"は、CommonMark の外側=拡張の領域なのです。そこを埋めたのが、次の GFM です。
公式:CommonMark / 仕様書。dingus というオンライン確認ツールで、「この記法は CommonMark だとどうなるか」をその場で試せます。
3. GFM(GitHub Flavored Markdown)
CommonMark を土台に、GitHub が実用的な拡張を足したものが GFM です。「Flavored(風味)」=方言・拡張版、という意味合いです。
GFM は CommonMark 準拠 + 以下の拡張という構成になっています。
| 拡張 | 記法 |
|---|---|
| テーブル | \| A \| B \| のパイプ記法 |
| 打ち消し線 | ~~text~~ |
| タスクリスト | - [ ] / - [x] |
| 自動リンク | https://… を書くだけでリンク化 |
Zenn・Qiita・GitHub をはじめ、多くのブログや投稿サービスは実質 GFM(相当)で動いています。私たちが普段「Markdown」と呼んで書いているものは、たいてい GFM だと考えて差し支えありません。
GFM のテーブルで注意したいこと
GFM のテーブルは、ヘッダ行のすぐ下に「区切り行(| --- |)」が必須です。これがないと、テーブルとして認識されず、ただの段落になってしまいます。
区切り行あり(正しく表になる):
| 列1 | 列2 |
| --- | --- |
| a | b |
区切り行なし(表にならない):
| 列1 | 列2 |
| a | b |
「表を書いたのに崩れる」ときは、まずこの区切り行を疑うと解決が早いです。
4. GLFM(GitLab Flavored Markdown)
GLFM は、GFM をさらに拡張した GitLab 版です。関係を式にすると、こうなります。
GLFM = CommonMark(土台) + GFM の拡張 + GitLab 独自の拡張
つまり GFM とほとんど同じで、表・タスクリスト・打ち消し線・自動リンクなどはそのまま使えます。GFM で書いたものは、基本的に GitLab でもそのまま通用すると考えてよいです。
そのうえで、GLFM には GitLab 環境と結びついた独自拡張が上乗せされています。代表的なものは:
- Issue / Merge Request の相互参照(
#123や!456で該当ページへのリンクになる) - 色チップ(
のように HEX / RGB / HSL を書くと色見本が表示される)#FF0000 - 数式(数式記法に対応)
- 複数行の引用、折りたたみセクション
- 説明リスト(定義リスト)、絵文字、図表・フローチャート など
GitLab 自身も「GLFM は CommonMark を核に、GFM の拡張と GitLab 独自の拡張を加えたもの」と説明しています。なお、呼称は GitLab 14.10 で "GFM" から "GLFM" に変更されました(それ以前は GitLab 内でも "GFM" と呼ばれていた名残があります)。
GLFM の位置づけ
GLFM 独自の拡張(Issue 参照・色チップなど)は、当然ながらGitLab の中でしか意味を持ちません。GitLab 外に持ち出すと、これらは単なる文字列として残ります。逆に言えば、「GitLab 独自機能を使わない限り、GLFM ≒ GFM」という理解で実用上は十分です。
4者の関係を一枚で
| 規格 | 位置づけ | 表 | 独自の特徴 | 主な場所 |
|---|---|---|---|---|
| オリジナル Markdown | 元祖(曖昧さあり) | ✗ | </& 自動エスケープなど |
Daring Fireball |
| CommonMark | 厳密な共通仕様(土台) | ✗ | エッジケースまで規定・テスト有 | 多くのパーサーの基準 |
| GFM | CommonMark + GitHub 拡張 | ✓ | 表・打消し・タスク・自動リンク | GitHub / Zenn / Qiita ほか |
| GLFM | GFM + GitLab 拡張 | ✓ | Issue 参照・色チップ・数式ほか | GitLab |
どの規格でも共通して効くのが HTML の直接記述です。CommonMark 系は HTML をそのまま通すため、<sup> <mark> <img width="..."> のように記法で表現しきれないものは HTML で書くと、環境差に強くなります(ただし GitHub などは一部タグ・属性をサニタイズする点に注意)。
まとめ
- Markdown には正式仕様がなく、オリジナル → CommonMark → GFM → GLFM という順で厳密化・拡張されてきた。
- CommonMark は基本記法だけの厳密な"土台"。表は含まれない。
- GFM は CommonMark に表・打ち消し線・タスクリストなどを足した実用版。多くの投稿先が実質これ。
- GLFM は GFM に GitLab 独自機能を足したもの。GFM とほぼ同じで、独自機能を使うときだけ意識すればよい。
- 迷ったら GFM を基準にし、表現しきれないものは HTML を直接書くのが安全。
Markdown の"方言"の地図が頭に入っていれば、原因を切り分けやすくなります。まずは自分の投稿先がどの規格に近いかを把握しておくとよいでしょう。