Skip to content

Commit ed8a5d7

Browse files
committed
Initial Commit
0 parents  commit ed8a5d7

File tree

7 files changed

+406
-0
lines changed

7 files changed

+406
-0
lines changed

.gitignore

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
### https://raw.github.com/github/gitignore/608690d6b9a78c2a003affc792e49a84905b3118/Node.gitignore
2+
3+
# Logs
4+
logs
5+
*.log
6+
7+
# Runtime data
8+
pids
9+
*.pid
10+
*.seed
11+
12+
# Directory for instrumented libs generated by jscoverage/JSCover
13+
lib-cov
14+
15+
# Coverage directory used by tools like istanbul
16+
coverage
17+
18+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
19+
.grunt
20+
21+
# node-waf configuration
22+
.lock-wscript
23+
24+
# Compiled binary addons (http://nodejs.org/api/addons.html)
25+
build/Release
26+
27+
# Dependency directory
28+
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
29+
node_modules
30+
31+
# Debug log from npm
32+
npm-debug.log
33+
34+
35+
### https://raw.github.com/github/gitignore/608690d6b9a78c2a003affc792e49a84905b3118/Global/JetBrains.gitignore
36+
37+
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
38+
39+
*.iml
40+
41+
## Directory-based project format:
42+
.idea/
43+
# if you remove the above rule, at least ignore the following:
44+
45+
# User-specific stuff:
46+
# .idea/workspace.xml
47+
# .idea/tasks.xml
48+
# .idea/dictionaries
49+
50+
# Sensitive or high-churn files:
51+
# .idea/dataSources.ids
52+
# .idea/dataSources.xml
53+
# .idea/sqlDataSources.xml
54+
# .idea/dynamic.xml
55+
# .idea/uiDesigner.xml
56+
57+
# Gradle:
58+
# .idea/gradle.xml
59+
# .idea/libraries
60+
61+
# Mongo Explorer plugin:
62+
# .idea/mongoSettings.xml
63+
64+
## File-based project format:
65+
*.ipr
66+
*.iws
67+
68+
## Plugin-specific files:
69+
70+
# IntelliJ
71+
out/
72+
73+
# mpeltonen/sbt-idea plugin
74+
.idea_modules/
75+
76+
# JIRA plugin
77+
atlassian-ide-plugin.xml
78+
79+
# Crashlytics plugin (for Android Studio and IntelliJ)
80+
com_crashlytics_export_strings.xml
81+
crashlytics.properties
82+
crashlytics-build.properties
83+
84+
85+
/lib

.travis.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
sudo: false
2+
language: node_js
3+
node_js: "stable"

LICENSE

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2016 azu
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is
8+
furnished to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
SOFTWARE.

