Skip to content

Commit dd7f239

Browse files
committed
feat(rule): ignore \w言語
1 parent 53d9cc6 commit dd7f239

File tree

4 files changed

+58
-7
lines changed

4 files changed

+58
-7
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,9 @@ textlint --rule ja-unnatural-alphabet README.md
4949

5050
- `allow`: `string[]`
5151
- 無視するアルファベットの配列
52-
- デフォルト: `["a", "i", "u", "e", "o", "n"]`
52+
- デフォルト: `["a", "i", "u", "e", "o", "n", "/[a-zA-Za-zA-Z]言語/"]`
5353
- デフォルトでは母音とnを除外している
54+
- `"/正規表現/" のような文字列もサポート
5455

5556
```json5
5657
{

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"textlint-scripts": "^1.2.2"
3535
},
3636
"dependencies": {
37+
"escape-string-regexp": "^1.0.5",
3738
"match-index": "^1.0.1",
3839
"regx": "^1.0.4"
3940
}

src/textlint-rule-ja-unnatural-alphabet.js

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
// MIT © 2017 azu
22
"use strict";
3+
const escapeStringRegexp = require('escape-string-regexp');
34
const matchCaptureGroupAll = require("match-index").matchCaptureGroupAll;
45
const regx = require("regx").default;
56
// IME的に入力されそうな文字列
67
// 日本語 + 記号
7-
const japaneseRegExp = /(?:[\u3400-\u4DBF\u4E00-\u9FFF\uF900-\uFAFF]|[\uD840-\uD87F][\uDC00-\uDFFF]|[--])/;
8+
const japaneseRegExp = /(?:[\u3400-\u4DBF\u4E00-\u9FFF\uF900-\uFAFF]|[\uD840-\uD87F]|[\uFF00-\uFFEF]|[\uDC00-\uDFFF]|[--])/;
89
// 半角/全角のアルファベットの正規表現
910
const alphabetPattern = /([a-zA-Z--])/;
1011
/**
@@ -21,21 +22,59 @@ const matchUnnaturalAlphabet = (text) => {
2122
return matchCaptureGroupAll(text, unnaturalPattern);
2223
};
2324

25+
/**
26+
* if actual is in the `exceptGroups`, return true
27+
* @param {MatchCaptureGroup[]} exceptGroups
28+
* @param {MatchCaptureGroup} actual
29+
* @returns {boolean}
30+
*/
31+
const isIgnoredRange = (exceptGroups, actual) => {
32+
return exceptGroups.some(({ text, index }) => {
33+
const endIndex = index + text.length;
34+
return index <= actual.index && actual.index <= endIndex;
35+
});
36+
};
37+
/***
38+
*
39+
* @param {string} input
40+
* @param {string[]} allowAlphabets
41+
* @returns {MatchCaptureGroup[]}
42+
*/
43+
const createIgnoreRanges = (input, allowAlphabets) => {
44+
// str -> RegExp
45+
const patterns = allowAlphabets.map(allowWord => {
46+
if (!allowWord) {
47+
return /^$/;
48+
}
49+
if (allowWord[0] === "/" && allowWord[allowWord.length - 1] === "/") {
50+
const regExpString = allowWord.slice(1, allowWord.length - 1);
51+
return new RegExp(`(${regExpString})`, "g");
52+
}
53+
const escapeString = escapeStringRegexp(allowWord);
54+
return new RegExp(`(${escapeString})`, "g");
55+
});
56+
return patterns.reduce((total, pattern) => {
57+
return total.concat(matchCaptureGroupAll(input, pattern));
58+
}, []);
59+
};
60+
2461
const defaultOptions = {
2562
// 無視するアルファベット
2663
// 例) ["X"]
27-
// デフォルトでは母音とnを除外している
28-
"allow": ["a", "i", "u", "e", "o", "n"]
64+
// デフォルトでは母音とnと典型例を除外している
65+
"allow": ["a", "i", "u", "e", "o", "n", "/[a-zA-Za-zA-Z]言語/"]
2966
};
3067
const report = (context, options = {}) => {
3168
const { Syntax, RuleError, report, getSource } = context;
3269
const allowAlphabets = options.allow || defaultOptions.allow;
3370
return {
3471
[Syntax.Str](node){
3572
const text = getSource(node);
36-
matchUnnaturalAlphabet(text).forEach(({ text, index }) => {
37-
// 無視するアルファベットであるなら無視
38-
if (allowAlphabets.indexOf(text) !== -1) {
73+
const ignoreMatch = createIgnoreRanges(text, allowAlphabets);
74+
matchUnnaturalAlphabet(text).forEach((actual) => {
75+
const { text, index } = actual;
76+
// 無視する単語を含んでいるなら無視
77+
if (isIgnoredRange(ignoreMatch, actual)) {
3978
return;
4079
}
4180
report(node, new RuleError(`不自然なアルファベットがあります: ${text}`, {

test/textlint-rule-ja-unnatural-alphabet-test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ tester.run("textlint-rule-ja-unnatural-alphabet", rule, {
1010
"リリース",
1111
"aiueo",
1212
"This is pen.",
13+
"これはC言語",
14+
"これはD言語",
1315
{
1416
text: "アンドロイドNは良し",
1517
options: {
@@ -33,6 +35,14 @@ tester.run("textlint-rule-ja-unnatural-alphabet", rule, {
3335
message: "不自然なアルファベットがあります: k"
3436
}
3537
]
38+
},
39+
{
40+
text: "無駄なk脳",
41+
errors: [
42+
{
43+
message: "不自然なアルファベットがあります: k"
44+
}
45+
]
3646
}
3747
]
3848
});

0 commit comments

Comments
 (0)