Skip to content

Commit c09baf3

Browse files
authored
かっこ と スペースに関するルールの修正とオプションの追加 (#127)
* feat(4.3.1): 一部の条件で半角かっこをエラーにしない かっこの内側または外側が日本語以外のとき、半角かっこをエラーにしない。 ただし、かっこ内に日本語が含まれる場合は全角かっこを必須とする。 * feat(3.3): 半角かっこも検知するように修正 * chore(test): add support for options to create-fixtures * feat(3.3): 半角かっこのときに外側のスペースを許容するオプションを追加 * feat(3.3): 半角かっこのときに外側のスペースを必須にするオプションを追加 * docs(readme): add faq about 3.3
1 parent 19eb72c commit c09baf3

File tree

8 files changed

+238
-47
lines changed

8 files changed

+238
-47
lines changed

README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,42 @@ A. 正規表現の辞書ベースのルールが幾つかあります。
655655
}
656656
```
657657

658+
Q. 半角かっこの外側のスペースを禁止したい・必須にしたい
659+
660+
A. オプションで半角かっこの外側のスペースの扱いを変更することが出来ます。
661+
662+
[3.3.かっこ類と隣接する文字の間のスペースの有無](./src/3.3.js)のオプションを設定することで、半角かっこの外側のスペースの扱いを変更することができます。
663+
664+
`allowOutsideHalfParentheses` は半角かっこの外側の半角スペースを許容するオプションです。
665+
デフォルトは `true` です。
666+
`false` に設定することで、半角かっこの外側のスペースを禁止できます。
667+
668+
```json5
669+
{
670+
"rules": {
671+
"preset-jtf-style": {
672+
"3.3.かっこ類と隣接する文字の間のスペースの有無": {
673+
"allowOutsideHalfParentheses": false
674+
}
675+
}
676+
}
677+
}
678+
```
679+
680+
`requireOutsideHalfParentheses` は半角かっこの外側の半角スペースを必須にするオプションです。
681+
デフォルトは `false` です。
682+
683+
```json5
684+
{
685+
"rules": {
686+
"preset-jtf-style": {
687+
"3.3.かっこ類と隣接する文字の間のスペースの有無": {
688+
"requireOutsideHalfParentheses": true
689+
}
690+
}
691+
}
692+
}
693+
```
658694

659695
## Migration: `textlint-plugin-jtf-style` to `textlint-rule-preset-jtf-style`
660696

src/3.3.js

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,27 @@
66
*/
77
import { isUserWrittenNode } from "./util/node-util";
88
import { matchCaptureGroupAll } from "match-index";
9+
import { japaneseRegExp } from "./util/regexp";
910

10-
const brackets = ["\\[", "\\]", "(", ")", "[", "]", "「", "」", "『", "』"];
11-
11+
const brackets = ["\\(", "\\)", "\\[", "\\]", "(", ")", "[", "]", "「", "」", "『", "』"];
1212
const leftBrackets = brackets.map((bracket) => {
1313
return new RegExp("([  ])" + bracket, "g");
1414
});
1515
const rightBrackets = brackets.map((bracket) => {
1616
return new RegExp(bracket + "([  ])", "g");
1717
});
18-
function reporter(context) {
18+
const leftHalfParentheses = new RegExp(`${japaneseRegExp.source}(\\()`, "g");
19+
const rightHalfParentheses = new RegExp(`(\\))${japaneseRegExp.source}`, "g");
20+
const defaultOptions = {
21+
allowOutsideHalfParentheses: true,
22+
requireOutsideHalfParentheses: false
23+
};
24+
function reporter(context, options) {
1925
let { Syntax, RuleError, report, fixer, getSource } = context;
26+
const allowOutsideHalfParentheses =
27+
options.allowOutsideHalfParentheses ?? defaultOptions.allowOutsideHalfParentheses;
28+
const requireOutsideHalfParentheses =
29+
options.requireOutsideHalfParentheses ?? defaultOptions.requireOutsideHalfParentheses;
2030
return {
2131
[Syntax.Str](node) {
2232
if (!isUserWrittenNode(node, context)) {
@@ -27,6 +37,9 @@ function reporter(context) {
2737
leftBrackets.forEach((pattern) => {
2838
matchCaptureGroupAll(text, pattern).forEach((match) => {
2939
const { index } = match;
40+
if (allowOutsideHalfParentheses && text.substring(index, index + 2) === " (") {
41+
return;
42+
}
3043
report(
3144
node,
3245
new RuleError("かっこの外側、内側ともにスペースを入れません。", {
@@ -39,7 +52,10 @@ function reporter(context) {
3952
// 右にスペース
4053
rightBrackets.forEach((pattern) => {
4154
matchCaptureGroupAll(text, pattern).forEach((match) => {
42-
const { index, text } = match;
55+
const { index } = match;
56+
if (allowOutsideHalfParentheses && text.substring(index - 1, index + 1) === ") ") {
57+
return;
58+
}
4359
report(
4460
node,
4561
new RuleError("かっこの外側、内側ともにスペースを入れません。", {
@@ -49,6 +65,30 @@ function reporter(context) {
4965
);
5066
});
5167
});
68+
if (requireOutsideHalfParentheses) {
69+
// 左にスペース必須
70+
matchCaptureGroupAll(text, leftHalfParentheses).forEach((match) => {
71+
const { index } = match;
72+
report(
73+
node,
74+
new RuleError("半角かっこの外側に半角スペースが必要です。", {
75+
index,
76+
fix: fixer.replaceTextRange([index, index + 1], " " + match.text)
77+
})
78+
);
79+
});
80+
// 右にスペース必須
81+
matchCaptureGroupAll(text, rightHalfParentheses).forEach((match) => {
82+
const { index } = match;
83+
report(
84+
node,
85+
new RuleError("半角かっこの外側に半角スペースが必要です。", {
86+
index,
87+
fix: fixer.replaceTextRange([index, index + 1], match.text + " ")
88+
})
89+
);
90+
});
91+
}
5292
}
5393
};
5494
}

src/4.3.1.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ function reporter(context) {
3131
// 半角のかっこ()は使用しないで全角のかっこを使用する
3232
const text = getSource(node);
3333
const matchRegExps = [
34-
// FIXME: https://github.com/textlint-ja/textlint-rule-preset-JTF-style/issues/79
35-
// rx`([\(\)])(?:${japaneseRegExp}+)([\(\)])`,
36-
// rx`([\(\)])(?:${japaneseRegExp})`,
37-
rx`(?:${japaneseRegExp})([\(\)])`
34+
rx`([\(\)])(?:.*${japaneseRegExp}.*)([\(\)])`,
35+
rx`(?:${japaneseRegExp})([\(\)])(?:${japaneseRegExp})`,
36+
rx`^(\()(?:${japaneseRegExp})`,
37+
rx`(?:${japaneseRegExp})(\))$`
3838
];
3939
matchRegExps.forEach((matchRegExp) => {
4040
matchCaptureGroupAll(text, matchRegExp).forEach((match) => {

test/3.3-test.js

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,19 @@ tester.run("3.3.かっこ類と隣接する文字の間のスペースの有無"
77
valid: [
88
"「良い」",
99
"テスト[文章]です",
10+
"これは (test) です",
1011
`
1112
実装をみてもらうと分かりますが、JavaScriptの\`prototype\`の仕組みをそのまま利用しています。
1213
そのため、特別な実装は必要なく
1314
「拡張する時は\`calculator.prototype\`の代わりに\`calculator.fn\`を拡張してください」
1415
というルールがあるだけとも言えます。
15-
`
16+
`,
17+
{
18+
text: "Page(s)",
19+
options: {
20+
requireOutsideHalfParentheses: true
21+
}
22+
}
1623
],
1724
invalid: [
1825
{
@@ -31,6 +38,60 @@ tester.run("3.3.かっこ類と隣接する文字の間のスペースの有無"
3138
}
3239
]
3340
},
41+
{
42+
text: "これは (ダメ) です",
43+
output: "これは(ダメ)です",
44+
errors: [
45+
{
46+
message: "かっこの外側、内側ともにスペースを入れません。",
47+
line: 1,
48+
column: 4
49+
},
50+
{
51+
message: "かっこの外側、内側ともにスペースを入れません。",
52+
line: 1,
53+
column: 9
54+
}
55+
]
56+
},
57+
{
58+
text: "これはダメ (test) です",
59+
output: "これはダメ(test)です",
60+
options: {
61+
allowOutsideHalfParentheses: false
62+
},
63+
errors: [
64+
{
65+
message: "かっこの外側、内側ともにスペースを入れません。",
66+
line: 1,
67+
column: 6
68+
},
69+
{
70+
message: "かっこの外側、内側ともにスペースを入れません。",
71+
line: 1,
72+
column: 13
73+
}
74+
]
75+
},
76+
{
77+
text: "これはダメ(test)です",
78+
output: "これはダメ (test) です",
79+
options: {
80+
requireOutsideHalfParentheses: true
81+
},
82+
errors: [
83+
{
84+
message: "半角かっこの外側に半角スペースが必要です。",
85+
line: 1,
86+
column: 6
87+
},
88+
{
89+
message: "半角かっこの外側に半角スペースが必要です。",
90+
line: 1,
91+
column: 11
92+
}
93+
]
94+
},
3495
{
3596
text: `TEST
3697

