Open24

技術書リンタ

ほげさんほげさん
README.md
これは日本語のドキュメントですです。

ちゃんと書けてると思います

todo: あとでちゃんと Git Hub と DockerHub について書く。

todo: 全く Typescript について確認してない。
$ npx textlint README.md

/path/to/README.md
  1:16  error  "です" が連続して2回使われています。     ja-technical-writing/ja-no-successive-word
  3:10  error  弱い表現: "思います" が使われています。  ja-technical-writing/ja-no-weak-phrase
  3:13  error  文末が"。"で終わっていません。           ja-technical-writing/ja-no-mixed-period

✖ 3 problems (3 errors, 0 warnings)
ほげさんほげさん

textlint 追加ルール

package.json
{
  "dependencies": {
    "textlint": "^14.3.0",
    "textlint-rule-preset-ja-technical-writing": "^10.0.1",
+   "textlint-rule-no-todo": "^2.0.1"
  }
}
.textlintrc.json
{
  "plugins": {},
  "filters": {},
  "rules": {
    "preset-ja-technical-writing": true,
+   "no-todo": true
  }
}
$ npx textlint README.md

/path/to/README.md
  1:16  error  "です" が連続して2回使われています。                                    ja-technical-writing/ja-no-successive-word
  3:10  error  弱い表現: "思います" が使われています。                                 ja-technical-writing/ja-no-weak-phrase
  3:13  error  文末が"。"で終わっていません。                                          ja-technical-writing/ja-no-mixed-period
  5:1   error  Found TODO: 'todo: あとでちゃんと Git Hub と DockerHub について書く。'  no-todo
  7:1   error  Found TODO: 'todo: 全く Typescript について確認してない。'              no-todo

✖ 5 problems (5 errors, 0 warnings)
ほげさんほげさん

textlint VSCode

プラグイン名だけ紹介

グローバルに入れろ ( 本ごとにはできないが )

GitHub Actions

一言だけ

ほげさんほげさん

textlint 除外

todo を意図して書きたいことがある

README.md
  これは日本語のドキュメントですです。

  ちゃんと書けてると思います

  todo: あとでちゃんと Git Hub と DockerHub について書く。

+ このリポジトリはツールでテキストを校正しているので todo はありません

  todo: 全く Typescript について確認してない。
package.json
{
  "dependencies": {
    "textlint": "^14.3.0",
+   "textlint-filter-rule-comments": "^1.2.2",
    "textlint-rule-preset-ja-technical-writing": "^10.0.1",
    "textlint-rule-no-todo": "^2.0.1"
  }
}

.textlintrc.json
{
  "plugins": {},
  "filters": {},
  "rules": {
    "preset-ja-technical-writing": true,
    "no-todo": true
  },
+ "filters": {
+   "comments": true
+ }
}
README.md
  これは日本語のドキュメントですです。

  ちゃんと書けてると思います

  todo: あとでちゃんと Git Hub と DockerHub について書く。

+ <!-- textlint-disable -->
  このリポジトリはツールでテキストを校正しているので todo はありません
+ <!-- textlint-enable -->

  todo: 全く Typescript について確認してない。
$ npx textlint README.md

/path/to/README.md
   1:16  error  "です" が連続して2回使われています。                                    ja-technical-writing/ja-no-successive-word
   3:10  error  弱い表現: "思います" が使われています。                                 ja-technical-writing/ja-no-weak-phrase
   3:13  error  文末が"。"で終わっていません。                                          ja-technical-writing/ja-no-mixed-period
   5:1   error  Found TODO: 'todo: あとでちゃんと Git Hub と DockerHub について書く。'  no-todo
  11:1   error  Found TODO: 'todo: 全く Typescript について確認してない。'              no-todo

✖ 5 problems (5 errors, 0 warnings)
ほげさんほげさん

textlint 除外 ( ルール指定 )

todo だけ除外もできる

README.md
  これは日本語のドキュメントですです。

  ちゃんと書けてると思います

  todo: あとでちゃんと Git Hub と DockerHub について書く。

- <!-- textlint-disable -->
+ <!-- textlint-disable no-todo -->
  このリポジトリはツールでテキストを校正しているので todo はありません。
- <!-- textlint-enable -->
+ <!-- textlint-enable no-todo -->

  todo: 全く Typescript について確認してない。
$ npx textlint ./README.md

