forked from mapbox/rehype-highlight-code-block
/
index.js
47 lines (38 loc) · 1.23 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
'use strict';
const visit = require('unist-util-visit');
const nodeToString = require('hast-util-to-string');
const Parser5 = require('parse5/lib/parser');
const nodeFromParse5 = require('hast-util-from-parse5');
const parse5 = new Parser5();
const LANGUAGE_CLASS_REGEXP = /^(?:language-|lang-)(\S+)/;
function getLanguage(node) {
const className = node.properties.className || [];
const length = className.length;
let index = -1;
let classListItem;
while (++index < length) {
classListItem = className[index];
const match = classListItem.match(LANGUAGE_CLASS_REGEXP);
if (match) {
return match[1];
}
}
return null;
}
module.exports = options => {
if (!options || typeof options.highlight !== 'function') {
throw new Error('You must provide a highlight function');
}
return tree => {
visit(tree, 'element', visitor);
};
function visitor(node, index, parent) {
if (node.tagName !== 'code') return;
if (!parent || parent.tagName !== 'pre') return;
const lang = getLanguage(node);
const html = options.highlight(nodeToString(node), lang);
if (!html) return;
const highlightedAst = nodeFromParse5(parse5.parseFragment(html));
node.children = highlightedAst.children;
}
};