UNPKG

fumadocs-mdx

Version:

The built-in source for Fumadocs

159 lines (156 loc) 4.66 kB
import { n as flattenNode, t as remarkInclude } from "./remark-include-D3G3mAnv.js"; import { visit } from "unist-util-visit"; import { VFile } from "vfile"; import { createProcessor } from "@mdx-js/mdx"; import { toMarkdown } from "mdast-util-to-markdown"; import { valueToEstree } from "estree-util-value-to-estree"; import { removePosition } from "unist-util-remove-position"; import remarkMdx from "remark-mdx"; //#region src/loaders/mdx/remark-postprocess.ts /** * - collect references * - write frontmatter (auto-title & description) */ function remarkPostprocess({ _format, includeProcessedMarkdown = false, includeMDAST = false, extractLinkReferences = false, valueToExport = [] }) { let _stringifyProcessor; const getStringifyProcessor = () => { return _stringifyProcessor ??= _format === "mdx" ? this : this().use(remarkMdx).freeze(); }; return (tree, file) => { const frontmatter = file.data.frontmatter ??= {}; if (!frontmatter.title) visit(tree, "heading", (node) => { if (node.depth === 1) { frontmatter.title = flattenNode(node); return false; } }); file.data["mdx-export"] ??= []; file.data["mdx-export"].push({ name: "frontmatter", value: frontmatter }); if (extractLinkReferences) { const urls = []; visit(tree, "link", (node) => { urls.push({ href: node.url }); return "skip"; }); file.data["mdx-export"].push({ name: "extractedReferences", value: urls }); } if (includeProcessedMarkdown) { const { headingIds = true } = typeof includeProcessedMarkdown === "object" ? includeProcessedMarkdown : {}; const processor = getStringifyProcessor(); const markdown = toMarkdown(tree, { ...processor.data("settings"), extensions: processor.data("toMarkdownExtensions") || [], handlers: { heading: (node) => { const id = node.data?.hProperties?.id; const content = flattenNode(node); return headingIds && id ? `${content} [#${id}]` : content; } } }); file.data["mdx-export"].push({ name: "_markdown", value: markdown }); } if (includeMDAST) { const options = includeMDAST === true ? {} : includeMDAST; const mdast = JSON.stringify(options.removePosition ? removePosition(structuredClone(tree)) : tree); file.data["mdx-export"].push({ name: "_mdast", value: mdast }); } for (const { name, value } of file.data["mdx-export"]) tree.children.unshift(getMdastExport(name, value)); file.data["mdx-export"] = []; for (const name of valueToExport) { if (!(name in file.data)) continue; tree.children.unshift(getMdastExport(name, file.data[name])); } }; } /** * MDX.js first converts javascript (with esm support) into mdast nodes with remark-mdx, then handle the other remark plugins * * Therefore, if we want to inject an export, we must convert the object into AST, then add the mdast node */ function getMdastExport(name, value) { return { type: "mdxjsEsm", value: "", data: { estree: { type: "Program", sourceType: "module", body: [{ type: "ExportNamedDeclaration", attributes: [], specifiers: [], source: null, declaration: { type: "VariableDeclaration", kind: "let", declarations: [{ type: "VariableDeclarator", id: { type: "Identifier", name }, init: valueToEstree(value) }] } }] } } }; } //#endregion //#region src/loaders/mdx/build-mdx.ts async function buildMDX(core, collection, { filePath, frontmatter, source, _compiler, environment, isDevelopment }) { const mdxOptions = await core.getConfig().getMDXOptions(collection, environment); function getProcessor(format) { const cache = core.cache; const key = `build-mdx:${collection?.name ?? "global"}:${format}`; let processor = cache.get(key); if (!processor) { const postprocessOptions = { _format: format, ...collection?.postprocess }; processor = createProcessor({ outputFormat: "program", development: isDevelopment, ...mdxOptions, remarkPlugins: [ remarkInclude, ...mdxOptions.remarkPlugins ?? [], [remarkPostprocess, postprocessOptions] ], format }); cache.set(key, processor); } return processor; } let vfile = new VFile({ value: source, path: filePath, cwd: collection?.cwd, data: { frontmatter, _compiler, _getProcessor: getProcessor } }); if (collection) vfile = await core.transformVFile({ collection, filePath, source }, vfile); return getProcessor(filePath.endsWith(".mdx") ? "mdx" : "md").process(vfile); } //#endregion export { buildMDX as t }; //# sourceMappingURL=build-mdx-Blq7ZKoM.js.map