UNPKG

@kobalte/solidbase

Version:

Fully featured, fully customisable static site generation for SolidStart

184 lines (165 loc) 5.73 kB
import { pluginCollapsibleSections } from "@expressive-code/plugin-collapsible-sections"; import { pluginLineNumbers } from "@expressive-code/plugin-line-numbers"; import { nodeTypes } from "@mdx-js/mdx"; import type { PluginTwoslashOptions } from "expressive-code-twoslash"; import ecTwoSlash from "expressive-code-twoslash"; import rehypeAutoLinkHeadings from "rehype-autolink-headings"; import rehypeExpressiveCode, { type ExpressiveCodePlugin, type ExpressiveCodeTheme, type RehypeExpressiveCodeOptions, } from "rehype-expressive-code"; import rehypeRaw from "rehype-raw"; import rehypeSlug from "rehype-slug"; import remarkDirective from "remark-directive"; import remarkFrontmatter from "remark-frontmatter"; import remarkGfm from "remark-gfm"; import { convertCompilerOptionsFromJson } from "typescript"; import type { PluggableList } from "unified"; import type { PluginOption } from "vite"; import mdx from "../vite-mdx/index.js"; import type { SolidBaseResolvedConfig } from "./index.js"; import { rehypeFixExpressiveCodeJsx } from "./rehype-plugins/fix-expressive-code.js"; import { remarkCodeTabs } from "./remark-plugins/code-tabs.js"; import { remarkDirectiveContainers } from "./remark-plugins/directives.js"; import { remarkGithubAlertsToDirectives } from "./remark-plugins/gh-directives.js"; import { type ImportCodeFileOptions, remarkImportCodeFile, viteAliasCodeImports, } from "./remark-plugins/import-code-file.js"; import { remarkInlineFrontmatter } from "./remark-plugins/inline-frontmatter.js"; import { remarkIssueAutolink } from "./remark-plugins/issue-autolink.js"; import { remarkAddClass } from "./remark-plugins/kbd.js"; import { remarkMdxFrontmatter } from "./remark-plugins/mdx-frontmatter.js"; import type { PackageManagerConfig } from "./remark-plugins/package-manager-tabs.js"; import { remarkPackageManagerTabs } from "./remark-plugins/package-manager-tabs.js"; import { remarkRelativeImports } from "./remark-plugins/relative-imports.js"; import { remarkSteps } from "./remark-plugins/steps.js"; import { remarkTabGroup } from "./remark-plugins/tab-group.js"; import type { TOCOptions } from "./remark-plugins/toc.js"; import { remarkTOC } from "./remark-plugins/toc.js"; export type TwoslashOptions = PluginTwoslashOptions & { tsconfig: any }; export interface MdxOptions { expressiveCode?: | (RehypeExpressiveCodeOptions & { twoSlash?: TwoslashOptions | true; }) | false; toc?: TOCOptions | false; remarkPlugins?: PluggableList; rehypePlugins?: PluggableList; packageManagers?: PackageManagerConfig | false; importCodeFile?: ImportCodeFileOptions | false; steps?: false; } export function solidBaseMdx( sbConfig: SolidBaseResolvedConfig<any>, ): PluginOption { return [ viteAliasCodeImports(), mdx.withImports({})({ jsx: true, jsxImportSource: "solid-js", providerImportSource: "@kobalte/solidbase/solid-mdx", stylePropertyNameCase: "css", rehypePlugins: getRehypePlugins(sbConfig), remarkPlugins: getRemarkPlugins(sbConfig), }), ]; } function getRehypePlugins(sbConfig: SolidBaseResolvedConfig<any>) { const rehypePlugins: any[] = []; if (sbConfig.markdown?.expressiveCode !== false) { const plugins: (ExpressiveCodePlugin | ExpressiveCodePlugin[])[] = [ pluginLineNumbers(), pluginCollapsibleSections(), ]; if (sbConfig.markdown?.expressiveCode?.twoSlash) { const twoSlash = sbConfig.markdown.expressiveCode.twoSlash === true ? ({} as TwoslashOptions) : sbConfig.markdown.expressiveCode.twoSlash; plugins.push( ecTwoSlash({ ...twoSlash, twoslashOptions: { ...twoSlash.twoslashOptions, compilerOptions: { ...convertCompilerOptionsFromJson( { allowSyntheticDefaultImports: true, esModuleInterop: true, target: "ESNext", module: "ESNext", lib: ["dom", "esnext"], jsxImportSource: "solid-js", jsx: "preserve", ...twoSlash.tsconfig, }, ".", ).options, ...twoSlash.twoslashOptions?.compilerOptions, }, }, }), ); } rehypePlugins.push( [ rehypeExpressiveCode, { themes: ["github-dark", "github-light"], themeCssSelector: (theme: ExpressiveCodeTheme) => `[data-theme="${theme.type}"]`, plugins, defaultProps: { showLineNumbers: false, collapseStyle: "collapsible-auto", }, ...sbConfig.markdown?.expressiveCode, } satisfies RehypeExpressiveCodeOptions, ], rehypeFixExpressiveCodeJsx, ); } rehypePlugins.push( [rehypeRaw, { passThrough: nodeTypes }], rehypeSlug, [ rehypeAutoLinkHeadings, { behavior: "wrap", properties: { "data-auto-heading": "", }, }, ], ...(sbConfig.markdown?.rehypePlugins ?? []), ); return rehypePlugins; } function getRemarkPlugins(sbConfig: SolidBaseResolvedConfig<any>) { const remarkPlugins: any[] = []; if (sbConfig.markdown?.steps !== false) remarkPlugins.push(remarkSteps); remarkPlugins.push( remarkFrontmatter, remarkMdxFrontmatter, remarkInlineFrontmatter, [remarkImportCodeFile, sbConfig.markdown?.importCodeFile], remarkGfm, remarkGithubAlertsToDirectives, remarkCodeTabs, [remarkPackageManagerTabs, sbConfig.markdown?.packageManagers ?? {}], remarkTabGroup, remarkDirective, remarkRelativeImports, ); if (sbConfig.markdown?.toc !== false) remarkPlugins.push([remarkTOC, sbConfig.markdown?.toc]); remarkPlugins.push(remarkDirectiveContainers, remarkAddClass); if (sbConfig.issueAutolink !== false) remarkPlugins.push([remarkIssueAutolink, sbConfig.issueAutolink]); remarkPlugins.push(...(sbConfig.markdown?.remarkPlugins ?? [])); return remarkPlugins; }