Markdownの中のコードをフォーマットするツールを作った
dprintを使おう
dprintはMarkdown中のコードを整形してくれる上、Vscodeに対応しています。こちらを使いましょう。
TL;DR
技術記事を書いていると当然ながらコードを書く必要があります。
コードをVScodeなどを用いて書くときは、rustfmtやblack、prettierなどのコードフォーマッターを使っています。記事内のコードを書くときも実際のコードが動くか確かめることが多いので、VScodeで書いてコピペすることが多いです。
しかし、記事内でなんとなく書いているコードや、ちょっと修正しただけならコピペじゃなくて記事のコードを書き換えることもあります。そういったときにフォーマッターを通していないので、普段自分が書くコーディングからずれていたり、括弧の数などのフォーマッターレベルでわかるミスが出たりすることがあります。
そこで、今回はMarkdown内のコードを任意のフォーマッターを使って整形して出力するツールcmfmtを作ったので宣伝します。
使い方
binaryをおいてあるので、ダウンロードしてパスを通したあとcmfmt example.mdの用な感じで使えます。デフォルトではファイルを置き換えてしまうので、それが嫌な場合は--stdoutフラグをつければ置き換える代わりに標準出力に出力されます。
USAGE:
cmfmt [FLAGS] [OPTIONS] <markdown>
FLAGS:
-h, --help Prints help information
--stdout Output formatted markdown to stdout instead of overwrite the input markdown
-V, --version Prints version information
OPTIONS:
--config <config> Path of the config file. default: ${home}/.config/cmfmt.toml
ARGS:
<markdown> Path of the input markdown you would like to format
設定ファイルについて
設定ファイルは以下のような形式です。これが~/.config/cmfmt.tomlに勝手に出力されます。中身をいじれば、自分の好きな言語・フォーマッターを使ってMarkdown内のコードをフォーマットできるはず。
[fmt.python]
command = "black"
name = ["py", "python", "python3"]
extention = "py"
[fmt.rust]
command = "rustfmt"
name = ["rs", "rust"]
extention = "rs"
[fmt.js]
command = "prettier"
args = ["--write"]
name = ["js", "javascript"]
extention = "js"
fmt.langnameは特に意味はなく、人間が読みやすいからつけています。fmt.xxxxxみたいな形式ならなんでもいいです。そのうちlintもつけてみたいのでfmtを接頭語としてつけてます。
どの言語名を認識するかをnameで配列形式で指定します。その後、指定した言語をどのコマンドでフォーマットするかをcommandで指定しています。引数が必要な場合はargsで必要な引数を配列形式で指定できます。
また、prettierなどは特定の拡張子がファイルにないとフォーマットしてくれないので、一時ファイル作成時に拡張子を指定できます。
使用技術
| type | |
|---|---|
| 言語 | rust |
| 設定ファイル | toml |
| Markdownのパース | pulldown-cmark |
原理
やっていることは滅茶苦茶単純で、
- Markdownをパースする
- code blockから言語名を検出
- code本体を一時ファイルとして保存
- 一時ファイルを対象として、設定ファイルに書かれたコマンドを実行
- 一時ファイルを読み込んで、フォーマットされたコードをもとのコードとおきかえ
- Markdownに戻す
という処理をしています。
終わりに
cmfmtでブログ記事内のコードにも統一感を出したい