1
1
// LICENSE : MIT
2
2
"use strict" ;
3
- import { RuleHelper } from "textlint-rule-helper"
4
- import { getTokenizer } from "kuromojin" ;
5
- import { split as splitSentences } from "sentence-splitter" ;
6
- import Source from "structured-source" ;
3
+ import { RuleHelper } from "textlint-rule-helper"
4
+ import { getTokenizer } from "kuromojin" ;
5
+ import { splitAST , Syntax as SentenceSyntax } from "sentence-splitter" ;
6
+ import { StringSource } from "textlint-util-to-string" ;
7
+
7
8
const defaultOptions = {
8
9
max : 3 , // 1文に利用できる最大の、の数
9
10
strict : false // 例外ルールを適応するかどうか
10
11
} ;
11
12
12
13
function isSandwichedMeishi ( {
13
- before,
14
- token,
15
- after
16
- } ) {
14
+ before,
15
+ token,
16
+ after
17
+ } ) {
17
18
if ( before === undefined || after === undefined || token === undefined ) {
18
19
return false ;
19
20
}
20
21
return before . pos === "名詞" && after . pos === "名詞" ;
21
22
}
22
- /**
23
- * add two positions.
24
- * note: line starts with 1, column starts with 0.
25
- * @param {Position } base
26
- * @param {Position } relative
27
- * @return {Position }
28
- */
29
- function addPositions ( base , relative ) {
30
- return {
31
- line : base . line + relative . line - 1 , // line 1 + line 1 should be line 1
32
- column : relative . line == 1 ? base . column + relative . column // when the same line
33
- : relative . column // when another line
34
- } ;
35
- }
23
+
36
24
/**
37
25
* @param {RuleContext } context
38
26
* @param {object } [options]
39
27
*/
40
- module . exports = function ( context , options = { } ) {
28
+ module . exports = function ( context , options = { } ) {
41
29
const maxLen = options . max || defaultOptions . max ;
42
30
const isStrict = options . strict || defaultOptions . strict ;
43
- let helper = new RuleHelper ( context ) ;
44
- let { Syntax, RuleError, report, getSource} = context ;
31
+ const helper = new RuleHelper ( context ) ;
32
+ const { Syntax, RuleError, report, getSource } = context ;
45
33
return {
46
- [ Syntax . Paragraph ] ( node ) {
34
+ [ Syntax . Paragraph ] ( node ) {
47
35
if ( helper . isChildNode ( node , [ Syntax . BlockQuote ] ) ) {
48
36
return ;
49
37
}
50
- let sentences = splitSentences ( getSource ( node ) , {
51
- charRegExp : / [ 。 \? \! ? ! ] / ,
52
- newLineCharacters : "\n\n"
53
- } ) ;
38
+ const resultNode = splitAST ( node ) ;
39
+ const sentences = resultNode . children . filter ( childNode => childNode . type === SentenceSyntax . Sentence ) ;
54
40
/*
55
41
<p>
56
42
<str><code><img><str>
@@ -65,10 +51,10 @@ module.exports = function(context, options = {}) {
65
51
*/
66
52
return getTokenizer ( ) . then ( tokenizer => {
67
53
sentences . forEach ( sentence => {
68
- let text = sentence . value ;
69
- let source = new Source ( text ) ;
54
+ const source = new StringSource ( sentence ) ;
55
+ const text = source . toString ( ) ;
56
+ const tokens = tokenizer . tokenizeForSentence ( text ) ;
70
57
let currentTenCount = 0 ;
71
- let tokens = tokenizer . tokenizeForSentence ( text ) ;
72
58
let lastToken = null ;
73
59
tokens . forEach ( ( token , index ) => {
74
60
let surface = token . surface_form ;
@@ -92,11 +78,10 @@ module.exports = function(context, options = {}) {
92
78
}
93
79
// report
94
80
if ( currentTenCount >= maxLen ) {
95
- let positionInSentence = source . indexToPosition ( lastToken . word_position - 1 ) ;
96
- let positionInNode = addPositions ( sentence . loc . start , positionInSentence ) ;
97
- let ruleError = new context . RuleError ( `一つの文で"、"を${ maxLen } つ以上使用しています` , {
98
- line : positionInNode . line - 1 ,
99
- column : positionInNode . column
81
+ const positionInSentence = source . originalIndexFromIndex ( lastToken . word_position - 1 ) ;
82
+ const index = sentence . range [ 0 ] + positionInSentence ;
83
+ const ruleError = new context . RuleError ( `一つの文で"、"を${ maxLen } つ以上使用しています` , {
84
+ index
100
85
} ) ;
101
86
report ( node , ruleError ) ;
102
87
currentTenCount = 0 ;
0 commit comments