Skip to content

Commit cf12c2b

Browse files
authored
feat: improve error message (#56)
* feat: improve error message * test: update test case * fix
1 parent ea57481 commit cf12c2b

File tree

2 files changed

+211
-22
lines changed

2 files changed

+211
-22
lines changed

src/no-doubled-joshi.ts

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,50 @@ export interface Options {
107107
commaCharacters?: string[];
108108
}
109109

110+
interface ToTextWithPrevTokenParams {
111+
tokens: KuromojiToken[];
112+
sentence: SentenceNode;
113+
}
114+
115+
116+
/**
117+
* "~~~~~~{助詞}" から {Token}"{助詞}" という形になるように、前の単語を含めた助詞の文字列を取得する
118+
*
119+
* 前のNodeがStrの場合は、一つ前のTokenを取得する
120+
* {Str}{助詞} -> {Token}"{助詞}"
121+
*
122+
* それ以外のNodeの場合は、そのNodeの文字列を取得する
123+
* {Code}{助詞} -> {Code}"{助詞}"
124+
* {Strong}{助詞} -> {Strong}"{助詞}"
125+
*
126+
* @param token
127+
* @param tokens
128+
* @param sentence
129+
*/
130+
const toTextWithPrevWord = (token: KuromojiToken, { tokens, sentence }: ToTextWithPrevTokenParams) => {
131+
const index = tokens.indexOf(token);
132+
const prevToken = tokens[index - 1];
133+
// 前のTokenがない場合は、Tokenのsurface_formを返す
134+
const DEFAULT_RESULT = `"${token.surface_form}"`;
135+
if (!prevToken) {
136+
return DEFAULT_RESULT;
137+
}
138+
const originalIndex = prevToken.word_position - 1;
139+
if (originalIndex === undefined) {
140+
return DEFAULT_RESULT;
141+
}
142+
// Tokenの位置に該当するNodeを取得する
143+
const originalNode = sentence.children.find(node => {
144+
return node.range[0] <= originalIndex && originalIndex < node.range[1];
145+
});
146+
if (originalNode === undefined) {
147+
return DEFAULT_RESULT;
148+
}
149+
if (originalNode.type === "Str") {
150+
return `${prevToken.surface_form}"${token.surface_form}"`
151+
}
152+
return `${originalNode.raw}"${token.surface_form}"`;
153+
}
110154
/*
111155
1. Paragraph Node -> text
112156
2. text -> sentences
@@ -198,36 +242,53 @@ const report: TextlintRuleModule<Options> = function (context, options = {}) {
198242
}
199243
*/
200244
Object.keys(joshiTokenSurfaceKeyMap).forEach((key) => {
201-
const tokens: KuromojiToken[] = joshiTokenSurfaceKeyMap[key];
245+
const joshiTokenSurfaceTokens: KuromojiToken[] = joshiTokenSurfaceKeyMap[key];
202246
const joshiName = restoreToSurfaceFromKey(key);
203247
// check allow
204-
if (allow.indexOf(joshiName) >= 0) {
248+
if (allow.includes(joshiName)) {
205249
return;
206250
}
207251
// strict mode ではない時例外を除去する
208252
if (!isStrict) {
209-
if (matchExceptionRule(tokens)) {
253+
if (matchExceptionRule(joshiTokenSurfaceTokens)) {
210254
return;
211255
}
212256
}
213-
if (tokens.length <= 1) {
257+
if (joshiTokenSurfaceTokens.length <= 1) {
214258
return; // no duplicated token
215259
}
216260
// if found differenceIndex less than
217261
// tokes are sorted ascending order
218-
tokens.reduce((prev, current) => {
262+
joshiTokenSurfaceTokens.reduce((prev, current) => {
219263
const startPosition = countableTokens.indexOf(prev);
220264
const otherPosition = countableTokens.indexOf(current);
221265
// 助詞token同士の距離が設定値以下ならエラーを報告する
222266
const differenceIndex = otherPosition - startPosition;
223267
if (differenceIndex <= minInterval) {
268+
// 連続する助詞を集める
269+
const startWord = toTextWithPrevWord(prev, {
270+
tokens: tokens,
271+
sentence: sentence
272+
});
273+
const endWord = toTextWithPrevWord(current, {
274+
tokens: tokens,
275+
sentence: sentence
276+
});
224277
// padding positionを計算する
225278
const originalIndex = sentenceSource.originalIndexFromIndex(current.word_position - 1);
226279
report(
227280
// @ts-expect-error: SentenceNodeは独自であるため
228281
sentence,
229282
new RuleError(
230-
`一文に二回以上利用されている助詞 "${joshiName}" がみつかりました。`,
283+
`一文に二回以上利用されている助詞 "${joshiName}" がみつかりました。
284+
285+
次の助詞が連続しているため、文を読みにくくしています。
286+
287+
- ${startWord}
288+
- ${endWord}
289+
290+
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
291+
`,
231292
{
232293
index: originalIndex,
233294
}

test/no-doubled-joshi-test.ts

Lines changed: 144 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,15 @@ tester.run("no-double-joshi", rule, {
7474
text: "私は彼は好きだ",
7575
errors: [
7676
{
77-
message: `一文に二回以上利用されている助詞 "は" がみつかりました。`,
77+
message: `一文に二回以上利用されている助詞 "は" がみつかりました。
78+
79+
次の助詞が連続しているため、文を読みにくくしています。
80+
81+
- 私"は"
82+
- 彼"は"
83+
84+
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
85+
`,
7886
// last match
7987
line: 1,
8088
column: 4,
@@ -85,7 +93,15 @@ tester.run("no-double-joshi", rule, {
8593
text: "あなたは「私は彼は好きだ」と言った。",
8694
errors: [
8795
{
88-
message: `一文に二回以上利用されている助詞 "は" がみつかりました。`,
96+
message: `一文に二回以上利用されている助詞 "は" がみつかりました。
97+
98+
次の助詞が連続しているため、文を読みにくくしています。
99+
100+
- 私"は"
101+
- 彼"は"
102+
103+
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
104+
`,
89105
index: 8,
90106
},
91107
],
@@ -94,7 +110,15 @@ tester.run("no-double-joshi", rule, {
94110
text: "材料不足で代替素材で製品を作った。",
95111
errors: [
96112
{
97-
message: `一文に二回以上利用されている助詞 "で" がみつかりました。`,
113+
message: `一文に二回以上利用されている助詞 "で" がみつかりました。
114+
115+
次の助詞が連続しているため、文を読みにくくしています。
116+
117+
- 不足"で"
118+
- 素材"で"
119+
120+
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
121+
`,
98122
line: 1,
99123
column: 10,
100124
},
@@ -104,7 +128,15 @@ tester.run("no-double-joshi", rule, {
104128
text: "クォートで囲むことで文字列を作成できる点は、他の文字列リテラルと同じです。",
105129
errors: [
106130
{
107-
message: `一文に二回以上利用されている助詞 "で" がみつかりました。`,
131+
message: `一文に二回以上利用されている助詞 "で" がみつかりました。
132+
133+
次の助詞が連続しているため、文を読みにくくしています。
134+
135+
- クォート"で"
136+
- こと"で"
137+
138+
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
139+
`,
108140
index: 9,
109141
},
110142
],
@@ -113,7 +145,15 @@ tester.run("no-double-joshi", rule, {
113145
text: "列車事故でバスで振り替え輸送を行った。 ",
114146
errors: [
115147
{
116-
message: `一文に二回以上利用されている助詞 "で" がみつかりました。`,
148+
message: `一文に二回以上利用されている助詞 "で" がみつかりました。
149+
150+
次の助詞が連続しているため、文を読みにくくしています。
151+
152+
- 事故"で"
153+
- バス"で"
154+
155+
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
156+
`,
117157
line: 1,
118158
column: 8,
119159
},
@@ -126,12 +166,28 @@ tester.run("no-double-joshi", rule, {
126166
},
127167
errors: [
128168
{
129-
message: `一文に二回以上利用されている助詞 "で" がみつかりました。`,
169+
message: `一文に二回以上利用されている助詞 "で" がみつかりました。
170+
171+
次の助詞が連続しているため、文を読みにくくしています。
172+
173+
- 機"で"
174+
- 洗剤"で"
175+
176+
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
177+
`,
130178
line: 1,
131179
column: 17,
132180
},
133181
{
134-
message: `一文に二回以上利用されている助詞 "で" がみつかりました。`,
182+
message: `一文に二回以上利用されている助詞 "で" がみつかりました。
183+
184+
次の助詞が連続しているため、文を読みにくくしています。
185+
186+
- 洗剤"で"
187+
- 機"で"
188+
189+
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
190+
`,
135191
line: 1,
136192
column: 24,
137193
},
@@ -141,7 +197,15 @@ tester.run("no-double-joshi", rule, {
141197
text: "法律案は十三日の衆議院本会議で賛成多数で可決され、参議院に送付されます",
142198
errors: [
143199
{
144-
message: `一文に二回以上利用されている助詞 "で" がみつかりました。`,
200+
message: `一文に二回以上利用されている助詞 "で" がみつかりました。
201+
202+
次の助詞が連続しているため、文を読みにくくしています。
203+
204+
- 会議"で"
205+
- 多数"で"
206+
207+
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
208+
`,
145209
line: 1,
146210
column: 20,
147211
},
@@ -155,7 +219,15 @@ tester.run("no-double-joshi", rule, {
155219
},
156220
errors: [
157221
{
158-
message: `一文に二回以上利用されている助詞 "で" がみつかりました。`,
222+
message: `一文に二回以上利用されている助詞 "で" がみつかりました。
223+
224+
次の助詞が連続しているため、文を読みにくくしています。
225+
226+
- 表情"で"
227+
- 小声"で"
228+
229+
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
230+
`,
159231
line: 1,
160232
column: 15,
161233
},
@@ -168,7 +240,15 @@ tester.run("no-double-joshi", rule, {
168240
},
169241
errors: [
170242
{
171-
message: `一文に二回以上利用されている助詞 "で" がみつかりました。`,
243+
message: `一文に二回以上利用されている助詞 "で" がみつかりました。
244+
245+
次の助詞が連続しているため、文を読みにくくしています。
246+
247+
- 白装束"で"
248+
- 足どり"で"
249+
250+
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
251+
`,
172252
line: 1,
173253
column: 13,
174254
},
@@ -181,7 +261,15 @@ tester.run("no-double-joshi", rule, {
181261
},
182262
errors: [
183263
{
184-
message: `一文に二回以上利用されている助詞 "の" がみつかりました。`,
264+
message: `一文に二回以上利用されている助詞 "の" がみつかりました。
265+
266+
次の助詞が連続しているため、文を読みにくくしています。
267+
268+
- 既存"の"
269+
- コード"の"
270+
271+
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
272+
`,
185273
line: 1,
186274
column: 7,
187275
},
@@ -191,7 +279,15 @@ tester.run("no-double-joshi", rule, {
191279
text: "これは`obj.method`は何をしているかを示します。",
192280
errors: [
193281
{
194-
message: `一文に二回以上利用されている助詞 "は" がみつかりました。`,
282+
message: `一文に二回以上利用されている助詞 "は" がみつかりました。
283+
284+
次の助詞が連続しているため、文を読みにくくしています。
285+
286+
- これ"は"
287+
- \`obj.method\`"は"
288+
289+
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
290+
`,
195291
line: 1,
196292
column: 16,
197293
},
@@ -203,7 +299,15 @@ tester.run("no-double-joshi", rule, {
203299
text: "文字列にはそこには問題がある。",
204300
errors: [
205301
{
206-
message: `一文に二回以上利用されている助詞 "には" がみつかりました。`,
302+
message: `一文に二回以上利用されている助詞 "には" がみつかりました。
303+
304+
次の助詞が連続しているため、文を読みにくくしています。
305+
306+
- 列"には"
307+
- そこ"には"
308+
309+
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
310+
`,
207311
line: 1,
208312
column: 8,
209313
},
@@ -219,7 +323,15 @@ tester.run("no-double-joshi", rule, {
219323
* 複数articleを束ねてFirebaseへデプロイ`,
220324
errors: [
221325
{
222-
message: `一文に二回以上利用されている助詞 "は" がみつかりました。`,
326+
message: `一文に二回以上利用されている助詞 "は" がみつかりました。
327+
328+
次の助詞が連続しているため、文を読みにくくしています。
329+
330+
- サイト"は"
331+
- スライド"は"
332+
333+
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
334+
`,
223335
index: 19,
224336
},
225337
],
@@ -231,7 +343,15 @@ tester.run("no-double-joshi", rule, {
231343
options: { separatorCharacters: ["。"] },
232344
errors: [
233345
{
234-
message: `一文に二回以上利用されている助詞 "は" がみつかりました。`,
346+
message: `一文に二回以上利用されている助詞 "は" がみつかりました。
347+
348+
次の助詞が連続しているため、文を読みにくくしています。
349+
350+
- これ"は"
351+
- これ"は"
352+
353+
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
354+
`,
235355
index: 10,
236356
},
237357
],
@@ -242,7 +362,15 @@ tester.run("no-double-joshi", rule, {
242362
options: { commaCharacters: [] },
243363
errors: [
244364
{
245-
message: `一文に二回以上利用されている助詞 "が" がみつかりました。`,
365+
message: `一文に二回以上利用されている助詞 "が" がみつかりました。
366+
367+
次の助詞が連続しているため、文を読みにくくしています。
368+
369+
- これ"が"
370+
- これ"が"
371+
372+
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
373+
`,
246374
index: 12,
247375
},
248376
],

0 commit comments

Comments
 (0)