LoginSignup
89
51

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

Last updated at Posted at 2018-08-08

TL;DR

(2023.07追記)

  • Prettierを入れているとMarkdownも自動フォーマットされる
    • Prettier v2までは日本語Markdown文書の整形ルールに問題があった
    • JS整形に比べて、Markdown整形はルール設定はほとんどできない
    • Prettier v3にアップグレードするといい感じになる
  • 整形ルールを自由に設定したければ
    • .prettierignoreを作って*.mdはフォーマットさせないように
    • Remarkをインストールすれば柔軟な整形ルール設定が可能

この記事を書いた背景

(2023.07追記)

Prettier v2時代にハマったのがきっかけですが、v3.0になって見事に改善されました。めでたい!!!
Prettier 3.0: Hello, ECMAScript Modules!

原文引用

Stop inserting spaces between Chinese or Japanese and Western characters
Previously, Prettier would insert spaces between Chinese or Japanese and Western characters (letters and digits). While some people prefer this style, it isn’t standard, and is in fact contrary to official guidelines. Please see here for more details. We decided it’s not Prettier’s job to enforce a particular style in this case, so spaces aren’t inserted anymore, while existing ones are preserved. If you need a tool for enforcing spacing style, consider textlint-ja or lint-md (rules space-round-alphabet and space-round-number).

DeepL訳

中国語または日本語と欧米語の文字の間にスペースを挿入しないようにした。
以前は、Prettierは中国語または日本語と西洋文字(文字と数字)の間にスペースを挿入していました。このスタイルを好む人もいますが、標準ではありませんし、公式ガイドラインにも反しています。詳しくはこちらをご覧ください。この場合、特定のスタイルを強制するのはPrettierの仕事ではないと判断し、スペースは挿入されなくなり、既存のスペースは保持されるようになりました。スペーシングスタイルを強制するツールが必要なら、textlint-jaかlint-md(ルールspace-round-alphabetとspace-round-number)を検討してください。

「詳しくはこちら」で紹介されてるように、こんなプラグインが2022年にリリースされていたんですね。知らなかった!Qiita記事も見つけました。
和欧文字間(漢字仮名と英数字の間)に半角スペースが挿入されないようにするPrettier Markdownプラグインを作った

Prettier v3ではこのプラグインの機能がデフォルトで入ったようです。
@tats-u さん、良い仕事してくださってありがとうございました!!!

ほとんどの方は、Prettier v3に移行すればこの記事の解説は不要だと思います。
しかし、やはり整形ルールは細かいところまで自分で調整したいのだ!という方は、整形ルールを自由に設定する方法から読んでください :smiley:

当時の苦悩の記録として以下は残しておきますが、あくまでPrettire v2以前の問題として理解をお願いします。

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

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

特にフォーマッタの設定をした覚えがないのに、やって欲しくないフォーマットを勝手にするので結構悩んでたのですよ。
例えば以下のように、英語・日本語が連続する文字を入れると

PDFテンプレート
   ↓
PDF テンプレート

ご丁寧に、境界にスペースを入れてくださるのです。
これはレンダリング後の表示にも影響してくるので勘弁してほしい。
英語圏の人は、こんな問題には気づかないんだろうなー。

犯人はPrettier

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

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

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

整形ルールを自由に設定する方法

PrettierではMarkdownの整形ルール設定がほとんどできないので、自由に設定したければ他のツールでフォーマットする必要があります。

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/

紛らわしい。。。

89
51
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
89
51