Chienomi

Markdownのリストマーカーはハイフンよりアスタリスクのほうがむしろcanonical

文化::programming

序

Markdownにおける順序なしリスト(ul)のリストマーカーとして*ではなく-を使うのが正しい、と強硬に主張されることが増えてきた。

しかし、別に-を使うのが正しいわけではないということにとどまらず、そもそもどちらかというと*のほうがMarkdown的にはcanonicalである。

-を愛好するのは主にGitHub内の一部文化圏によるところで、一部のlinterがそれをあたかも「正しいこと」であるかのように主張していることでそれを「正しいこと」だと信じ込んだ人が侵略的に-以外を使用する者を攻撃している、というのが実情。

Markdown的にはどちらかというとアスタリスク寄り

最初期のMarkdownではリストマーカーは*のみがサポートされていた。

Markdown 1.0時点では「選択できるように」と*, -, +がサポートされている。1 2

ちなみに、そもそも選択可能にしたかったらしいので、本当にどちらかといえばである。それでも-が唯一絶対の正当なのだと言われたら何を言ってるんだになる部分ではある。

Markdown風syntaxもアスタリスクのほうが主流

Slackは*をリストとして認識する。

Mattermostは結構ちゃんとMarkdownを理解するのでどれでも認識される。

Google Documentは*はbullet listとして認識されるが、-はリスト風の取り扱いになるだけである。

Wordは*も-もbullet listとして認識されるが、公式には*を案内している。3 4

Markdownではないが、reStructuredTextはリストは*, +, -, •, ‣, ⁃である。5

逆に-のみをサポートするものとしてはtag2textがある。

おまけ: インデント

「リストのインデントはスペース2個」という指定をするlinterがいたりするのだが、「リストならなんでも2スペース固定」という仕様ではない。

Markdown.pl

Markdownの仕様を要約すると

  • リストマーカーの前には最大3スペースまで置ける。
  • リストマーカーの後には1個以上のスペース、またはタブが必要。
  • リスト項目内の2段落目以降は、4スペースまたは1タブでインデントする。
  • リスト内のコードブロックは、8スペースまたは2タブでインデントする。

ちなみにこの仕様のためリストの中に段落があるとき

*   abc

    def

ともかけるけど、リストマーカーの後ろに求められるスペースは1+、対して後続段落は4なので

* abc

    def

という気持ち悪いことになったりする。

そして、オリジナルMarkdownはネストについての仕様の言及がない。

CommonMark

CommonMarkの仕様としては頭が揃うようなインデントを要求している。つまりバレットリストの場合

* a
* b
  * c
    * d

と2個以上のスペースとなるのだけど、番号付きリストだと

1. a
2. b
   3. c
      4. d

となり、3個以上のスペースが必要となる。

これはGFMでも継承されている仕様。

Markdownlint

まずmarkdownlintのindentは順序付きリストに適用されないので、indent: 2の状態でも順序付きリストで3個以上(2桁になれば4個以上)のスペースを入れることができる。

さらに、順序付きリストの子も無視されるので問題ない。

ところが問題になるのがミックスしたとき。

* a
  1. b
     - c
       - d
  2. e
     1. f
        - g

これだとdとgが同一階層なのにインデントが異なることになるため、MD005のほうが問題になる。

で、この問題を踏まえてRuby版markdownlintはMD007のデフォルトルールが3。

ただこれなら解決するかというと、インデックスが2桁になると4個のスペースが必要になるので、実は限定的な解決策だったりする。

対して、JavaScript版はMD005が違う親を持つリストアイテムの高さを揃えるところまでは要求しないようだ。 Rubyはソースコードを見る限り

indent_levels = {}
bullets.each do |b|
  indent_level = doc.indent_for(doc.element_line(b))
  list_type = b[].type
  key = [b[], list_type]
  indent_levels[key] = indent_level if indent_levels[key].nil?
  errors << doc.element_linenumber(b) if indent_level != indent_levels[key]
end

違反になる。

私が言いたいのは

間違っているわけでもない人のスタイルに文句をつけるんじゃない。


  1. Unordered list items can now be denoted by any of the following bullet markers: [*+-].

    ↩︎
  2. 1.0.1のリリースノートに

    Added >, +, and - to the list of backslash-escapable characters. These should have been done when these characters were added as unordered list item markers.

    という記載もある。↩︎

  3. To start a numbered list, type 1, a period (.), a space, and some text. Word will automatically start a numbered list for you. Type * and a space before your text, and Word will make a bulleted list.

    To complete your list, press Enter until the bullets or numbering switch off.

    (2026-10-27閲覧)↩︎

  4. 実際は *, -, --, >, ->, => が使える。そしてWordの場合、Markdown風というか、Markdown以前からある仕様であるらしい。↩︎

  5. Sphinxのドキュメントではアスタリスクが唯一みたいに書いているが、Docutilsのドキュメントでは例に出ているのも先頭に書かれているのもハイフンで、どちらかというとハイフン推しでも別のドキュメントで先頭にあるのはアスタリスク。ただし例ではハイフン↩︎