fumadocs-core
Version:
The React.js library for building a documentation website
77 lines (75 loc) • 2.04 kB
JavaScript
import { visit } from "unist-util-visit";
//#region src/mdx-plugins/remark-steps.ts
const StepRegex = /^(\d+)\.\s(.+)$/;
/**
* Convert headings in the format of `1. Hello World` into steps.
*/
function remarkSteps({ steps = "fd-steps", step = "fd-step" } = {}) {
function convertToSteps(nodes) {
const depth = nodes[0].depth;
const children = [];
for (const node of nodes) if (node.type === "heading" && node.depth === depth) children.push({
type: "mdxJsxFlowElement",
name: "div",
attributes: [{
type: "mdxJsxAttribute",
name: "className",
value: step
}],
children: [node]
});
else children[children.length - 1].children.push(node);
return {
type: "mdxJsxFlowElement",
name: "div",
attributes: [{
type: "mdxJsxAttribute",
name: "className",
value: steps
}],
data: { _fd_step: true },
children
};
}
return (tree) => {
visit(tree, (parent) => {
if (!("children" in parent) || parent.type === "heading") return;
if (parent.data && "_fd_step" in parent.data) return "skip";
let startIdx = -1;
let i = 0;
const onEnd = () => {
if (startIdx === -1) return;
const item = {};
const nodes = parent.children.splice(startIdx, i - startIdx, item);
Object.assign(item, convertToSteps(nodes));
i = startIdx + 1;
startIdx = -1;
};
for (; i < parent.children.length; i++) {
const node = parent.children[i];
if (node.type !== "heading") continue;
if (startIdx !== -1) {
const startDepth = parent.children[startIdx].depth;
if (node.depth > startDepth) continue;
else if (node.depth < startDepth) onEnd();
}
const head = node.children.filter((c) => c.type === "text").at(0);
if (!head) {
onEnd();
continue;
}
const match = StepRegex.exec(head.value);
if (!match) {
onEnd();
continue;
}
head.value = match[2];
if (startIdx === -1) startIdx = i;
}
onEnd();
});
};
}
//#endregion
export { remarkSteps };
//# sourceMappingURL=remark-steps.js.map