Skip to content

Commit 23b1759

Browse files
committed
initial commit
0 parents  commit 23b1759

File tree

11 files changed

+364
-0
lines changed

11 files changed

+364
-0
lines changed

.babelrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"presets": ["es2015"]
3+
}

.gitignore

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
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+

LICENSE

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2015 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: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## References
2+
3+
- http://repository.kulib.kyoto-u.ac.jp/dspace/bitstream/2433/187059/1/Ronko3_043.pdf

package.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"name": "textlint-rule-no-doubled-negative-ja",
3+
"repository": {
4+
"type": "git",
5+
"url": "git+https://github.com/azu/textlint-rule-no-doubled-negative-ja.git"
6+
},
7+
"author": "azu",
8+
"email": "azuciao@gmail.com",
9+
"homepage": "https://github.com/azu/textlint-rule-no-doubled-negative-ja",
10+
"license": "MIT",
11+
"bugs": {
12+
"url": "https://github.com/azu/textlint-rule-no-doubled-negative-ja/issues"
13+
},
14+
"version": "1.0.0",
15+
"description": "二重否定をチェックするtextlint rule",
16+
"main": "index.js",
17+
"directories": {
18+
"test": "test"
19+
},
20+
"scripts": {
21+
"test": "mocha"
22+
},
23+
"keywords": [
24+
"textlint"
25+
],
26+
"devDependencies": {
27+
"babel-cli": "^6.3.17",
28+
"babel-preset-es2015": "^6.3.13",
29+
"babel-register": "^6.3.13",
30+
"mocha": "^2.3.4",
31+
"textlint-tester": "^0.4.1"
32+
},
33+
"dependencies": {
34+
"kuromojin": "^1.1.0"
35+
}
36+
}

src/matchTokenStream.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// LICENSE : MIT
2+
"use strict";
3+
function matchToken(token, expectShape) {
4+
return Object.keys(expectShape).every(key => {
5+
const actualValue = token[key];
6+
const expectedValue = expectShape[key];
7+
return actualValue === expectedValue;
8+
})
9+
}
10+
export default function expectTokenStream(tokenStream) {
11+
let currentTokenPosition = 0;
12+
const tokenCount = tokenStream.length;
13+
return (token) => {
14+
const expectedToken = tokenStream[currentTokenPosition];
15+
if (matchToken(token, expectedToken)) {
16+
currentTokenPosition += 1;
17+
} else {
18+
// restart
19+
currentTokenPosition = 0;
20+
}
21+
// match
22+
if (currentTokenPosition === tokenCount) {
23+
// match -> reset
24+
currentTokenPosition = 0;
25+
return true;
26+
}
27+
return false;
28+
}
29+
}

src/no-doubled-negative-ja.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// LICENSE : MIT
2+
"use strict";
3+
// tokens -> event emitter -> return check
4+
import {getTokenizer} from "kuromojin";
5+
import NakumonaiRule from "./rules/なくもない";
6+
import NidemoNaiRule from "./rules/ないでも-ない";
7+
export default function (context) {
8+
const {Syntax,getSource, report,RuleError} = context;
9+
const ruleなくもない = NakumonaiRule(context);
10+
const ruleないでもない = NidemoNaiRule(context);
11+
return {
12+
[Syntax.Str](node){
13+
const text = getSource(node);
14+
const results = [];
15+
const pushError = (error) => {
16+
if (error) {
17+
results.push(error);
18+
}
19+
};
20+
return getTokenizer().then(tokenizer => {
21+
return tokenizer.tokenizeForSentence(text);
22+
}).then(tokens => {
23+
tokens.forEach(token => {
24+
pushError(ruleなくもない(token));
25+
pushError(ruleないでもない(token));
26+
});
27+
}).then(()=> {
28+
results.forEach(error => {
29+
report(node, error);
30+
})
31+
})
32+
}
33+
}
34+
35+
}

src/rules/ないでも-ない.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// LICENSE : MIT
2+
"use strict";
3+
/*
4+
5+
(b)「~ないでも / はない」
6+
~ない(否定助動詞/否定形容詞「ない」の連体形)+連用形「で」+とりたて助詞「も / は」+補助形容詞「ない」
7+
*/
8+
import matchTokenStream from "./../matchTokenStream";
9+
export default function (context) {
10+
const {RuleError} = context;
11+
const monaiTokens = [
12+
{
13+
"basic_form": "ない"
14+
},
15+
{
16+
"surface_form": "で",
17+
"pos": "助詞"
18+
},
19+
20+
{
21+
"surface_form": "も",
22+
"pos": "助詞"
23+
},
24+
{
25+
"basic_form": "ない",
26+
"pos": "形容詞"
27+
}
28+
];
29+
30+
const nakuhaTokens = [
31+
{
32+
"basic_form": "ない"
33+
},
34+
{
35+
"surface_form": "で",
36+
"conjugated_form": "連用形"
37+
},
38+
39+
{
40+
"surface_form": "は",
41+
"pos": "助詞"
42+
},
43+
{
44+
"basic_form": "ない",
45+
"pos": "形容詞"
46+
}
47+
];
48+
const matchPatternNaku = matchTokenStream(nakuhaTokens);
49+
const matchPatternMonai = matchTokenStream(monaiTokens);
50+
return (token) => {
51+
if (matchPatternNaku(token) || matchPatternMonai(token)) {
52+
// (a)「~なくは / もない」
53+
return new RuleError("二重否定: ~ない(否定助動詞/否定形容詞「ない」の連体形)+連用形「で」+とりたて助詞「も / は」+補助形容詞「ない」", {
54+
column: token.word_position - 1
55+
})
56+
}
57+
}
58+
}

src/rules/なくもない.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// LICENSE : MIT
2+
"use strict";
3+
/*
4+
(a)「~なくは / もない」
5+
「~なく」(否定助動詞 / 否定形容詞)「ない」の連用形)+とりたて助詞「は / も」+ 補助形容詞「ない」
6+
は: だが、それが事件の発端だったといえなくもない。
7+
も: いや、本音を言えば、それよりこちらの方が大事ではないかという思いもなくはなかった。
8+
*/
9+
import matchTokenStream from "./../matchTokenStream";
10+
export default function nakumonai(context) {
11+
const {RuleError} = context;
12+
const monaiTokens = [
13+
{
14+
"basic_form": "ない"
15+
},
16+
{
17+
"surface_form": "は",
18+
"pos": "助詞"
19+
},
20+
{
21+
"basic_form": "ない",
22+
"pos": "形容詞"
23+
}
24+
];
25+
26+
const nakuhaTokens = [
27+
{
28+
"basic_form": "ない"
29+
},
30+
{
31+
"surface_form": "も",
32+
"pos": "助詞"
33+
},
34+
{
35+
"basic_form": "ない",
36+
"pos": "形容詞"
37+
}
38+
];
39+
const matchPatternNaku = matchTokenStream(nakuhaTokens);
40+
const matchPatternMonai = matchTokenStream(monaiTokens);
41+
return (token) => {
42+
if (matchPatternNaku(token) || matchPatternMonai(token)) {
43+
// (a)「~なくは / もない」
44+
return new RuleError("二重否定: 「~なく」(否定助動詞 / 否定形容詞)「ない」の連用形)+とりたて助詞「は / も」+ 補助形容詞「ない」", {
45+
column: token.word_position - 1
46+
})
47+
}
48+
}
49+
}

test/mocha.opts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--compilers js:babel-register

0 commit comments

Comments
 (0)