/path/to/README.md
   1:16  error  "です" が連続して2回使われています。                                    ja-technical-writing/ja-no-successive-word
   3:10  error  弱い表現: "思います" が使われています。                                 ja-technical-writing/ja-no-weak-phrase
   3:13  error  文末が"。"で終わっていません。                                          ja-technical-writing/ja-no-mixed-period
   5:1   error  Found TODO: 'todo: あとでちゃんと Git Hub と DockerHub について書く。'  no-todo
   8:37  error  文末が"。"で終わっていません。                                          ja-technical-writing/ja-no-mixed-period
  11:1   error  Found TODO: 'todo: 全く Typescript について確認してない。'              no-todo

✖ 6 problems (6 errors, 0 warnings)

説明の都合で記号として ! を使いたいが感嘆詞を禁止しているなどもある

あと URL とかがひっかかりやすい

ほげさんほげさん

prh

prh

https://github.com/prh/prh

proofreading ( 校正 ) helper

こちらも npm でインストールして prh コマンドもしくは npx prh スクリプトとして使用できる

textlint に組み込んで使うこともできるので、今回はそちらを紹介する

package.json
{
  "dependencies": {
    "textlint": "^14.3.0",
    "textlint-filter-rule-comments": "^1.2.2",
+   "textlint-rule-prh": "^6.0.0",
    "textlint-rule-preset-ja-technical-writing": "^10.0.1",
    "textlint-rule-no-todo": "^2.0.1"
  }
}
.textlintrc.json
{
  "plugins": {},
  "filters": {},
  "rules": {
+   "prh": {
+     "rulePaths": [
+       "./prh.yml"
+     ]
+   },
    "preset-ja-technical-writing": true,
    "no-todo": true
  },
  "filters": {
    "comments": true
  }
}
prh.yml
version: 1
rules:
  - expected: GitHub
    pattern: Git Hub

  - expected: Docker Hub
    pattern: DockerHub
$ npx textlint ./README.md

/path/to/README.md
   1:16  error    "です" が連続して2回使われています。                                    ja-technical-writing/ja-no-successive-word
   3:10  error    弱い表現: "思います" が使われています。                                 ja-technical-writing/ja-no-weak-phrase
   3:13  error    文末が"。"で終わっていません。                                          ja-technical-writing/ja-no-mixed-period
   5:1   error    Found TODO: 'todo: あとでちゃんと Git Hub と DockerHub について書く。'  no-todo
   5:15  ✓ error  Git Hub => GitHub                                                       prh
   5:25  ✓ error  DockerHub => Docker Hub                                                 prh
   8:37  error    文末が"。"で終わっていません。                                          ja-technical-writing/ja-no-mixed-period
  11:1   error    Found TODO: 'todo: 全く Typescript について確認してない。'              no-todo

✖ 8 problems (8 errors, 0 warnings)
✓ 2 fixable problems.
Try to run: $ textlint --fix [file]
ほげさんほげさん

prh 自動修正

$ npx textlint --fix ./README.md

/path/to/README.md
  5:15  ✔   Git Hub => GitHub        prh
  5:25  ✔   DockerHub => Docker Hub  prh

✔ Fixed 2 problems
✖ Remaining 2 problems
README.md
  これは日本語のドキュメントですです。

  ちゃんと書けてると思います

- todo: あとでちゃんと Git Hub と DockerHub について書く。
+ todo: あとでちゃんと GitHub と Docker Hub について書く。

  <!-- textlint-disable no-todo -->
  このリポジトリはツールでテキストを校正しているので todo はありません
  <!-- textlint-enable no-todo -->

  todo: 全く Typescript について確認してない。
ほげさんほげさん

prh 正規表現

prh.yml
  version: 1
  rules:
    - expected: GitHub
      pattern: Git Hub

    - expected: Docker Hub
-     pattern:  DockerHub
+     pattern:  /docker[-_\s]?hub/i
dockerhub.txt
dockerhub
docker hub
docker-hub
docker_hub

Dockerhub
Docker hub
Docker-hub
Docker_hub

DockerHub
Docker Hub
Docker-Hub
Docker_Hub

DOCKERHUB
DOCKER HUB
DOCKER-HUB
DOCKER_HUB
$ npx textlint --fix dockerhub.txt

/path/to/dockerhub.txt
   1:1  ✔   dockerhub => Docker Hub   prh
   2:1  ✔   docker hub => Docker Hub  prh
   3:1  ✔   docker-hub => Docker Hub  prh
   4:1  ✔   docker_hub => Docker Hub  prh
   8:1  ✔   Dockerhub => Docker Hub   prh
   9:1  ✔   Docker hub => Docker Hub  prh
  10:1  ✔   Docker-hub => Docker Hub  prh
  11:1  ✔   Docker_hub => Docker Hub  prh
  15:1  ✔   DockerHub => Docker Hub   prh
  17:1  ✔   Docker-Hub => Docker Hub  prh
  18:1  ✔   Docker_Hub => Docker Hub  prh
  22:1  ✔   DOCKERHUB => Docker Hub   prh
  23:1  ✔   DOCKER HUB => Docker Hub  prh
  24:1  ✔   DOCKER-HUB => Docker Hub  prh
  25:1  ✔   DOCKER_HUB => Docker Hub  prh

