UNPKG

@scalar/code-highlight

Version:

Central methods and themes for code highlighting in Scalar projects

91 lines (90 loc) 2.84 kB
import { toText } from "hast-util-to-text"; import { createLowlight } from "lowlight"; import { visit } from "unist-util-visit"; import { lowlightLanguageMappings } from "../constants.js"; const emptyOptions = {}; function rehypeHighlight(options) { const settings = options || emptyOptions; const aliases = settings.aliases; const detect = options?.detect ?? false; const languages = settings.languages; const plainText = settings.plainText; const prefix = settings.prefix; const subset = settings.subset; let name = "hljs"; const lowlight = options?.lowlight ?? createLowlight(languages); if (aliases) { lowlight.registerAlias(aliases); } if (prefix) { const pos = prefix.indexOf("-"); name = pos > -1 ? prefix.slice(0, pos) : prefix; } return (tree, file) => { visit(tree, "element", (node, _, parent) => { if (node.tagName !== "code" || !parent || parent.type !== "element" || parent.tagName !== "pre") { return; } const lang = language(node); if (lang === "no-highlight" || !lang && !detect || lang && plainText?.includes(lang)) { return; } if (!Array.isArray(node.properties.className)) { node.properties.className = []; } if (!node.properties.className.includes(name)) { node.properties.className.unshift(name); } let result; try { result = lang ? lowlight.highlight(lang, toText(parent), { prefix }) : lowlight.highlightAuto(toText(parent), { prefix, subset }); } catch (error) { const cause = error; if (lang && /Unknown language/.test(cause.message)) { file.message(`Cannot highlight as \`${lang}\`, it's not registered`, { ancestors: [parent, node], cause, place: node.position, ruleId: "missing-language", source: "rehype-highlight" }); return; } throw cause; } if (!lang && result.data?.language) { node.properties.className.push("language-" + result.data.language); } if (result.children.length > 0) { node.children = result.children; } }); }; } function language(node) { const list = node.properties.className; if (!Array.isArray(list)) { return ""; } const name = list.reduce((result, _item) => { if (result) { return result; } const item = String(_item); if (item === "no-highlight" || item === "nohighlight") { return "no-highlight"; } if (item.slice(0, 5) === "lang-") { return item.slice(5); } if (item.slice(0, 9) === "language-") { return item.slice(9); } return result; }, ""); return lowlightLanguageMappings[name || ""] || name; } export { rehypeHighlight }; //# sourceMappingURL=rehype-highlight.js.map