Windows メモ帳はバージョン 11.2504.62.0 から Markdown を扱えるようになりました。
Markdown が使えるようになると気になるのは「Markdown がどのような仕様になっているのだろう」という点です。
どの記法が利用できるかは Windows のブログ や 窓の杜 を見れば明らかですが、細かな仕様に関して確認することは出来ません。
そこで本記事では、Windows メモ帳で使える Markdown の仕様がどのようなものになっているのか検証した結果を紹介します。
本記事では Windows メモ帳の書式付きモードで装飾として解釈される記法および Markdown 仕様を “Windows Notepad Markdown” と呼称します。
Windows メモ帳の対象バージョンは 11.2504.62.0 です。
また、Windows Notepad Markdown の仕様は公開されていないため、本記事には間違いが含まれている可能性があります。
使い方
Windows メモ帳では、以下 2 つの入力モードがあります。これはメモ帳下部のステータスバー 3 列目を見ることで確認できます。
- テキストモード(起動時デフォルト)
- マークダウンモード
Markdown に対応するには、[新しいマークダウン] タブ
を選択し、タブを新たに開くことでマークダウンモードに切り替えます。あるいは、フォーマットツールバーにある書式変更ボタンを利用すると自動的にマークダウンモードに移行します。
加えて、マークダウンモードでは、以下 2 つのモードがあります。
-
書式付きモード:
MS Word のように見たままに編集
-
構文モード:
Markdown 記法を用いて編集
これらのモードは [表示] タブ
> マークダウン
から変更できます。あるいは、ステータスバーの 3 列目をクリックすることでトグル変更できます。
また、.md で保存されたファイルをメモ帳で開くと、書式付きモードで開かれます。
書式付きモードでは、フォーマットツールバーに書式変更ボタンがあるため、これを使って装飾できます。あるいは、それぞれにキーボードショートカットが割り当てられています。
使える記法
Windows Notepad Markdown では、以下の記法が利用できました。
- パラグラフ
- 強調(斜体・太字) (
_italic_
,**strong**
) - HTML エンティティ参照 (
etc.) - リンク
- 行内リンク (
[text](link)
) - 参照リンク (
[text][id]
,[id]: link
) - 自動リンク (
<link>
)
- 行内リンク (
- 見出し
- ATX スタイル見出し (1~6)
- Setext スタイル見出し (1~2)
- リスト
- 箇条書きリスト (
-
,+
,*
) - 番号付きリスト (
1.
,1)
)
- 箇条書きリスト (
統一される記法
本記事では、“構文モード → 書式付きモード → 構文モード” とする操作、あるいは、“書式付きモード → 構文モード → 書式付きモード” とする操作を「モード往復」と呼称します。
Windows メモ帳では、編集を構文モードと書式付きモードの 2 つがあります。
構文モードからモード往復をすると、いくつかの記法が(勝手に)元の書き方と異なる書き方に変更されることがあります。
影響のある記法は次の通りでした。
-
強調(斜体・太字):
_
による強調 ⇒*
による強調強調に利用されない
_
・*
はエスケープされます。 -
リンク:
参照リンク、自動リンク ⇒ 行内リンク
-
特定の文字:
&
、_
、*
、\
、[
⇒\&
、\_
、\*
、\\
、\[
-
HTML エンティティ参照:
HTML エンティティ参照 ⇒ Unicode 文字(特定の文字の場合、
\
も与えられる (e.g.*
⇒\*
)) -
見出し:
Setext スタイル ⇒ ATX スタイル
ただし、以下のような Setext スタイル見出しが複数行に渡る場合、ATX スタイル見出しに変換されません。
Setext スタイル見出し =====
-
箇条書きリスト:
-
・+
⇒*
-
番号付きリスト:
1)
⇒1.
かつ連番
したがって、実際に使われる記法で重複する記法は 1 つにまとめられると考えても良さそうです。
サポートされていない構文
構文モードで文書を作成し書式付きモードに移行するとき、サポートされていない構文が存在する場合、以下のような警告画面が表示されます。
[続ける]
をクリックすると、そのままリテラルに表示されます。
この警告が表示される構文は次の通りでした。
- リンクタイトルを含むリンク
- 行内コード
- コードブロック (Indented code block, Fenced code block)
- ブロッククォート
- 画像
- テーマ区切り(
***
・- - -
は---
に統一されます) - 表
- HTML(コメントアウトも含む)
一方で、取り消し線 (~~strikethrough~~
) や絵文字 (:emoji:
) のような記法は “サポートされていない構文” として認識されません。
一部の “サポートされていない構文” はサポートされていないだけであり、Markdown としては認識されているようです。
構文の仕様
本節では CommonMark に準拠した書き方をすることを前提とし、Windows Notepad Markdown が CommonMark とどのように異なるかと言う観点から見てみます。
パラグラフ
パラグラフの仕様は CommonMark と概ね変わりませんが、半角スペース 4 つによるインデントがある場合、モード往復の際に警告が表示されます。(Indented code block と解釈されるため)
初回のモード往復では先頭の半角スペースが
になりますが、2 回目以降では半角スペースに戻ってそのまま保たれます。(内部状態が変わる?)
4 つのインデントのあるパラグラフ。
⇓
4 つのインデントのあるパラグラフ。
半角スペース 3 つ以下のインデントではそのまま保持されます。
一方で、タブストップによるインデントの場合では、モード往復でタブストップが削除されます。
パラグラフが複数行に渡る場合、いずれの行がインデントされていてもモード往復に伴ってインデントは削除されます。
寿限無、寿限無
五劫の擦り切れ
海砂利水魚の
水行末 雲来末 風来末
⇓
寿限無、寿限無
五劫の擦り切れ
海砂利水魚の
水行末 雲来末 風来末
パラグラフ中の連続する 2 つ以上の半角スペースはそのまま保持されます。
(実際、CommonMark であっても連続する 2 つ以上の半角スペースは保持されますが、多くの場合 CSS (white-space
) が連続する半角スペースを統合するように構成してあるため、この場合では結果として 1 つになります。)
パラグラフを分離するには 1 行以上の空白行を挟みますが、構文モードに複数の空白行がある場合、書式付きモードであっても空白行の数がそのまま反映されます。
Windows Notepad Markdown では改行が強制改行として解釈されるため、改行が保たれます。
一方で、強制改行の記法はありません。
強調
CommonMark と同様に強調される文字の両端いずれかに約物等がある場合、強調として認識されません。
このように**「括弧」**に接した強調は強調として認識されない
そのため、モード往復すると次のようになります。
このように\*\*「括弧」\*\*に接した強調は強調として認識されない
一方でこの仕様は CommonMark 0.30 に準拠しているようです。(0.31.2 では☆
や →
を含む Symbol も約物等と同じ対象になっています)
そのため、次のような文章は強調として解釈されます。
**らき☆**すた
<!-- CommonMark 0.31.2 以降では強調として認識されない -->
ちなみに、書式付きモードでは 「強調」
を選択して太字を選択して装飾すると強調されます。しかし、モード往復すると上記の理由から強調されなくなります。
リンク
Windows Notepad Markdown のリンクは以下の 3 つの記法に対応します。
- 行内リンク:
[Example Domain](https://www.example.com)
- 参照リンク:
[Example Domain][id], [id][], [ID] [id]: https://www.example.com
- 自動リンク:
<https://www.example.com>
ただし、モード往復をするとすべて行内リンクになります。
この影響で、参照されていないリンク参照定義はモード往復によって削除されます。
[参照されていないリンク]: https://www.example.com
<!-- これは消える -->
例外として、リンク内に半角スペースが含まれる場合、(脚注と見なされるのか)先頭の [
が \[
となりリンク参照定義がそのまま残されます。
リンクにリンクタイトルを含めることは出来ません。モード往復するとリンクタイトルが削除されます。
[text](https://www.example.com "Example Domain")
<!-- 〈"Example Domain"〉 は含められない -->
行内リンクと参照リンクはリンクアドレス全体を <>
で囲っても問題ありませんが、書式付きモードでは無視されます。
そのため、次のような半角スペースを含むリンクをモード往復すると、リンクとして機能しなくなります。(対策として、半角スペースは %20
として URL エンコードしてください)
[link](</my uri>)
⇓
\[link](/my uri)
CommonMark と同様に、強調とリンクを組み合わせた場合、リンクの方が強力です。そのため、次のような例では強調は無視されます。(強調の *
はエスケープされる)
*[Example Domain*](https://www.example.com)
一方で、リンクテキスト全体を強調する場合、以下のようにリンク全体を強調することも出来ますが、モード往復をするとリンクテキストのみの強調に変更されます。
**[Example Domain](https://www.example.com)**
⇓
[**Example Domain**](https://www.example.com)
リンク内にリンクがある場合、CommonMark と同様に内側のリンクが優先されます。
[Example Domain [Qiita](https://qiita.com)](https://www.example.com)
⇓
\[Example Domain [Qiita](https://qiita.com)](https://www.example.com)
しかし、自動リンクがリンクテキストに入っている場合、CommonMark と異なる結果を得ます。
[<https://qiita.com>](https://www.example.com)
CommonMark では以下の記事の通り、内側の自動リンクが優先されます。
しかし、Windows Notepad Markdown では行内リンクが優先されます。そのため、次のような結果を得ます。
[<https://qiita.com>](https://www.example.com)
⇓
[https://qiita.com](https://www.example.com)
リンクの含まれる文章の全体を強調する場合、モード往復に伴って複雑な強調に変換されます。
**これは[リンク](/link)です。**
⇓
**これは**[**リンク**](/link)**です。**
見出し
CommonMark と同様に、ATX スタイルでは見出しレベル 1~6、Setext スタイルでは見出しレベル 1~2 です。
ATX スタイル見出しは #
を 7 つ使用した場合、モード往復によって先頭の #
に \
が追加されます。
ATX スタイル見出しの見出しインデントや Setext スタイル見出しの見出しテキストのインデントはモード往復で削除されます。
## ATX headings
<!-- “##” と “Heading” の間のインデントは削除される -->
Setext
headings
===
<!-- インデントが削除される -->
ATX スタイル見出しでは、見出しの右側に装飾用の #
を配置することが可能です。これはモード往復で削除されます。
### ATX heading ###
<!-- 最右の ### は削除される -->
ただし、装飾用の #
の右側に #
以外の文字がある場合、そのまま残されます。
見出しのネスト
見出し内にリストをネストする場合、CommonMark と同様にリストとは認識されずにリテラルに表示されますが、Windows Notepad Markdown では \
でエスケープされた形で返ってきます。
# - list
# * list
# + list
# 1. list
# 1) list
⇓
# \- list
# \* list
# \+ list
# 1\. list
# 1\) list
リスト
箇条書きリスト
箇条書きリストは -
、+
、*
のいずれもリストとして解釈されますが、これらに区別はありません。
すなわち、次のように書いたとしても 1 つのリストとして解釈されます。
- 項目
+ 項目
* 項目
上のリストはモード往復によって次のようなリストになります。
* 項目
* 項目
* 項目
加えて、ルーズなリストはモード往復に伴ってタイトなリストに変換されます。
番号付きリスト
番号付きリストは 1.
、1)
のいずれもリストとして解釈されます。しかし、これらに区別はありません。
すなわち、次のように書いたとしても 1 つのリストとして解釈されます。
1. 項目 1
1) 項目 2
上のリストはモード往復によって次のようなリストになります。
1. 項目 1
2. 項目 2
加えて、ルーズなリストはモード往復に伴ってタイトなリストに変換されます。
リストの番号が途中から始まる場合、書式付きモードにでも途中からになります。(0.
から始まっても同様です)
3. 項目 3
3. 項目 4
3. 項目 5
この番号付けは 003.
のように 00
から始まっても問題ありません。ただし、モード往復に伴って 00
は削除されます。
番号は 32768.
($2^{15}$) 以上から始まる場合、リストは上手く機能しません。もしも、32768.
以上から始まる番号付けリストを作成すると、モード往復に伴ってクラッシュします。(当該リストを削除すればクラッシュは解消されます)
32768. 項目 32768
32768. 項目 32769
32768. 項目 32770
加えて、65536.
($2^{16}$) を超えるとモード往復に伴って $0$ にループ ($2^{16}\to0$) します。
そのため 98304.
($2^{16}+2^{15}$) の場合、モード往復によって 32768.
($2^{15}$) となるため、2 度目以降のモード往復でクラッシュします。
リストのネスト
箇条書きリスト・番号付きリストともに、ネストのためのインデントは CommonMark と変わりません。
一方で、モード往復すると箇条書きリストでのネストのインデントは半角スペース 2 つ、番号付きリストでのネストのインデントは半角スペース 3 つに変換されます。
加えて、ルーズなリストに変換されます。
リスト内にネストする方法は構文モードでのみ再現できます。
書式付きモードの罠
書式付きモードではきちんと書式を指定できているにも拘わらず、構文モードではダメなパターンがいくつかありました。
もしもこのダメパターンでファイルを作成し、モード往復や .md で保存して次回 Windows メモ帳で開いた場合、作成した書式が壊れてしまいます。
確認されいているダメパターンは以下の通りでした。
-
約物と内側で接する強調(e.g.
「括弧全体の強調」
) -
アドレス内に半角スペースを含むリンク (e.g.
[text](link address)
) -
サポートされていない構文に含まれる
&
等の\
が追加される特定の文字 (e.g.`*`
,> &
)
書式付きモードのみで Markdown を扱う人の場合は注意が必要です。
余談
Windows メモ帳を Markdown のプレビュー代わりとして書式付きモードを利用すると、構文モードで作成した状態から一部が改変されたり削除されるため、直感的ではない部分があり非常に厄介です。
このような指摘は以下の記事でもクリティカルな問題として言及されています。
個人的に Windows メモ帳で Markdown を利用することはないと思いますが、「Markdown をまだ使ったことがないよ!」という層には良いかもしれません。
私のように Windows メモ帳で Markdown を使用しない場合は、 ウィンドウ右上の の設定から
[書式設定]
をオフにすると、Markdown の機能が利用できなくなります。
番外編
サポートされていない構文は Windows Notepad Markdown でサポートされていませんが、リテラルとして認識していないがために、弊害をもたらしたり隠れた仕様を感じさせたりすることがあるようです。
行内コード
Windows Notepad Markdown における `
の扱いはかなり面倒です。
まず、\
によるエスケープができません。\`
とした場合でもモード往復に伴って \
が奪われます。
そのため、以下のように \`
で囲った文章があった場合、1 度目のモード往復で \
が削除され、2 度目のモード往復で警告ウィンドウが表示されるようになります。
\`ここはコードではない\`
1 文に `
が複数回登場する場合は注意が必要です。
複数行に渡る行内コードもサポートされていない構文として認識されます。そのため、次のような例ではモード往復によって大幅な書き換えが行われます。
`foo
baz`
``
foo
baz
``
⇓
`foo baz`
`foo baz`
Indented code block
Indented code block は半角スペース 4 つまたはタブストップでインデントすることでコードブロックとする記法です。(Windows Notepad Markdown ではタブストップによる Indented code block の表現はできません)
Windows Notepad Markdown では利用できませんが、複数回のモード往復によって、Indented code block に相当する部分の “状態” を変化させます。
パラグラフを半角スペース 4 つでインデントした場合、モード往復に伴って 1 度目は警告ウィンドウが表示された上で行頭の半角スペースが
になりますが、2 度目以降では警告ウィンドウは表示されず半角スペースのままになります。(“状態” が変わらないのであれば、
と半角スペースとが交互に現れるべき)
また、ATX スタイル見出しを半角スペース 4 つでインデントした場合、パラグラフと同様に 2 度目以降のモード往復では半角スペースによるインデントのままになります。
この状態でインデントの数を減らしたとき、通常であれば見出しとして認識されインデントが削除されますが、見出しとして認識されずにインデントが残り続けます。(何らかの “状態” が変わったと見る方が自然だと思います)
この現象はリストでは発生しません。
ブロッククォート
Windows Notepad Markdown では、サポートされていない構文内の特定の文字はモード往復に伴って \
が追加されます。加えて、繰り返しモード往復を行うと、\
が増えます。
すなわち、ブロッククォート内で &
等の特定の文字を利用すると \
がモード往復の回数に応じて増えます。この性質を利用すれば、ブロッククォートに lazy 性があるかを判定できます。
lazy 性とは、以下のようにブロッククォートがどこまで続くかを決める性質です。
> ここはブロッククォートの中です。
先頭に `>` が無くても、
ここもブロッククォートの中です。
ここはブロッククォートの外です。
これらを踏まえて、特定の文字を含むブロッククォートのある文章を 2 回モード往復させてみた結果は次のようになりました。
> &&&
&&&
&&&
&&&
⇓⇓
> \\\&\\\&\\\&
\\\&\\\&\\\&
\\\&\\\&\\\&
\&\&\&
したがって、2 行目、3 行目の &
の \
が増えているため、この部分もブロッククォートとなっていることが分かりました。
すなわち、Windows Notepad Markdown のブロッククォートには lazy 性があります。