UNPKG

svem

Version:

Svelte in Markdown preprocessor

88 lines (87 loc) 2.34 kB
import { visit } from "unist-util-visit"; import { getAttributes } from "./attribute.js"; const remarkDirective = () => { return (tree) => { visit(tree, "paragraph", (node, index = 0, parent) => { if (!isSectionOpen(node)) { return; } wrapDirective(node, index, parent); }); }; }; const wrapDirective = (node, index = 0, parent) => { const children = []; const initNode = node.children?.[0]; if (!initNode?.value) { return node; } const [name, ...rest] = initNode.value.replace(/:::\s?/, "").trim().split(/\s+/); const meta = rest.join(" "); node.type = "directive"; node.name = name.trim(); node.meta = meta.trim(); node.attributes = getAttributes(meta); if (!node.name && node.attributes?.name) { node.name = node.attributes.name; } if (parent.children?.length) { let done = false; while (!done) { const child = parent.children.splice(index + 1, 1)[0]; if (!child || isSectionClose(child)) { done = true; break; } if (isSectionOpen(child)) { wrapDirective(child, index, parent); } children.push(child); } } node.children = children; return node; }; const remarkDirectiveEject = () => { return (tree) => { visit(tree, "directive", (node) => { node.type = "html-node"; node.tagName = "div"; if (!node.attributes) { node.attributes = {}; } if (!Array.isArray(node.attributes.class)) { node.attributes.class = [node.attributes.class].filter(Boolean); } node.attributes.class.push("directive", node.name); }); }; }; const isSectionOpen = (node) => { if (node.type === "text" && /^:::/.test(node.value ?? "")) { return true; } if (node.type !== "paragraph") { return false; } const firstChild = node.children?.[0]; if (firstChild?.type === "text" && /^:::/.test(firstChild?.value ?? "")) { return true; } }; const isSectionClose = (node) => { if (node.type === "text" && /^:::$/.test(node.value?.trim() ?? "")) { return true; } if (node.type !== "paragraph") { return false; } const firstChild = node.children?.[0]; if (firstChild?.type === "text" && /^:::$/.test(firstChild?.value?.trim() ?? "")) { return true; } }; export { remarkDirective, remarkDirectiveEject };