はじめに
私は弊社のTech Blogを運営させていただいていて、その際に大きな課題となっているのが添削です。
複数人で1つの記事を添削するのですが、誤字脱字や表現間違い、typoなど多くミスがあり、人間の目だけでチェックするのには限界があり、見落としてしまうこともあります。
そんなときに自動でチェックしてくれるツールがないかと調べたときに見つけたのが、textlintでした。
今回はそのtextlintを使った文章チェック環境をDockerで作成するところまで書いていこうと思います。
textlint とは
npmで提供されているOSSライブラリで、textlint
コマンドを使うと簡単に文章内のミスを検知してくれます。
textlintは予め用意されているルールをnpm install
することで使えます。
そして、自分でルールを作成してローカルや、publicに公開して使うこともできます。
textlint 使い方
使い方は簡単です。
まずtextlintをinstallします。
$ npm install textlint
次に適当なルールをインストールします。試しに文中で助詞が複数回連続で出てくるミスを検知してくれるルールを選択。
$ npm install textlint-rule-no-doubled-joshi
あとはファイルをチェックするだけ
$ echo "AWSでCloudWatchでログを収集します。" > text.md $ textlint --rule no-doubled-joshi text.md /Users/xxx/text.md 1:15 error 一文に二回以上利用されている助詞 "で" がみつかりました。 no-doubled-joshi ✖ 1 problem (1 error, 0 warnings)
このように連続で助詞を使うような間違った使い方を指摘してくれます。
.textlintrc
.textlintにルールを予め書いておくことでtextlintコマンドを用いるときにルールの指定をする必要がありません。
{ "rules": { "no-doubled-joshi": true } }
$ textlint text.md /Users/xxx/text.md 1:15 error 一文に二回以上利用されている助詞 "で" がみつかりました。 no-doubled-joshi ✖ 1 problem (1 error, 0 warnings)
大まかな使い方の説明は以上です。
Docker環境作成
今回作ったものはGitHub上に公開しています。
text-checkerというシステムを作成しました。
これをgit clone
してDocker環境を立ち上げれば誰でも簡単にセットアップされたtextlintが使えるようにしていて、例としてカスタムルールも作成しています。
詳しく作る過程を説明していきます。
カスタムルールの作成
今回作成する環境では自分でカスタマイズしたルールも使えるようにします。
先ほど説明したように、textlintには便利なルールが多数用意されています。
ですがほしいルールがなかった場合は、自分で作成することをおすすめします。
作成したルールはnpmパッケージとしてパブリックに公開することもできますし、ローカルのみで使うこともできます。
まずは、create−textlint−ruleをインストールします。
$ npm install create-textlint-rule
次にルールを作成します。
$ create-textlint-rule test-rule
できたルールを見ると以下のような構成です。
. ├── README.md ├── lib │ ├── index.js │ └── index.js.map ├── package.json ├── package-lock.json ├── node_modules ├── src │ └── index.js └── test └── index-test.js
index.jsにルール、index−test.jsにtestのテンプレートが用意されています。
今回は特定の文字を見つけたらアラートを出すルールを作成します。
以下のようにios、IOSといった誤った表記(正しくはiOS)のものをcheckします。
index.ts
import { TextlintRuleModule } from '@textlint/types'; import { tokenize } from "kuromojin"; // https://github.com/MosasoM/inappropriate-words-ja const inappropriateWords = [ 'ios', 'IOS' ] const module: TextlintRuleModule = (context) => { const { getSource, report, RuleError, Syntax } = context; return { async [Syntax.Str](node) { const text = getSource(node); const tokens = await tokenize(text); tokens.forEach(({ surface_form, word_position }) => { if (!inappropriateWords.includes(surface_form)) { return; } const index = word_position - 1; const ruleError = new RuleError( `不適切表現「${surface_form}」が含まれています。`, { index } ); report(node, ruleError); }); } } }; export default module;
typescriptも利用できます。
1からカスタムルールを作成することもできますが、既存で作成されているカスタムルールを参考にすると楽です。textlintはそのやり方を推奨しています。
私はこちらのカスタムルールを参考にさせていただきました。
次にpackage.jsonとtsconfig.jsonです。
package.json
{ "version": "1.0.0", "keywords": [ "textlintrule" ], "main": "lib/index.js", "files": [ "lib/", "src/" ], "scripts": { "build": "textlint-scripts build", "test": "textlint-scripts test", "watch": "textlint-scripts build --watch", "tsc": "tsc" }, "dependencies": { "kuromojin": "^2.0.0" }, "devDependencies": { "@textlint/types": "^1.3.1", "@types/node": "^12.12.39", "textlint-scripts": "^3.0.0", "textlint-tester": "^5.1.15", "ts-node": "^8.10.1", "typescript": "^3.6.4" }, "name": "textlint-rule-mistaken-ward-check", "directories": { "test": "test" }, "author": "", "license": "ISC", "description": "" }
tsconfig.json
{ "compilerOptions": { /* Basic Options */ "module": "commonjs", "moduleResolution": "node", "esModuleInterop": true, "noEmit": true, "target": "es2015", /* Strict Type-Checking Options */ "strict": true, /* Additional Checks */ /* Report errors on unused locals. */ "noUnusedLocals": true, /* Report errors on unused parameters. */ "noUnusedParameters": true, /* Report error when not all code paths in function return a value. */ "noImplicitReturns": true, /* Report errors for fallthrough cases in switch statement. */ "noFallthroughCasesInSwitch": true } }
これで環境は整いました。
以下のコマンドでセットアップすれば使えるようになります。
$ npm install $ npm run build
Dockerfile
実際にカスタムルールを作成できたので、それとマネージドルールを使って文章チェックの環境を作成してみましょう。
以下が作成したDockerfileです。
FROM node:14-slim # setting RUN apt-get update RUN apt-get -y install vim RUN { \ echo 'set encoding=utf-8'; \ echo 'set fileencodings=utf-8'; \ echo 'set fileformats=unix,dos,mac'; \ } > ~/.vimrc RUN . ~/.vimrc # copy COPY package*.json /text-checker/ COPY .textlintrc /text-checker/ COPY textlint-rule-mistaken-ward-check /text-checker/textlint-rule-mistaken-ward-check WORKDIR /text-checker RUN npm install # custom rule setting WORKDIR /text-checker/textlint-rule-mistaken-ward-check RUN npm install RUN npm run build WORKDIR /text-checker RUN npm install ./textlint-rule-mistaken-ward-check # path textlint WORKDIR /usr/bin RUN touch textlint RUN ln -s --force /text-checker/node_modules/.bin/textlint textlint WORKDIR /
いくつかポイントがあります。
vimを使う際のエンコード
環境内でvimエディターを使うことにします。
今回は日本語の添削をするので、vimを使う際に.vimrc
にutf-8でエンコードするような処理を入れる必要があります。
これをしないと正しく日本語チェックをtextlintでできません。
RUN apt-get -y install vim RUN { \ echo 'set encoding=utf-8'; \ echo 'set fileencodings=utf-8'; \ echo 'set fileformats=unix,dos,mac'; \ } > ~/.vimrc RUN . ~/.vimrc
textlintのパスを通す
実際にnpm install
でtextlintをインストールしただけではtextlintコマンドを使うことはできないのでPATHを通しましょう。
以下のようにusr/binにコマンドの設定が配置されているので、そこにtextlintファイルを作成して、機能へのシンボリックリンクを貼ります。
実際は/text-checker/node_modules/.bin/textlint
を打つことで機能は使えますが、usr/binにコマンド設定を追加したことでtextlint
コマンドとして使うことができます。
WORKDIR /usr/bin RUN touch textlint RUN ln -s --force /text-checker/node_modules/.bin/textlint textlint
これでDockerfileは作成完了です。
カスタムルールのサブモジュール化
実際にこの環境をローカルに落として使うときに、カスタムルールはサブモジュール化することをおすすめします。
そうでないと環境本体の更新カスタムルールの更新が煩雑になり、機能開発維持に支障が出ます。
サブモジュール化することでカスタムルールは別のgitリポジトリとして捉えられるので別個のシステムとして組み込み、機能開発のプロセスを分けることができます。
サブモジュール化するのは簡単で、以下のようなコマンドを打ちます。
$ git submodule add https://github.com/KenFujimoto12/textlint-rule-mistaken-ward-check.git textlint-rule-mistaken-ward-check
これによってルートディレクトリのように以下のような設定が作成されて、カスタムルールのサブモジュール化は完了です。
.gitmodules
[submodule "textlint-rule-mistaken-ward-check"] path = textlint-rule-mistaken-ward-check url = https://github.com/KenFujimoto12/textlint-rule-mistaken-ward-check.git
動作
実際に使ってみましょう。
今回の環境は以下のように取得、立ち上げをします。
$ git clone git@github.com:KenFujimoto12/text-checker.git $ cd text-checker $ git clone --recursive git@github.com:KenFujimoto12/textlint-rule-mistaken-ward-check.git $ docker build -t text-checker . $ docker run -it --name text-checker text-checker:latest bin/bash
docker run
で環境に入ることができたら、実際にtextファイルを作成してチェックしてみましょう。
> cd text-checker > vim test.txt ## copy and paste blog text into xxx.txt > textlint --rulesdir node_modules/textlint-rule-mistaken-ward-check/lib/ test.txt -f pretty-error index: 不適切表現「ios」が含まれています。 /text-checker/test.txt:3:6 v 2. 3. こんかいはiosについての話をしたいと思います。 4. ^ ja-no-weak-phrase: 弱い表現: "思います" が使われています。 /text-checker/test.txt:3:20 v 2. 3. こんかいはiosについての話をしたいと思います。 4. ^ index: 不適切表現「ios」が含まれています。 /text-checker/test.txt:5:1 v 4. 5. iosアプリは実際はそんなに難しいものでもなく、誰でも簡単に開発できちゃいます。 6. ^ ✖ 3 problems (3 errors, 0 warnings)
ちゃんと意図したようなチェックをしてくれています。
終わりに
実際にtextlintを使ったweb添削サービスはいくつかあるみたいですが、自分でオリジナルの添削環境が作成できるので、今回のようにDockerを使った環境構築がおすすめです。
他にもいろんなルールを作成していきましょう。