|
@@ -1,68 +1,74 @@
|
|
|
-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 "/@/components/markdown/plugins/impl/VueCharts.vue";
|
|
|
-
|
|
|
+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 '/@/components/markdown/plugins/impl/VueCharts.vue'
|
|
|
|
|
|
// 验证JSON格式
|
|
|
function isValidJSON(str: string): boolean {
|
|
|
- try {
|
|
|
- JSON.parse(str)
|
|
|
- return true
|
|
|
- } catch {
|
|
|
- return false
|
|
|
- }
|
|
|
+ if (str.startsWith('[')) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ const expr = JSON.parse(str)
|
|
|
+
|
|
|
+ return expr["series"] !== undefined;
|
|
|
+
|
|
|
+ } catch {
|
|
|
+ return false
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// 渲染echarts代码块
|
|
|
const renderEcharts: RenderRule = (tokens: Token[], idx: number) => {
|
|
|
- const token = tokens[idx]
|
|
|
- const content = token.content.trim()
|
|
|
+ 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>`
|
|
|
+ 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)
|
|
|
- }
|
|
|
+ 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' })
|
|
|
- // }
|
|
|
+ // 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() : ''
|
|
|
+ // 重写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' || info == 'json') && isValidJSON(token.content.trim())) {
|
|
|
- return renderEcharts(tokens, idx, options, env, renderer)
|
|
|
- }
|
|
|
+ // 检查是否是echarts代码块
|
|
|
+ if ((info === 'echarts' || info == 'json') && 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'
|
|
|
- }
|
|
|
- )
|
|
|
- }
|
|
|
+ // 其他代码块使用默认渲染器
|
|
|
+ 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
|