Skip to content

Commit 1d35645

Browse files
authored
feat(rule): add textlint-rule-ja-space-around-link (#22)
1 parent 38320d1 commit 1d35645

File tree

5 files changed

+370
-0
lines changed

5 files changed

+370
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Change Log
2+
3+
All notable changes to this project will be documented in this file.
4+
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5+
6+
## [2.0.2](https://github.com/textlint-ja/textlint-rule-preset-ja-spacing/compare/v2.0.1...v2.0.2) (2020-09-09)
7+
8+
**Note:** Version bump only for package textlint-rule-ja-space-around-code
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# textlint-rule-ja-space-around-link [![textlint rule](https://img.shields.io/badge/textlint-fixable-green.svg?style=social)](https://textlint.github.io/)
2+
3+
リンクの周りをスペースで囲むかどうかを決めるtextlintルール
4+
5+
リンクとは[TxtAST](https://github.com/textlint/textlint/blob/master/docs/txtnode.md "TxtAST")`Link` nodeのことです。
6+
7+
このルールでは、リンクの前後が日本語である場合に半角スペースを入れるかを決定します。
8+
オプションでスペースの有無を決定できます。
9+
10+
[README](README.md) と日本語の間はスペースを空ける
11+
[README](README.md)と日本語の間はスペースを空けない
12+
13+
## Install
14+
15+
Install with [npm](https://www.npmjs.com/):
16+
17+
npm install textlint-rule-ja-space-around-link
18+
19+
## Usage
20+
21+
Via `.textlintrc`(Recommended)
22+
23+
```json
24+
{
25+
"rules": {
26+
"ja-space-around-link": true
27+
}
28+
}
29+
```
30+
31+
Via CLI
32+
33+
```
34+
textlint --rule ja-space-around-link README.md
35+
```
36+
37+
38+
## Options
39+
40+
- `before`: `boolean`
41+
- デフォルト: `false`
42+
- `true`なら、`Link`の前に半角スペースを入れる
43+
- `after`: `boolean`
44+
- デフォルト: `false`
45+
- `true`なら、`Link`の後に半角スペースを入れる
46+
47+
デフォルト値は次のようになります。
48+
49+
```json
50+
{
51+
"rules": {
52+
"ja-space-around-link": {
53+
"before": false,
54+
"after": false
55+
}
56+
}
57+
}
58+
```
59+
60+
## Fixable
61+
62+
[![textlint rule](https://img.shields.io/badge/textlint-fixable-green.svg?style=social)](https://textlint.github.io/)
63+
64+
`textlint --fix`の自動修正に対応しています。
65+
66+
## Changelog
67+
68+
See [Releases page](https://github.com/textlint-ja/textlint-rule-preset-ja-spacing/releases).
69+
70+
## Running tests
71+
72+
Install devDependencies and Run `npm test`:
73+
74+
npm i -d && npm test
75+
76+
## Contributing
77+
78+
Pull requests and stars are always welcome.
79+
80+
For bugs and feature requests, [please create an issue](https://github.com/textlint-ja/textlint-rule-preset-ja-spacing/issues).
81+
82+
1. Fork it!
83+
2. Create your feature branch: `git checkout -b my-new-feature`
84+
3. Commit your changes: `git commit -am 'Add some feature'`
85+
4. Push to the branch: `git push origin my-new-feature`
86+
5. Submit a pull request :D
87+
88+
## Author
89+
90+
- [github/0x6b](https://github.com/0x6b)
91+
92+
## License
93+
94+
MIT © 0x6b
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"name": "textlint-rule-ja-space-around-link",
3+
"version": "2.0.2",
4+
"description": "リンクの周りをスペースで囲むかどうかを決めるtextlintルール",
5+
"main": "lib/index.js",
6+
"files": [
7+
"src/",
8+
"lib/"
9+
],
10+
"repository": {
11+
"type": "git",
12+
"url": "git+https://github.com/textlint-ja/textlint-rule-preset-ja-spacing.git"
13+
},
14+
"author": "0x6b",
15+
"homepage": "https://github.com/textlint-ja/textlint-rule-preset-ja-spacing",
16+
"license": "MIT",
17+
"bugs": {
18+
"url": "https://github.com/textlint-ja/textlint-rule-preset-ja-spacing/issues"
19+
},
20+
"scripts": {
21+
"build": "textlint-scripts build",
22+
"watch": "textlint-scripts build --watch",
23+
"prepublish": "npm run --if-present build",
24+
"test": "textlint-scripts test"
25+
},
26+
"keywords": [
27+
"textlint",
28+
"textlintrule"
29+
],
30+
"devDependencies": {
31+
"textlint-scripts": "^3.0.0"
32+
},
33+
"dependencies": {
34+
"match-index": "^1.0.1",
35+
"textlint-rule-helper": "^2.0.0"
36+
}
37+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// LICENSE : MIT
2+
"use strict";
3+
const isJapaneseChar = (text) => {
4+
return /^(?:[\u3400-\u4DBF\u4E00-\u9FFF\uF900-\uFAFF]|[\uD840-\uD87F][\uDC00-\uDFFF]|[--])$/.test(
5+
text
6+
);
7+
};
8+
const defaultOptions = {
9+
before: false,
10+
after: false,
11+
};
12+
function reporter(context, options) {
13+
const { Syntax, RuleError, report, fixer, getSource } = context;
14+
const allowBeforeSpace = options.before || defaultOptions.before;
15+
const allowAfterSpace = options.after || defaultOptions.after;
16+
return {
17+
[Syntax.Link](node) {
18+
const nodeText = getSource(node);
19+
// | `code` |
20+
// InlineCodeの前後2文字文を取得
21+
// スペース + 前後の文字を取るため
22+
// 文字が日本語以外はチェック対象にしないようにするため
23+
const textWithPadding = getSource(node, 2, 2);
24+
if (!textWithPadding) {
25+
return;
26+
}
27+
const beforeChar = textWithPadding[1];
28+
const beforeBeforeChar = textWithPadding[0];
29+
const existBeforeChar = nodeText[0] !== beforeChar;
30+
const afterChar = textWithPadding[textWithPadding.length - 2];
31+
const afterAfterChar = textWithPadding[textWithPadding.length - 1];
32+
const existAfterChar = nodeText[textWithPadding.length - 1] !== afterChar;
33+
// InlineCodeの前に文字が存在している時のみチェック
34+
if (existBeforeChar) {
35+
if (allowBeforeSpace) {
36+
if (beforeChar !== " " && isJapaneseChar(beforeChar)) {
37+
report(
38+
node,
39+
new RuleError("リンクの前にスペースを入れてください。", {
40+
index: -1, // before `
41+
fix: fixer.insertTextBeforeRange([0, 0], " "),
42+
})
43+
);
44+
}
45+
} else {
46+
if (beforeChar === " " && isJapaneseChar(beforeBeforeChar)) {
47+
report(
48+
node,
49+
new RuleError("リンクの前にスペースを入れません。", {
50+
index: -1, // before `
51+
fix: fixer.replaceTextRange([-1, 0], ""),
52+
})
53+
);
54+
}
55+
}
56+
}
57+
// InlineCodeの後に文字が存在している時のみチェック
58+
if (existAfterChar) {
59+
if (allowAfterSpace) {
60+
if (afterChar !== " " && isJapaneseChar(beforeChar)) {
61+
report(
62+
node,
63+
new RuleError("リンクの後にスペースを入れてください。", {
64+
index: nodeText.length,
65+
fix: fixer.insertTextAfterRange([0, nodeText.length], " "),
66+
})
67+
);
68+
}
69+
} else {
70+
if (afterChar === " " && isJapaneseChar(afterAfterChar)) {
71+
report(
72+
node,
73+
new RuleError("リンクの後にスペースを入れません。", {
74+
index: nodeText.length + 1,
75+
fix: fixer.replaceTextRange(
76+
[nodeText.length, nodeText.length + 1],
77+
""
78+
),
79+
})
80+
);
81+
}
82+
}
83+
}
84+
},
85+
};
86+
}
87+
module.exports = {
88+
linter: reporter,
89+
fixer: reporter,
90+
};
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
// LICENSE : MIT
2+
"use strict";
3+
import TextLintTester from "textlint-tester";
4+
import rule from "../src/index";
5+
6+
var tester = new TextLintTester();
7+
tester.run("Link周りのスペース", rule, {
8+
valid: [
9+
{
10+
text: "[README](./README.md) と日本語の間はスペースを空ける",
11+
options: {
12+
before: true,
13+
after: true,
14+
},
15+
},
16+
{
17+
text: "[README](./README.md)と日本語の間はスペースを空けない",
18+
options: {
19+
before: false,
20+
after: false,
21+
},
22+
},
23+
{
24+
text: "[README](./README.md) is good in english text.",
25+
options: {
26+
before: false,
27+
after: false,
28+
},
29+
},
30+
{
31+
text: "[`README`](./README.md) と日本語の間はスペースを空ける",
32+
options: {
33+
before: true,
34+
after: true,
35+
},
36+
},
37+
{
38+
text: "[`README`](./README.md)と日本語の間はスペースを空けない",
39+
options: {
40+
before: false,
41+
after: false,
42+
},
43+
},
44+
{
45+
text: "[`README`](./README.md) is good in english text.",
46+
options: {
47+
before: false,
48+
after: false,
49+
},
50+
},
51+
{
52+
text: "[**README**](./README.md) と日本語の間はスペースを空ける",
53+
options: {
54+
before: true,
55+
after: true,
56+
},
57+
},
58+
{
59+
text: "[**README**](./README.md)と日本語の間はスペースを空けない",
60+
options: {
61+
before: false,
62+
after: false,
63+
},
64+
},
65+
{
66+
text: "[**README**](./README.md) is good in english text.",
67+
options: {
68+
before: false,
69+
after: false,
70+
},
71+
},
72+
],
73+
invalid: [
74+
// before only
75+
{
76+
text: "これは [README](./README.md) おかしい",
77+
output: "これは [README](./README.md)おかしい",
78+
options: {
79+
before: true,
80+
after: false,
81+
},
82+
errors: [
83+
{
84+
message: "リンクの後にスペースを入れません。",
85+
column: 27,
86+
},
87+
],
88+
},
89+
// after only
90+
{
91+
text: "これは [README](./README.md) おかしい",
92+
output: "これは[README](./README.md) おかしい",
93+
options: {
94+
before: false,
95+
after: true,
96+
},
97+
errors: [
98+
{
99+
message: "リンクの前にスペースを入れません。",
100+
column: 4,
101+
},
102+
],
103+
},
104+
{
105+
text: "これは [README](./README.md) おかしい",
106+
output: "これは[README](./README.md)おかしい",
107+
options: {
108+
before: false,
109+
after: false,
110+
},
111+
errors: [
112+
{
113+
message: "リンクの前にスペースを入れません。",
114+
column: 4,
115+
},
116+
{
117+
message: "リンクの後にスペースを入れません。",
118+
column: 27,
119+
},
120+
],
121+
},
122+
{
123+
text: "これは[README](./README.md)おかしい",
124+
output: "これは [README](./README.md) おかしい",
125+
options: {
126+
before: true,
127+
after: true,
128+
},
129+
errors: [
130+
{
131+
message: "リンクの前にスペースを入れてください。",
132+
column: 3,
133+
},
134+
{
135+
message: "リンクの後にスペースを入れてください。",
136+
column: 25,
137+
},
138+
],
139+
},
140+
],
141+
});

0 commit comments

Comments
 (0)