@scalar/code-highlight
Version:
Central methods and themes for code highlighting in Scalar projects
91 lines (90 loc) • 2.84 kB
JavaScript
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