textlintで特定のルールのエラーを無視する


textlintにはさまざまなルールがありますが、特定の行や場所においてはルールを無効化したい場合があります。

例えば、asciidwango/js-primer: JavaScriptの入門書という書籍では、表記揺れを防止するためにtextlint-rule-prhというルールを使っています。

この書籍では、匿名関数無名関数の表記揺れを防止するために匿名関数統一する辞書が入っています。
しかし、どちらもよく使われる単語なので、「この書籍では無名関数の事を匿名関数と呼ぶ」という言及が必要です。

このように関数式では、名前を持たない関数を変数に代入できます。
このような名前を持たない関数を匿名関数(または無名関数)と呼びます。
https://asciidwango.github.io/js-primer/basic/function-declaration/より

この時、この部分だけはtextlint-rule-prhを無効化する必要があります。

textlintではそのような無効化を扱うフィルタールールという種類のルールが用意されています。

コメントで指定範囲を無視する

フィルタールールの一種としてコメントで指定範囲を無効化できるtextlint-filter-rule-commentsがあります。
このフィルタールールを有効化した場合は次のようにコメント(MarkdownならHTMLコメント)で特定のルールを無効化できます。

<!-- textlint-disable prh -->

このように関数式では、名前を持たない関数を変数に代入できます。
このような名前を持たない関数を**匿名関数**(または無名関数)と呼びます。

<!-- textlint-enable prh -->

導入方法は通常のルールと殆ど同じでnpmでインストールします。

npm install textlint-filter-rule-comments

そしてfiltersのフィールドにtextlint-filter-rule-commentsを追加するだけです。

{
    "filters": {
        "comments": true
    }
}

正規表現で指定範囲を無視する

類似するフィルタールールとして指定文字列やパターンを無視できるtextlint-filter-rule-allowlistがあります。こちらは文章全体で無視したいパターンを正規表現文字列で書けます。

{
    "filters": {
        "allowlist": {
            "allow": [
                "ignored-word", // <= 特定の単語を無視
                "/\\d{4}-\\d{2}-\\d{2}/", // <= 日付っぽい表現を無視
                "/===IGNORE===[\\s\\S]*?===\/IGNORE===/m" // <= `===IGNORE===`で囲んだ範囲を無視
            ]
        }
    }
}

たとえば、js-primerだとコードをブラウザ上で実行できるコンソールモードのマクロとして{{book.console}}という特殊な文字列が自動で展開されるようになっています。
しかし、Markdown的にはただの文字列であるためなんらかのルールに引っかかる可能性があります。
そのため、/{{[a-zA-Z.]*?}}/というパターンを文書全体で無視しています。

{
  "filters": {
    "comments": true,
    "allowlist": {
      "allow": [
        "/{{[a-zA-Z.]*?}}/",
        "と考えるかもしれません"
      ]
    }
}

ルールのオプションに無視リストを指定できる場合はそちらを優先した方が無意味な無効化が減って良いと思います。

例) 数式を無視する

QiitaなどMarkdownに数式の拡張($$)をサポートしている場合があります。
これはMarkdownの標準ではないため、textlintは$$で囲んだ範囲もただのテキストとして扱ってしまいます。

これもtextlint-filter-rule-allowlist$$で囲んだ範囲できます。
(ルールがエラーとして扱っても、そのエラーは無視される)

{
    "filters": {
        "allowlist": {
            "allow": [
                "/\\$\\$[\\s\\S]*?\\$\\$/m"
            ]
        }
    }
}

数式の例)

$$
\begin{pmatrix}
1 & 0 & 0 \\\ 
0 & 1 & 0 \\\
0 & 0 & 1
\end{pmatrix}
$$

$$
\begin{pmatrix}
1 & 0 & 0 \\
0 & 1 & 0 \\
0 & 0 & 1
\end{pmatrix}
$$

フィルターの作り方

textlintではフィルタールールもユーザーが作れるようになっています。
詳しくは次のドキュメントを参照すると良いですが、shouldIgnoreというメソッドを使う以外は基本的に通常のルールの作り方と同じです。

textlintがASTベースでチェックするのは誤検知を防止する目的が大きいので、すべての文章に万能なルールはないという前提にしています。そのため、すべてのルールはプラグインであり、フィルタールールもプラグインとなっています。

textlintのコアロジックだけを取り出した@textlint/kernelというコアモジュールがあるので、その上に便利な(最初から何でも入ってる)層を作ることもできます。

.textlintignoreファイルで無視する

.textlintignoreファイルを使うことで、特定のファイルをLintの対象外にできます。

まとめ

textlintでは、フィルタールールを使うことで指定した範囲のエラーを無効化できる。