✔ Fixed 15 problems
dockerhub.txt
Docker Hub
Docker Hub
Docker Hub
Docker Hub

Docker Hub
Docker Hub
Docker Hub
Docker Hub

Docker Hub
Docker Hub
Docker Hub
Docker Hub

Docker Hub
Docker Hub
Docker Hub
Docker Hub
ほげさんほげさん

別のディレクトリから実行

$ cat ./sample.txt
dockerhub について確認する
$ npx --prefix ~/dev/lint textlint --config ~/dev/lint/.textlintrc.json ./sample.txt

/path/to/sample.txt
  1:1   ✓ error  dockerhub => Docker Hub         prh
  1:18  error    文末が"。"で終わっていません。  ja-technical-writing/ja-no-mixed-period

✖ 2 problems (2 errors, 0 warnings)
✓ 1 fixable problem.
Try to run: $ textlint --fix [file]

こうしておけばいい

$ alias tlint='npx --prefix ~/dev/lint textlint --config ~/dev/lint/.textlintrc.json'
$ tlint ./sample.txt

/path/to/sample.txt
  1:1   ✓ error  dockerhub => Docker Hub         prh
  1:18  error    文末が"。"で終わっていません。  ja-technical-writing/ja-no-mixed-period

✖ 2 problems (2 errors, 0 warnings)
✓ 1 fixable problem.
Try to run: $ textlint --fix [file]
ほげさんほげさん

prh 複数ルール

prh の辞書は複数登録できる

拾ってきたものを追加するほか、~ なども展開できる

.textlintrc.json を git 管理しつつ、ターミナルに出がちな自分の名前や案件名やうっかりするとヤバい秘密の文字列などを git 管理外の YAML ファイルでチェックできる

.textlintrc.json
{
  "plugins": {},
  "filters": {},
  "rules": {
    "prh": {
      "rulePaths": [
        "./prh.yml",
+       "~/secret-prh.yml"
      ]
    },
    "preset-ja-technical-writing": true,
    "no-todo": true
  },
  "filters": {
    "comments": true
  }
}
~/secret-prh.yml
version: 1
rules:
  - expected: token1111
    pattern: token1234
sample.txt
dockerhub について確認する
token1234
$ tlint ./sample.txt

/path/to/sample.txt
  1:1   ✓ error  dockerhub => Docker Hub         prh
  1:18  error    文末が"。"で終わっていません。  ja-technical-writing/ja-no-mixed-period
  2:1   ✓ error  token1234 => token1111          prh

✖ 3 problems (3 errors, 0 warnings)
✓ 2 fixable problems.
Try to run: $ textlint --fix [file]
ほげさんほげさん

現実的には

  • code syntax はエラーになりやすい
  • URL も同様
  • どうしても半角カッコを全角にしろとか言われやすい
    • ![image](./foo.jpg)
    • ここで foo(42)
  • macOS に対して Docker Desktop for Mac などがあるとひっかかる
ほげさんほげさん
foo.test.js
import {createLinter, loadTextlintrc} from 'textlint'

let linter

beforeAll(async () => {
    const descriptor = await loadTextlintrc({configFilePath: '.textlintrc.yml'})
    linter = createLinter({descriptor})
})

describe('foo', () => {
    test('bar', async () => {
        const result = await linter.lintText('DockerHub', 'dummy.txt')
        const errors = result.messages.map(message => `${message.ruleId}: ${message.message}`)
        console.log(errors)
    })

    test('pon', async () => {
        const result = await linter.lintText('dockerhub', 'dummy.txt')
        const errors = result.messages.map(message => `${message.ruleId}: ${message.message}`)
        console.log(errors)
    })
})
  "type": "module",
  "scripts": {
    "test": "NODE_OPTIONS=--experimental-vm-modules npx jest"
  },
ほげさんほげさん

これも可

prh.yml
version: 1
rules:
  - expected: GitHub
    pattern: /git[-_\s]?hub/i

  - expected: Docker Hub
    pattern:  /docker[-_\s]?hub/i
    specs:
      - from: dockerhub
        to: DockerHub
                
  - expected: macOS
    pattern: /\bmac\b/i
  • 感覚的にテストは分けたい
  • prh 以外もテストしたい
  • 実行にテストがついて回る気がする