1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- import MarkdownIt from "markdown-it";
- import type {RenderRule} from "markdown-it/lib/renderer.mjs";
- import type Token from "markdown-it/lib/token.mjs";
- import {defineMarkdownPlugin} from "../type/markdown.ts";
- import {h} from "vue";
- import VueCharts from "./VueCharts.vue";
- // 验证JSON格式
- function isValidJSON(str: string): boolean {
- try {
- JSON.parse(str)
- return true
- } catch {
- return false
- }
- }
- // 渲染echarts代码块
- const renderEcharts: RenderRule = (tokens: Token[], idx: number) => {
- const token = tokens[idx]
- const content = token.content.trim()
- if (!content) {
- return '<div style="padding: 16px;background-color: #fff5f5;border: 1px solid #fed7d7;border-radius: 6px;color: #c53030;margin: 16px 0;">ECharts配置不能为空</div>'
- }
- // 生成完整HTML
- return `<echarts-container style="width: 100%;height: 350px;margin: 16px 0; border-radius: 6px" data="${encodeURIComponent(content)}"></echarts-container>`
- }
- const EChartsPlugin = defineMarkdownPlugin({
- tagName: 'echarts-container',
- mdItPlugin: function (md: MarkdownIt) {
- // 保存原始的fence渲染器
- const defaultRender = md.renderer.rules.fence ?? function (tokens, idx, options, _env, renderer) {
- return renderer.renderToken(tokens, idx, options)
- }
- // if (customElements.get('echarts-container') === undefined) {
- // customElements.define('echarts-container', EChartsElement, { extends: 'div' })
- // }
- // 重写fence渲染器
- md.renderer.rules.fence = function (tokens, idx, options, env, renderer) {
- const token = tokens[idx]
- const info = token.info ? token.info.trim() : ''
- // 检查是否是echarts代码块
- if (info === 'echarts' && isValidJSON(token.content.trim())) {
- return renderEcharts(tokens, idx, options, env, renderer)
- }
- // 其他代码块使用默认渲染器
- return defaultRender(tokens, idx, options, env, renderer)
- }
- },
- renderer: (node: {attribs: Record<string, string>}) => {
- return h(VueCharts, {
- data: node.attribs.data,
- charts: node.attribs.id,
- style: 'width: 100%;height: 350px;margin: 16px 0; border-radius: 6px'
- }
- )
- }
- })
- export default EChartsPlugin
|