不正な構文や誤字脱字をリポジトリに混入させないために
マークダウンに書く文章はコンパイルもなければ、実際に読まれるときの動的なチェックもできません。
そのため、マークダウンテキストを事前に解析することは「糸くず(lint)」を取る以上に重要な役割を占めると考えています。
静的解析をMarkdownにも適用させれば、eslintやstylelintのようにマークダウンの構文チェックや文章の校正ができます。
これらのチェックは、VSCodeの拡張機能を使うことで問題があればエディタ上で編集しながらリアルタイムで確認できます。
VSCodeの拡張機能 | 説明 |
---|---|
markdownlint | VSCodeのエディタ上でマークダウン構造を解析 |
vscode-textlint | VSCodeのエディタ上でテキストを解析 |
Code Spell Checker | VSCodeのエディタ上で英単語の誤字をチェック |
もちろん、CLIでの確認も可能です。
ライブラリ | 説明 |
---|---|
markdownlint | マークダウンの構文をチェックする |
textlint | 設定や辞書に従い文章を校正する |
cspell | 英単語の誤字をチェックする |
さらに husky
と lint-staged
を使えば、コミット時に変更対象ファイルだけコマンドを使って自動でチェックできます。
ライブラリ | 説明 |
---|---|
husky | Gitコミット時に任意のコマンドを組み込むことができる |
lint-staged | Gitのステージに上がっているファイルを対象に処理を実行できる |
VSCodeで確認しながら編集して、コミット時も保険的に確認すれば、誤った構文のマークダウンがリポジトリに入り込む余地が一切無くなります。
VSCodeの拡張機能でlintする
markdownlint
markdownlintの拡張機能をインストールすると、VSCodeでマークダウンの構文がチェックできます。
書き方に問題がある場合、VSCodeのエディタ上に波線が表示されて警告されます。
markdownlintは拡張機能をインストールすればすぐ使えます。
ですが、デフォルトの構文チェックはかなり厳しめに設定されています。
そのため、markdownlintのルールを確認して markdownlint.config
の設定を調整してから使うのが現実的です。
.vscode/settings.json
にmarkdownlintの設定を書いておけば、プロジェクト固有の設定として有効になります。
以下は調整した設定の一例です。
{
"markdownlint.config": {
"line-length": false, // MD013: 1文の最大文字数をはtextlintと競合するため無効化
"no-duplicate-heading": false, // MD024: 見出し文字列の重複を許容
"no-trailing-punctuation": false, // MD026: 見出しに.,;:が入ることを許容
"no-inline-html": false, // MD033: HTML記述を許容
"no-bare-urls": false // MD034: URLそのままの表記を許容
}
}
vscode-textlint
vscode-textlintの拡張機能で、VSCodeのエディタ上で文章の校正ができます。
校正の設定は .textlintrc
で行います。CLIと設定ファイルを共有できるので、詳細は後述します。
Code Spell Checker
英単語のスペルチェックのためにCode Spell Checkerの拡張機能をインストールします。
設定ファイルは .cspell.json
です。こちらも、後述するCLIと同じ設定ファイルが使えます。
CLIで静的解析(lint)する
markdownlint-cli2
マークダウン構文をコマンド(CLI)でチェックするなら markdownlint-cli2
がオススメです。
従来から利用されていたmarkdownlintの伝統的なCLIである markdownlint-cli
でも良いのですが、新しく登場した markdownlint-cli2
の方が設定ベースで調整しやすく、VSCodeとうまく連動するように設計されています。
markdownlint-cli2のインストール
npm
または yarn
でインストールします。
npm install --save-dev markdownlint-cli2
yarn add -D markdownlint-cli2
lint実行とスクリプト登録
インストール後、以下のコマンドでlintできます。
markdownlint-cli2 "**/*.md"
実際には package.json
の scripts
に登録して使うのが通例です。以下を追記します。
"scripts": {
"lint:markdown": "markdownlint-cli2 \"**/*.md\""
}
markdownlint-cli2の設定ファイル調整
ただし、このままではすべてのマークダウンファイルに対してすべてのルールが対象となるため、設定ファイルで調整します。
プロジェクトルートに .markdownlint-cli2.jsonc
を作成すれば設定が読み込まれます。
.jsonc
はコメントが書けるJSONフォーマットです。(JSONC = JSON with comments)
ちなみに、VSCode設定ファイルのJSONは暗黙的にJSONCで解釈されます。そのため .vscode/settings.json
をはじめとする .json
拡張子の設定ファイルにコメントを書いてもエラーになりません。
設定ファイルは複数のフォーマットに対応していますが、VSCodeと揃えるために .jsonc
がおすすめです。
config
の項目にはVSCode拡張機能のmarkdownlintの設定をそのまま記載できます。
また、解析対象から外したいファイルやフォルダは ignores
で設定します。
{
"config": {
"line-length": false, // MD013: 1文の最大文字数をはtextlintと競合するため無効化
"no-duplicate-heading": false, // MD024: 見出し文字列の重複を許容
"no-trailing-punctuation": false, // MD026: 見出しに.,;:が入ることを許容
"no-inline-html": false, // MD033: HTML記述を許容
"no-bare-urls": false // MD034: URLそのままの表記を許容
},
"ignores": ["node_modules"]
}
textlint
テキストの校正は textlint
で行います。プリセットと組み合わせて使うことが通例です。
ここでは、ベースとして以下の2つのプリセットを適用する前提で手順を説明していきます。
プリセット名 | 説明 |
---|---|
textlint-rule-preset-ja-spacing | 日本語のスペース有無を決定するtextlintルールプリセット |
textlint-rule-preset-ja-technical-writing | 技術文書向けのtextlintルールプリセット |
また、他にも校正辞書やコメントでlintを無効化できるライブラリも一緒にインストールします。
ライブラリ | 説明 |
---|---|
textlint-rule-prh | textlintでprh(校正辞書)を使えるようにする |
textlint-filter-rule-comments | コメントでtextlintを部分的に無効化できる |
textlintとプリセットのインストール
npm
または yarn
でインストールします。
npm install --save-dev textlint textlint-rule-preset-ja-spacing textlint-rule-preset-ja-technical-writing
yarn add -D textlint textlint-rule-preset-ja-spacing textlint-rule-preset-ja-technical-writing
lint実行とスクリプト登録
インストール後、以下のコマンドでlintできます。
textlint "**/*.md"
package.json
の scripts
に登録する一例です。
"scripts": {
"lint:text": "textlint \"**/*.md\""
}
textlintの設定を調整
プリセットの内容を調整したい場合は .textlintrc
で設定を上書きします。VSCode拡張機能も、この設定を使います。
以下は調整した設定ファイルの一例です。
{
"plugins": {
"@textlint/markdown": {
"extensions": [
".md"
]
}
},
"filters": {
"comments": true
},
"rules": {
"prh": {
"rulePaths": [
"./prh/index.yml"
]
},
"preset-ja-technical-writing": {
"sentence-length": {
"max": 150
},
"no-exclamation-question-mark": {
"allowFullWidthExclamation": true,
"allowFullWidthQuestion": true
},
"ja-no-successive-word": false,
"ja-no-mixed-period": {
"allowPeriodMarks": [
":",
":"
]
},
"no-doubled-joshi": {
"strict": false,
"allow": [
"も",
"や",
"か"
],
"separatorCharacters": [
",",
",",
"、",
".",
".",
"。",
"?",
"!",
"?",
"!",
"「",
"」",
"\"",
"”",
"“"
]
}
},
"preset-ja-spacing": {
"ja-space-around-code": {
"before": true,
"after": true
}
}
}
}
./prh/index.yml
は校正辞書のインデックスです。
imports:
- ./rules/tech.yml
ここから、個別のルール設定をインポートします。カテゴライズして必要な辞書を増やしていくことを想定しています。
以下は「技術用語の固有名詞ルール」の校正辞書を定義した一例です。
meta:
- title: 技術用語の固有名詞ルール
rules:
- expected: インターフェース
patterns:
- インターフェイス
- インタフェース
- インタフェイス
prh: 技術用語
- expected: ソフトウェア
pattern: ソフトウェアー
prh: 技術用語
- expected: ハードウェア
pattern: ハードウェアー
prh: 技術用語
- expected: デフォルト
pattern: ディフォルト
prh: 技術用語
また textlint-filter-rule-comments
を有効化しているので、以下のようにコメントでtextlintの設定を部分的に無効化できます。
<!-- textlint-disable -->
This is ignored text by rule.
Disables all rules between comments
<!-- textlint-enable -->
cspell(Code Spell Checker)
cspellはVSCode拡張機能の「Code Spell Checker」をCLIでも使えるようにしたライブラリです。
cspellとプリセットのインストール
npm
または yarn
でインストールします。
npm install --save-dev cspell
yarn add -D cspell
lint実行とスクリプト登録
インストール後、以下のコマンドでlintできます。
以下はすべてのファイルをチェックする例です。
cspell "**"
package.json
の scripts
に登録する一例です。
"scripts": {
"lint:cspell": "cspell \"**\" ."
}
cspellの設定
設定ファイルは .cspell.json
です。VSCode拡張機能もこの設定ファイルをもとにスペルをチェックします。
{
"version": "0.2",
"language": "en",
// allowCompoundWords - set to true to allow compound words by default
"allowCompoundWords": true,
// words - list of words to be always considered correct
"words": [
"qiita",
],
// flagWords - list of words to be always considered incorrect
// "flagWords": [],
// ignorePaths - a list of globs to specify which files are to be ignored
"ignorePaths": [
".vscode",
".devcontainer",
".git",
".history",
".cspell.json",
"node_modules",
"package.json",
"yarn.lock"
]
}
許可する言葉は .cspell.json
の words
に追加します。対象の文字列にカーソルを合わせてVSCodeのクイックフィックスで登録するのが便利です。
コミット時にステージ上のファイルだけチェックする
huskyとlint-stagedでプレコミット時に確認
huskyを使うとコミットやプッシュ時に、任意のコマンドを自動で実行できます。これに加えてlint-stagedを使うと、ソースコード全体ではなく git stage
されたファイルに対してlintできます。
これらを使って、コミット時にステージ対象のファイルに対してmarkdownlint-cli2のコマンドを実行します。
huskyとlint-stagedのインストール
huskyとlint-stagedが入ってない場合、npm
または yarn
でインストールします。
npm install --save-dev husky lint-staged
yarn add -D husky lint-staged
huskyを有効化
続いて、huskyのインストールコマンドを実行します。
npx husky install
yarn husky install
この操作で .husky
ディレクトリが作成されます。
.husky
├── _
│ └── husky.sh
└── .gitignore
さらに package.json
のscriptsにhuskyが有効化される設定を入れておきます。
prepare
に husky install
を記述します。
"scripts": {
"prepare": "husky install"
}
Monorepo(モノレポ)構成を採用している場合は、ルート直下の package.json
に設定を入れます。
yarn2を採用している場合は prepare
でなく postinstall
に記述します。プライベートパッケージと公開パッケージで記述が異なります。詳しくはhuskyの公式ドキュメントを確認してください。
huskyのpre-commitファイルを作成
その後、コミット時にチェックするためpre-commitファイルを作成します。
npx husky add .husky/pre-commit "npm lint-staged"
yarn husky add .husky/pre-commit "yarn lint-staged"
以下の .husky/pre-commit
ファイルが作成されます。
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
# npmの場合
npm lint-staged
# yarnの場合
yarn lint-staged
Monorepo(モノレポ)の場合は、リポジトリ内のいずれかのプロジェクトで実行したいケースが多いでしょう。その場合、フォルダを移動するコマンドを追記します。
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
# frontフォルダへ移動
cd front
# lintを実行
yarn lint-staged
これでコミット時に更新したファイルがlintされるようになりました。
lint-stagedの設定ファイルを作成
最後にlint-stagedの設定ファイルで実行する静的解析(lint)を指定します。
以下は .md
の拡張子のファイルに対してmarkdownlintを行う設定です。
module.exports = {
'*.{md}': ['yarn lint:markdown']
};
ここで記載している yarn lint:markdown
は、前述のmarkdownlint-cli2を設定した際に package.json
の scripts
に自分で記述したコマンドです。
lint-stagedの動作は package.json
に書くこともできますが、別の設定ファイルに書いて yarn
のコマンドを直接叩くのがオススメです。
設定ファイルは .lintstagedrc.js
のようにlint-stagedのConfigurationに記載されている設定ファイル名にすれば自動で読み込んでくれます。
不正なMarkdownはコミットできなくなる
ここまでの設定できたら、コミット時にmarkdownlintで構文チェックされるようになります。不正な構文が含まれたファイルをコミットした場合、警告メッセージが出てコミットできません。
Markdownの自動整形(format)はあえてやらない
静的解析(lint)だけでなく、自動整形(format)までやる考え方もあります。
VSCodeと一緒に使うフォーマッターはPrettierが有名です。
自動整形の設定を入れておけば、たとえばファイルの保存時にフォーマッターへ設定した形式に自動的に補正してくれます。
markdownlint-cli2には自動修正モードで実行できるコマンド(markdownlint-cli2-fix
)があるので、これも同義です。
ソースコード全体の形式を手間なく統一できるので、原則プログラムを動かすためのソースコードには自動整形(フォーマット)を適用させるべきだと考えます。
しかし、Markdownファイルの自動整形はオススメできません。
なぜなら、マークダウンはシステムのためでなく「人が読むために書かれること」が多いからです。
マークダウンはその歴史的背景からパーサの仕様が完全には統一されていません。MDXやMDCなど拡張構文も日々増えています。
そのため、自動整形を入れると見た目が意図せず補正されて崩れるリスクがあります。Markdownファイルは静的解析(lint)にとどめ、自動整形(format)まではやらないのが無難です。
MarkdownをVSCodeで効率良く書くTIPS
VSCodeの拡張機能とスニペットを活用してマークダウンを効率良く書くテクニックを以下でまとめています。無駄な機能は使わず、よく使う機能にフォーカスして使う(覚える)のがポイントです。
Markdownの構文チェックをブログ記事で実践している例
実際の技術ブログでマークダウンのブログ記事を効率良く書いて確認する方法を以下にまとめています。マークダウンの構文チェックについても書いています。合わせて参考にしてみてください。