svem
Version:
Svelte in Markdown preprocessor
122 lines (121 loc) • 3.37 kB
JavaScript
import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkGfm from "remark-gfm";
import remarkMatter from "remark-frontmatter";
import remarkRehype from "remark-rehype";
import rehypeCallouts from "rehype-callouts";
import rehypeStringify from "rehype-stringify";
import { VFile } from "vfile";
import {
remarkAttributes,
remarkCallout,
remarkCodeGroup,
remarkCodeHighlight,
remarkCodeImport,
remarkCodePreview,
remarkDeepParse,
remarkDirective,
remarkDirectiveEject,
remarkFlatMatter,
remarkHeadingLink,
remarkHeadingSection
} from "../plugins/index.js";
import { remarkHtmlNodes } from "../plugins/html.js";
const defaultHighlightOptions = {
langs: [
"javascript",
"typescript",
"jsx",
"html",
"css",
"json",
"bash",
"shell",
"yaml",
"markdown",
"mdx",
"svelte",
"sql"
],
themes: {
light: "catppuccin-latte",
dark: "catppuccin-mocha"
}
};
const defaultHeadingLinkOptions = {
depths: [2, 3]
};
const rehypeOptions = {
allowDangerousHtml: true,
allowDangerousCharacters: true,
entities: {
useNamedReferences: true
}
};
async function transform(content, filename, options) {
if (options?.codeHighlight?.theme) {
options.codeHighlight.themes = {
light: options.codeHighlight.theme
};
}
const remark = unified().use(remarkParse).use(remarkDeepParse).use(remarkFlatMatter).use(remarkDirective).use(remarkAttributes);
if (Array.isArray(options?.decoder)) {
for (const plugin of options?.decoder ?? []) {
if (Array.isArray(plugin)) {
remark.use(plugin[0], plugin[1]);
} else {
remark.use(plugin);
}
}
}
remark.use(remarkMatter).use(remarkGfm).use(remarkCodeImport, options?.codeImport).use(remarkCodePreview).use(remarkCodeGroup).use(remarkCallout).use(remarkCodeHighlight, {
...defaultHighlightOptions,
...options?.codeHighlight
}).use(remarkHeadingLink, {
...defaultHeadingLinkOptions,
...options?.headingLinks
});
if (Array.isArray(options?.remark)) {
for (const plugin of options?.remark ?? []) {
if (Array.isArray(plugin)) {
remark.use(plugin[0], plugin[1]);
} else {
remark.use(plugin);
}
}
}
if (options?.headingSections) {
remark.use(remarkHeadingSection, typeof options.headingSections === "object" ? options.headingSections : void 0);
}
remark.use(remarkDirectiveEject).use(remarkHtmlNodes, { brandAlias: options?.brandAlias });
if (Array.isArray(options?.encoder)) {
for (const plugin of options?.encoder ?? []) {
if (Array.isArray(plugin)) {
remark.use(plugin[0], plugin[1]);
} else {
remark.use(plugin);
}
}
}
const rehype = remark.use(remarkRehype, rehypeOptions).use(rehypeCallouts).use(() => {
return () => {
};
});
if (Array.isArray(options?.rehype)) {
for (const plugin of options?.rehype ?? []) {
if (Array.isArray(plugin)) {
rehype.use(plugin[0], plugin[1]);
} else {
rehype.use(plugin);
}
}
}
rehype.use(rehypeStringify, rehypeOptions);
const file = new VFile({ value: content, path: filename });
let { value: code, data } = await rehype.process(file);
code = code.replace(/&/g, "&").replace(/&\s?/g, "&");
return { code, data };
}
export {
transform
};