Skip to content

Commit

Permalink
feat(options): 読点文字をcommaCharactersで指定できるように
Browse files Browse the repository at this point in the history
- デフォルト読点文字として","(全角カンマ)を追加
  • Loading branch information
azu committed Dec 7, 2019
1 parent 1a85f3f commit 804b382
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 34 deletions.
87 changes: 61 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,35 @@
# textlint-rule-no-doubled-joshi [![Build Status](https://travis-ci.org/textlint-ja/textlint-rule-no-doubled-joshi.svg?branch=master)](https://travis-ci.org/textlint-ja/textlint-rule-no-doubled-joshi)

文中に同じ助詞が複数出てくるのをチェックする[textlint](https://github.com/textlint/textlint "textlint")ルールです。
1つの文中に同じ助詞が連続して出てくるのをチェックする[textlint](https://github.com/textlint/textlint)ルールです。

例)
文中で同じ助詞が連続すると文章が読みにくくなります。

例) ****という助詞が連続している

> 材料不足で代替素材で製品を作った。
**** という助詞が一文で複数回でてきているのをチェックすることができます。
**** という助詞が1つの文中に連続して書かれているのをチェックすることができます。

**OK**:

```
私は彼が好きだ
オブジェクトを返す関数を公開した
これがiPhone、これがAndroidです。
これがiPhone,これがAndroidです。
言うのは簡単の法則。
```

**NG**:

```
私は彼は好きだ
材料不足で代替素材で製品を作った。
列車事故でバスで振り替え輸送を行った。
法律案は十三日の衆議院本会議で賛成多数で可決され、参議院に送付されます
これは`obj.method`は何をしているかを示します。
これとあれとそれを持ってきて。
```


## Installation
Expand Down Expand Up @@ -55,48 +78,65 @@ textlint --rule no-doubled-joshi README.md
"!", // exclamation mark
"", // (ja) 全角 question mark
"" // (ja) 全角 exclamation mark
],
"commaCharacters": [
"",
"" // 全角カンマ
]
}
}
}
```

- `min_interval`(default: `1`) : 助詞の最低間隔値
- `min_interval`: 助詞の最低間隔値
- Default: `1`
- 指定した`min_interval`以内にある同じ助詞は連続しているとみなされます
- 指定した間隔値以下で同じ助詞が出現した場合エラーが出力されます
- `strict`(default: `false`) : 例外もエラーとするかどうか
- `strict`: 厳しくチェックするかどうか
- Default: `false`
- 下記参照。例外としているものもエラーとするかどうか
- `allow`(default: `[]`) :複数回の出現を許す助詞
- false-positiveが発生しやすくなります
- `allow`: 複数回の出現を許す助詞
- Default: `[]`
- 並立の助詞など、複数回出現しても無視する助詞を指定します
- 例) `"も"`を許可したい場合は `{ "allow": ["も"] }`
- `separatorCharacters`(default: `[".", ".", "。", "?", "!", "?", "!"]`) : 文の区切り文字として使用する文字の配列
- `separatorCharacters`: 文の区切り文字の配列
- Default: `[".", ".", "。", "?", "!", "?", "!"]`
- `separatorCharacters`を設定するとデフォルト値は上書きされます
- ``のみを文の区切り文字にしたい場合は。`{ "separatorCharacters" : ["。"] }`のように指定します
- `commaCharacters`: 句点となる文字の配列
- Default: `["、", ","]`
- 読点として認識する文字の配列を指定します
- 読点は間隔値を+1する効果があります

**min_interval**について
## 判定処理

> ********好き
ある助詞(かつ品詞細分類)が、最低間隔値(距離)以内に連続して書かれている場合をエラーとして検出します

この場合の、********の間隔値は1
> 材料不足で代替素材で製品を作った。
> 既存****文と絵****修正
この文中の助詞 `` 同士の間隔値 は `1` となります。
デフォルトの最低間隔値(`min_interval`)は`1`となるなるため、このケースはエラーとして判定されます。

この場合の、********の間隔値は2(****の間に****がある)
> これはペンです。これは鉛筆です。
## 判定処理
この文は句点(``)によって2つの文として認識されます。
そのため、それぞれの文では助詞``は1度のみとなるためエラーとはなりません。

ある助詞(かつ品詞細分類)が一致するものが、一定最低間隔値(距離)以下に書かれている場合を検出する
句点は `separatorCharacters` オプションで指定できます

[元ネタ](https://github.com/redpen-cc/redpen/issues/460 "Doubled Joshi Validator · Issue #460 · redpen-cc/redpen")は助詞が1文(センテンス)に2回以上でてきた際にエラーとしてる
このルールが助詞として認識するものは、次のサイトで確認できます

少し厳しすぎると感じたので、1文(センテンス)ではなく最低間隔値(距離)という概念を導入した
- [kuromoji.js demo](https://takuyaa.github.io/kuromoji.js/demo/tokenize.html "kuromoji.js demo")

> この書籍はJavaScriptのライブラリやツールにおけるプラグインアーキテクチャを見ていく事を目的としたものです
### 句点での区切り

この場合 "を" が最低間隔値2で並んでいるため、デフォルト設定ではエラーとしている
> これがiPhone、これがAndroidです
助詞にはどのようなものがあるかは次のサイトで確認できます。
句点文字が助詞の間にある場合、間隔値は+1されます。
そのため、助詞``の間隔値は`2`となりデフォルトではエラーとなりません。

- [kuromoji.js demo](http://takuyaa.github.io/kuromoji.js/demo/tokenize.html "kuromoji.js demo")
句点文字は `commaCharacters` オプションで指定できます。

## 例外

Expand Down Expand Up @@ -156,12 +196,6 @@ NG: 文字列**には**そこ**には***問題がある。
}
```

