簡単なtextlintサーバーを作る


[textlint/textlint: The pluggable natural language linter for text and markdown\.](https://github.com/textlint/textlint)

より、apiで問い合わせられるようにしてみる。

## ファイル構成

appフォルダーを`textlint`などこの後にインストールするパッケージ名と同じにするとエラーになるので注意。

```
app/
  ├ .textlintrc // 設定
  ├ app.js      // webメイン
  └ a.py        // クライアント
```

## パッケージのインストール

`--save`が良いとかは適宜

```bash
$ npm init --yes
$ npm install --save-dev express
$ npm install --save-dev textlint
// TODOをチェックするルール
$ npm install --save-dev textlint-rule-no-todo
// 連続する漢字をチェックするルール
$ npm install --save-dev textlint-rule-max-kanji-continuous-len
```

現在のバージョンは以下の通り。

```
$ node --version
v10.21.0
$ npm --version
6.14.4
$ rpm list
express@4.17.1
textlint@11.7.6
textlint-rule-no-todo@2.0.1
textlint-rule-max-kanji-continuous-len@1.1.1
```


## ファイル

```js:app.js
const TextLintEngine = require('textlint').TextLintEngine;
const express = require('express');
const bodyParser = require('body-parser');
const app = express();

// postデータのjsonをパースするおまじない
app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(bodyParser.json());

// 8080番ポートで待ちうける
app.listen(8080, () => {
    console.log('Running at Port 8080...');
});

app.post('/api/textlint', (req, res, next) => {
    const req_text = req.body.text;
    const engine = new TextLintEngine();
    engine.executeOnText(req_text).then(results => {
        res.json({
            messages: results[0].messages
        });
    });
});

// その他のリクエストに対する404エラー
app.use((req, res) => {
    res.sendStatus(404);
});
```

書き方は各ルールのgithub参照

```text:.textlintrc
{
  "filters": {},
  "rules": {
    "no-todo": true,
    "max-kanji-continuous-len": true,
  }
}
```

text変数の文字列に対してlintをかける

```py:a.py
import json
import urllib.request

url = 'http://localhost:8080/api/textlint'
text = '''
TODO: this is TODO
一二三四五六
'''.strip()

data = {"text": text}
headers = {
    'Content-Type': 'application/json',
}
req = urllib.request.Request(url, json.dumps(data).encode(), headers)
try:
    with urllib.request.urlopen(req) as res:
        body = json.load(res)
        json_str = json.dumps(body)
        print(json_str)
except:
    print("fail")
```

## サーバーを起動

```bash
$ node app.js
Running at Port 8080...
```

## リクエストしてみる

```bash
$ python3 a.py | jq .
{
  "messages": [
    {
      "type": "lint",
      "ruleId": "no-todo",
      "message": "Found TODO: 'TODO: this is TODO'",
      "index": 0,
      "line": 1,
      "column": 1,
      "severity": 2
    },
    {
      "type": "lint",
      "ruleId": "max-kanji-continuous-len",
      "message": "漢字が6つ以上連続しています: 一二三四五六",
      "index": 19,
      "line": 2,
      "column": 1,
      "severity": 2
    }
  ]
}
```

もちろんコマンドラインからも呼べる

```bash
$ curl -X POST -H "Content-Type: application/json" \
  -d '{"text":"TODO: this is TODO\n一二三四五六"}'  \
  localhost:8080/api/textlint | jq .
{
  "messages": [
    {
      "type": "lint",
      "ruleId": "no-todo",
      "message": "Found TODO: 'TODO: this is TODO'",
      "index": 0,
      "line": 1,
      "column": 1,
      "severity": 2
    },
    {
      "type": "lint",
      "ruleId": "max-kanji-continuous-len",
      "message": "漢字が6つ以上連続しています: 一二三四五六",
      "index": 19,
      "line": 2,
      "column": 1,
      "severity": 2
    }
  ]
}
```

# 参考情報

[Node\.jsとExpressでローカルサーバーを構築する\(1\) ―Node\.jsとnpmの導入― \- Qiita](https://qiita.com/koedamon/items/37ea8e9175cf0fd62371)
[コードからtextlintを実行する \- Qiita](https://qiita.com/Horie1024/items/a21faa2b129022823dfb)
[textlintをnodejs/express環境で動作させる](https://seoda.dev/textlint-web/)
[node\.js \- Textlint の実行結果が空になる \- スタック・オーバーフロー](https://ja.stackoverflow.com/questions/60015/textlint-%E3%81%AE%E5%AE%9F%E8%A1%8C%E7%B5%90%E6%9E%9C%E3%81%8C%E7%A9%BA%E3%81%AB%E3%81%AA%E3%82%8B/70543)
[Node\.js \+ Express でPOSTデータを取得後、WebAPIへ問い合わせる \- Qiita](https://qiita.com/TakeshiNickOsanai/items/b1720dcbe2bb5f9e524f)
[node\.js\(express\)のbody\-parserを理解する \- Qiita](https://qiita.com/anoonoll/items/050ebb62143ada022a32)