@@ -3,6 +3,7 @@ import { StringSource } from "textlint-util-to-string";
3
3
import { RuleHelper } from "textlint-rule-helper" ;
4
4
import { createRegExp } from "@textlint/regexp-string-matcher" ;
5
5
import { TextlintRuleReporter } from "@textlint/types" ;
6
+ import { TxtNode , TxtParentNode } from "@textlint/ast-node-types" ;
6
7
7
8
function removeRangeFromString ( text : string , regExpStrings : string [ ] ) {
8
9
const patterns = regExpStrings . map ( ( pattern ) => {
@@ -17,20 +18,50 @@ function removeRangeFromString(text: string, regExpStrings: string[]) {
17
18
18
19
export type Options = {
19
20
max ?: number ;
21
+ /**
22
+ * The strings that match following patterns is un-count of the sentence
23
+ * See https://github.com/textlint/regexp-string-matcher
24
+ */
25
+ skipPatterns ?: string [ ] ;
26
+ /**
27
+ * If it is true, skip the count of following link node.
28
+ *
29
+ * [https://example.com](https://example.com)
30
+ * <https://example.com>
31
+ *
32
+ * UrlStringLink is has the title which is same of href.
33
+ */
34
+ skipUrlStringLink ?: boolean ;
35
+ /**
36
+ * @deprecated use skipPatterns
37
+ */
20
38
exclusionPatterns ?: string [ ] ;
21
39
} ;
22
40
const defaultOptions : Required < Options > = {
23
41
max : 100 ,
24
- // The strings that match following patterns is uncount of the sentence
25
- // See https://github.com/textlint/regexp-string-matcher
42
+ skipPatterns : [ ] ,
43
+ skipUrlStringLink : true ,
44
+ /**
45
+ * @deprecated
46
+ */
26
47
exclusionPatterns : [ ]
27
48
} ;
28
49
29
50
const reporter : TextlintRuleReporter < Options > = ( context , options = { } ) => {
30
51
const maxLength = options . max ?? defaultOptions . max ;
31
- const exclusionPatterns = options . exclusionPatterns ?? defaultOptions . exclusionPatterns ;
52
+ const skipPattern = options . skipPatterns ?? options . exclusionPatterns ?? defaultOptions . skipPatterns ;
53
+ const skipUrlStringLink = options . skipUrlStringLink ?? defaultOptions . skipUrlStringLink ;
32
54
const helper = new RuleHelper ( context ) ;
33
55
const { Syntax, RuleError, report } = context ;
56
+ const isUrlStringLink = ( node : TxtNode | TxtParentNode ) : boolean => {
57
+ if ( node . type !== Syntax . Link ) {
58
+ return false ;
59
+ }
60
+ const linkNode = node as TxtParentNode ;
61
+ const nodeText = new StringSource ( linkNode ) . toString ( ) ;
62
+ return node . url === nodeText ;
63
+ } ;
64
+
34
65
// toPlainText
35
66
return {
36
67
[ Syntax . Paragraph ] ( node ) {
@@ -47,17 +78,25 @@ const reporter: TextlintRuleReporter<Options> = (context, options = {}) => {
47
78
paragraph . children
48
79
. filter ( ( sentence ) => sentence . type === SentenceSyntax . Sentence )
49
80
. forEach ( ( sentence ) => {
81
+ const filteredSentence = skipUrlStringLink
82
+ ? {
83
+ ...sentence ,
84
+ children : sentence . children . filter ( ( sentenceChildNode : TxtNode | TxtParentNode ) => {
85
+ return ! isUrlStringLink ( sentenceChildNode ) ;
86
+ } )
87
+ }
88
+ : sentence ;
50
89
// @ts -expect-error: wrong types
51
- const source = new StringSource ( sentence ) ;
90
+ const source = new StringSource ( filteredSentence ) ;
52
91
const actualText = source . toString ( ) ;
53
- const sentenceText = removeRangeFromString ( actualText , exclusionPatterns ) ;
92
+ const sentenceText = removeRangeFromString ( actualText , skipPattern ) ;
54
93
// larger than > 100
55
94
const actualTextLength = actualText . length ;
56
95
const sentenceLength = sentenceText . length ;
57
96
if ( sentenceLength > maxLength ) {
58
- const startLine = sentence . loc . start . line ;
97
+ const startLine = filteredSentence . loc . start . line ;
59
98
report (
60
- sentence ,
99
+ filteredSentence ,
61
100
new RuleError ( `Line ${ startLine } sentence length(${
62
101
sentenceLength !== actualTextLength
63
102
? `${ sentenceLength } , original:${ actualTextLength } `
0 commit comments