textlint + prhで文章を校正する方法

textlintとprhを用いて、文章を校正する方法を紹介します。

## textlintとは
[textlint](https://textlint.github.io/)は、自然言語の校正に特化したNode.js製の文章校正ツールです。
JavaScriptを書いている人には、「ESLintのテキスト版」と言えば分かりやすいでしょうか。
ESLint同様プラガブルな仕組みになっており、様々なルールを組み合わせて使用します。
コマンドライン上で実行することもできますが、[Atom](https://atom.io/)や[Visual Studio Code](https://code.visualstudio.com/)などのエディタ上で動かすこともできます。

## prhとは
[prh](https://github.com/prh/prh)は、表記ゆれの修正に特化したNode.js製の文章校正ツールです。
textlintのルールにも表記ゆれのためのものはありますが、prhではYAMLファイルで辞書を柔軟に管理できます。
単体で実行することもできますが、textlintのルールの一つとして動かすこともできます。

## 環境構築
コマンドライン上で実行するにせよエディタ上で動かすにせよ、以下のものが必要になります。

* `package.json`ファイル
* textlint本体
* textlintのルール
* textlintの設定ファイル

### package.jsonファイルを作成
textlintはNode.js上で動作するため、`package.json`ファイルが必要です。
この時点では、中身は`name`ぐらいでいいでしょう。

```json:package.json
{
  "name": "textlint-prh-example"
}
```

### textlint本体をインストール
textlint本体をインストールします。

```sh
$ npm i -D textlint
```

この時点で、`package.json`ファイルは以下のようになっているはずです。

```json:package.json
{
  "name": "textlint-prh-example",
  "devDependencies": {
    "textlint": "^11.2.6"
  }
}
```

### textlintのルールをインストール
textlint自体はルールを持っていないので、使用するルールは自分でインストールする必要があります。
数ある[ルール](https://github.com/textlint/textlint/wiki/Collection-of-textlint-rule)の中から、使用したいルールを選んでインストールしましょう。
ここでは、日本語向けのルールをいくつかまとめたプリセットである[textlint-rule-preset-japanese](https://www.npmjs.com/package/textlint-rule-preset-japanese)をインストールします。

```sh
$ npm i -D textlint-rule-preset-japanese
```

この時点で、`package.json`ファイルは以下のようになっているはずです。

```json:package.json
{
  "name": "textlint-prh-example",
  "devDependencies": {
    "textlint": "^11.2.6",
    "textlint-rule-preset-japanese": "^4.0.3"
  }
}
```

次に、prhをtextlint上で動かすために[textlint-rule-prh](https://www.npmjs.com/package/textlint-rule-prh)をインストールします。

```sh
$ npm i -D textlint-rule-prh
```

この時点で、`package.json`ファイルは以下のようになっているはずです。

```json:package.json
{
  "name": "textlint-prh-example",
  "devDependencies": {
    "textlint": "^11.2.6",
    "textlint-rule-preset-japanese": "^4.0.3",
    "textlint-rule-prh": "^5.2.1"
  }
}
```

### textlintの設定ファイルを作成
textlintの設定は、`.textlintrc`という設定ファイルに記述します。
フォーマットはJSON、YAML、JavaScriptのいずれかが使用できますが、ここではJSON形式で記述します。
先程インストールした`textlint-rule-preset-japanese`と`textlint-rule-prh`を使用するには、次のように書きます。

```json:.textlintrc
{
  "rules": {
    "preset-japanese": true,
    "prh": {
      "rulePaths": [
        "node_modules/prh/prh-rules/media/WEB+DB_PRESS.yml"
      ]
    }
  }
}
```

ここでは、textlint-rule-prhに同梱されている`WEB+DB_PRESS.yml`をprhで使用する辞書ファイルとして指定していますが、[他の辞書ファイル](https://github.com/prh/rules)を使用することもできます。
もちろん、YAML形式の辞書ファイルを自作して使用することもできます。

## リント対象のファイルを作成
`docs`ディレクトリ内のMarkdownファイルをリント対象とすることを想定し、`docs`ディレクトリに`README.md`ファイルを作成します。

```md:docs/README.md
# サンプル
これは、MarkDownで書かれたサンプルドキュメントです。  
まあ、あの、このように、あえてエラーとなるような文章にしています。
```

この文章はあえてエラーとなるようなものにしており、次の点が導入したルールに違反します。

* 2行目：`Markdown`を`MarkDown`と書いている
* 3行目：読点を3個以上使用している

## リントを実行
textlintはコマンドライン上で実行するか、[Atom](https://atom.io/)や[Visual Studio Code](https://code.visualstudio.com/)などのエディタ上で動かすことができます。

### コマンドライン上で実行
`package.json`ファイルに、textlintによるリントを実行するためのコマンドを追加します。
コマンド名はなんでもいいのですが、ここではわかりやすく`lint`とします。

```json:package.json
{
  "name": "textlint-prh-example",
  "scripts": {
    "lint": "textlint 'docs/**/*.md'"
  },
  "devDependencies": {
    "textlint": "^11.2.6",
    "textlint-rule-preset-japanese": "^4.0.3",
    "textlint-rule-prh": "^5.2.1"
  }
}
```

以下のコマンドを実行すると、textlintによるリントが実行されます。

```sh
$ npm run lint
```

![https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132608/39aeea1e-25e5-985a-07f1-4b513bc85cf5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132608/39aeea1e-25e5-985a-07f1-4b513bc85cf5.png)

#### fixableなルールを自動修正
一部のfixable（修正可能）なルールは、`--fix`オプションで自動修正できます。
`package.json`ファイルに、textlintによる修正を実行するためのコマンドを追加します。
コマンド名はなんでもいいのですが、ここではわかりやすく`fix`とします。

```json:package.json
{
  "name": "textlint-prh-example",
  "scripts": {
    "lint": "textlint 'docs/**/*.md'",
    "fix": "textlint 'docs/**/*.md' --fix"
  },
  "devDependencies": {
    "textlint": "^11.2.6",
    "textlint-rule-preset-japanese": "^4.0.3",
    "textlint-rule-prh": "^5.2.1"
  }
}
```

以下のコマンドを実行すると、textlintによる修正が実行されます。

```sh
$ npm run fix
```

![https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132608/f6038e14-fa77-5aa2-9863-07a7f7c93782.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132608/f6038e14-fa77-5aa2-9863-07a7f7c93782.png)

### Atom上で動かす
[linter-textlint](https://atom.io/packages/linter-textlint)をインストールします。

```sh
$ apm install linter-textlint
```

これだけで動きます。
うまく動かない場合は、ファイルを開き直したり、エディタを再起動したりしましょう。

![https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132608/aac4f72e-6e2a-10f3-e6bc-7a648c5a1ca0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132608/aac4f72e-6e2a-10f3-e6bc-7a648c5a1ca0.png)

現時点では、fixableなルールの自動修正には対応していないようです。

### Visual Studio Code上で動かす
[vscode-textlint](https://marketplace.visualstudio.com/items?itemName=taichi.vscode-textlint)をインストールします。

```sh
$ code --install-extension taichi.vscode-textlint
```

これだけで動きます。
うまく動かない場合は、ファイルを開き直したり、エディタを再起動したりしましょう。

![https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132608/22c2f647-93e2-ba62-088d-fa6f755eb5e0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132608/22c2f647-93e2-ba62-088d-fa6f755eb5e0.png)

#### fixableなルールを自動修正
「Auto Fix On Save」オプションを有効にすることで、ファイル保存時にfixableなルールが自動修正されます。

![https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132608/669d949d-c7fd-da39-cdbf-b0c85abda854.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132608/669d949d-c7fd-da39-cdbf-b0c85abda854.png)

### その他のエディタ上で動かす
textlintは他にも、Sublime TextやVimなどのエディタ上で動かすことができます。

* [Integrating with Editors, Tools, etc.. · textlint](https://textlint.github.io/docs/integrations.html)

あなたのお気に入りのエディタのためのプラグインが存在しない場合、是非作ってみてください。

### GitHub上で動かす
今回はローカル上で実行する方法を紹介しましたが、GitHub Actionsやreviewdogと連携すれば、GitHub上でリント結果を確認できるようになります。

* [GitHub Actionsでtextlintしてみた ｜ DevelopersIO](https://dev.classmethod.jp/ci/github-actions-textlint/)
* [reviewdogを使ってtextlintの結果をPull Requestに書き込む方法 - Qiita](https://qiita.com/azu/items/c563da0b5455a1b1dca2)

## 参考リンク
* [Getting Started with textlint · textlint](https://textlint.github.io/docs/getting-started.html)
* [textlintで日本語の文章をチェックする | Web Scratch](https://efcl.info/2015/09/10/introduce-textlint/)
* [textlint + prhで表記ゆれを検出する | Web Scratch](https://efcl.info/2015/09/14/textlint-rule-prh/)