tree-sitter-hast
Version:
Convert tree-sitter parsed trees to syntax-highlighted HAST
75 lines (74 loc) • 2.83 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const Parser = require("tree-sitter");
const highlight_tree_sitter_1 = require("highlight-tree-sitter");
function convertSexp(sexp, convertElement, convertText) {
function print(node) {
if (typeof node === 'string')
return convertText(node);
const [name, ...children] = node;
return convertElement(name, children.map(print));
}
return print(sexp);
}
function highlightTree(scopeMappings, text, tree, options) {
const classWhitelist = options ? options.classWhitelist : null;
const full = highlight_tree_sitter_1.fullSexp(text, tree);
const highlight = highlight_tree_sitter_1.highlightSexpFromScopes(full, scopeMappings);
const sexp = convertSexp(highlight.sexp, (name, children) => {
const mergedChildren = [];
let currentText = null;
for (const child of [].concat(...children)) {
if (child.type === 'text') {
if (!currentText)
mergedChildren.push(currentText = { type: 'text', value: '' });
currentText.value += child.value;
}
else {
currentText = null;
mergedChildren.push(child);
}
}
const className = name.split('.').slice(1)
.filter(name => !classWhitelist || classWhitelist.indexOf(name) !== -1);
if (className.length === 0)
return mergedChildren;
return [{
type: 'element',
tagName: 'span',
properties: {
className
},
children: mergedChildren
}];
}, value => [{ type: 'text', value }]);
if (sexp.length === 1)
return sexp[0];
return {
type: 'element',
tagName: 'span',
children: sexp
};
}
exports.highlightTree = highlightTree;
function isParser(p) {
return !!p.parse;
}
function highlightText(arg1, arg2, arg3, arg4) {
const { parser, scopeMappings, text, options } = (() => {
if (isParser(arg1)) {
if (typeof arg3 === 'string')
return { parser: arg1, scopeMappings: arg2, text: arg3, options: arg4 };
}
else if (arg1.grammar && arg1.scopeMappings && typeof arg2 === 'string') {
const parser = new Parser();
parser.setLanguage(arg1.grammar);
const options = typeof arg3 === 'string' ? undefined : arg3;
return { parser, scopeMappings: arg1.scopeMappings, text: arg2, options };
}
throw new Error('Invalid arguments to highlightText()');
})();
const tree = parser.parse(text);
return highlightTree(scopeMappings, text, tree, options);
}
exports.highlightText = highlightText;