fumadocs-mdx
Version:
The built-in source for Fumadocs
159 lines (156 loc) • 4.66 kB
JavaScript
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