Skip to content

かっこ と スペースに関するルールの修正とオプションの追加 #127

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,42 @@ A. 正規表現の辞書ベースのルールが幾つかあります。
}
```

Q. 半角かっこの外側のスペースを禁止したい・必須にしたい

A. オプションで半角かっこの外側のスペースの扱いを変更することが出来ます。

[3.3.かっこ類と隣接する文字の間のスペースの有無](./src/3.3.js)のオプションを設定することで、半角かっこの外側のスペースの扱いを変更することができます。

`allowOutsideHalfParentheses` は半角かっこの外側の半角スペースを許容するオプションです。
デフォルトは `true` です。
`false` に設定することで、半角かっこの外側のスペースを禁止できます。

```json5
{
"rules": {
"preset-jtf-style": {
"3.3.かっこ類と隣接する文字の間のスペースの有無": {
"allowOutsideHalfParentheses": false
}
}
}
}
```

`requireOutsideHalfParentheses` は半角かっこの外側の半角スペースを必須にするオプションです。
デフォルトは `false` です。

```json5
{
"rules": {
"preset-jtf-style": {
"3.3.かっこ類と隣接する文字の間のスペースの有無": {
"requireOutsideHalfParentheses": true
}
}
}
}
```

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

Expand Down
48 changes: 44 additions & 4 deletions src/3.3.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,27 @@
*/
import { isUserWrittenNode } from "./util/node-util";
import { matchCaptureGroupAll } from "match-index";
import { japaneseRegExp } from "./util/regexp";

const brackets = ["\\[", "\\]", "(", ")", "[", "]", "「", "」", "『", "』"];

const brackets = ["\\(", "\\)", "\\[", "\\]", "(", ")", "[", "]", "「", "」", "『", "』"];
const leftBrackets = brackets.map((bracket) => {
return new RegExp("([  ])" + bracket, "g");
});
const rightBrackets = brackets.map((bracket) => {
return new RegExp(bracket + "([  ])", "g");
});
function reporter(context) {
const leftHalfParentheses = new RegExp(`${japaneseRegExp.source}(\\()`, "g");
const rightHalfParentheses = new RegExp(`(\\))${japaneseRegExp.source}`, "g");
const defaultOptions = {
allowOutsideHalfParentheses: true,
requireOutsideHalfParentheses: false
};
function reporter(context, options) {
let { Syntax, RuleError, report, fixer, getSource } = context;
const allowOutsideHalfParentheses =
options.allowOutsideHalfParentheses ?? defaultOptions.allowOutsideHalfParentheses;
const requireOutsideHalfParentheses =
options.requireOutsideHalfParentheses ?? defaultOptions.requireOutsideHalfParentheses;
Comment on lines +28 to +29
Copy link
Member

@azu azu Nov 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defaultOptions.requireOutsideHalfParentheses
こちらってデフォルト値が未定義になっています?
明示的に入れた方がいいので、 defaultOptions.requireOutsideHalfParentheses を定義するのがよさそうですね

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

コメントありがとうございます。
すみません、こちらデフォルト値の定義が漏れていたため追加いたしました。

return {
[Syntax.Str](node) {
if (!isUserWrittenNode(node, context)) {
Expand All @@ -27,6 +37,9 @@ function reporter(context) {
leftBrackets.forEach((pattern) => {
matchCaptureGroupAll(text, pattern).forEach((match) => {
const { index } = match;
if (allowOutsideHalfParentheses && text.substring(index, index + 2) === " (") {
return;
}
report(
node,
new RuleError("かっこの外側、内側ともにスペースを入れません。", {
Expand All @@ -39,7 +52,10 @@ function reporter(context) {
// 右にスペース
rightBrackets.forEach((pattern) => {
matchCaptureGroupAll(text, pattern).forEach((match) => {
const { index, text } = match;
const { index } = match;
if (allowOutsideHalfParentheses && text.substring(index - 1, index + 1) === ") ") {
return;
}
report(
node,
new RuleError("かっこの外側、内側ともにスペースを入れません。", {
Expand All @@ -49,6 +65,30 @@ function reporter(context) {
);
});
});
if (requireOutsideHalfParentheses) {
// 左にスペース必須
matchCaptureGroupAll(text, leftHalfParentheses).forEach((match) => {
const { index } = match;
report(
node,
new RuleError("半角かっこの外側に半角スペースが必要です。", {
index,
fix: fixer.replaceTextRange([index, index + 1], " " + match.text)
})
);
});
// 右にスペース必須
matchCaptureGroupAll(text, rightHalfParentheses).forEach((match) => {
const { index } = match;
report(
node,
new RuleError("半角かっこの外側に半角スペースが必要です。", {
index,
fix: fixer.replaceTextRange([index, index + 1], match.text + " ")
})
);
});
}
}
};
}
Expand Down
8 changes: 4 additions & 4 deletions src/4.3.1.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ function reporter(context) {
// 半角のかっこ()は使用しないで全角のかっこを使用する
const text = getSource(node);
const matchRegExps = [
// FIXME: https://github.com/textlint-ja/textlint-rule-preset-JTF-style/issues/79
// rx`([\(\)])(?:${japaneseRegExp}+)([\(\)])`,
// rx`([\(\)])(?:${japaneseRegExp})`,
rx`(?:${japaneseRegExp})([\(\)])`
rx`([\(\)])(?:.*${japaneseRegExp}.*)([\(\)])`,
rx`(?:${japaneseRegExp})([\(\)])(?:${japaneseRegExp})`,
rx`^(\()(?:${japaneseRegExp})`,
rx`(?:${japaneseRegExp})(\))$`
];
matchRegExps.forEach((matchRegExp) => {
matchCaptureGroupAll(text, matchRegExp).forEach((match) => {
Expand Down
63 changes: 62 additions & 1 deletion test/3.3-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,19 @@ tester.run("3.3.かっこ類と隣接する文字の間のスペースの有無"
valid: [
"「良い」",
"テスト[文章]です",
"これは (test) です",
`
実装をみてもらうと分かりますが、JavaScriptの\`prototype\`の仕組みをそのまま利用しています。
そのため、特別な実装は必要なく
「拡張する時は\`calculator.prototype\`の代わりに\`calculator.fn\`を拡張してください」
というルールがあるだけとも言えます。
`
`,
{
text: "Page(s)",
options: {
requireOutsideHalfParentheses: true
}
}
],
invalid: [
{
Expand All @@ -31,6 +38,60 @@ tester.run("3.3.かっこ類と隣接する文字の間のスペースの有無"
}
]
},
{
text: "これは (ダメ) です",
output: "これは(ダメ)です",
errors: [
{
message: "かっこの外側、内側ともにスペースを入れません。",
line: 1,
column: 4
},
{
message: "かっこの外側、内側ともにスペースを入れません。",
line: 1,
column: 9
}
]
},
{
text: "これはダメ (test) です",
output: "これはダメ(test)です",
options: {
allowOutsideHalfParentheses: false
},
errors: [
{
message: "かっこの外側、内側ともにスペースを入れません。",
line: 1,
column: 6
},
{
message: "かっこの外側、内側ともにスペースを入れません。",
line: 1,
column: 13
}
]
},
{
text: "これはダメ(test)です",
output: "これはダメ (test) です",
options: {
requireOutsideHalfParentheses: true
},
errors: [
{
message: "半角かっこの外側に半角スペースが必要です。",
line: 1,
column: 6
},
{
message: "半角かっこの外側に半角スペースが必要です。",
line: 1,
column: 11
}
]
},
{
text: `TEST

