Skip to content

Commit 882c2bb

Browse files
shirayuazu
authored andcommitted
feat(rule): 複数の助詞にマッチするように (#9)
#7 の一部に対処しました. - "することを可能" - "することをできる" の検出を - "すること[助詞]可能" - "すること[助詞]できる" に拡充しました. またREADMEも修正しました. #6 と同様にtechnological-book-corpus-jaを使った[比較結果](https://gist.github.com/shirayu/0507909cb8b5f3b689d46fcd29b489e4)も添付します.
1 parent b635c51 commit 882c2bb

File tree

5 files changed

+113
-40
lines changed

5 files changed

+113
-40
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@
66

77
## 表現の一覧
88

9-
- "することが可能"は冗長な表現です。"することが可能"を省き簡潔な表現にすると文章が明瞭になります。
9+
- "すること[助詞]可能"は冗長な表現です。"すること[助詞]可能"を省き簡潔な表現にすると文章が明瞭になります。
1010
- 参考: <http://qiita.com/takahi-i/items/a93dc2ff42af6b93f6e0>
11-
- "することができる"は冗長な表現です。"することが"を省き簡潔な表現にすると文章が明瞭になります。
11+
- "すること[助詞]できる"は冗長な表現です。"すること[助詞]"を省き簡潔な表現にすると文章が明瞭になります。
1212
- 参考: <http://qiita.com/takahi-i/items/a93dc2ff42af6b93f6e0>
1313
- "であると言えます"は冗長な表現です。"である" または "と言えます"を省き簡潔な表現にすると文章が明瞭になります。
1414
- 参考: <http://www.sekaihaasobiba.com/entry/2014/10/24/204024>
1515
- "であると考えている"は冗長な表現です。"である" または "と考えている"を省き簡潔な表現にすると文章が明瞭になります。
1616
- 参考: <http://www.atmarkit.co.jp/ait/articles/1001/19/news106_2.html>
17-
- "を行う"は冗長な表現です。"$1する"など簡潔な表現にすると文章が明瞭になります。
17+
- "を行う"は冗長な表現です。"する"など簡潔な表現にすると文章が明瞭になります。
1818
- 参考: <http://www.atmarkit.co.jp/ait/articles/1001/19/news106_2.html>
19-
- "を実行"は冗長な表現です。"$1する"など簡潔な表現にすると文章が明瞭になります。
19+
- "を実行"は冗長な表現です。"する"など簡潔な表現にすると文章が明瞭になります。
2020
- 参考: <http://www.atmarkit.co.jp/ait/articles/1001/19/news106_2.html>
2121

2222
## Install

src/dictionary.js

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
module.exports = [
44
{
55
// https://azu.github.io/morpheme-match/?text=省略(することが可能)。
6-
message: `"することが可能$1"は冗長な表現です。"することが可能"を省き簡潔な表現にすると文章が明瞭になります。`,
6+
message: `"すること$3可能$1"は冗長な表現です。"すること$3可能"を省き簡潔な表現にすると文章が明瞭になります。`,
77
url: "http://qiita.com/takahi-i/items/a93dc2ff42af6b93f6e0",
88
tokens: [
99
{
@@ -29,16 +29,9 @@ module.exports = [
2929
"reading": "コト",
3030
"pronunciation": "コト"
3131
}, {
32-
"surface_form": "が",
3332
"pos": "助詞",
34-
"pos_detail_1": "格助詞",
35-
"pos_detail_2": "一般",
36-
"pos_detail_3": "*",
37-
"conjugated_type": "*",
38-
"conjugated_form": "*",
39-
"basic_form": "が",
40-
"reading": "ガ",
41-
"pronunciation": "ガ"
33+
"_capture": "$3",
34+
"_readme": "[助詞]",
4235
}, {
4336
"surface_form": "可能",
4437
"pos": "名詞",
@@ -58,9 +51,9 @@ module.exports = [
5851
},
5952
{
6053
// https://azu.github.io/morpheme-match/?text=解析(することができます)。
61-
message: `"することが$1$2"は冗長な表現です。"することが"を省き簡潔な表現にすると文章が明瞭になります。`,
54+
message: `"すること$3$1$2"は冗長な表現です。"すること$3"を省き簡潔な表現にすると文章が明瞭になります。`,
6255
url: "http://qiita.com/takahi-i/items/a93dc2ff42af6b93f6e0",
63-
expected: "$1$2",
56+
expected: "$3$1$2",
6457
tokens: [
6558
{
6659
"surface_form": "する",
@@ -87,16 +80,17 @@ module.exports = [
8780
"pronunciation": "コト"
8881
},
8982
{
90-
"surface_form": "が",
9183
"pos": "助詞",
92-
"pos_detail_1": "格助詞",
93-
"pos_detail_2": "一般",
94-
"pos_detail_3": "*",
95-
"conjugated_type": "*",
96-
"conjugated_form": "*",
97-
"basic_form": "が",
98-
"reading": "ガ",
99-
"pronunciation": "ガ"
84+
"_capture": "$3",
85+
"_capture_to_expected": function(actualToken) {
86+
if (actualToken.surface_form === "も") {
87+
return "も"
88+
} else if (actualToken.surface_form === "は") {
89+
return "は"
90+
}
91+
return "";
92+
},
93+
"_readme": "[助詞]",
10094
},
10195
{
10296
"pos": "動詞",

src/index.js

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,38 @@
33
const tokenize = require("kuromojin").tokenize;
44
const dictionaryList = require("./dictionary");
55
const createMatchAll = require("morpheme-match-all");
6-
const replaceWithCaptureTokens = (text, tokens, actualTokens) => {
6+
7+
const replaceTokenWith = (matcherToken, actualToken, specialTo) => {
8+
// _captureがないのは無視
9+
if (!matcherToken._capture) {
10+
return null;
11+
}
12+
if (matcherToken[specialTo]) {
13+
return matcherToken[specialTo](actualToken);
14+
}
15+
return actualToken.surface_form;
16+
};
17+
const createExpected = ({text, matcherTokens, actualTokens}) => {
18+
let resultText = text;
19+
matcherTokens.forEach((token, index) => {
20+
const to = replaceTokenWith(token, actualTokens[index], "_capture_to_expected");
21+
if (to !== null) {
22+
resultText = resultText.split(token._capture).join(to);
23+
}
24+
});
25+
return resultText;
26+
};
27+
const createMessage = ({text, matcherTokens, actualTokens}) => {
728
let resultText = text;
8-
tokens.forEach((token, index) => {
9-
// _captureがないのは無視
10-
if (!token._capture) {
11-
return;
29+
matcherTokens.forEach((token, index) => {
30+
const to = replaceTokenWith(token, actualTokens[index], "_capture_to_message");
31+
if (to !== null) {
32+
resultText = resultText.split(token._capture).join(to);
1233
}
13-
const actualToken = actualTokens[index];
14-
resultText = resultText.split(token._capture).join(actualToken.surface_form);
1534
});
1635
return resultText;
1736
};
37+
1838
const reporter = (context) => {
1939
const {Syntax, RuleError, report, fixer, getSource} = context;
2040
const matchAll = createMatchAll(dictionaryList);
@@ -32,10 +52,18 @@ const reporter = (context) => {
3252
const firstWordIndex = Math.max(firstToken.word_position - 1, 0);
3353
const lastWorkIndex = Math.max(lastToken.word_position - 1, 0);
3454
// replace $1
35-
const message = replaceWithCaptureTokens(matchResult.dict.message, matchResult.dict.tokens, matchResult.tokens)
55+
const message = createMessage({
56+
text: matchResult.dict.message,
57+
matcherTokens: matchResult.dict.tokens,
58+
actualTokens: matchResult.tokens
59+
})
3660
+ (matchResult.dict.url ? `参考: ${matchResult.dict.url}` : "");
3761
const expected = matchResult.dict.expected
38-
? replaceWithCaptureTokens(matchResult.dict.expected, matchResult.dict.tokens, matchResult.tokens)
62+
? createExpected({
63+
text: matchResult.dict.expected,
64+
matcherTokens: matchResult.dict.tokens,
65+
actualTokens: matchResult.tokens
66+
})
3967
: undefined;
4068
if (expected) {
4169
report(node, new RuleError(message, {

test/index-test.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,24 @@ tester.run("textlint-rule-ja-no-redundant-expression", rule, {
3030
}
3131
]
3232
},
33+
{
34+
text: "これは省略することも可能だ。",
35+
errors: [
36+
{
37+
message: `"することも可能だ"は冗長な表現です。"することも可能"を省き簡潔な表現にすると文章が明瞭になります。参考: http://qiita.com/takahi-i/items/a93dc2ff42af6b93f6e0`,
38+
index: 5
39+
}
40+
]
41+
},
42+
{
43+
text: "これは省略することは可能だ。",
44+
errors: [
45+
{
46+
message: `"することは可能だ"は冗長な表現です。"することは可能"を省き簡潔な表現にすると文章が明瞭になります。参考: http://qiita.com/takahi-i/items/a93dc2ff42af6b93f6e0`,
47+
index: 5
48+
}
49+
]
50+
},
3351
{
3452
text: "必要なら解析することができます。",
3553
output: "必要なら解析できます。",
@@ -40,6 +58,36 @@ tester.run("textlint-rule-ja-no-redundant-expression", rule, {
4058
}
4159
]
4260
},
61+
{
62+
text: "解析することもできますよ。",
63+
output: "解析もできますよ。",
64+
errors: [
65+
{
66+
message: `"することもできます"は冗長な表現です。"することも"を省き簡潔な表現にすると文章が明瞭になります。参考: http://qiita.com/takahi-i/items/a93dc2ff42af6b93f6e0`,
67+
index: 2
68+
}
69+
]
70+
},
71+
{
72+
text: "解析することはできますよ。",
73+
output: "解析はできますよ。",
74+
errors: [
75+
{
76+
message: `"することはできます"は冗長な表現です。"することは"を省き簡潔な表現にすると文章が明瞭になります。参考: http://qiita.com/takahi-i/items/a93dc2ff42af6b93f6e0`,
77+
index: 2
78+
}
79+
]
80+
},
81+
{
82+
text: "解析することをできますよ。",
83+
output: "解析できますよ。",
84+
errors: [
85+
{
86+
message: `"することをできます"は冗長な表現です。"することを"を省き簡潔な表現にすると文章が明瞭になります。参考: http://qiita.com/takahi-i/items/a93dc2ff42af6b93f6e0`,
87+
index: 2
88+
}
89+
]
90+
},
4391
{
4492
text: "これは必要であると言えます。",
4593
errors: [

tools/update-readme.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,24 @@ const replaceWithCaptureTokens = (text, tokens) => {
1212
if (!token._capture) {
1313
return;
1414
}
15-
if (token.basic_form) {
16-
resultText = resultText.replace(token._capture, token.basic_form);
17-
}else{
18-
resultText = resultText.replace(token._capture, "");
15+
if (token._readme) {
16+
resultText = resultText.split(token._capture).join(token._readme);
17+
} else if (token.basic_form) {
18+
resultText = resultText.split(token._capture).join(token.basic_form);
19+
} else {
20+
resultText = resultText.split(token._capture).join("");
1921
}
2022
});
2123
return resultText;
2224
};
2325
const createExamples = (dictionaries) => {
2426
return dictionaries.map((dict) => {
25-
return `- ${replaceWithCaptureTokens(dict.message, dict.tokens)}` + (dict.url ? `\n - 参考: ${dict.url}` : "")
27+
return `- ${replaceWithCaptureTokens(dict.message, dict.tokens)}` + (dict.url ? `
28+
- 参考: ${dict.url}` : "")
2629
}).join("\n");
2730
};
2831

2932
const README_PATH = path.join(__dirname, "..", "README.md");
3033
const README = fs.readFileSync(README_PATH, "utf-8");
3134
const UpdatedREADM = addMarkdown(README, createExamples(dict), SectionName);
32-
fs.writeFileSync(README_PATH, UpdatedREADM, "utf-8");
35+
fs.writeFileSync(README_PATH, UpdatedREADM, "utf-8");

0 commit comments

Comments
 (0)