Slack のメッセージ記法と Markdown を比較してみる

少し前に Slack の UI が変更され、ビジュアルエディタになりましたね。ビジュアルエディタが出てくるのは一般ユーザーが増えてきた証左ではないかと思うものの、テキストマークアップに慣れ親しんだ身にはあまり便利ではないですし、仕上がってきたエディタの完成度を見てウッとなった人も少なくはないでしょう。
さて、そんな変化の中で、qiita だったか twitter だかで「**Slack の Markdown**」という表記を目にする機会がありました。Markdown の仕様を調べているものとしては、Slack の記法と Markdown は似てはいるが異なるものとコメントせざるを得ないのですが、一方で似ているという感覚には首肯せざるを得ないものがあります。
その違和感について整理してみたいと思います。

## Slack の記法を見てみる

まずは Slack のマニュアルを見てみましょう。[メッセージの書式設定](https://slack.com/intl/ja-jp/help/articles/202288908) というページに内容がまとまっています。

このページでは以下の 8種類の記法が紹介されています。

* 太文字 (`*対象のテキスト*`)
* 斜体 (`_対象のテキスト_`)
* 取り消し線 (`~対象のテキスト~`)
* インラインコード (``` `対象のテキスト` ```)
* コードブロック

  ~~~
    ```
    対象のテキスト
    ```
  ~~~

* 引用タグ (`>対象のテキスト`)
* 順序付きリスト (`1. 対象のテキスト`)
* 箇条書き (`* 対象のテキスト`)

ここで紹介されている他にも、以下のような記法が確認されています。

* 絵文字 (`:+1:`)
* 引用ブロック (`>>>`)
* カラーコード (`#ffffff`)
* メンション (`@tk0miya`)
* チャンネル (`#random`)

こうして並べてみると、結構いろんな要素が存在しますね。

## Slack の書式設定と Markdown を比較する。

さて、これらの要素を Markdown と比較してみましょう。
比較対象には[オリジナルの Markdown](https://daringfireball.net/projects/markdown/)を用いますが、備考として拡張 Markdown 記法でのサポート状況に触れます。

||Slack|Markdown|備考|
|:--|:--|:--|:--|
|太文字|`*対象のテキスト*`|`**対象のテキスト**` もしくは `__対象のテキスト__`|Markdown では太文字そのものを表す記法は存在しません。慣習的により強い強調(strong)が太字としてレンダリングされるため、これが利用されます。また、Markdown では記号を入れ替えることで `*` 自体を太字にできますが、Slack では太字にできないようです。|
|斜体|`_対象のテキスト_`|`*対象のテキスト*` もしくは `_対象のテキスト_`|Markdown では斜体そのものを表す記法は存在しません。慣習的に強調(emphasis)が斜体としてレンダリングされるため、これが利用されます。また、Markdown では記号を入れ替えることで `_` 自体を斜体にできますが、Slack では斜体にできないようです。
|取り消し線|`~対象のテキスト~`|なし|一部の拡張 Markdown ではサポートされています。たとえば、[GFM では](https://github.github.com/gfm/#strikethrough-extension-) `~対象のテキスト~` 、[Pandoc では](https://pandoc.org/MANUAL.html#strikeout) `~~対象のテキスト~~` と表現します。|
|インラインコード|``` `対象のテキスト` ```|``` `対象のテキスト` ```||
|コードブロック|(略)|インデントで表現|よく使われているバッククォート 3つによるコードブロックは、オリジナルの Markdown ではサポートされていません。PHP Markdown Extra や GFM などの拡張 Markdown では、バッククォート 3つもしくはチルダ 3つでテキストを囲って表現します。また、先頭行に言語などのメタデータを記述できます。|
|引用タグ|`>対象のテキスト`|`>対象のテキスト`||
|順序付きリスト|`1. 対象のテキスト`|`1. 対象のテキスト`|Markdown 処理系によっては `1.` の他にも `1)` もサポートしています。なお、Slack ではネストしたリストは扱えません。また、Slack では 1 から始まるリストだけが順序付きリストとみなされます。|
|箇条書き|`* 対象のテキスト`|`* 対象のテキスト`, `+ 対象のテキスト`, `- 対象のテキスト`|Markdown では、箇条書きに 3種類の記号が使えます。なお、Slack ではネストしたリストは扱えません。|
|絵文字|`:+1:`|なし|GFM では `:+1:` が使えます。Slack ではカスタム絵文字が設定可能です。|
|引用ブロック|`>>>`|なし||
|カラーコード|`#ffffff`|なし|Qiita では `#ffffff` が使えます。|
|メンション|`@tk0miya`|なし|GFM や Qiita では `@tk0miya` が使えます。|
|チャンネル|`#random`|なし|GFM ではイシューの参照に `#1234` が使えます。|

こうして比較してみるとオリジナルの Markdown との共通項はあまり多くないようです。
おおよそ同等なものはインラインコード、引用タグ、順序付きリスト、箇条書きの 4つです [^1]。
太文字、斜体については、利用している記号は同じであるものの解釈が大きく変わっています。
メンションやチャンネルなどといった要素はコミュニケーションチャンネルである Slack ならではの記法ですので、Markdown と乖離があるのは致し方ない部分だとは思いますが、それ以外の要素は Markdown と似ているとは言いづらい結果です。

[^1]: ここでは Slack で記述したものを Markdown 処理系で扱えるものを同等としています。その逆は成り立たないものもあります。

## Markdown っぽさとはなにか

さて、それでは我々はなぜ Slack の記法が Markdown と似ていると感じるのでしょう。その答えは先程の表の備考欄にあります。

読み返してみると、登場する各記法は拡張 Markdown のひとつである GFM (GitHub Flavored Markdown)と非常によく似ています。
同等の要素を見ていくと、太文字、斜体、取り消し線、インラインコード、コードブロック、引用タグ、順序付きリスト、箇条書き、絵文字、メンションの各要素が Slack と GFM 共通で表現できます。
差異があるのは太文字、斜体、引用ブロック、カラーコード、チャンネルの 5種類だけです [^2]。

[^2]: ここで取り上げたもののほかにも、行末の解釈が Hardline break であることや、ブロックの切れ目に改行を必要とすることなど、GFM との類似点はいくつも見つかります。

つまり、Slack 記法は GFM のサブセットに機能を追加したものといっても、大きく外していることはなさそうです。

## まとめ

Slack の Markdown という表現は不正確だということがわかりました。
みなさん、Slack の GFM と呼ぶことにしましょう。

## 余談

このツイートがきっかけで書き始めました。

<blockquote class="twitter-tweet"><a href="https://twitter.com/tk0miya/status/1199188710178189318"/></blockquote>
<blockquote class="twitter-tweet"><a href="https://twitter.com/tk0miya/status/1199189024436449280"/></blockquote>

チャットツールである Slack がフルセットの Markdown の記法をサポートするのはやりすぎですし、サブセットとして実装されているのは当然だとさえ思うのですが、果たしてどこまで要素を削っても Markdown であると認識されるのかは興味深いところです。

それを知るには個々の「Markdown とはなにか」という認識を調べていく必要がありそうです。Markdown は多くの処理系を持ち、発展の中で多くの派生言語を生んだ巨大なキメラです。統一された仕様は存在しませんし、処理系によって実装が異なる状態も続いています [^3] 。しかし、現在では GitHub が広く使われるようになったため、GFM が Markdown のベースラインとして認識されているのではないかとも考えられます。調査はしていませんが、コードブロック(より正確には Fenced Code Block)は、オリジナルの Markdown には含まれないにも関わらず Markdown の要素として広く認知されているような気がします (要出典)。

[^3]: Markdown 界の混乱を収束させるべく登場した CommonMark も正式リリースには至っていませんし、拡張文法については基本的にノータッチの姿勢を貫いています。そのため、Markdown の亜種が乱立する状況は解決していません。上の表でも取り消し線の記法が GFM と Pandoc で異なっていますね…。

Markdown っぽさに関して、個人的な予想としては見出し、箇条書き、インラインコード、コードブロックさえ存在すれば Markdown っぽいのでは、と考えています。もちろん、利便性を考えるとこれだけでは足りないとは思うものの、使う頻度やバランスを考えるとここまで削ぎ落としても違和感はなさそうな気がしています。

また、興味として絵文字は Markdown の要素として捉えているのか、Slack 独自の要素として見ているのかは気になります。個人的にはカスタム絵文字をよく見かけるので "Markdown のもの" ではないように感じているのですが、みなさんはどうでしょうか。ちなみに、メンションも Slack の使い方のひとつとして解釈していることを付記しておきます。

みなさんの Markdown 観を教えてもらえるとありがたいです。