-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
70 lines (59 loc) · 2.48 KB
/
index.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
const visit = require("unist-util-visit");
const toString = require("mdast-util-to-string")
module.exports = ({ markdownAST }, pluginOptions) => {
const trie = getTrie(pluginOptions.dictionary);
visit(markdownAST, "paragraph", (node) => {
addDictionaryDefinitions(node, trie);
});
return markdownAST
}
const getTrie = (dictionary) => {
const trie = {};
dictionary.forEach(definition => {
definition.matchers.forEach(matcher => {
let trieMatcherNode = trie;
const matcherWords = matcher.toLowerCase().split(' ');
matcherWords.forEach(word => {
trieMatcherNode[word] = trieMatcherNode[word] || {};
trieMatcherNode = trieMatcherNode[word];
});
trieMatcherNode.definition = definition;
});
});
return trie;
}
const addDictionaryDefinitions = (node, trie) => {
// Grab the innerText of the paragraph node
let originalText = text = toString(node);
const textSplittedToWords = text.toLowerCase().split(' ');
let currPlaceInTrie = trie, streakTextIndex = null, currTextIndex = 0;
for (let i = 0; i < textSplittedToWords.length; i++) {
const currWord = textSplittedToWords[i];
const nextPlaceInTrie = currPlaceInTrie[currWord];
if (!nextPlaceInTrie) {
streakTextIndex = null;
currPlaceInTrie = trie;
} else if (!nextPlaceInTrie.definition) {
streakTextIndex = streakTextIndex || currTextIndex;
currPlaceInTrie = nextPlaceInTrie;
} else {
streakTextIndex = streakTextIndex || currTextIndex;
const end = currTextIndex + currWord.length;
const oldPart = text.substring(streakTextIndex, end);
const linkVal = nextPlaceInTrie.definition.title ? `<abbr title="${nextPlaceInTrie.definition.title}">${oldPart}</abbr>`: oldPart;
const linkText = nextPlaceInTrie.definition.link ? `<a class="dict-link" href="${nextPlaceInTrie.definition.link}">${linkVal}</a>` : linkVal;
text = text.substring(0, streakTextIndex) + linkText + text.substring(end);
currTextIndex += linkText.length - oldPart.length + 1;
continue;
}
currTextIndex += currWord.length + 1;
}
if (originalText !== text) {
const parentChildrenArray = node.children;
const indexOfTextNodeInParent = parentChildrenArray.findIndex((n) => n.value === originalText);
parentChildrenArray.splice(indexOfTextNodeInParent, 1, {
type: 'html',
value: text
});
}
}