-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtextlint-rule-en-max-word-count.js
85 lines (82 loc) · 3.29 KB
/
textlint-rule-en-max-word-count.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Helper for creating new AST using map function
// https://github.com/azu/unist-util-map
// if you want to filter, use https://github.com/eush77/unist-util-filter
import map from "unist-util-map";
// Helper for converting plain text from Syntax-ed text(markdown AST
// https://github.com/azu/textlint-util-to-string
import { StringSource } from "textlint-util-to-string";
// Helper for splitting text to sentences
// https://github.com/azu/sentence-splitter
import { split as splitSentence, Syntax as SplitterSyntax } from "sentence-splitter";
// Helper for splitting text to words
// https://github.com/timjrobinson/split-string-words
import { splitWords } from "./split-words";
// Default options
const defaultOptions = {
// max count of words >
max: 50
};
/**
* @param {TextLintRuleContext} context
* @param {Object} options
*/
function report(context, options = {}) {
const { Syntax, getSource, RuleError, report, locator } = context;
const maxWordCount = options.max ? options.max : defaultOptions.max;
return {
[Syntax.Paragraph](node) {
// replace code with dummy code
// if you want to filter(remove) code, use https://github.com/eush77/unist-util-filter
const filteredNode = map(node, (node) => {
if (node.type === Syntax.Code) {
// only change `value` to dummy
return {
...node,
value: "code"
}
}
return node;
});
const source = new StringSource(filteredNode);
// text in a paragraph
const text = source.toString();
// get sentences from Paragraph
const sentences = splitSentence(text).filter(node => {
// ignore break line
return node.type === SplitterSyntax.Sentence;
});
// text in a sentence
sentences.forEach(sentence => {
/* sentence object is a node
{
type: "Sentence",
raw: text,
value: text,
loc: loc,
range: range
};
*/
const sentenceText = sentence.raw;
console.log({
sentence: sentence.loc
})
// words in a sentence
const words = splitWords(sentenceText);
// over count of word, then report error
if (words.length > maxWordCount) {
// get original index value of sentence.loc.start
const [startIndex, endIndex] = [
source.originalIndexFromPosition(sentence.loc.start),
source.originalIndexFromPosition(sentence.loc.end),
];
const sentenceFragment = `${words.slice(0, 3).join(' ')} ...`;
const ruleError = new RuleError(`Maximum word count (${maxWordCount}) exceeded (${words.length}) by "${sentenceFragment}".`, {
padding: locator.range([startIndex, endIndex])
});
report(node, ruleError);
}
});
}
};
}
export default report