svem
Version:
Svelte in Markdown preprocessor
101 lines (100 loc) • 2.58 kB
JavaScript
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
};