### "、"での区切り

> 右がiPhone、左がAndroidです。
"、"を間隔値+1としてカウントするため、上記の文章はデフォルトでは許容される。

## Tests

npm test
Expand All @@ -175,6 +209,7 @@ NG: 文字列**には**そこ**には***問題がある。
- [助詞の連続使用を避け分かりやすい文章を書こう! - 有限な時間の果てに](http://popoon.hatenablog.com/entry/2014/07/11/232057 "助詞の連続使用を避け分かりやすい文章を書こう! - 有限な時間の果てに")
- [作文入門](http://www.slideshare.net/takahi-i/ss-13429892 "作文入門")
- [形態素解析ツールの品詞体系](http://www.unixuser.org/~euske/doc/postag/index.html#chasen "形態素解析ツールの品詞体系")
- [Redpenの実装](https://github.com/redpen-cc/redpen/issues/460 "Doubled Joshi Validator · Issue #460 · redpen-cc/redpen")

## Related Libraries

Expand Down
31 changes: 28 additions & 3 deletions src/no-doubled-joshi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { RuleHelper } from "textlint-rule-helper";
import { splitAST as splitSentences, Syntax as SentenceSyntax, SentenceNode } from "sentence-splitter";
import { getTokenizer, KuromojiToken } from "kuromojin";
import {
is助詞Token, is読点Token,
is助詞Token,
create読点Matcher,
concatJoishiTokens,
createKeyFromKey,
restoreToSurfaceFromKey
Expand Down Expand Up @@ -66,15 +67,37 @@ const defaultOptions = {
"!", // exclamation mark
"?", // (ja) zenkaku question mark
"!" // (ja) zenkaku exclamation mark
],
commaCharacters: [
"、",
"," // 全角カンマ
]
};


export interface Options {
/**
* 助詞の最低間隔値
* 指定した間隔値以下で同じ助詞が出現した場合エラーが出力されます
*/
min_interval?: number;
/**
* デフォルトの例外パターンもエラーにするかどうか
* デフォルト: false
*/
strict?: boolean;
/**
* 複数回の出現を許す助詞の配列
* 例): ["も", "や"]
*/
allow?: string[];
separatorChars?: string[]
/**
* 文の区切りとなる文字(句点)の配列
*/
separatorCharacters?: string[];
/**
* 読点となる文字の配列
*/
commaCharacters?: string[];
}

/*
Expand All @@ -92,7 +115,9 @@ const report: TextlintRuleModule<Options> = function (context, options = {}) {
const isStrict = options.strict || defaultOptions.strict;
const allow = options.allow || defaultOptions.allow;
const separatorCharacters = options.separatorCharacters || defaultOptions.separatorCharacters;
const commaCharacters = options.commaCharacters || defaultOptions.commaCharacters;
const {Syntax, report, RuleError} = context;
const is読点Token = create読点Matcher(commaCharacters);
return {
[Syntax.Paragraph](node) {
if (helper.isChildNode(node, [Syntax.Link, Syntax.Image, Syntax.BlockQuote, Syntax.Emphasis])) {
Expand Down
16 changes: 14 additions & 2 deletions src/token-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,20 @@ export const is助詞Token = (token: KuromojiToken) => {
return token && /^/.test(token.pos);
};

export const is読点Token = (token: KuromojiToken) => {
return token.surface_form === "、" && token.pos === "名詞";
/**
* 読点を判定する関数を返す
* 注意: 名詞や記号ではないトークンは読点として扱えない
* @param commaCharacters
*/
export const create読点Matcher = (commaCharacters: string[]) => {
return function is読点Token(token: KuromojiToken) {
return commaCharacters.includes(token.surface_form) && (
// 、や, は名詞扱い
token.pos === "名詞" ||
// ,は記号 && 読点となる(surface_formを優先するために pos_detail_1/読点 のチェックを省く)
token.pos === "記号"
);
}
};
/**
* aTokenの_extraKeyに結合したkeyを追加する
Expand Down
23 changes: 20 additions & 3 deletions test/no-doubled-joshi-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ tester.run("no-double-joshi", rule, {
"既存のコードの利用", // "の" の例外
"オブジェクトを返す関数を公開した", // "を" の例外
"私は彼の鼻は好きだ",
// 、 tokenを距離 + 1 として考える
"右がiPhone、左がAndroidです。",
// 、 と ,をtokenを距離 + 1 として考える
"これがiPhone、これがAndroidです。",
"これがiPhone,これがAndroidです。",
"ナイフで切断した後、ハンマーで破砕した。",
// 接続助詞のてが重複は許容
"まずは試していただいて",
Expand All @@ -30,8 +31,12 @@ tester.run("no-double-joshi", rule, {
{
text: "これはペンです♪これは鉛筆です♪",
options: {separatorCharacters: ["♪"]},
},
// ,を読点とみなす
{
text: "これがiPhone,これがAndroidです。",
options: {commaCharacters: [","]},
}

],
invalid: [
// エラー位置は最後の助詞の位置を表示する
Expand Down Expand Up @@ -204,6 +209,18 @@ tester.run("no-double-joshi", rule, {
index: 10
}
]
},
// 、を読点と認識させなくする
{
text: "これがiPhone、これがAndroidです。",
options: {commaCharacters: []},
errors: [
{

message: `一文に二回以上利用されている助詞 "が" がみつかりました。`,
index: 12
}
]
}
]
});

0 comments on commit 804b382

Please sign in to comment.