test/4.3.1-test.js

Lines changed: 66 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@ var tester = new TextLintTester();
66
tester.run("4.3.1.丸かっこ()", rule, {
77
valid: [
88
"クォーク(物質の素粒子)",
9+
"(物質の素粒子)クォーク",
910
"(物質の素粒子)",
1011
"(npm 2.x以上をインストールしている必要があります)",
12+
"(必要バージョン: 2.x)",
1113
// 英語のみの半角括弧は許可
1214
// https://github.com/textlint-ja/textlint-rule-preset-JTF-style/issues/79
13-
"これは (English text in half-width parens) です。"
15+
"これは (English text in half-width parens) です。",
16+
"これは(English text in half-width parens)です。"
1417
],
1518
invalid: [
1619
{
@@ -28,41 +31,70 @@ tester.run("4.3.1.丸かっこ()", rule, {
2831
}
2932
]
3033
},
31-
// // FIXME: https://github.com/textlint-ja/textlint-rule-preset-JTF-style/issues/79
32-
// {
33-
// // 半角かっこ
34-
// text: "(物質の素粒子)",
35-
// output: "(物質の素粒子)",
36-
// errors: [
37-
// {
38-
// message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
39-
// column: 1
40-
// },
41-
// {
42-
// message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
43-
// column: 8
44-
// }
45-
// ]
46-
// },
47-
// {
48-
// // 半角かっこ
49-
// text: "(npm 2.x以上をインストールしている必要があります)",
50-
// output: "(npm 2.x以上をインストールしている必要があります)",
51-
// errors: [
52-
// {
53-
// message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
54-
// column: 1
55-
// },
56-
// {
57-
// message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
58-
// column: 29
59-
// }
60-
// ]
61-
// },
6234
{
6335
// 半角かっこ
64-
text: "例)test",
65-
output: "例)test",
36+
text: "(物質の素粒子)クォーク",
37+
output: "(物質の素粒子)クォーク",
38+
errors: [
39+
{
40+
message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
41+
column: 1
42+
},
43+
{
44+
message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
45+
column: 8
46+
}
47+
]
48+
},
49+
{
50+
// 半角かっこ
51+
text: "(物質の素粒子)",
52+
output: "(物質の素粒子)",
53+
errors: [
54+
{
55+
message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
56+
column: 1
57+
},
58+
{
59+
message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
60+
column: 8
61+
}
62+
]
63+
},
64+
{
65+
// 半角かっこ
66+
text: "(npm 2.x以上をインストールしている必要があります)",
67+
output: "(npm 2.x以上をインストールしている必要があります)",
68+
errors: [
69+
{
70+
message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
71+
column: 1
72+
},
73+
{
74+
message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
75+
column: 29
76+
}
77+
]
78+
},
79+
{
80+
// 半角かっこ
81+
text: "(必要バージョン: 2.x)",
82+
output: "(必要バージョン: 2.x)",
83+
errors: [
84+
{
85+
message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
86+
column: 1
87+
},
88+
{
89+
message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
90+
column: 14
91+
}
92+
]
93+
},
94+
{
95+
// 半角かっこ
96+
text: "例)テスト",
97+
output: "例)テスト",
6698
errors: [
6799
{
68100
message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",

test/fixtures/input.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ JTF 標準
7373

7474
これは 「ダメ」です
7575

76+
これは (ダメ) です
77+
7678
A氏は「5月に新製品を発売します。」と述べました。
7779

7880
従業員は約30,000人です(関連企業を含みます。)
@@ -91,7 +93,15 @@ A氏は「5月に新製品を発売します。」と述べました。
9193

9294
クォーク(物質の素粒子)
9395

94-
例)test
96+
(物質の素粒子)クォーク
97+
98+
(物質の素粒子)
99+
100+
(npm 2.x以上をインストールしている必要があります)
101+
102+
(必要バージョン: 2.x)
103+
104+
例)テスト
95105

96106
半角[かっこ
97107

test/fixtures/output.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ JTF標準
7373

7474
これは「ダメ」です
7575

76+
これは(ダメ)です
77+
7678
A氏は「5月に新製品を発売します」と述べました。
7779

7880
従業員は約30,000人です(関連企業を含みます)
@@ -91,7 +93,15 @@ A氏は「5月に新製品を発売します」と述べました。
9193

9294
クォーク(物質の素粒子)
9395

94-
例)test
96+
(物質の素粒子)クォーク
97+
98+
(物質の素粒子)
99+
100+
(npm 2.x以上をインストールしている必要があります)
101+
102+
(必要バージョン: 2.x)
103+
104+
例)テスト
95105

96106
半角[かっこ
97107

0 commit comments

Comments
 (0)