VSCodeでMarkdownの自動フォーマット&整形ルールを自由に設定


Markdownの自動フォーマットが意味不明だった

Visual Studio Codeでeditor.formatOnSaveを有効にすると、なぜかMarkdownのファイルも保存時に自動整形されちゃってました。

特にフォーマッタの設定をした覚えがないのに、やって欲しくないフォーマットを勝手にするので結構悩んでたのですよ。

例えば以下のように、英語・日本語が連続する文字を入れると

PDFテンプレート


PDF テンプレート

ご丁寧に、境界にスペースを入れてくださるのです。

これはレンダリング後の表示にも影響してくるので勘弁してほしい。

英語圏の人は、こんな問題には気づかないんだろうなー。


犯人はPrettier

JavaScriptコードを自動フォーマットする目的で入れているPrettier - Code formatterが、Markdownも自動フォーマットしてくれてたのが原因でした。JS専用じゃなくて、言語の守備範囲はかなり広いのですな・・・

Prettierのドキュメントを読んでも、JSのルールは調整できるんですが、Markdownのルール調整が全然できなくて、上記の「英語と日本語の境界にスペースが入る問題」は解決できませんでした。

parserを何とかしてやれば行けそうな気もするけど、ハードル高いのでやめておく。


解決策

MarkdownはPrettier以外のツールでフォーマットすることにしました。


PrettierのMarkdownフォーマットを無効化

まずはVSCodeの設定に以下を追記して、Markdownをフォーマットしないように設定します。

    "prettier.disableLanguages": [

"vue",
"markdown",
],

ちなみにvueはデフォルトなのでそのまま含んでますが、vueにはPrettier使いたければ含まなくてもOK。


RemarkでMarkdownを独自にフォーマット

Markdownの自動フォーマットができて、自分で設定調整もできるVSCodeの機能拡張を探したところ、Remarkが一番良さげでした。

インストールして、コマンドパレットからRemark: Beautify markdown codeを選ぶとmdファイルのフォーマットができます。なぜかeditor.formatOnSaveでは動いてくれないので、「フォーマットする」というトリガは自分で操作しないとダメっぽいですね。

この時点で、最初の「英語と日本語の境界にスペースが入る問題」は解決されとります!あとは、もう少し自分好みの整形ルールに調整してあげるだけ。

整形ルールの調整は、VSCodeの設定ファイル内にこんな感じで書けます。

    "remark.format": {

"rules": {
"bullet": "*",
"listItemIndent": 1,
"fences": true,
}
},

rulesの設定項目は、こちら本家Remarkドキュメントのoptionsのプロパティが使えます。

https://github.com/remarkjs/remark/blob/master/packages/remark-stringify/readme.md#options

VSCodeのプラグインとしてもデフォルト値は持っていて、package.jsonにベタ書きされてました。

https://github.com/mrmlnc/vscode-remark/blob/master/package.json

ほとんどは本家Remarkのdefaultそのまんまだけど、一部書かれてないプロパティもあったので、本家とは若干違うのかも。詳しくは見てません。

あと「英語と日本語の境界にスペースを入れる」設定を、そもそもどうやるのか分かりませんでしたw


remark.js系ツールについて


remarkとremark-lintの違い

僕が以前書いたこの記事

Atomのlinter-markdownを.remarkrcで設定する方法

当時はVSCodeではなくAtom使ってたわけですが、そこではremark-lintというのを使ってました。

今回のVSCode機能拡張で使われてるremarkとは別物で、でも両方同じGitHub Organizationのremarkjs配下のリポジトリです。

VSCode機能拡張の方に、こんなIssueも出てました。

Implement remark-lint #4

なので、remark-lintの方が新しくて機能充実してるってことなのかな?

上の記事ではremark-lintの設定を.remarkrcファイルで書いてたんですけど、remarkではそのファイルが使えないっぽいです。できればVSCodeの設定じゃなくて、プロジェクト単位で.remarkrcを置いておきたいなーと思うので、対応してほしいですねー。


PrettierのParserもremark-parseだった

PrettierドキュメントのParserセクションからリンク貼られてるのも、「remark-parse」という「remark」リポジトリ内のページでした。

https://github.com/remarkjs/remark/tree/master/packages/remark-parse

とにかくMarkdownを解析するならremarkって感じなんでしょうね。(テキトーな解釈)


MDAST

そもそもremark.js系の色々なリポジトリからリンク貼られてるのが、こちらの「MDAST」というリポジトリ。

https://github.com/syntax-tree/mdast

remarkは、全体的にこのMDASTを使っているっぽいです。

MDASTやASTについては、この辺の記事が参考になりそう。(あまりしっかり読んでないけど、奥が深そうです・・・)

markdownを直接ReactElementに変換するコンパイラを書いた

QiitaとMarkdownとコンテンツオーサリング#Markdown AST


おわりに

例のごとく、後半は色々と枝葉の情報ばかり調べちゃいました。

コードフォーマッタを作るときは、結局はその言語の構文解析が必要で、末端のツールは違っても最終的に同じツールに収束していくのが面白かったです。

あと「remark.js」って、全然別物として2種類あるんですね。。

今回使った「Markdownプロセッサ」がこちら。

https://remark.js.org/

もひとつが、「Markdownのスライドショーツール」

https://remarkjs.com/

紛らわしい。。。