@ztl-uwu/nuxt-content
Version:
Write your content inside your Nuxt app
89 lines (88 loc) • 2.57 kB
JavaScript
import { parseMarkdown } from "@nuxtjs/mdc/runtime";
import { normalizeUri } from "micromark-util-sanitize-uri";
import { isRelative } from "ufo";
import { defineTransformer } from "./utils.js";
import { generatePath } from "./path-meta.js";
export default defineTransformer({
name: "markdown",
extensions: [".md"],
parse: async (_id, content, options = {}) => {
const config = { ...options };
config.rehypePlugins = await importPlugins(config.rehypePlugins);
config.remarkPlugins = await importPlugins(config.remarkPlugins);
const highlightOptions = options.highlight ? {
...options.highlight,
// Pass only when it's an function. String values are handled by `@nuxtjs/mdc`
highlighter: typeof options.highlight?.highlighter === "function" ? options.highlight.highlighter : void 0
} : void 0;
const parsed = await parseMarkdown(content, {
...config,
highlight: highlightOptions,
remark: {
plugins: config.remarkPlugins
},
rehype: {
options: {
handlers: {
link
}
},
plugins: config.rehypePlugins
},
toc: config.toc
});
return {
...parsed.data,
excerpt: parsed.excerpt,
body: {
...parsed.body,
toc: parsed.toc
},
_type: "markdown",
_id
};
}
});
async function importPlugins(plugins = {}) {
const resolvedPlugins = {};
for (const [name, plugin] of Object.entries(plugins)) {
if (plugin) {
resolvedPlugins[name] = {
instance: plugin.instance || await import(
/* @vite-ignore */
name
).then((m) => m.default || m),
options: plugin
};
} else {
resolvedPlugins[name] = false;
}
}
return resolvedPlugins;
}
function link(state, node) {
const properties = {
...node.attributes || {},
href: normalizeUri(normalizeLink(node.url))
};
if (node.title !== null && node.title !== void 0) {
properties.title = node.title;
}
const result = {
type: "element",
tagName: "a",
properties,
children: state.all(node)
};
state.patch(node, result);
return state.applyData(node, result);
}
function normalizeLink(link2) {
const match = link2.match(/#.+$/);
const hash = match ? match[0] : "";
if (link2.replace(/#.+$/, "").endsWith(".md") && (isRelative(link2) || !/^https?/.test(link2) && !link2.startsWith("/"))) {
return generatePath(link2.replace(".md" + hash, ""), { forceLeadingSlash: false }) + hash;
} else {
return link2;
}
}