1
1
// LICENSE : MIT
2
2
"use strict" ;
3
- import { RuleHelper } from "textlint-rule-helper"
3
+ import { RuleHelper } from "textlint-rule-helper" ;
4
4
import { getTokenizer } from "kuromojin" ;
5
5
import { splitAST , Syntax as SentenceSyntax } from "sentence-splitter" ;
6
6
import { StringSource } from "textlint-util-to-string" ;
7
+ import { SeparatorParser } from "sentence-splitter/lib/parser/SeparatorParser" ;
7
8
8
9
const defaultOptions = {
9
- max : 3 , // 1文に利用できる最大の、の数
10
- strict : false // 例外ルールを適応するかどうか
10
+ // 1文に利用できる最大の、の数
11
+ max : 3 ,
12
+ // 例外ルールを適応するかどうか,
13
+ strict : false ,
14
+ // 読点として扱う文字
15
+ // https://ja.wikipedia.org/wiki/%E8%AA%AD%E7%82%B9
16
+ touten : "、" ,
17
+ // 句点として扱う文字
18
+ // https://ja.wikipedia.org/wiki/%E5%8F%A5%E7%82%B9
19
+ kuten : "。"
11
20
} ;
12
21
13
- function isSandwichedMeishi ( {
14
- before,
15
- token,
16
- after
17
- } ) {
22
+ function isSandwichedMeishi ( { before, token, after } ) {
18
23
if ( before === undefined || after === undefined || token === undefined ) {
19
24
return false ;
20
25
}
@@ -23,20 +28,31 @@ function isSandwichedMeishi({
23
28
24
29
/**
25
30
* @param {RuleContext } context
26
- * @param {object } [options]
31
+ * @param {typeof defaultOptions } [options]
27
32
*/
28
33
module . exports = function ( context , options = { } ) {
29
- const maxLen = options . max || defaultOptions . max ;
30
- const isStrict = options . strict || defaultOptions . strict ;
34
+ const maxLen = options . max ?? defaultOptions . max ;
35
+ const isStrict = options . strict ?? defaultOptions . strict ;
36
+ const touten = options . touten ?? defaultOptions . touten ;
37
+ const kuten = options . kuten ?? defaultOptions . kuten ;
31
38
const helper = new RuleHelper ( context ) ;
32
39
const { Syntax, RuleError, report, getSource } = context ;
33
40
return {
34
41
[ Syntax . Paragraph ] ( node ) {
35
42
if ( helper . isChildNode ( node , [ Syntax . BlockQuote ] ) ) {
36
43
return ;
37
44
}
38
- const resultNode = splitAST ( node ) ;
39
- const sentences = resultNode . children . filter ( childNode => childNode . type === SentenceSyntax . Sentence ) ;
45
+ const resultNode = splitAST ( node , {
46
+ SeparatorParser : {
47
+ separatorCharacters : [
48
+ "?" , // question mark
49
+ "!" , // exclamation mark
50
+ "?" , // (ja) zenkaku question mark
51
+ "!" // (ja) zenkaku exclamation mark
52
+ ] . concat ( kuten )
53
+ }
54
+ } ) ;
55
+ const sentences = resultNode . children . filter ( ( childNode ) => childNode . type === SentenceSyntax . Sentence ) ;
40
56
/*
41
57
<p>
42
58
<str><code><img><str>
@@ -49,18 +65,18 @@ module.exports = function (context, options = {}) {
49
65
2. sentence to tokens
50
66
3. check tokens
51
67
*/
52
- return getTokenizer ( ) . then ( tokenizer => {
53
- sentences . forEach ( sentence => {
68
+ return getTokenizer ( ) . then ( ( tokenizer ) => {
69
+ sentences . forEach ( ( sentence ) => {
54
70
const source = new StringSource ( sentence ) ;
55
71
const text = source . toString ( ) ;
56
72
const tokens = tokenizer . tokenizeForSentence ( text ) ;
57
73
let currentTenCount = 0 ;
58
74
let lastToken = null ;
59
75
tokens . forEach ( ( token , index ) => {
60
- let surface = token . surface_form ;
61
- if ( surface === "、" ) {
76
+ const surface = token . surface_form ;
77
+ if ( surface === touten ) {
62
78
// 名詞に囲まわれている場合は例外とする
63
- let isSandwiched = isSandwichedMeishi ( {
79
+ const isSandwiched = isSandwichedMeishi ( {
64
80
before : tokens [ index - 1 ] ,
65
81
token : token ,
66
82
after : tokens [ index + 1 ]
@@ -80,15 +96,18 @@ module.exports = function (context, options = {}) {
80
96
if ( currentTenCount >= maxLen ) {
81
97
const positionInSentence = source . originalIndexFromIndex ( lastToken . word_position - 1 ) ;
82
98
const index = sentence . range [ 0 ] + positionInSentence ;
83
- const ruleError = new context . RuleError ( `一つの文で"、"を${ maxLen } つ以上使用しています` , {
84
- index
85
- } ) ;
99
+ const ruleError = new context . RuleError (
100
+ `一つの文で"${ touten } "を${ maxLen } つ以上使用しています` ,
101
+ {
102
+ index
103
+ }
104
+ ) ;
86
105
report ( node , ruleError ) ;
87
106
currentTenCount = 0 ;
88
107
}
89
108
} ) ;
90
109
} ) ;
91
110
} ) ;
92
111
}
93
- }
94
- }
112
+ } ;
113
+ } ;
0 commit comments