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/
紛らわしい。。。