Expand Down
100 changes: 66 additions & 34 deletions test/4.3.1-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ var tester = new TextLintTester();
tester.run("4.3.1.丸かっこ()", rule, {
valid: [
"クォーク(物質の素粒子)",
"(物質の素粒子)クォーク",
"(物質の素粒子)",
"(npm 2.x以上をインストールしている必要があります)",
"(必要バージョン: 2.x)",
// 英語のみの半角括弧は許可
// https://github.com/textlint-ja/textlint-rule-preset-JTF-style/issues/79
"これは (English text in half-width parens) です。"
"これは (English text in half-width parens) です。",
"これは(English text in half-width parens)です。"
],
invalid: [
{
Expand All @@ -28,41 +31,70 @@ tester.run("4.3.1.丸かっこ()", rule, {
}
]
},
// // FIXME: https://github.com/textlint-ja/textlint-rule-preset-JTF-style/issues/79
// {
// // 半角かっこ
// text: "(物質の素粒子)",
// output: "(物質の素粒子)",
// errors: [
// {
// message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
// column: 1
// },
// {
// message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
// column: 8
// }
// ]
// },
// {
// // 半角かっこ
// text: "(npm 2.x以上をインストールしている必要があります)",
// output: "(npm 2.x以上をインストールしている必要があります)",
// errors: [
// {
// message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
// column: 1
// },
// {
// message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
// column: 29
// }
// ]
// },
{
// 半角かっこ
text: "例)test",
output: "例)test",
text: "(物質の素粒子)クォーク",
output: "(物質の素粒子)クォーク",
errors: [
{
message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
column: 1
},
{
message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
column: 8
}
]
},
{
// 半角かっこ
text: "(物質の素粒子)",
output: "(物質の素粒子)",
errors: [
{
message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
column: 1
},
{
message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
column: 8
}
]
},
{
// 半角かっこ
text: "(npm 2.x以上をインストールしている必要があります)",
output: "(npm 2.x以上をインストールしている必要があります)",
errors: [
{
message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
column: 1
},
{
message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
column: 29
}
]
},
{
// 半角かっこ
text: "(必要バージョン: 2.x)",
output: "(必要バージョン: 2.x)",
errors: [
{
message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
column: 1
},
{
message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
column: 14
}
]
},
{
// 半角かっこ
text: "例)テスト",
output: "例)テスト",
errors: [
{
message: "半角のかっこ()が使用されています。全角のかっこ()を使用してください。",
Expand Down
12 changes: 11 additions & 1 deletion test/fixtures/input.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ JTF 標準

これは 「ダメ」です

これは (ダメ) です

A氏は「5月に新製品を発売します。」と述べました。

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

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

例)test
(物質の素粒子)クォーク

(物質の素粒子)

(npm 2.x以上をインストールしている必要があります)

(必要バージョン: 2.x)

例)テスト

半角[かっこ

Expand Down
12 changes: 11 additions & 1 deletion test/fixtures/output.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ JTF標準

これは「ダメ」です

これは(ダメ)です

A氏は「5月に新製品を発売します」と述べました。

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

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

例)test
(物質の素粒子)クォーク

(物質の素粒子)

(npm 2.x以上をインストールしている必要があります)

(必要バージョン: 2.x)

例)テスト

半角[かっこ

Expand Down
Loading