Skip to content

Commit 804b382

Browse files
committed
feat(options): 読点文字をcommaCharactersで指定できるように
- デフォルト読点文字として","(全角カンマ)を追加
1 parent 1a85f3f commit 804b382

File tree

4 files changed

+123
-34
lines changed

4 files changed

+123
-34
lines changed

README.md

Lines changed: 61 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,35 @@
11
# 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)
22

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

5-
例)
5+
文中で同じ助詞が連続すると文章が読みにくくなります。
6+
7+
例) ****という助詞が連続している
68

79
> 材料不足で代替素材で製品を作った。
810
9-
**** という助詞が一文で複数回でてきているのをチェックすることができます。
11+
**** という助詞が1つの文中に連続して書かれているのをチェックすることができます。
12+
13+
**OK**:
14+
15+
```
16+
私は彼が好きだ
17+
オブジェクトを返す関数を公開した
18+
これがiPhone、これがAndroidです。
19+
これがiPhone,これがAndroidです。
20+
言うのは簡単の法則。
21+
```
22+
23+
**NG**:
24+
25+
```
26+
私は彼は好きだ
27+
材料不足で代替素材で製品を作った。
28+
列車事故でバスで振り替え輸送を行った。
29+
法律案は十三日の衆議院本会議で賛成多数で可決され、参議院に送付されます
30+
これは`obj.method`は何をしているかを示します。
31+
これとあれとそれを持ってきて。
32+
```
1033

1134

1235
## Installation
@@ -55,48 +78,65 @@ textlint --rule no-doubled-joshi README.md
5578
"!", // exclamation mark
5679
"", // (ja) 全角 question mark
5780
"" // (ja) 全角 exclamation mark
81+
],
82+
"commaCharacters": [
83+
"",
84+
"" // 全角カンマ
5885
]
5986
}
6087
}
6188
}
6289
```
6390

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

75-
**min_interval**について
112+
## 判定処理
76113

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

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

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

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

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

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

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

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

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

101141
## 例外
102142

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

159-
### "、"での区切り
160-
161-
> 右がiPhone、左がAndroidです。
162-
163-
"、"を間隔値+1としてカウントするため、上記の文章はデフォルトでは許容される。
164-
165199
## Tests
166200

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

179214
## Related Libraries
180215

src/no-doubled-joshi.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import { RuleHelper } from "textlint-rule-helper";
44
import { splitAST as splitSentences, Syntax as SentenceSyntax, SentenceNode } from "sentence-splitter";
55
import { getTokenizer, KuromojiToken } from "kuromojin";
66
import {
7-
is助詞Token, is読点Token,
7+
is助詞Token,
8+
create読点Matcher,
89
concatJoishiTokens,
910
createKeyFromKey,
1011
restoreToSurfaceFromKey
@@ -66,15 +67,37 @@ const defaultOptions = {
6667
"!", // exclamation mark
6768
"?", // (ja) zenkaku question mark
6869
"!" // (ja) zenkaku exclamation mark
70+
],
71+
commaCharacters: [
72+
"、",
73+
"," // 全角カンマ
6974
]
7075
};
7176

72-
7377
export interface Options {
78+
/**
79+
* 助詞の最低間隔値
80+
* 指定した間隔値以下で同じ助詞が出現した場合エラーが出力されます
81+
*/
7482
min_interval?: number;
83+
/**
84+
* デフォルトの例外パターンもエラーにするかどうか
85+
* デフォルト: false
86+
*/
7587
strict?: boolean;
88+
/**
89+
* 複数回の出現を許す助詞の配列
90+
* 例): ["も", "や"]
91+
*/
7692
allow?: string[];
77-
separatorChars?: string[]
93+
/**
94+
* 文の区切りとなる文字(句点)の配列
95+
*/
96+
separatorCharacters?: string[];
97+
/**
98+
* 読点となる文字の配列
99+
*/
100+
commaCharacters?: string[];
78101
}
79102

80103
/*
@@ -92,7 +115,9 @@ const report: TextlintRuleModule<Options> = function (context, options = {}) {
92115
const isStrict = options.strict || defaultOptions.strict;
93116
const allow = options.allow || defaultOptions.allow;
94117
const separatorCharacters = options.separatorCharacters || defaultOptions.separatorCharacters;
118+
const commaCharacters = options.commaCharacters || defaultOptions.commaCharacters;
95119
const {Syntax, report, RuleError} = context;
120+
const is読点Token = create読点Matcher(commaCharacters);
96121
return {
97122
[Syntax.Paragraph](node) {
98123
if (helper.isChildNode(node, [Syntax.Link, Syntax.Image, Syntax.BlockQuote, Syntax.Emphasis])) {

src/token-utils.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,20 @@ export const is助詞Token = (token: KuromojiToken) => {
99
return token && /^/.test(token.pos);
1010
};
1111

12-
export const is読点Token = (token: KuromojiToken) => {
13-
return token.surface_form === "、" && token.pos === "名詞";
12+
/**
13+
* 読点を判定する関数を返す
14+
* 注意: 名詞や記号ではないトークンは読点として扱えない
15+
* @param commaCharacters
16+
*/
17+
export const create読点Matcher = (commaCharacters: string[]) => {
18+
return function is読点Token(token: KuromojiToken) {
19+
return commaCharacters.includes(token.surface_form) && (
20+
// 、や, は名詞扱い
21+
token.pos === "名詞" ||
22+
// ,は記号 && 読点となる(surface_formを優先するために pos_detail_1/読点 のチェックを省く)
23+
token.pos === "記号"
24+
);
25+
}
1426
};
1527
/**
1628
* aTokenの_extraKeyに結合したkeyを追加する

test/no-doubled-joshi-test.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ tester.run("no-double-joshi", rule, {
88
"既存のコードの利用", // "の" の例外
99
"オブジェクトを返す関数を公開した", // "を" の例外
1010
"私は彼の鼻は好きだ",
11-
// 、 tokenを距離 + 1 として考える
12-
"右がiPhone、左がAndroidです。",
11+
// 、 と ,をtokenを距離 + 1 として考える
12+
"これがiPhone、これがAndroidです。",
13+
"これがiPhone,これがAndroidです。",
1314
"ナイフで切断した後、ハンマーで破砕した。",
1415
// 接続助詞のてが重複は許容
1516
"まずは試していただいて",
@@ -30,8 +31,12 @@ tester.run("no-double-joshi", rule, {
3031
{
3132
text: "これはペンです♪これは鉛筆です♪",
3233
options: {separatorCharacters: ["♪"]},
34+
},
35+
// ,を読点とみなす
36+
{
37+
text: "これがiPhone,これがAndroidです。",
38+
options: {commaCharacters: [","]},
3339
}
34-
3540
],
3641
invalid: [
3742
// エラー位置は最後の助詞の位置を表示する
@@ -204,6 +209,18 @@ tester.run("no-double-joshi", rule, {
204209
index: 10
205210
}
206211
]
212+
},
213+
// 、を読点と認識させなくする
214+
{
215+
text: "これがiPhone、これがAndroidです。",
216+
options: {commaCharacters: []},
217+
errors: [
218+
{
219+
220+
message: `一文に二回以上利用されている助詞 "が" がみつかりました。`,
221+
index: 12
222+
}
223+
]
207224
}
208225
]
209226
});

0 commit comments

Comments
 (0)