UNPKG

svem

Version:

Svelte in Markdown preprocessor

101 lines (100 loc) 2.58 kB
import { visit } from "unist-util-visit"; import { Caution, ChevronRight, Important, Note, Tip, Warning } from "../icons/index.js"; const calloutTypes = { note: { text: "Note", icon: Note }, tip: { text: "Tip", icon: Tip }, important: { text: "Important", icon: Important }, warning: { text: "Warning", icon: Warning }, caution: { text: "Caution", icon: Caution } }; const calloutTypeKeys = Object.keys(calloutTypes); const remarkCallout = () => { return (tree) => { visit(tree, "directive", (node) => { if (!calloutTypeKeys.includes(node.name.toLowerCase().replace(/-$/, ""))) { return; } let collapsible = node.attributes.collapsible ?? false; const { children = [] } = node; node.name = node.name.toLowerCase(); if (node.name.endsWith("-")) { collapsible = true; node.name = node.name.slice(0, -1); } const head = { type: "html-node", tagName: collapsible ? "summary" : "div", attributes: { class: ["callout-title"] }, children: [ { type: "html-node", tagName: "span", value: calloutTypes[node.name].icon, attributes: { class: ["callout-title-icon"] } }, { type: "html-node", tagName: "span", value: node.attributes?.title ?? calloutTypes[node.name].text, attributes: { class: ["callout-title-text"] } } ] }; if (collapsible) { head.children?.push({ type: "html-node", tagName: "span", value: ChevronRight, attributes: { class: ["callout-fold-icon"] } }); } const body = { type: "html-node", tagName: "div", attributes: { class: ["callout-content"] }, children }; if (!Array.isArray(node.attributes.class)) { node.attributes.class = [node.attributes.class].filter(Boolean); } node.attributes.class.push("callout", node.name); Object.assign(node.attributes, { "data-callout": node.name, "data-collapsible": collapsible ? "true" : "false" }); delete node.attributes.title; delete node.attributes.collapsible; node.type = "html-node"; node.tagName = collapsible ? "details" : "div"; node.children = [head, body]; }); }; }; export { remarkCallout };