fumadocs-core
Version:
The React.js library for building a documentation website
106 lines (104 loc) • 3.54 kB
JavaScript
import { n as toMdxExport, t as flattenNode } from "../mdast-utils-mc9-X-PK.js";
import { remark } from "remark";
import remarkGfm from "remark-gfm";
import Slugger from "github-slugger";
import { visit } from "unist-util-visit";
//#region src/mdx-plugins/remark-structure.ts
const remarkStructureDefaultOptions = {
types: [
"heading",
"paragraph",
"blockquote",
"tableCell",
"mdxJsxFlowElement"
],
allowedMdxAttributes: (node) => {
if (!node.name) return false;
return ["TypeTable", "Callout"].includes(node.name);
},
exportAs: false
};
/**
* Extract content into structured data.
*
* By default, the output is stored into VFile (`vfile.data.structuredData`), you can specify `exportAs` to export it.
*/
function remarkStructure({ types = remarkStructureDefaultOptions.types, allowedMdxAttributes = remarkStructureDefaultOptions.allowedMdxAttributes, exportAs = remarkStructureDefaultOptions.exportAs } = {}) {
const slugger = new Slugger();
if (Array.isArray(allowedMdxAttributes)) {
const arr = allowedMdxAttributes;
allowedMdxAttributes = (_node, attribute) => attribute.type === "mdxJsxAttribute" && arr.includes(attribute.name);
}
if (Array.isArray(types)) {
const arr = types;
types = (node) => arr.includes(node.type);
}
return (tree, file) => {
slugger.reset();
const data = {
contents: [],
headings: []
};
let lastHeading;
if (file.data.frontmatter) {
const frontmatter = file.data.frontmatter;
if (frontmatter._openapi?.structuredData) {
data.headings.push(...frontmatter._openapi.structuredData.headings);
data.contents.push(...frontmatter._openapi.structuredData.contents);
}
}
visit(tree, (element) => {
if (element.type === "root" || !types(element)) return;
if (element.type === "heading") {
element.data ||= {};
element.data.hProperties ||= {};
const properties = element.data.hProperties;
const content$1 = flattenNode(element).trim();
const id = properties.id ?? slugger.slug(content$1);
data.headings.push({
id,
content: content$1
});
lastHeading = id;
return "skip";
}
if (element.data?._string) {
for (const content$1 of element.data._string) data.contents.push({
heading: lastHeading,
content: content$1
});
return "skip";
}
if (element.type === "mdxJsxFlowElement" && element.name) {
data.contents.push(...element.attributes.flatMap((attribute) => {
const value = typeof attribute.value === "string" ? attribute.value : attribute.value?.value;
if (!value || value.length === 0) return [];
if (allowedMdxAttributes && !allowedMdxAttributes(element, attribute)) return [];
return {
heading: lastHeading,
content: attribute.type === "mdxJsxAttribute" ? `${attribute.name}: ${value}` : value
};
}));
return;
}
const content = flattenNode(element).trim();
if (content.length === 0) return;
data.contents.push({
heading: lastHeading,
content
});
return "skip";
});
file.data.structuredData = data;
if (exportAs) tree.children.unshift(toMdxExport(typeof exportAs === "string" ? exportAs : "structuredData", data));
};
}
/**
* Extract data from markdown/mdx content
*/
function structure(content, remarkPlugins = [], options = {}) {
return remark().use(remarkGfm).use(remarkPlugins).use(remarkStructure, options).processSync(content).data.structuredData;
}
//#endregion
export { remarkStructure, remarkStructureDefaultOptions, structure };
//# sourceMappingURL=remark-structure.js.map