mio-previewer 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +408 -141
- package/README.zh-CN.md +404 -125
- package/dist/{_basePickBy-wjzVR2ZI.cjs → _basePickBy-CWzy8CIJ.cjs} +1 -1
- package/dist/{_basePickBy-ClXR16YL.js → _basePickBy-m5_T47yz.js} +2 -2
- package/dist/{_baseUniq-BvAvxwqe.js → _baseUniq-BnywwJBY.js} +1 -1
- package/dist/{_baseUniq-BtmrXn_-.cjs → _baseUniq-DzAGUMoa.cjs} +1 -1
- package/dist/{arc-CBMtpv9r.cjs → arc-BAZxwgoG.cjs} +1 -1
- package/dist/{arc-Hx3N9DvE.js → arc-BDHD79aE.js} +1 -1
- package/dist/{architecture-O4VJ6CD3-BNArGrzK.cjs → architecture-O4VJ6CD3-B3mtkY33.cjs} +1 -1
- package/dist/{architecture-O4VJ6CD3-xCUefH5y.js → architecture-O4VJ6CD3-DXA5X_yx.js} +1 -1
- package/dist/{architectureDiagram-VXUJARFQ-BJuzZIv9.cjs → architectureDiagram-VXUJARFQ-CBEmF4c4.cjs} +1 -1
- package/dist/{architectureDiagram-VXUJARFQ-B6mJb2i9.js → architectureDiagram-VXUJARFQ-WrHvlvqz.js} +3 -3
- package/dist/{blockDiagram-VD42YOAC-BGxFHnMs.js → blockDiagram-VD42YOAC-B8yzpSUt.js} +5 -5
- package/dist/{blockDiagram-VD42YOAC-CG3089Xu.cjs → blockDiagram-VD42YOAC-iGUQhHOa.cjs} +1 -1
- package/dist/{c4Diagram-YG6GDRKO-Cmg_2WS3.cjs → c4Diagram-YG6GDRKO-BC0oVCkM.cjs} +1 -1
- package/dist/{c4Diagram-YG6GDRKO-Rr7zONcv.js → c4Diagram-YG6GDRKO-r1vmxT4H.js} +2 -2
- package/dist/{channel-DgGKpNRA.js → channel-BlCmYLjm.js} +1 -1
- package/dist/channel-CybseUM2.cjs +1 -0
- package/dist/{chunk-4BX2VUAB-Bt9zCVip.cjs → chunk-4BX2VUAB-6PxxKRiV.cjs} +1 -1
- package/dist/{chunk-4BX2VUAB-BbICN0Ec.js → chunk-4BX2VUAB-BvRfkHhg.js} +1 -1
- package/dist/{chunk-55IACEB6-DYOSrdgH.js → chunk-55IACEB6-B6RNQ_Dl.js} +1 -1
- package/dist/{chunk-55IACEB6-CBJvnwMn.cjs → chunk-55IACEB6-BaqZa58T.cjs} +1 -1
- package/dist/{chunk-B4BG7PRW-l7q-a31H.cjs → chunk-B4BG7PRW-B2nNYsy_.cjs} +1 -1
- package/dist/{chunk-B4BG7PRW-TxrPoDdp.js → chunk-B4BG7PRW-DlrKAjak.js} +4 -4
- package/dist/{chunk-DI55MBZ5-Bp0pNyM4.cjs → chunk-DI55MBZ5-BUn8iSqn.cjs} +1 -1
- package/dist/{chunk-DI55MBZ5-CsB2AXBx.js → chunk-DI55MBZ5-CZnuDYt1.js} +3 -3
- package/dist/{chunk-FMBD7UC4-D5PKNbki.js → chunk-FMBD7UC4-Kiqgsjq0.js} +1 -1
- package/dist/{chunk-FMBD7UC4-BcpCv0n4.cjs → chunk-FMBD7UC4-QZu7cQhg.cjs} +1 -1
- package/dist/{chunk-QN33PNHL-B5zdVrte.js → chunk-QN33PNHL-CN23wkk5.js} +1 -1
- package/dist/{chunk-QN33PNHL-B1Px0282.cjs → chunk-QN33PNHL-NFeQwU1C.cjs} +1 -1
- package/dist/{chunk-QZHKN3VN-Dg1DeAnJ.cjs → chunk-QZHKN3VN-Bq63ipAz.cjs} +1 -1
- package/dist/{chunk-QZHKN3VN-C-Vfb6xz.js → chunk-QZHKN3VN-DRwz5CXr.js} +1 -1
- package/dist/{chunk-TZMSLE5B-xm8uzxSg.js → chunk-TZMSLE5B-Bwr0045t.js} +1 -1
- package/dist/{chunk-TZMSLE5B-Bd4ivTqX.cjs → chunk-TZMSLE5B-Dp8UhykY.cjs} +1 -1
- package/dist/{classDiagram-2ON5EDUG-DaNkCwSZ.cjs → classDiagram-2ON5EDUG-CWAjzXtp.cjs} +1 -1
- package/dist/{classDiagram-v2-WZHVMYZB-CK_iHiNY.js → classDiagram-2ON5EDUG-DxjNGm48.js} +2 -2
- package/dist/{classDiagram-v2-WZHVMYZB-DaNkCwSZ.cjs → classDiagram-v2-WZHVMYZB-CWAjzXtp.cjs} +1 -1
- package/dist/{classDiagram-2ON5EDUG-CK_iHiNY.js → classDiagram-v2-WZHVMYZB-DxjNGm48.js} +2 -2
- package/dist/clone-W1VAscty.cjs +1 -0
- package/dist/{clone-Bha0jTOw.js → clone-xXnwx9JX.js} +1 -1
- package/dist/{cose-bilkent-S5V4N54A-CV1wgztW.cjs → cose-bilkent-S5V4N54A-DGtDnCf_.cjs} +1 -1
- package/dist/{cose-bilkent-S5V4N54A-hCsgqyKM.js → cose-bilkent-S5V4N54A-DwACfiOr.js} +1 -1
- package/dist/{custom-DUStvHau.cjs → custom-BB9B2BL2.cjs} +90 -48
- package/dist/{custom-B4yTjcNy.js → custom-C1QhDj-y.js} +3153 -3094
- package/dist/{dagre-6UL2VRFP-yXKAxpPT.cjs → dagre-6UL2VRFP-B7OkXNwm.cjs} +1 -1
- package/dist/{dagre-6UL2VRFP-DgeWg1SE.js → dagre-6UL2VRFP-D8jgPXZB.js} +6 -6
- package/dist/{diagram-PSM6KHXK-Cvtq1BMM.js → diagram-PSM6KHXK-CVislPq4.js} +4 -4
- package/dist/{diagram-PSM6KHXK-D8-R7SoU.cjs → diagram-PSM6KHXK-DSJu8JZ6.cjs} +1 -1
- package/dist/{diagram-QEK2KX5R-BJwfOJRv.cjs → diagram-QEK2KX5R-CoE4joH1.cjs} +1 -1
- package/dist/{diagram-QEK2KX5R-Bk1U0LhS.js → diagram-QEK2KX5R-JH3FlTXl.js} +3 -3
- package/dist/{diagram-S2PKOQOG-C1GhQvXr.js → diagram-S2PKOQOG-BgorvXyP.js} +3 -3
- package/dist/{diagram-S2PKOQOG-CrU1lFAd.cjs → diagram-S2PKOQOG-CtcEZ9xO.cjs} +1 -1
- package/dist/{erDiagram-Q2GNP2WA-DwCMcLlJ.cjs → erDiagram-Q2GNP2WA-DjGQSNEd.cjs} +1 -1
- package/dist/{erDiagram-Q2GNP2WA-BW644HGe.js → erDiagram-Q2GNP2WA-DyFoT35Q.js} +4 -4
- package/dist/{flowDiagram-NV44I4VS-wXa2zQjd.js → flowDiagram-NV44I4VS-Bp-q8kkE.js} +5 -5
- package/dist/{flowDiagram-NV44I4VS-CwBt-lqk.cjs → flowDiagram-NV44I4VS-C5_i8vKb.cjs} +1 -1
- package/dist/{ganttDiagram-LVOFAZNH-CFZ-PmU5.cjs → ganttDiagram-LVOFAZNH-CWj5yJz4.cjs} +1 -1
- package/dist/{ganttDiagram-LVOFAZNH-DEQvlmR2.js → ganttDiagram-LVOFAZNH-D5BjYh4O.js} +2 -2
- package/dist/{gitGraph-ZV4HHKMB-CbfGP-N9.cjs → gitGraph-ZV4HHKMB-6xujjpfY.cjs} +1 -1
- package/dist/{gitGraph-ZV4HHKMB-Bd_PHDMp.js → gitGraph-ZV4HHKMB-CMC3ZF2n.js} +1 -1
- package/dist/{gitGraphDiagram-NY62KEGX-j4D9jXL4.cjs → gitGraphDiagram-NY62KEGX-Bijj3zxW.cjs} +1 -1
- package/dist/{gitGraphDiagram-NY62KEGX-xl70htLN.js → gitGraphDiagram-NY62KEGX-DYmh2kRW.js} +4 -4
- package/dist/{graph-D6yOZd92.js → graph-D3gnYK1X.js} +2 -2
- package/dist/{graph-6iViBDku.cjs → graph-DFTHBY71.cjs} +1 -1
- package/dist/info-63CPKGFF-BLYzhYAj.js +5 -0
- package/dist/{info-63CPKGFF-gOwyweiZ.cjs → info-63CPKGFF-CEKaKKTJ.cjs} +1 -1
- package/dist/{infoDiagram-F6ZHWCRC-Vx_DX2z8.cjs → infoDiagram-F6ZHWCRC-CGakmtht.cjs} +1 -1
- package/dist/{infoDiagram-F6ZHWCRC-BfGS0mg6.js → infoDiagram-F6ZHWCRC-CvuN8Xe0.js} +2 -2
- package/dist/{journeyDiagram-XKPGCS4Q-C74m57vy.js → journeyDiagram-XKPGCS4Q-CMD1dNlA.js} +4 -4
- package/dist/{journeyDiagram-XKPGCS4Q-Cwfm3gkE.cjs → journeyDiagram-XKPGCS4Q-NZ7Zwwno.cjs} +1 -1
- package/dist/{kanban-definition-3W4ZIXB7-CgUhoGem.cjs → kanban-definition-3W4ZIXB7-DKjyogIQ.cjs} +1 -1
- package/dist/{kanban-definition-3W4ZIXB7-Zs307aAz.js → kanban-definition-3W4ZIXB7-DdiLRhLn.js} +2 -2
- package/dist/{layout-DiSbzXpp.cjs → layout-BKa4J6c-.cjs} +1 -1
- package/dist/{layout-BVJXml4k.js → layout-D4zQO2o2.js} +4 -4
- package/dist/{linear-CF8o0osj.cjs → linear-DZQR44UC.cjs} +1 -1
- package/dist/{linear-BE7L7Wq8.js → linear-DsHZ7VTP.js} +1 -1
- package/dist/{mermaid-parser.core-D8AljRep.cjs → mermaid-parser.core-DilcMT1B.cjs} +2 -2
- package/dist/{mermaid-parser.core-CvS4VcbX.js → mermaid-parser.core-scIqCLhe.js} +11 -11
- package/dist/{mindmap-definition-VGOIOE7T-BidsJOPm.cjs → mindmap-definition-VGOIOE7T-Ei8sTs44.cjs} +1 -1
- package/dist/{mindmap-definition-VGOIOE7T-BAXsNT0n.js → mindmap-definition-VGOIOE7T-tfBKngxr.js} +3 -3
- package/dist/mio-previewer.css +1 -1
- package/dist/{packet-HUATNLJX-CgY4KC5-.cjs → packet-HUATNLJX-DJA8At21.cjs} +1 -1
- package/dist/{packet-HUATNLJX-B1eLognS.js → packet-HUATNLJX-Dj4GcjQR.js} +1 -1
- package/dist/{pie-WTHONI2E-DBm7_2Ma.cjs → pie-WTHONI2E-B79PEY8l.cjs} +1 -1
- package/dist/pie-WTHONI2E-L2ei45O-.js +5 -0
- package/dist/{pieDiagram-ADFJNKIX-DTKW3svv.cjs → pieDiagram-ADFJNKIX-BIV_iyZL.cjs} +1 -1
- package/dist/{pieDiagram-ADFJNKIX-CWK1C9xc.js → pieDiagram-ADFJNKIX-CJrJzhlE.js} +4 -4
- package/dist/plugins/custom.cjs.js +1 -1
- package/dist/plugins/custom.es.js +1 -1
- package/dist/{quadrantDiagram-AYHSOK5B-BNrGATyu.js → quadrantDiagram-AYHSOK5B-42v2tFCR.js} +2 -2
- package/dist/{quadrantDiagram-AYHSOK5B-qLZyIHgG.cjs → quadrantDiagram-AYHSOK5B-UCGi708D.cjs} +1 -1
- package/dist/radar-NJJJXTRR-BF1JzV5Y.js +5 -0
- package/dist/{radar-NJJJXTRR-EpcDInzR.cjs → radar-NJJJXTRR-PPOjSXgX.cjs} +1 -1
- package/dist/{requirementDiagram-UZGBJVZJ-BTCSXGaW.cjs → requirementDiagram-UZGBJVZJ-CCCu9RXm.cjs} +1 -1
- package/dist/{requirementDiagram-UZGBJVZJ-CkxxLi7P.js → requirementDiagram-UZGBJVZJ-m_gma9iH.js} +3 -3
- package/dist/{sankeyDiagram-TZEHDZUN-BNlI2aP-.cjs → sankeyDiagram-TZEHDZUN-Dt6lrgnr.cjs} +1 -1
- package/dist/{sankeyDiagram-TZEHDZUN-DJ1q5E3K.js → sankeyDiagram-TZEHDZUN-eY44cJlE.js} +1 -1
- package/dist/{sequenceDiagram-WL72ISMW-CjMzI1c2.cjs → sequenceDiagram-WL72ISMW-CBoGDk3g.cjs} +1 -1
- package/dist/{sequenceDiagram-WL72ISMW-nQ6UBL1y.js → sequenceDiagram-WL72ISMW-Chw20cva.js} +3 -3
- package/dist/{stateDiagram-FKZM4ZOC-Dr_-m8dE.js → stateDiagram-FKZM4ZOC-3yy_Kvnk.js} +4 -4
- package/dist/{stateDiagram-FKZM4ZOC-BBEPk90z.cjs → stateDiagram-FKZM4ZOC-t7WnWKbx.cjs} +1 -1
- package/dist/{stateDiagram-v2-4FDKWEC3-D7NtOxif.cjs → stateDiagram-v2-4FDKWEC3-Ct9Imkjc.cjs} +1 -1
- package/dist/{stateDiagram-v2-4FDKWEC3-CG--f0tc.js → stateDiagram-v2-4FDKWEC3-DELyMBBc.js} +2 -2
- package/dist/{timeline-definition-IT6M3QCI-d0F8eBhC.js → timeline-definition-IT6M3QCI-DSbrx1um.js} +2 -2
- package/dist/{timeline-definition-IT6M3QCI-2DClSZLV.cjs → timeline-definition-IT6M3QCI-imDDAjaW.cjs} +1 -1
- package/dist/{treemap-75Q7IDZK-BBuuvHE0.js → treemap-75Q7IDZK-Bwj_esWs.js} +1 -1
- package/dist/{treemap-75Q7IDZK-CI86AmBT.cjs → treemap-75Q7IDZK-DaCs42wt.cjs} +1 -1
- package/dist/{xychartDiagram-PRI3JC2R-BkUjTJNu.cjs → xychartDiagram-PRI3JC2R-CBaFcd4q.cjs} +1 -1
- package/dist/{xychartDiagram-PRI3JC2R-DLXTvnDG.js → xychartDiagram-PRI3JC2R-CpYE-5EP.js} +2 -2
- package/package.json +1 -1
- package/dist/channel-BleEicRr.cjs +0 -1
- package/dist/clone-C1QAYyzI.cjs +0 -1
- package/dist/info-63CPKGFF-du1jd1Lv.js +0 -5
- package/dist/pie-WTHONI2E-RplLoGbc.js +0 -5
- package/dist/radar-NJJJXTRR-DRmyBDWp.js +0 -5
package/README.md
CHANGED
|
@@ -2,217 +2,484 @@
|
|
|
2
2
|
|
|
3
3
|
[中文文档](./README.zh-CN.md) | English
|
|
4
4
|
|
|
5
|
-
A
|
|
6
|
-
converts Markdown -> HTML -> htmlparser2 AST and renders the AST to Vue
|
|
7
|
-
VNode with a tiny recursive renderer. There's an optional module Worker
|
|
8
|
-
(`public/parser.worker.js`) that can handle Markdown parsing off the main
|
|
5
|
+
A Vue 3 markdown renderer optimized for streaming updates with powerful plugin system. Features real-time rendering, syntax highlighting, math formulas, diagrams, and more.
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
✨ **Key Features:**
|
|
8
|
+
- 🚀 Streaming-friendly real-time rendering
|
|
9
|
+
- 🎨 Built-in syntax highlighting (Prism.js, 20+ languages)
|
|
10
|
+
- 📐 Math formulas support (KaTeX)
|
|
11
|
+
- 📊 Diagram rendering (Mermaid)
|
|
12
|
+
- 🔌 Extensible plugin system
|
|
13
|
+
- 📦 Tree-shakeable & lightweight
|
|
14
|
+
- 🎯 TypeScript support
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
Install dependencies:
|
|
16
|
+
## Installation
|
|
18
17
|
|
|
19
18
|
```bash
|
|
20
|
-
|
|
19
|
+
npm install mio-previewer
|
|
20
|
+
# or
|
|
21
|
+
pnpm add mio-previewer
|
|
22
|
+
# or
|
|
23
|
+
yarn add mio-previewer
|
|
21
24
|
```
|
|
22
25
|
|
|
23
|
-
|
|
26
|
+
## Quick Start
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
pnpm dev
|
|
27
|
-
```
|
|
28
|
+
### Basic Usage
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
```vue
|
|
31
|
+
<template>
|
|
32
|
+
<MdRenderer :md="markdown" />
|
|
33
|
+
</template>
|
|
30
34
|
|
|
31
|
-
|
|
35
|
+
<script setup>
|
|
36
|
+
import { ref } from 'vue'
|
|
37
|
+
import { MdRenderer } from 'mio-previewer'
|
|
38
|
+
import 'mio-previewer/dist/mio-previewer.css'
|
|
32
39
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
pnpm preview
|
|
40
|
+
const markdown = ref('# Hello World\n\nThis is **markdown**!')
|
|
41
|
+
</script>
|
|
36
42
|
```
|
|
37
43
|
|
|
38
|
-
|
|
44
|
+
### Streaming Mode
|
|
39
45
|
|
|
40
|
-
|
|
41
|
-
# from npm (when published)
|
|
42
|
-
pnpm add mio-previewer
|
|
46
|
+
Perfect for AI chatbots or real-time content:
|
|
43
47
|
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
```vue
|
|
49
|
+
<template>
|
|
50
|
+
<MdRenderer
|
|
51
|
+
:md="streamContent"
|
|
52
|
+
:isStreaming="isStreaming"
|
|
53
|
+
/>
|
|
54
|
+
</template>
|
|
55
|
+
|
|
56
|
+
<script setup>
|
|
57
|
+
import { ref } from 'vue'
|
|
58
|
+
import { MdRenderer } from 'mio-previewer'
|
|
59
|
+
import 'mio-previewer/dist/mio-previewer.css'
|
|
60
|
+
|
|
61
|
+
const streamContent = ref('')
|
|
62
|
+
const isStreaming = ref(true)
|
|
63
|
+
|
|
64
|
+
// Simulate streaming
|
|
65
|
+
const text = '# Streaming Demo\n\nContent appears **gradually**...'
|
|
66
|
+
let index = 0
|
|
67
|
+
|
|
68
|
+
const interval = setInterval(() => {
|
|
69
|
+
if (index < text.length) {
|
|
70
|
+
streamContent.value += text[index++]
|
|
71
|
+
} else {
|
|
72
|
+
isStreaming.value = false
|
|
73
|
+
clearInterval(interval)
|
|
74
|
+
}
|
|
75
|
+
}, 50)
|
|
76
|
+
</script>
|
|
46
77
|
```
|
|
47
78
|
|
|
48
|
-
|
|
79
|
+
## Plugin System
|
|
80
|
+
|
|
81
|
+
### Using Built-in Plugins
|
|
49
82
|
|
|
50
|
-
|
|
51
|
-
|
|
83
|
+
#### Math Formulas (KaTeX)
|
|
84
|
+
|
|
85
|
+
```vue
|
|
86
|
+
<script setup>
|
|
52
87
|
import { MdRenderer } from 'mio-previewer'
|
|
53
|
-
import '
|
|
88
|
+
import { katexPlugin } from 'mio-previewer/plugins/markdown-it'
|
|
89
|
+
import 'mio-previewer/dist/mio-previewer.css'
|
|
90
|
+
|
|
91
|
+
const markdown = `
|
|
92
|
+
# Math Example
|
|
54
93
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
94
|
+
Inline: $E = mc^2$
|
|
95
|
+
|
|
96
|
+
Block:
|
|
97
|
+
$$
|
|
98
|
+
\\int_{-\\infty}^{\\infty} e^{-x^2} dx = \\sqrt{\\pi}
|
|
99
|
+
$$
|
|
100
|
+
`
|
|
101
|
+
|
|
102
|
+
const markdownItPlugins = [
|
|
103
|
+
{ plugin: katexPlugin }
|
|
104
|
+
]
|
|
105
|
+
</script>
|
|
106
|
+
|
|
107
|
+
<template>
|
|
108
|
+
<MdRenderer
|
|
109
|
+
:md="markdown"
|
|
110
|
+
:markdownItPlugins="markdownItPlugins"
|
|
111
|
+
/>
|
|
112
|
+
</template>
|
|
58
113
|
```
|
|
59
114
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
115
|
+
#### Alert Boxes
|
|
116
|
+
|
|
117
|
+
```vue
|
|
118
|
+
<script setup>
|
|
119
|
+
import { MdRenderer } from 'mio-previewer'
|
|
120
|
+
import { AlertPlugin } from 'mio-previewer/plugins/markdown-it'
|
|
121
|
+
import 'mio-previewer/dist/mio-previewer.css'
|
|
65
122
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
- Publish with `pnpm publish --access public` (or use CI automation).
|
|
71
|
-
## Project overview
|
|
123
|
+
const markdown = `
|
|
124
|
+
::: info
|
|
125
|
+
This is an **info** alert with markdown support!
|
|
126
|
+
:::
|
|
72
127
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
component node while streaming.
|
|
77
|
-
- `src/components/RecursiveRenderer.vue` — recursively renders the
|
|
78
|
-
htmlparser2 AST to Vue VNodes. Supports a `plugins` array where each
|
|
79
|
-
plugin is `{ test, render }`.
|
|
80
|
-
- `src/components/BlinkingCursor.vue` — small visual cursor used during
|
|
81
|
-
streaming.
|
|
82
|
-
- `public/parser.worker.js` — (optional) module Worker. When enabled
|
|
83
|
-
(`useWorker`), `MdRenderer` posts `{ markdownText }` and expects a
|
|
84
|
-
response `{ ast }` where `ast` matches `parseDocument(html).children`.
|
|
128
|
+
::: warning
|
|
129
|
+
⚠️ Warning message
|
|
130
|
+
:::
|
|
85
131
|
|
|
86
|
-
|
|
132
|
+
::: error
|
|
133
|
+
❌ Error message
|
|
134
|
+
:::
|
|
87
135
|
|
|
88
|
-
|
|
136
|
+
::: success
|
|
137
|
+
✅ Success message
|
|
138
|
+
:::
|
|
139
|
+
`
|
|
89
140
|
|
|
90
|
-
|
|
91
|
-
|
|
141
|
+
const markdownItPlugins = [
|
|
142
|
+
{ plugin: AlertPlugin }
|
|
143
|
+
]
|
|
144
|
+
</script>
|
|
145
|
+
|
|
146
|
+
<template>
|
|
147
|
+
<MdRenderer
|
|
148
|
+
:md="markdown"
|
|
149
|
+
:markdownItPlugins="markdownItPlugins"
|
|
150
|
+
/>
|
|
151
|
+
</template>
|
|
152
|
+
```
|
|
92
153
|
|
|
93
|
-
|
|
154
|
+
#### Syntax Highlighting
|
|
94
155
|
|
|
95
|
-
|
|
156
|
+
```vue
|
|
157
|
+
<script setup>
|
|
158
|
+
import { MdRenderer } from 'mio-previewer'
|
|
159
|
+
import { CodeBlockPlugin } from 'mio-previewer/plugins/custom'
|
|
160
|
+
import 'mio-previewer/dist/mio-previewer.css'
|
|
96
161
|
|
|
97
|
-
|
|
162
|
+
const markdown = `
|
|
163
|
+
\`\`\`javascript
|
|
164
|
+
function hello() {
|
|
165
|
+
console.log('Hello World!')
|
|
166
|
+
}
|
|
167
|
+
\`\`\`
|
|
168
|
+
|
|
169
|
+
\`\`\`python
|
|
170
|
+
def greet():
|
|
171
|
+
print("Hello from Python!")
|
|
172
|
+
\`\`\`
|
|
173
|
+
`
|
|
174
|
+
|
|
175
|
+
const customPlugins = [CodeBlockPlugin]
|
|
176
|
+
</script>
|
|
177
|
+
|
|
178
|
+
<template>
|
|
179
|
+
<MdRenderer
|
|
180
|
+
:md="markdown"
|
|
181
|
+
:customPlugins="customPlugins"
|
|
182
|
+
/>
|
|
183
|
+
</template>
|
|
184
|
+
```
|
|
98
185
|
|
|
99
|
-
|
|
186
|
+
#### Mermaid Diagrams
|
|
187
|
+
|
|
188
|
+
```vue
|
|
189
|
+
<script setup>
|
|
190
|
+
import { MdRenderer } from 'mio-previewer'
|
|
191
|
+
import { mermaidPlugin } from 'mio-previewer/plugins/custom'
|
|
192
|
+
import 'mio-previewer/dist/mio-previewer.css'
|
|
193
|
+
|
|
194
|
+
const markdown = `
|
|
195
|
+
\`\`\`mermaid
|
|
196
|
+
graph TD
|
|
197
|
+
A[Start] --> B{Decision}
|
|
198
|
+
B -->|Yes| C[Continue]
|
|
199
|
+
B -->|No| D[Stop]
|
|
200
|
+
\`\`\`
|
|
201
|
+
`
|
|
202
|
+
|
|
203
|
+
const customPlugins = [mermaidPlugin]
|
|
204
|
+
</script>
|
|
205
|
+
|
|
206
|
+
<template>
|
|
207
|
+
<MdRenderer
|
|
208
|
+
:md="markdown"
|
|
209
|
+
:customPlugins="customPlugins"
|
|
210
|
+
/>
|
|
211
|
+
</template>
|
|
212
|
+
```
|
|
100
213
|
|
|
101
|
-
|
|
214
|
+
#### Emoji Support
|
|
102
215
|
|
|
103
|
-
```
|
|
216
|
+
```vue
|
|
217
|
+
<script setup>
|
|
104
218
|
import { MdRenderer } from 'mio-previewer'
|
|
105
|
-
import
|
|
106
|
-
import
|
|
219
|
+
import { EmojiPlugin } from 'mio-previewer/plugins/custom'
|
|
220
|
+
import 'mio-previewer/dist/mio-previewer.css'
|
|
107
221
|
|
|
108
|
-
const
|
|
109
|
-
{ plugin: markdownItSub },
|
|
110
|
-
{ plugin: markdownItSup, options: { /* plugin options */ } }
|
|
111
|
-
]
|
|
222
|
+
const markdown = 'Hello :smile: Welcome! :tada: :rocket:'
|
|
112
223
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
224
|
+
const customPlugins = [EmojiPlugin]
|
|
225
|
+
</script>
|
|
226
|
+
|
|
227
|
+
<template>
|
|
228
|
+
<MdRenderer
|
|
229
|
+
:md="markdown"
|
|
230
|
+
:customPlugins="customPlugins"
|
|
231
|
+
/>
|
|
232
|
+
</template>
|
|
119
233
|
```
|
|
120
234
|
|
|
121
|
-
###
|
|
235
|
+
### Complete Example with All Plugins
|
|
122
236
|
|
|
123
|
-
|
|
237
|
+
```vue
|
|
238
|
+
<script setup>
|
|
239
|
+
import { ref } from 'vue'
|
|
240
|
+
import { MdRenderer } from 'mio-previewer'
|
|
241
|
+
import { AlertPlugin, katexPlugin } from 'mio-previewer/plugins/markdown-it'
|
|
242
|
+
import { mermaidPlugin, CodeBlockPlugin, EmojiPlugin } from 'mio-previewer/plugins/custom'
|
|
243
|
+
import 'mio-previewer/dist/mio-previewer.css'
|
|
124
244
|
|
|
125
|
-
|
|
126
|
-
import { AlertPlugin, EmojiPlugin } from 'mio-previewer'
|
|
245
|
+
const markdown = ref(`# Complete Demo :rocket:
|
|
127
246
|
|
|
128
|
-
|
|
129
|
-
|
|
247
|
+
## Alerts
|
|
248
|
+
::: info
|
|
249
|
+
This is **important** information!
|
|
250
|
+
:::
|
|
130
251
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
252
|
+
## Math
|
|
253
|
+
Inline: $E = mc^2$
|
|
254
|
+
|
|
255
|
+
Block: $$\\sum_{n=1}^{\\infty} \\frac{1}{n^2} = \\frac{\\pi^2}{6}$$
|
|
256
|
+
|
|
257
|
+
## Code
|
|
258
|
+
\`\`\`javascript
|
|
259
|
+
console.log('Hello World!')
|
|
260
|
+
\`\`\`
|
|
261
|
+
|
|
262
|
+
## Diagram
|
|
263
|
+
\`\`\`mermaid
|
|
264
|
+
graph LR
|
|
265
|
+
A --> B --> C
|
|
266
|
+
\`\`\`
|
|
267
|
+
|
|
268
|
+
Great work! :thumbsup: :100:
|
|
269
|
+
`)
|
|
270
|
+
|
|
271
|
+
const customPlugins = [
|
|
272
|
+
mermaidPlugin,
|
|
273
|
+
CodeBlockPlugin,
|
|
274
|
+
EmojiPlugin
|
|
275
|
+
]
|
|
276
|
+
|
|
277
|
+
const markdownItPlugins = [
|
|
278
|
+
{ plugin: AlertPlugin },
|
|
279
|
+
{ plugin: katexPlugin }
|
|
280
|
+
]
|
|
281
|
+
</script>
|
|
282
|
+
|
|
283
|
+
<template>
|
|
284
|
+
<MdRenderer
|
|
285
|
+
:md="markdown"
|
|
286
|
+
:customPlugins="customPlugins"
|
|
287
|
+
:markdownItPlugins="markdownItPlugins"
|
|
288
|
+
/>
|
|
289
|
+
</template>
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Creating Custom Plugins
|
|
293
|
+
|
|
294
|
+
#### Custom Rendering Plugin
|
|
295
|
+
|
|
296
|
+
```javascript
|
|
297
|
+
const HighlightPlugin = {
|
|
298
|
+
name: 'highlight',
|
|
299
|
+
priority: 50,
|
|
300
|
+
test: (node) => {
|
|
301
|
+
return node.type === 'tag' &&
|
|
302
|
+
node.name === 'mark'
|
|
303
|
+
},
|
|
136
304
|
render: (node, renderChildren, h) => {
|
|
137
|
-
return h('
|
|
305
|
+
return h('mark', {
|
|
306
|
+
style: {
|
|
307
|
+
backgroundColor: '#ffeb3b',
|
|
308
|
+
padding: '2px 4px',
|
|
309
|
+
borderRadius: '2px'
|
|
310
|
+
}
|
|
311
|
+
}, renderChildren())
|
|
138
312
|
}
|
|
139
313
|
}
|
|
140
314
|
|
|
141
|
-
|
|
315
|
+
// Use it
|
|
316
|
+
const customPlugins = [HighlightPlugin]
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
#### Custom Markdown-it Plugin
|
|
320
|
+
|
|
321
|
+
```javascript
|
|
322
|
+
function customContainerPlugin(md) {
|
|
323
|
+
md.use(require('markdown-it-container'), 'note', {
|
|
324
|
+
render: (tokens, idx) => {
|
|
325
|
+
if (tokens[idx].nesting === 1) {
|
|
326
|
+
return '<div class="note">\n'
|
|
327
|
+
} else {
|
|
328
|
+
return '</div>\n'
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
})
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
const markdownItPlugins = [
|
|
335
|
+
{ plugin: customContainerPlugin }
|
|
336
|
+
]
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## API Reference
|
|
340
|
+
|
|
341
|
+
### MdRenderer Props
|
|
342
|
+
|
|
343
|
+
| Prop | Type | Default | Description |
|
|
344
|
+
|------|------|---------|-------------|
|
|
345
|
+
| `md` | `string` | `''` | Markdown content to render |
|
|
346
|
+
| `isStreaming` | `boolean` | `false` | Show cursor during streaming |
|
|
347
|
+
| `useWorker` | `boolean` | `false` | Use Web Worker for parsing |
|
|
348
|
+
| `customPlugins` | `CustomPlugin[]` | `[]` | Custom rendering plugins |
|
|
349
|
+
| `markdownItPlugins` | `MarkdownItPluginConfig[]` | `[]` | Markdown-it plugins |
|
|
350
|
+
| `markdownItOptions` | `object` | `{}` | Markdown-it options |
|
|
351
|
+
|
|
352
|
+
### Plugin Types
|
|
353
|
+
|
|
354
|
+
#### CustomPlugin
|
|
355
|
+
|
|
356
|
+
```typescript
|
|
357
|
+
interface CustomPlugin {
|
|
358
|
+
name?: string
|
|
359
|
+
priority?: number // Higher = earlier execution
|
|
360
|
+
test: (node: ASTNode) => boolean
|
|
361
|
+
render: (
|
|
362
|
+
node: ASTNode,
|
|
363
|
+
renderChildren: () => VNode[],
|
|
364
|
+
h: typeof import('vue').h
|
|
365
|
+
) => VNode | string | null
|
|
366
|
+
}
|
|
142
367
|
```
|
|
143
368
|
|
|
144
|
-
|
|
369
|
+
#### MarkdownItPluginConfig
|
|
145
370
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
371
|
+
```typescript
|
|
372
|
+
interface MarkdownItPluginConfig {
|
|
373
|
+
plugin: (md: MarkdownIt, options?: any) => void
|
|
374
|
+
options?: any
|
|
375
|
+
}
|
|
376
|
+
```
|
|
151
377
|
|
|
152
|
-
|
|
378
|
+
## Built-in Plugins
|
|
153
379
|
|
|
154
|
-
|
|
380
|
+
### Markdown-it Plugins (Syntax)
|
|
155
381
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
- 0-9: Low priority (text processing, emoji)
|
|
382
|
+
| Plugin | Import Path | Description |
|
|
383
|
+
|--------|-------------|-------------|
|
|
384
|
+
| `AlertPlugin` | `mio-previewer/plugins/markdown-it` | Alert boxes (info, warning, error, success) |
|
|
385
|
+
| `katexPlugin` | `mio-previewer/plugins/markdown-it` | Math formulas with KaTeX |
|
|
161
386
|
|
|
162
|
-
###
|
|
387
|
+
### Custom Plugins (Rendering)
|
|
163
388
|
|
|
164
|
-
|
|
389
|
+
| Plugin | Import Path | Description |
|
|
390
|
+
|--------|-------------|-------------|
|
|
391
|
+
| `mermaidPlugin` | `mio-previewer/plugins/custom` | Diagram rendering with Mermaid |
|
|
392
|
+
| `CodeBlockPlugin` | `mio-previewer/plugins/custom` | Syntax highlighting with Prism |
|
|
393
|
+
| `EmojiPlugin` | `mio-previewer/plugins/custom` | Emoji code replacement |
|
|
165
394
|
|
|
166
|
-
|
|
395
|
+
## Advanced Usage
|
|
167
396
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
397
|
+
### Markdown-it Options
|
|
398
|
+
|
|
399
|
+
```vue
|
|
400
|
+
<script setup>
|
|
401
|
+
const markdownItOptions = {
|
|
402
|
+
html: true, // Enable HTML tags
|
|
403
|
+
linkify: true, // Auto-convert URLs
|
|
404
|
+
typographer: true, // Smart quotes, dashes
|
|
405
|
+
breaks: false // Convert \n to <br>
|
|
406
|
+
}
|
|
407
|
+
</script>
|
|
408
|
+
|
|
409
|
+
<template>
|
|
410
|
+
<MdRenderer
|
|
411
|
+
:md="markdown"
|
|
412
|
+
:markdownItOptions="markdownItOptions"
|
|
413
|
+
/>
|
|
414
|
+
</template>
|
|
172
415
|
```
|
|
173
416
|
|
|
174
|
-
|
|
417
|
+
### Web Worker Mode
|
|
175
418
|
|
|
176
|
-
|
|
419
|
+
For better performance with large documents:
|
|
177
420
|
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
421
|
+
```vue
|
|
422
|
+
<template>
|
|
423
|
+
<MdRenderer
|
|
424
|
+
:md="largeMarkdown"
|
|
425
|
+
:useWorker="true"
|
|
426
|
+
/>
|
|
427
|
+
</template>
|
|
182
428
|
```
|
|
183
429
|
|
|
184
|
-
|
|
185
|
-
that `RecursiveRenderer` can consume it directly.
|
|
430
|
+
**Note:** Worker mode requires `public/parser.worker.js` to be accessible.
|
|
186
431
|
|
|
187
|
-
##
|
|
188
|
-
|
|
189
|
-
This repo was migrated progressively to TypeScript. To keep the
|
|
190
|
-
conversion low-risk, a temporary `src/types-shims.d.ts` provides minimal
|
|
191
|
-
module declarations. Recommended next steps to tighten types:
|
|
432
|
+
## Development
|
|
192
433
|
|
|
193
434
|
```bash
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
435
|
+
# Install dependencies
|
|
436
|
+
pnpm install
|
|
437
|
+
|
|
438
|
+
# Start dev server
|
|
439
|
+
pnpm dev
|
|
440
|
+
|
|
441
|
+
# Build library
|
|
442
|
+
pnpm build
|
|
197
443
|
|
|
198
|
-
|
|
199
|
-
|
|
444
|
+
# Run benchmark
|
|
445
|
+
pnpm benchmark
|
|
446
|
+
```
|
|
200
447
|
|
|
201
|
-
##
|
|
448
|
+
## Project Structure
|
|
202
449
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
450
|
+
```
|
|
451
|
+
mio-previewer/
|
|
452
|
+
├── src/
|
|
453
|
+
│ ├── MdRenderer.vue # Main renderer component
|
|
454
|
+
│ ├── components/
|
|
455
|
+
│ │ ├── RecursiveRenderer.vue # AST to VNode renderer
|
|
456
|
+
│ │ ├── BlinkingCursor.vue # Streaming cursor
|
|
457
|
+
│ │ └── CodeBlock.vue # Code highlighting
|
|
458
|
+
│ ├── plugins/
|
|
459
|
+
│ │ ├── AlertPlugin.ts # Alert boxes
|
|
460
|
+
│ │ ├── katexPlugin.ts # Math formulas
|
|
461
|
+
│ │ ├── mermaidPlugin.ts # Diagrams
|
|
462
|
+
│ │ ├── CodeBlockPlugin.ts # Syntax highlighting
|
|
463
|
+
│ │ └── EmojiPlugin.ts # Emoji support
|
|
464
|
+
│ └── index.ts # Library entry
|
|
465
|
+
├── public/
|
|
466
|
+
│ └── parser.worker.js # Optional Web Worker
|
|
467
|
+
└── docs/ # Documentation
|
|
468
|
+
```
|
|
208
469
|
|
|
209
|
-
##
|
|
470
|
+
## Browser Support
|
|
210
471
|
|
|
211
|
-
-
|
|
212
|
-
-
|
|
213
|
-
-
|
|
214
|
-
- `public/parser.worker.js` — optional worker parsing contract
|
|
472
|
+
- Chrome/Edge: Latest 2 versions
|
|
473
|
+
- Firefox: Latest 2 versions
|
|
474
|
+
- Safari: Latest 2 versions
|
|
215
475
|
|
|
216
476
|
## License
|
|
217
477
|
|
|
218
478
|
MIT
|
|
479
|
+
|
|
480
|
+
## Links
|
|
481
|
+
|
|
482
|
+
- [GitHub Repository](https://github.com/Pretend-to/mio-previewer)
|
|
483
|
+
- [npm Package](https://www.npmjs.com/package/mio-previewer)
|
|
484
|
+
- [Plugin Guide](./docs/PLUGIN_GUIDE.md)
|
|
485
|
+
- [Changelog](./CHANGELOG.md)
|