9
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

VSCodeでマークダウンの構文と文章を校正してコミット時も自動でlintする

Last updated at Posted at 2022-09-18

不正な構文や誤字脱字をリポジトリに混入させないために

マークダウンに書く文章はコンパイルもなければ、実際に読まれるときの動的なチェックもできません。

そのため、マークダウンテキストを事前に解析することは「糸くず(lint)」を取る以上に重要な役割を占めると考えています。

静的解析をMarkdownにも適用させれば、eslintやstylelintのようにマークダウンの構文チェック文章の校正ができます。

これらのチェックは、VSCodeの拡張機能を使うことで問題があればエディタ上で編集しながらリアルタイムで確認できます。

VSCodeの拡張機能 説明
markdownlint VSCodeのエディタ上でマークダウン構造を解析
vscode-textlint VSCodeのエディタ上でテキストを解析
Code Spell Checker VSCodeのエディタ上で英単語の誤字をチェック

もちろん、CLIでの確認も可能です。

ライブラリ 説明
markdownlint マークダウンの構文をチェックする
textlint 設定や辞書に従い文章を校正する
cspell 英単語の誤字をチェックする

さらに huskylint-staged を使えば、コミット時に変更対象ファイルだけコマンドを使って自動でチェックできます。

ライブラリ 説明
husky Gitコミット時に任意のコマンドを組み込むことができる
lint-staged Gitのステージに上がっているファイルを対象に処理を実行できる

VSCodeで確認しながら編集して、コミット時も保険的に確認すれば、誤った構文のマークダウンがリポジトリに入り込む余地が一切無くなります。

VSCodeの拡張機能でlintする

markdownlint

markdownlintの拡張機能をインストールすると、VSCodeでマークダウンの構文がチェックできます。

書き方に問題がある場合、VSCodeのエディタ上に波線が表示されて警告されます。

markdown_lint.gif

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.jsonscripts に登録して使うのが通例です。以下を追記します。

package.json
"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 で設定します。

.markdownlint-cli2.jsonc
{
  "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.jsonscripts に登録する一例です。

package.json
"scripts": {
  "lint:text": "textlint \"**/*.md\""
}

textlintの設定を調整

プリセットの内容を調整したい場合は .textlintrc で設定を上書きします。VSCode拡張機能も、この設定を使います。

以下は調整した設定ファイルの一例です。

.textlintrc
{
  "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 は校正辞書のインデックスです。

/prh/index.yml
imports:
  - ./rules/tech.yml

ここから、個別のルール設定をインポートします。カテゴライズして必要な辞書を増やしていくことを想定しています。

以下は「技術用語の固有名詞ルール」の校正辞書を定義した一例です。

/prh/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.jsonscripts に登録する一例です。

package.json
"scripts": {
  "lint:cspell": "cspell \"**\" ."
}

cspellの設定

設定ファイルは .cspell.json です。VSCode拡張機能もこの設定ファイルをもとにスペルをチェックします。

.cspell.json
{
  "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.jsonwords に追加します。対象の文字列にカーソルを合わせてVSCodeのクイックフィックスで登録するのが便利です。

VSCodeのクイックフィックスでcspellのwordsに登録

コミット時にステージ上のファイルだけチェックする

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が有効化される設定を入れておきます。

preparehusky install を記述します。

package.json
"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 ファイルが作成されます。

.husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# npmの場合
npm lint-staged
# yarnの場合
yarn lint-staged

Monorepo(モノレポ)の場合は、リポジトリ内のいずれかのプロジェクトで実行したいケースが多いでしょう。その場合、フォルダを移動するコマンドを追記します。

.husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# frontフォルダへ移動
cd front

# lintを実行
yarn lint-staged

これでコミット時に更新したファイルがlintされるようになりました。

lint-stagedの設定ファイルを作成

最後にlint-stagedの設定ファイルで実行する静的解析(lint)を指定します。

以下は .md の拡張子のファイルに対してmarkdownlintを行う設定です。

.lintstagedrc.js
module.exports = {
  '*.{md}': ['yarn lint:markdown']
};

ここで記載している yarn lint:markdown は、前述のmarkdownlint-cli2を設定した際に package.jsonscripts に自分で記述したコマンドです。

lint-stagedの動作は package.json に書くこともできますが、別の設定ファイルに書いて yarn のコマンドを直接叩くのがオススメです。

設定ファイルは .lintstagedrc.js のようにlint-stagedのConfigurationに記載されている設定ファイル名にすれば自動で読み込んでくれます。

不正なMarkdownはコミットできなくなる

ここまでの設定できたら、コミット時にmarkdownlintで構文チェックされるようになります。不正な構文が含まれたファイルをコミットした場合、警告メッセージが出てコミットできません。

markdown_husky.gif

Markdownの自動整形(format)はあえてやらない

静的解析(lint)だけでなく、自動整形(format)までやる考え方もあります。

VSCodeと一緒に使うフォーマッターはPrettierが有名です。

自動整形の設定を入れておけば、たとえばファイルの保存時にフォーマッターへ設定した形式に自動的に補正してくれます。

markdownlint-cli2には自動修正モードで実行できるコマンド(markdownlint-cli2-fix)があるので、これも同義です。

ソースコード全体の形式を手間なく統一できるので、原則プログラムを動かすためのソースコードには自動整形(フォーマット)を適用させるべきだと考えます。

しかし、Markdownファイルの自動整形はオススメできません。

なぜなら、マークダウンはシステムのためでなく「人が読むために書かれること」が多いからです。

マークダウンはその歴史的背景からパーサの仕様が完全には統一されていません。MDXMDCなど拡張構文も日々増えています。

そのため、自動整形を入れると見た目が意図せず補正されて崩れるリスクがあります。Markdownファイルは静的解析(lint)にとどめ、自動整形(format)まではやらないのが無難です。

MarkdownをVSCodeで効率良く書くTIPS

VSCodeの拡張機能とスニペットを活用してマークダウンを効率良く書くテクニックを以下でまとめています。無駄な機能は使わず、よく使う機能にフォーカスして使う(覚える)のがポイントです。

Markdownの構文チェックをブログ記事で実践している例

実際の技術ブログでマークダウンのブログ記事を効率良く書いて確認する方法を以下にまとめています。マークダウンの構文チェックについても書いています。合わせて参考にしてみてください。

9
4
0

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
9
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?