README.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# textlint-rule-date-weekday-mismatch [![textlint rule](https://img.shields.io/badge/textlint-fixable-green.svg?style=social)](https://textlint.github.io/)
2+
3+
textlint rule that found mismatch date and weekday.
4+
5+
**OK**:
6+
7+
Correct date and weekday.
8+
9+
2016-12-29(Thursday)
10+
11+
**NG**:
12+
13+
Incorrect date and weekday.
14+
15+
2016-12-29(Friday)
16+
17+
// Error:
18+
2016-12-29(Friday) mismatch weekday.
19+
2016-12-29(Friday) => 2016-12-29(Thursday)
20+
21+
## Supported lang
22+
23+
- en
24+
- ja(日本語)
25+
- es
26+
- fr
27+
- zh
28+
29+
This rule depended on following library:
30+
31+
- [wanasit/chrono](https://github.com/wanasit/chrono)
32+
- [Moment.js](http://momentjs.com/)
33+
34+
## Install
35+
36+
Install with [npm](https://www.npmjs.com/):
37+
38+
npm install textlint-rule-date-weekday-mismatch
39+
40+
## Usage
41+
42+
Via `.textlintrc`(Recommended)
43+
44+
```json
45+
{
46+
"rules": {
47+
"date-weekday-mismatch": true
48+
}
49+
}
50+
```
51+
52+
Via CLI
53+
54+
```
55+
textlint --rule date-weekday-mismatch README.md
56+
```
57+
58+
## Acknowledge
59+
60+
- [日付曜日矛盾 // Speaker Deck](https://speakerdeck.com/shirayu/ri-fu-yao-ri-mao-dun "日付曜日矛盾 // Speaker Deck")
61+
62+
## Changelog
63+
64+
See [Releases page](https://github.com/azu/textlint-rule-date-weekday-mismatch/releases).
65+
66+
## Running tests
67+
68+
Install devDependencies and Run `npm test`:
69+
70+
npm i -d && npm test
71+
72+
## Contributing
73+
74+
Pull requests and stars are always welcome.
75+
76+
For bugs and feature requests, [please create an issue](https://github.com/azu/textlint-rule-date-weekday-mismatch/issues).
77+
78+
1. Fork it!
79+
2. Create your feature branch: `git checkout -b my-new-feature`
80+
3. Commit your changes: `git commit -am 'Add some feature'`
81+
4. Push to the branch: `git push origin my-new-feature`
82+
5. Submit a pull request :D
83+
84+
## Author
85+
86+
- [github/azu](https://github.com/azu)
87+
- [twitter/azu_re](https://twitter.com/azu_re)
88+
89+
## License
90+
91+
MIT © azu

package.json

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"directories": {
3+
"test": "test"
4+
},
5+
"author": "azu",
6+
"license": "MIT",
7+
"files": [
8+
"bin/",
9+
"lib/",
10+
"src/"
11+
],
12+
"name": "textlint-rule-date-weekday-mismatch",
13+
"version": "1.0.0",
14+
"description": "textlint rule that found mismatch date and weekday.",
15+
"main": "lib/textlint-rule-date-weekday-mismatch.js",
16+
"scripts": {
17+
"test": "textlint-scripts test",
18+
"prepublish": "npm run --if-present build",
19+
"build": "textlint-scripts build",
20+
"watch": "textlint-scripts build --watch"
21+
},
22+
"repository": {
23+
"type": "git",
24+
"url": "https://github.com/azu/textlint-rule-date-weekday-mismatch.git"
25+
},
26+
"bugs": {
27+
"url": "https://github.com/azu/textlint-rule-date-weekday-mismatch/issues"
28+
},
29+
"homepage": "https://github.com/azu/textlint-rule-date-weekday-mismatch",
30+
"devDependencies": {
31+
"textlint-scripts": "^1.2.2"
32+
},
33+
"keywords": [
34+
"textlintrule"
35+
],
36+
"dependencies": {
37+
"chrono-node": "^1.2.5",
38+
"intl": "^1.2.5",
39+
"moment": "^2.17.1"
40+
}
41+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// MIT © 2016 azu
2+
"use strict";
3+
const chrono = require("chrono-node");
4+
const moment = require('moment');
5+
/**
6+
* from chrono tags
7+
* @type {[RegExp]}
8+
*/
9+
const supportedLang = [
10+
[/^EN/, "en"],
11+
[/^JP/, "ja"],
12+
[/^ES/, "es"],
13+
[/^FR/, "fr"],
14+
[/^ZH/, "zh"]
15+
];
16+
17+
/**
18+
* detect lang and return language string
19+
* @param {string[]} tags
20+
* @returns {string|null}
21+
*/
22+
const detectLang = (tags) => {
23+
const targetLangs = supportedLang.filter(([langRegExp]) => {
24+
return tags.some(tag => langRegExp.test(tag));
25+
});
26+
if (targetLangs.length === 0) {
27+
return null;
28+
}
29+
const selectedLang = targetLangs[0];
30+
return selectedLang[1];
31+
};
32+
function reporter(context) {
33+
const {Syntax, RuleError, report, fixer, getSource} = context;
34+
if (typeof Intl === "undefined") {
35+
throw new Error("Not support your Node.js/browser. should be use latest version.");
36+
}
37+
return {
38+
[Syntax.Str](node){
39+
const text = getSource(node);
40+
const chronoDate = chrono.parse(text);
41+
chronoDate.forEach(chronoDate => {
42+
const lang = detectLang(Object.keys(chronoDate.tags));
43+
if (!lang) {
44+
// not found lang
45+
return;
46+
}
47+
// change lang
48+
moment.locale(lang);
49+
// get weekday from actual date string
50+
const kV = chronoDate.start.knownValues;
51+
const $moment = moment(`${kV.year}-${kV.month}-${kV.day}`, "YYYY-MM-DD", lang);
52+
const slicedText = text.slice(chronoDate.index);
53+
// (match) or (match)
54+
const match = slicedText.match(/\s*?([(])([^()]+)([)])/);
55+
if (!match) {
56+
return;
57+
}
58+
const actualDateText = match[0];
59+
const actualTextAll = `${chronoDate.text}${actualDateText}`;
60+
const pairStartSymbol = match[1];// (
61+
const pairEndSymbol = match[3]; // )
62+
const maybeWeekdayText = match[2].trim(); // weekday
63+
// 2016年12月30日 (金曜日)
64+
// ^ ^ ^
65+
// chronoDate.index match.index pairStartSymbol.length
66+
const paddingIndex = chronoDate.index + match.index + pairStartSymbol.length;
67+
// format http://momentjs.com/docs/#/parsing/string-format/
68+
const weekdayPatterns = [
69+
// date-format , symbols
70+
["dd", moment.weekdaysMin()],
71+
["ddd", moment.weekdaysShort()],
72+
["dddd", moment.weekdays()]
73+
];
74+
weekdayPatterns.forEach(([format, symbols]) => {
75+
if (symbols.indexOf(maybeWeekdayText) === -1) {
76+
return;
77+
}
78+
// e.g.) "Friday"
79+
const expectedWeekday = $moment.format(format);
80+
if (maybeWeekdayText !== expectedWeekday) {
81+
const fix = fixer.replaceTextRange(
82+
[paddingIndex, paddingIndex + expectedWeekday.length],
83+
expectedWeekday
84+
);
85+
report(node, new RuleError(`${actualTextAll} mismatch weekday.\n${actualTextAll} => ${chronoDate.text}${pairStartSymbol}${expectedWeekday}${pairEndSymbol}`, {
86+
index: paddingIndex,
87+
fix
88+
}));
89+
}
90+
});
91+
});
92+
}
93+
};
94+
}
95+
module.exports = {
96+
linter: reporter,
97+
fixer: reporter
98+
};

0 commit comments

Comments
 (0)