UNPKG

@scalar/code-highlight

Version:

Central methods and themes for code highlighting in Scalar projects

74 lines (73 loc) 2.29 kB
import { visit } from "unist-util-visit"; function isText(element) { return element?.type === "text"; } function isElement(node) { return node?.type === "element"; } function textElement(value) { return { type: "text", value }; } function lineBreak() { return { type: "text", value: "\n" }; } function codeBlockLinesPlugin() { return (tree) => { visit(tree, "element", (node, _i, parent) => { if (parent?.type === "element" && parent.tagName === "pre" && node.tagName === "code") { let numLines = 0; node.children = addLines(node); node.children.forEach((child) => { if (child.type === "element" && child.tagName === "span") { const lastChild = child.children[child.children.length - 1]; if (lastChild && (!isText(lastChild) || isText(lastChild) && !hasLineBreak(lastChild))) { child.children.push(lineBreak()); numLines++; } } }); node.properties.style = [`--line-count: ${numLines};`, `--line-digits: ${numLines.toString().length};`]; } }); }; } function addLines(node, lines = [], copyParent) { const line = () => lines[lines.length - 1] ?? (lines.push(createLine()) && lines[lines.length - 1] || void 0); node.children.forEach((child) => { if (isText(child) && hasLineBreak(child)) { const split = child.value.split(/\n/); split.forEach((content, i) => { if (copyParent) { line()?.children.push({ ...node, children: [textElement(content)] }); } else { line()?.children.push(textElement(content)); } i !== split.length - 1 && lines.push(createLine()); }); } else if (isElement(child) && child.children.some(hasLineBreak)) { addLines(child, lines, true); } else { line()?.children.push(child); } }); return lines; } function createLine(...children) { return { type: "element", tagName: "span", properties: { class: ["line"] }, children }; } function hasLineBreak(node) { return isText(node) && /\r?\n/.test(node.value) || isElement(node) && node.children.some(hasLineBreak); } export { codeBlockLinesPlugin, isElement, isText, lineBreak, textElement }; //# sourceMappingURL=line-numbers.js.map