Skip to content

Commit c6fc90b

Browse files
committed
feat(rule): 異なる種類の助詞の重複を許可する
助詞の品詞細分類1までを見て助詞同士を比較する。 > ターミナルで「test」**と**入力する**と**、画面に表示されます。 1個目の「と」は格助詞、2個めの「と」は接続助詞となるため、異なるものとして認識しエラーとしない。 fix #6
1 parent be216db commit c6fc90b

File tree

2 files changed

+40
-11
lines changed

2 files changed

+40
-11
lines changed

src/no-doubled-joshi.js

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,21 @@ import {getTokenizer} from "kuromojin";
55
import splitSentences, {Syntax as SentenceSyntax} from "sentence-splitter";
66
import StringSource from "textlint-util-to-string";
77
// 助詞どうか
8-
const is助詞Token = token => {
8+
const is助詞Token = (token) => {
99
return token.pos === "助詞";
1010
};
11-
const is読点Token = token => {
11+
const is読点Token = (token) => {
1212
return token.surface_form === "、" && token.pos === "名詞";
1313
};
14+
// 助詞tokenから品詞細分類1までを元にしたkeyを作る
15+
const createKeyFromKey = (token) => {
16+
// e.g.) は:助詞.係助詞
17+
return `${token.surface_form}:${token.pos}.${token.pos_detail_1}`
18+
};
19+
// keyからsurfaceを取り出す
20+
const restoreToSurfaceFromKey = (key) => {
21+
return key.split(":")[0];
22+
};
1423
/**
1524
* Create token map object
1625
* {
@@ -23,11 +32,12 @@ const is読点Token = token => {
2332
function createSurfaceKeyMap(tokens) {
2433
// 助詞のみを対象とする
2534
return tokens.filter(is助詞Token).reduce((keyMap, token) => {
26-
// "は" : [token]
27-
if (!keyMap[token.surface_form]) {
28-
keyMap[token.surface_form] = [];
35+
// "は:助詞.係助詞" : [token]
36+
const tokenKey = createKeyFromKey(token);
37+
if (!keyMap[tokenKey]) {
38+
keyMap[tokenKey] = [];
2939
}
30-
keyMap[token.surface_form].push(token);
40+
keyMap[tokenKey].push(token);
3141
return keyMap;
3242
}, {});
3343
}
@@ -100,12 +110,13 @@ export default function (context, options = {}) {
100110
101111
joshiTokens = [tokenA, tokenB, tokenC, tokenD, tokenE, tokenF]
102112
joshiTokenSurfaceKeyMap = {
103-
"は": [tokenA, tokenC, tokenE],
104-
"で": [tokenB, tokenD, tokenF]
113+
"は:助詞.係助詞": [tokenA, tokenC, tokenE],
114+
"で:助詞.係助詞": [tokenB, tokenD, tokenF]
105115
}
106116
*/
107117
Object.keys(joshiTokenSurfaceKeyMap).forEach(key => {
108-
let tokens = joshiTokenSurfaceKeyMap[key];
118+
const tokens = joshiTokenSurfaceKeyMap[key];
119+
const joshiName = restoreToSurfaceFromKey(key);
109120
// strict mode ではない時例外を除去する
110121
if (!isStrict) {
111122
if (matchExceptionRule(tokens)) {
@@ -134,7 +145,7 @@ export default function (context, options = {}) {
134145
// this is padding column start with 0 (== -1)
135146
column: originalPosition.column
136147
};
137-
report(node, new RuleError(`一文に二回以上利用されている助詞 "${key}" がみつかりました。`, padding));
148+
report(node, new RuleError(`一文に二回以上利用されている助詞 "${joshiName}" がみつかりました。`, padding));
138149
}
139150
return current;
140151
});

test/no-doubled-joshi-test.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ import assert from "power-assert";
22
import rule from "../src/no-doubled-joshi";
33
import TextLintTester from "textlint-tester";
44
var tester = new TextLintTester();
5+
/*
6+
`**`のような装飾は取り除かれてから評価されているので、
7+
テストでの強調という意味合いのみで利用する。
8+
*/
59
tester.run("no-double-joshi", rule, {
10+
611
valid: [
712
"私は彼が好きだ",
813
"既存のコードの利用", // "の" の例外
@@ -11,9 +16,13 @@ tester.run("no-double-joshi", rule, {
1116
// 、 tokenを距離 + 1 として考える
1217
"右がiPhone、左がAndroidです。",
1318
"ナイフで切断した後、ハンマーで破砕した。",
14-
"まずは試していただいて"
19+
// 接続助詞のてが重複は許容
20+
"まずは試していただいて",
21+
// 1個目の「と」は格助詞、2個めの「と」は接続助詞
22+
"ターミナルで「test」**と**入力する**と**、画面に表示されます。"
1523
],
1624
invalid: [
25+
// エラー位置は最後の助詞の位置を表示する
1726
{
1827
text: "私は彼は好きだ",
1928
errors: [
@@ -122,6 +131,15 @@ tester.run("no-double-joshi", rule, {
122131
column: 16
123132
}
124133
]
134+
}, {
135+
text: "これとあれとそれを持ってきて。",
136+
errors: [
137+
{
138+
message: `一文に二回以上利用されている助詞 "と" がみつかりました。`,
139+
line: 1,
140+
column: 6
141+
}
142+
]
125143
}
126144
]
127145
});

0 commit comments

Comments
 (0)