2026-03-08 16:35:52 +08:00

137 lines
4.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { Plugin } from 'vuepress/core'
import type { MarkdownPowerPluginOptions } from '../shared/index.js'
import { isPlainObject } from '@pengzhanbo/utils'
import { addViteOptimizeDepsInclude } from '@vuepress/helper'
import { getFullLocaleConfig } from '@vuepress/helper'
import { extendsPageWithCodeTree } from './container/codeTree.js'
import { containerPlugin } from './container/index.js'
import { demoPlugin, demoWatcher, extendsPageWithDemo, waitDemoRender } from './demo/index.js'
import { embedSyntaxPlugin } from './embed/index.js'
import { docsTitlePlugin } from './enhance/docsTitle.js'
import { imageSizePlugin } from './enhance/imageSize.js'
import { linksPlugin } from './enhance/links.js'
import { iconPlugin } from './icon/index.js'
import { inlineSyntaxPlugin } from './inline/index.js'
import { LOCALE_OPTIONS } from './locales/index.js'
import { prepareConfigFile } from './prepareConfigFile.js'
import { provideData } from './provideData.js'
/**
* Create markdown power plugin for VuePress.
*
* 为 VuePress 创建 markdown 增强插件。
*
* This plugin provides various markdown enhancements including:
* - Custom containers (tabs, collapse, timeline, etc.)
* - Code blocks enhancements (code tabs, file tree, demo)
* - Embed syntax (video, PDF, code playground)
* - Inline syntax (mark, subscript, superscript, footnote)
* - Icon support
*
* 该插件提供多种 markdown 增强功能,包括:
* - 自定义容器(标签页、折叠面板、时间线等)
* - 代码块增强(代码标签页、文件树、演示)
* - 嵌入语法视频、PDF、代码游乐场
* - 行内语法(标记、下标、上标、脚注)
* - 图标支持
*
* @param options - Plugin options / 插件配置选项
* @returns VuePress plugin instance / VuePress 插件实例
*
* @example
* ```ts
* // Basic usage
* markdownPowerPlugin()
*
* // With options
* markdownPowerPlugin({
* tabs: true,
* collapse: true,
* pdf: true,
* })
* ```
*/
export function markdownPowerPlugin(
options: MarkdownPowerPluginOptions = {},
): Plugin {
return (app) => {
const locales = getFullLocaleConfig({
app,
name: 'vuepress-plugin-md-power',
default: LOCALE_OPTIONS,
config: options.locales,
})
return {
name: 'vuepress-plugin-md-power',
clientConfigFile: app => prepareConfigFile(app, options),
define: provideData(options, locales),
alias: (_, isServer) => {
if (!isServer) {
return { ...options.encrypt ? { '/^vue$/': 'vue/dist/vue.esm-bundler.js' } : undefined }
}
return {}
},
extendsBundlerOptions(bundlerOptions, app) {
if (options.repl) {
addViteOptimizeDepsInclude(
bundlerOptions,
app,
['shiki/core', 'shiki/wasm', 'shiki/engine/oniguruma'],
)
if (options.repl.python)
addViteOptimizeDepsInclude(bundlerOptions, app, ['pyodide'])
}
if (options.artPlayer) {
addViteOptimizeDepsInclude(
bundlerOptions,
app,
['artplayer', 'dashjs', 'hls.js', 'mpegts.js/dist/mpegts.js'],
)
}
if (options.qrcode) {
addViteOptimizeDepsInclude(bundlerOptions, app, ['qrcode'])
}
},
extendsMarkdown: async (md, app) => {
linksPlugin(md)
docsTitlePlugin(md)
embedSyntaxPlugin(md, options)
inlineSyntaxPlugin(md, options)
iconPlugin(md, options.icon ?? (isPlainObject(options.icons) ? options.icons : {}))
if (options.demo)
demoPlugin(app, md)
await containerPlugin(app, md, options, locales)
await imageSizePlugin(app, md, options.imageSize)
},
onPrepared: async () => {
if (options.demo)
await waitDemoRender()
},
onWatched(app, watchers) {
if (options.demo) {
demoWatcher(app, watchers)
}
},
extendsPage: (page) => {
if (options.demo)
extendsPageWithDemo(page)
if (options.codeTree)
extendsPageWithCodeTree(page)
},
}
}
}