textlint 1 は自然言語向けの Linter のひとつ。 前回は勉強のために textlint のシンプルなルールを自作した。
今回は、それに引き続いてシンプルなプリセットを自作してみる。 プリセットは、複数のルールを束ねてチェックする内容を表現するときに実装する。 ただし、簡単のために含めるルールはひとつだけにする。
使った環境は次のとおり。
$ sw_vers ProductName: macOS ProductVersion: 26.3.1 BuildVersion: 25D2128 $ uname -srm Darwin 25.3.0 arm64 $ npm --version 11.11.0 $ node --version v25.8.1
もくじ
下準備
下準備として Node.js をインストールしておく。
$ brew install node
パッケージを作成する
ルールと同様、プリセットの場合もパッケージ名は textlint-rule- のプリセットをつける。
今回は textlint-rule-preset-internet-rojinkai というパッケージ名にした。
$ mkdir -p textlint-rule-preset-internet-rojinkai $ cd textlint-rule-preset-internet-rojinkai
パッケージのメタデータを記述した最低限の package.json を用意する。
今回はソースコードは src 以下のディレクトリに設置する。
{ "name": "textlint-rule-preset-internet-rojinkai", "version": "0.0.1", "description": "hantoshi ROM re", "type": "module", "main": "src/index.js", "scripts": { "test": "textlint-scripts test" } }
必要なパッケージを追加する。
$ npm install --save-dev textlint textlint-scripts textlint-tester
ルールを組み込む
続いて、ルールを配置するディレクトリを用意する。
$ mkdir -p src/rules
個別のルールを用意する。
今回は、前回作成したのと全く同じルールにしている。
内容は文章に「ぬるぽ」や「ヌルポ」があるとエラーになるもの。
これを src/rules/no-null-pointer-exception.js に設置する。
// ルールに対応する処理を記述した関数を export する export default function (context, options = {}) { // 処理に必要なオブジェクトは関数の引数として得られる const { Syntax, getSource, RuleError, report, locator } = context; return { // AST のオブジェクト毎にチェックする処理が書ける // 文字列の中身を見るだけなら Syntax.Str で良い [Syntax.Str](node) { // ノードに含まれるテキストを得る const text = getSource(node); // 特定の文字列が含まれるかチェックする (見つかったら違反) const matches = text.matchAll(/ぬるぽ|ヌルポ/g); // 特定の文字列が見つかった場合のループ for (const match of matches) { // テキストの中で見つかった場所を求める const index = match.index ?? 0; const length = match[0].length; const matchRange = [index, index + length]; // ルールに違反したことを RuleError で伝える const ruleError = new RuleError("ガッ!", { padding: locator.range(matchRange), }); // report() 関数を使って違反の詳細を報告する report(node, ruleError); } }, }; }
続いて、上記を組み込んだエントリポイントとして src/index.js を作成する。
ここで rules と rulesConfig を含むオブジェクトを export する。
rules がルールで、rulesConfig がルールを動作させる設定になる。
rulesConfig に true を指定するとデフォルトでルールが有効になる。
import noNullPointerException from "./rules/no-null-pointer-exception"; const preset = { rules: { "no-null-pointer-exception": noNullPointerException, }, rulesConfig: { "no-null-pointer-exception": true, } }; export default preset;
ここではパッケージ内のルールを読み込んで使っている。 もちろん外部のパッケージからインポートしたルールを組み込んでも良い。
テストを書く
続いて、ルールをテストするディレクトリを用意する。
$ mkdir -p test/rules
先ほどプリセットに組み込んだルールをテストするコードを用意する。
以下を test/rules/no-null-pointer-exception.test.js として作成する。
import TextLintTester from "textlint-tester"; // テストする対象を import する import rule from "../../src/rules/no-null-pointer-exception"; // TextLintTester を使ってテストが書ける const tester = new TextLintTester(); tester.run("no-null-pointer-exception", rule, { // 違反していないパターン valid: [ "こんにちは", "NullPointerException", ], // 違反しているパターン invalid: [ { // 違反しているテキスト text: "ぬるぽ", // 違反したときのメッセージと場所 errors: [ { message: "ガッ!", range: [0, 3] } ] }, { text: "ヌルポ", errors: [ { message: "ガッ!", range: [0, 3], } ] } ] });
npm run test コマンドを実行してテストを実行する。
$ npm run test > textlint-rule-preset-internet-rojinkai@0.0.1 test > textlint-scripts test no-null-pointer-exception ✔ ぬるぽ ✔ ヌルポ ✔ こんにちは ✔ NullPointerException 4 passing (8ms)
テストがパスして、ちゃんとルールが動作していることが確認できた。
コマンドラインから動かしてみる
続いて、実際にコマンドラインからプリセットを使ってみる。
チェックする対象のファイルを用意する。
$ cat << EOF > /tmp/nullpo.md # 「NullPointerExceptionを「ぬるぽ」と呼ぶスレ ∧_∧ ( ´∀`)< ぬるぽ EOF
パッケージをリンクして使えるようにする。
$ npm link $ npm link textlint-rule-preset-internet-rojinkai
textlint コマンドに --preset オプションを使って今回作成したプリセットを読み込む。
プリセット名を指定するとき textlint-rule- をつける必要はない。
$ ./node_modules/.bin/textlint --preset preset-internet-rojinkai -f pretty-error /tmp/nullpo.md internet-rojinkai/no-null-pointer-exception: ガッ! /tmp/nullpo.md:1:26 v 0. 1. # 「NullPointerExceptionを「ぬるぽ」と呼ぶスレ 2. ^ internet-rojinkai/no-null-pointer-exception: ガッ! /tmp/nullpo.md:4:9 v 3. ∧_∧ 4. ( ´∀`)< ぬるぽ 5. ^ ✖ 2 problems (2 errors)
ちゃんとルールに基づいてエラーになっている。
まとめ
今回は勉強のために textlint のシンプルなプリセットを自作してみた。
