2025-12-01 11:37:01 +08:00

109 lines
3.8 KiB
TypeScript

import type { MarkdownChartPluginOptions } from '@vuepress/plugin-markdown-chart'
import type { MarkdownHintPluginOptions } from '@vuepress/plugin-markdown-hint'
import type { MarkdownImagePluginOptions } from '@vuepress/plugin-markdown-image'
import type { MarkdownIncludePluginOptions } from '@vuepress/plugin-markdown-include'
import type { MarkdownMathPluginOptions } from '@vuepress/plugin-markdown-math'
import type { PluginConfig } from 'vuepress'
import type { MarkdownPowerPluginOptions } from 'vuepress-plugin-md-power'
import type { MarkdownOptions, ThemeBuiltinPlugins } from '../../shared/index.js'
import { isPlainObject } from '@vuepress/helper'
import { markdownChartPlugin } from '@vuepress/plugin-markdown-chart'
import { markdownHintPlugin } from '@vuepress/plugin-markdown-hint'
import { markdownImagePlugin } from '@vuepress/plugin-markdown-image'
import { markdownIncludePlugin } from '@vuepress/plugin-markdown-include'
import { markdownMathPlugin } from '@vuepress/plugin-markdown-math'
import { markdownPowerPlugin } from 'vuepress-plugin-md-power'
import { MARKDOWN_CHART_FIELDS, MARKDOWN_POWER_FIELDS } from '../detector/index.js'
import { getThemeConfig } from '../loadConfig/index.js'
export function markdownPlugins(pluginOptions: ThemeBuiltinPlugins): PluginConfig {
const options = getThemeConfig()
const plugins: PluginConfig = []
let { hint, image, include, math, mdChart, mdPower } = splitMarkdownOptions(options.markdown ?? {})
plugins.push(markdownHintPlugin({
hint: hint.hint ?? true,
alert: hint.alert ?? true,
injectStyles: false,
}))
if (pluginOptions.markdownPower !== false) {
const shikiOptions = options.codeHighlighter ?? pluginOptions.shiki
const shikiTheme = shikiOptions && 'theme' in shikiOptions
? shikiOptions.theme
: shikiOptions && 'themes' in shikiOptions
? shikiOptions.themes
: { light: 'vitesse-light', dark: 'vitesse-dark' }
const repl = mdPower?.repl ?? pluginOptions.markdownPower?.repl
plugins.push(markdownPowerPlugin({
fileTree: true,
plot: true,
icons: true,
...pluginOptions.markdownPower || {},
...mdPower,
repl: repl ? { theme: shikiTheme as any, ...repl } : repl,
}))
}
mdChart ??= pluginOptions.markdownChart
if (mdChart) {
plugins.push(markdownChartPlugin({
DANGEROUS_ALLOW_SCRIPT_EXECUTION: true,
DANGEROUS_SCRIPT_EXECUTION_ALLOWLIST: '*',
...mdChart,
}))
}
math ??= pluginOptions.markdownMath
if (math !== false) {
plugins.push(markdownMathPlugin(math ?? { type: 'katex' }))
}
image ??= pluginOptions.markdownImage
if (image) {
plugins.push(markdownImagePlugin(image))
}
include ??= pluginOptions.markdownInclude
if (include !== false) {
plugins.push(markdownIncludePlugin(isPlainObject(include) ? include : {}))
}
return plugins
}
function splitMarkdownOptions(options: MarkdownOptions): {
mdPower: MarkdownPowerPluginOptions
mdChart?: false | MarkdownChartPluginOptions
image?: false | MarkdownImagePluginOptions
include?: boolean | MarkdownIncludePluginOptions
math?: false | MarkdownMathPluginOptions
hint: MarkdownHintPluginOptions
} {
const { hint, alert, oldDemo, image, include, math, ...restOptions } = options
const mdChart: MarkdownChartPluginOptions = {}
const mdPower: MarkdownPowerPluginOptions = {}
for (const key in restOptions) {
if (MARKDOWN_CHART_FIELDS.includes(key as keyof MarkdownChartPluginOptions)) {
mdChart[key] = restOptions[key]
}
else if (MARKDOWN_POWER_FIELDS.includes(key as keyof MarkdownPowerPluginOptions)) {
mdPower[key] = restOptions[key]
}
}
const mdChartKeys = Object.keys(mdChart)
return {
hint: { hint, alert },
image,
include,
math,
mdChart: mdChartKeys.length && mdChartKeys.some(key => mdChart[key] !== false) ? mdChart : false,
mdPower,
}
}