mio-previewer 0.1.3 → 0.1.5

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.
Files changed (124) hide show
  1. package/README.md +408 -141
  2. package/README.zh-CN.md +404 -125
  3. package/dist/AlertPlugin-B74_-nlo.cjs +3 -0
  4. package/dist/AlertPlugin-DUG0ldg_.js +66 -0
  5. package/dist/{_basePickBy-xJ9BT3zN.cjs → _basePickBy-DVE1TNXC.cjs} +1 -1
  6. package/dist/{_basePickBy-BPvpJ2um.js → _basePickBy-eLNY48BA.js} +2 -2
  7. package/dist/{_baseUniq-BZgquYGf.cjs → _baseUniq-CsrG_oBm.cjs} +1 -1
  8. package/dist/{_baseUniq-Tf9Kt8z-.js → _baseUniq-Db85A0t5.js} +1 -1
  9. package/dist/{arc-C73RRLiG.cjs → arc-omcJcwL3.cjs} +1 -1
  10. package/dist/{arc-Dr6aCVTp.js → arc-xWD0pw5h.js} +1 -1
  11. package/dist/{architecture-O4VJ6CD3-DksHFJ_w.cjs → architecture-O4VJ6CD3-DS0gsucM.cjs} +1 -1
  12. package/dist/{architecture-O4VJ6CD3-CeeoNnpL.js → architecture-O4VJ6CD3-OmCnGY-G.js} +1 -1
  13. package/dist/{architectureDiagram-VXUJARFQ-CoK0Gwu-.js → architectureDiagram-VXUJARFQ-CkVk2S0A.js} +3 -3
  14. package/dist/{architectureDiagram-VXUJARFQ-3NLUlleK.cjs → architectureDiagram-VXUJARFQ-mdyHLeOz.cjs} +1 -1
  15. package/dist/{blockDiagram-VD42YOAC-BK-0UQu9.cjs → blockDiagram-VD42YOAC-CYpjD9I4.cjs} +1 -1
  16. package/dist/{blockDiagram-VD42YOAC-B7F_8nB6.js → blockDiagram-VD42YOAC-DaMjTa0C.js} +5 -5
  17. package/dist/{c4Diagram-YG6GDRKO-SAX7mzVM.cjs → c4Diagram-YG6GDRKO-DVNaP7kB.cjs} +1 -1
  18. package/dist/{c4Diagram-YG6GDRKO-DzMoPOvT.js → c4Diagram-YG6GDRKO-DonOCmA8.js} +2 -2
  19. package/dist/{channel-DZNU43d3.js → channel-B486ftOX.js} +1 -1
  20. package/dist/channel-wbveyzLS.cjs +1 -0
  21. package/dist/{chunk-4BX2VUAB-BM6KMQlI.js → chunk-4BX2VUAB-C6w9Js6N.js} +1 -1
  22. package/dist/{chunk-4BX2VUAB-BNg9BEzs.cjs → chunk-4BX2VUAB-ChbzOXZw.cjs} +1 -1
  23. package/dist/{chunk-55IACEB6-CDfNhGdc.js → chunk-55IACEB6-CwVAbm6z.js} +1 -1
  24. package/dist/{chunk-55IACEB6-CIkpKv5G.cjs → chunk-55IACEB6-D-33yVA5.cjs} +1 -1
  25. package/dist/{chunk-B4BG7PRW-DBjDqSED.js → chunk-B4BG7PRW-DrzZmWQJ.js} +4 -4
  26. package/dist/{chunk-B4BG7PRW-DXRjU9TI.cjs → chunk-B4BG7PRW-DuZZcGQH.cjs} +1 -1
  27. package/dist/{chunk-DI55MBZ5-D6sD1SDV.cjs → chunk-DI55MBZ5-CHDlmh3z.cjs} +1 -1
  28. package/dist/{chunk-DI55MBZ5-BCMfI46s.js → chunk-DI55MBZ5-CNPyCRNf.js} +3 -3
  29. package/dist/{chunk-FMBD7UC4-hNxmxOeA.cjs → chunk-FMBD7UC4-CnXch5Qs.cjs} +1 -1
  30. package/dist/{chunk-FMBD7UC4-C-N17wry.js → chunk-FMBD7UC4-DnkBtCqY.js} +1 -1
  31. package/dist/{chunk-QN33PNHL-E13ckPQD.js → chunk-QN33PNHL-BbAoMVzz.js} +1 -1
  32. package/dist/{chunk-QN33PNHL-DD0xRcz_.cjs → chunk-QN33PNHL-BlRWoDnV.cjs} +1 -1
  33. package/dist/{chunk-QZHKN3VN-Kkn2ItIi.cjs → chunk-QZHKN3VN-5fxikjdo.cjs} +1 -1
  34. package/dist/{chunk-QZHKN3VN-CJGCT_qs.js → chunk-QZHKN3VN-BJYsUa-h.js} +1 -1
  35. package/dist/{chunk-TZMSLE5B-B32hxMvx.cjs → chunk-TZMSLE5B-6qnVCnWY.cjs} +1 -1
  36. package/dist/{chunk-TZMSLE5B-DvKudy0L.js → chunk-TZMSLE5B-hAlPmzmK.js} +1 -1
  37. package/dist/{classDiagram-v2-WZHVMYZB-BmtUBt0j.js → classDiagram-2ON5EDUG-CGcrYift.js} +2 -2
  38. package/dist/{classDiagram-2ON5EDUG-x5SSUt5v.cjs → classDiagram-2ON5EDUG-CLGdd0_Z.cjs} +1 -1
  39. package/dist/{classDiagram-2ON5EDUG-BmtUBt0j.js → classDiagram-v2-WZHVMYZB-CGcrYift.js} +2 -2
  40. package/dist/{classDiagram-v2-WZHVMYZB-x5SSUt5v.cjs → classDiagram-v2-WZHVMYZB-CLGdd0_Z.cjs} +1 -1
  41. package/dist/clone-Bans8tLG.cjs +1 -0
  42. package/dist/{clone-AbZIjD3b.js → clone-DNjp7kbc.js} +1 -1
  43. package/dist/{cose-bilkent-S5V4N54A-Bdj7Vz_1.js → cose-bilkent-S5V4N54A-BzRqHvjq.js} +1 -1
  44. package/dist/{cose-bilkent-S5V4N54A-DJ49z974.cjs → cose-bilkent-S5V4N54A-CE_6-gPk.cjs} +1 -1
  45. package/dist/{custom-Bj6wd8Zo.cjs → custom-CCK8DUtS.cjs} +90 -48
  46. package/dist/{custom-DpenvaVL.js → custom-IdAwxsT0.js} +3153 -3094
  47. package/dist/{dagre-6UL2VRFP-wwVKK1c4.js → dagre-6UL2VRFP-B3ff7Qa0.js} +6 -6
  48. package/dist/{dagre-6UL2VRFP-e70bbbAo.cjs → dagre-6UL2VRFP-C8h2QmYJ.cjs} +1 -1
  49. package/dist/{diagram-PSM6KHXK-BvHkTFl-.js → diagram-PSM6KHXK-CwDc0n1y.js} +4 -4
  50. package/dist/{diagram-PSM6KHXK-ByERYM-3.cjs → diagram-PSM6KHXK-DY7M1J0U.cjs} +1 -1
  51. package/dist/{diagram-QEK2KX5R-piVunPtl.cjs → diagram-QEK2KX5R-7LB8awLg.cjs} +1 -1
  52. package/dist/{diagram-QEK2KX5R-DDeHGuBu.js → diagram-QEK2KX5R-B5zlx6uC.js} +3 -3
  53. package/dist/{diagram-S2PKOQOG-Cr055G-z.cjs → diagram-S2PKOQOG-DdadVvM8.cjs} +1 -1
  54. package/dist/{diagram-S2PKOQOG-BKInMDUf.js → diagram-S2PKOQOG-OtcMeBMe.js} +3 -3
  55. package/dist/{erDiagram-Q2GNP2WA-B4-4JFTr.js → erDiagram-Q2GNP2WA-C2LSeZL7.js} +4 -4
  56. package/dist/{erDiagram-Q2GNP2WA-B8J7KiVg.cjs → erDiagram-Q2GNP2WA-Dl2XuLmP.cjs} +1 -1
  57. package/dist/{flowDiagram-NV44I4VS-QOrkavK7.cjs → flowDiagram-NV44I4VS-97EAn9XA.cjs} +1 -1
  58. package/dist/{flowDiagram-NV44I4VS-5cNi0vQA.js → flowDiagram-NV44I4VS-CKDrEgDC.js} +5 -5
  59. package/dist/{ganttDiagram-LVOFAZNH-CigIkVoy.cjs → ganttDiagram-LVOFAZNH-BbIlc35J.cjs} +1 -1
  60. package/dist/{ganttDiagram-LVOFAZNH-DymzdMvs.js → ganttDiagram-LVOFAZNH-DfkshJiH.js} +2 -2
  61. package/dist/{gitGraph-ZV4HHKMB-CWbWsOyk.cjs → gitGraph-ZV4HHKMB-C6zvlbKy.cjs} +1 -1
  62. package/dist/{gitGraph-ZV4HHKMB-B-D8cNhE.js → gitGraph-ZV4HHKMB-ybVsjPzA.js} +1 -1
  63. package/dist/{gitGraphDiagram-NY62KEGX-CaafXshn.cjs → gitGraphDiagram-NY62KEGX-BaI23Cyn.cjs} +1 -1
  64. package/dist/{gitGraphDiagram-NY62KEGX-TPmwKAE3.js → gitGraphDiagram-NY62KEGX-BkSiHbh-.js} +4 -4
  65. package/dist/{graph-DxA9vrvy.cjs → graph-B5ZoHckb.cjs} +1 -1
  66. package/dist/{graph-DuYupv9-.js → graph-D8I9GkNk.js} +2 -2
  67. package/dist/{info-63CPKGFF-B0dB6Gmo.cjs → info-63CPKGFF-6eKHmqS-.cjs} +1 -1
  68. package/dist/info-63CPKGFF-BUd_m-Si.js +5 -0
  69. package/dist/{infoDiagram-F6ZHWCRC-BRxO2gbr.js → infoDiagram-F6ZHWCRC-BMMAyAdj.js} +2 -2
  70. package/dist/{infoDiagram-F6ZHWCRC-BmeO40po.cjs → infoDiagram-F6ZHWCRC-DIRSzuRh.cjs} +1 -1
  71. package/dist/{journeyDiagram-XKPGCS4Q-DC3T_hOS.cjs → journeyDiagram-XKPGCS4Q-C8IeHV-s.cjs} +1 -1
  72. package/dist/{journeyDiagram-XKPGCS4Q-B5MOGiml.js → journeyDiagram-XKPGCS4Q-DO73Fqz4.js} +4 -4
  73. package/dist/{kanban-definition-3W4ZIXB7-C0DqXzkl.cjs → kanban-definition-3W4ZIXB7-BAJ5FzmH.cjs} +1 -1
  74. package/dist/{kanban-definition-3W4ZIXB7-DgJ6Uj7K.js → kanban-definition-3W4ZIXB7-Dh8GKJ2U.js} +2 -2
  75. package/dist/{layout-C2ZYHFpX.js → layout-C9FQT4er.js} +4 -4
  76. package/dist/{layout-DWd-riGk.cjs → layout-EG3PPlQF.cjs} +1 -1
  77. package/dist/{linear-CHYqhRsW.cjs → linear-P18TKbMd.cjs} +1 -1
  78. package/dist/{linear-BOcw0RYN.js → linear-WyvCjWfX.js} +1 -1
  79. package/dist/{mermaid-parser.core-2hw0AO3p.cjs → mermaid-parser.core-D6oiFfri.cjs} +2 -2
  80. package/dist/{mermaid-parser.core-9Cm7d5-2.js → mermaid-parser.core-DZzEoXek.js} +11 -11
  81. package/dist/{mindmap-definition-VGOIOE7T-z7ScFjvc.cjs → mindmap-definition-VGOIOE7T-C_quwk04.cjs} +1 -1
  82. package/dist/{mindmap-definition-VGOIOE7T-DqOPFPo-.js → mindmap-definition-VGOIOE7T-DJv6Etzn.js} +3 -3
  83. package/dist/mio-previewer.cjs.js +2 -2
  84. package/dist/mio-previewer.css +1 -1
  85. package/dist/mio-previewer.es.js +12 -4
  86. package/dist/{packet-HUATNLJX-CZHu-nbR.cjs → packet-HUATNLJX-BP2PL506.cjs} +1 -1
  87. package/dist/{packet-HUATNLJX-1wKSvaMq.js → packet-HUATNLJX-CBmfZU1b.js} +1 -1
  88. package/dist/pie-WTHONI2E-CTg9RtIm.js +5 -0
  89. package/dist/{pie-WTHONI2E-DXv4_T2x.cjs → pie-WTHONI2E-D9uuNfvy.cjs} +1 -1
  90. package/dist/{pieDiagram-ADFJNKIX-D2Z---Zh.cjs → pieDiagram-ADFJNKIX-Cli4W-Cd.cjs} +1 -1
  91. package/dist/{pieDiagram-ADFJNKIX-D6VHJbDG.js → pieDiagram-ADFJNKIX-kTbzcM2c.js} +4 -4
  92. package/dist/plugins/custom.cjs.js +1 -1
  93. package/dist/plugins/custom.es.js +1 -1
  94. package/dist/plugins/markdown-it.cjs.js +1 -1
  95. package/dist/plugins/markdown-it.es.js +66 -78
  96. package/dist/{quadrantDiagram-AYHSOK5B-DkReeODO.cjs → quadrantDiagram-AYHSOK5B-BN3oiHK0.cjs} +1 -1
  97. package/dist/{quadrantDiagram-AYHSOK5B-D5OPLeMW.js → quadrantDiagram-AYHSOK5B-BoWJsSRs.js} +2 -2
  98. package/dist/{radar-NJJJXTRR-CsSvUZzP.cjs → radar-NJJJXTRR-6s1MXgpO.cjs} +1 -1
  99. package/dist/radar-NJJJXTRR-EHgY_Bp9.js +5 -0
  100. package/dist/{requirementDiagram-UZGBJVZJ-C5hVzY2x.cjs → requirementDiagram-UZGBJVZJ-Cv4g11kh.cjs} +1 -1
  101. package/dist/{requirementDiagram-UZGBJVZJ-BtuFN9mE.js → requirementDiagram-UZGBJVZJ-DfeezqhH.js} +3 -3
  102. package/dist/{sankeyDiagram-TZEHDZUN-DpRrZxqg.cjs → sankeyDiagram-TZEHDZUN-Ci99ek50.cjs} +1 -1
  103. package/dist/{sankeyDiagram-TZEHDZUN-Cg-JIJqC.js → sankeyDiagram-TZEHDZUN-DnJ5Q_82.js} +1 -1
  104. package/dist/{sequenceDiagram-WL72ISMW-KoQgtSet.cjs → sequenceDiagram-WL72ISMW-B-x48OW0.cjs} +1 -1
  105. package/dist/{sequenceDiagram-WL72ISMW-nEmJoaMy.js → sequenceDiagram-WL72ISMW-CGSwMa_I.js} +3 -3
  106. package/dist/{stateDiagram-FKZM4ZOC-DT6rGE9e.cjs → stateDiagram-FKZM4ZOC-CDTWIBaR.cjs} +1 -1
  107. package/dist/{stateDiagram-FKZM4ZOC-DBDLAMfm.js → stateDiagram-FKZM4ZOC-DnxlIDvy.js} +4 -4
  108. package/dist/{stateDiagram-v2-4FDKWEC3-uHZFzERJ.cjs → stateDiagram-v2-4FDKWEC3-BX076pCs.cjs} +1 -1
  109. package/dist/{stateDiagram-v2-4FDKWEC3-BlnZMiIk.js → stateDiagram-v2-4FDKWEC3-DsI4gK5l.js} +2 -2
  110. package/dist/{timeline-definition-IT6M3QCI-nu6lhLaG.js → timeline-definition-IT6M3QCI-BZ1Bt6EI.js} +2 -2
  111. package/dist/{timeline-definition-IT6M3QCI-5sT2JElf.cjs → timeline-definition-IT6M3QCI-doRyfVBa.cjs} +1 -1
  112. package/dist/{treemap-75Q7IDZK-0YVmrH6l.cjs → treemap-75Q7IDZK-CJKHGaSh.cjs} +1 -1
  113. package/dist/{treemap-75Q7IDZK-CjQGnPQL.js → treemap-75Q7IDZK-CmDuYBJ9.js} +1 -1
  114. package/dist/types/helpers/containerHelpers.d.ts +11 -0
  115. package/dist/types/index.d.ts +1 -1
  116. package/dist/types/plugins/AlertPlugin.d.ts +10 -8
  117. package/dist/{xychartDiagram-PRI3JC2R-Df-nQpxQ.cjs → xychartDiagram-PRI3JC2R-B88yMO5N.cjs} +1 -1
  118. package/dist/{xychartDiagram-PRI3JC2R-COTy5kPs.js → xychartDiagram-PRI3JC2R-BL9ENoB-.js} +2 -2
  119. package/package.json +1 -1
  120. package/dist/channel-K9KCfQVN.cjs +0 -1
  121. package/dist/clone-BIUMbfGI.cjs +0 -1
  122. package/dist/info-63CPKGFF-C4jcTOlN.js +0 -5
  123. package/dist/pie-WTHONI2E-Tnd3n2cn.js +0 -5
  124. package/dist/radar-NJJJXTRR-B7MWPc1b.js +0 -5
package/README.md CHANGED
@@ -2,217 +2,484 @@
2
2
 
3
3
  [中文文档](./README.zh-CN.md) | English
4
4
 
5
- A small Vue 3 markdown previewer optimized for streaming updates. It
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
- This project is also configured to be published as an npm library (see
11
- `package.json` scripts). The library exposes a named export `MdRenderer`
12
- from the package root (import { MdRenderer } from 'mio-previewer').
13
- ## Quick start
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
- Prerequisites: Node 18+ recommended, pnpm (or npm/yarn).
16
-
17
- Install dependencies:
16
+ ## Installation
18
17
 
19
18
  ```bash
20
- pnpm install
19
+ npm install mio-previewer
20
+ # or
21
+ pnpm add mio-previewer
22
+ # or
23
+ yarn add mio-previewer
21
24
  ```
22
25
 
23
- Run dev server:
26
+ ## Quick Start
24
27
 
25
- ```bash
26
- pnpm dev
27
- ```
28
+ ### Basic Usage
28
29
 
29
- Open http://localhost:5173/ to view the live preview.
30
+ ```vue
31
+ <template>
32
+ <MdRenderer :md="markdown" />
33
+ </template>
30
34
 
31
- Build for production:
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
- ```bash
34
- pnpm build
35
- pnpm preview
40
+ const markdown = ref('# Hello World\n\nThis is **markdown**!')
41
+ </script>
36
42
  ```
37
43
 
38
- Install the package (after publishing or using a local install):
44
+ ### Streaming Mode
39
45
 
40
- ```bash
41
- # from npm (when published)
42
- pnpm add mio-previewer
46
+ Perfect for AI chatbots or real-time content:
43
47
 
44
- # or install from a local folder
45
- pnpm add /path/to/mio-previewer
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
- Usage example (consumer project with Vue 3):
79
+ ## Plugin System
80
+
81
+ ### Using Built-in Plugins
49
82
 
50
- ```js
51
- import { createApp } from 'vue'
83
+ #### Math Formulas (KaTeX)
84
+
85
+ ```vue
86
+ <script setup>
52
87
  import { MdRenderer } from 'mio-previewer'
53
- import 'github-markdown-css/github-markdown.css'
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
- const app = createApp({})
56
- app.component('MdRenderer', MdRenderer)
57
- app.mount('#app')
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
- Notes for bundlers and consumers
61
- - `vue` is marked as external in the library bundle. Add `vue@^3` to
62
- your project's dependencies (or peerDependencies) when publishing.
63
- - Types are emitted to `dist/types` during build; the package `types`
64
- field points to the generated declaration file.
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
- Publishing checklist
67
- - Ensure `package.json` has `name`, `version`, `description`, `repository`,
68
- and `peerDependencies: { "vue": "^3" }` (recommended).
69
- - Run `pnpm run build` (this runs the lib build and emits types).
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
- - `src/MdRenderer.vue` — core component. Accepts props `md` (string),
74
- `isStreaming` (boolean) and `useWorker` (boolean). Handles parsing,
75
- streaming-friendly incremental updates, and manages a special cursor
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
- ## Streaming behavior and cursor management
132
+ ::: error
133
+ ❌ Error message
134
+ :::
87
135
 
88
- The `isStreaming` prop controls whether a blinking cursor is displayed at the end of the rendered content:
136
+ ::: success
137
+ ✅ Success message
138
+ :::
139
+ `
89
140
 
90
- - `isStreaming=false` — No cursor is shown. Use this for static content or when streaming has finished.
91
- - `isStreaming=true` A blinking cursor is displayed at the end, indicating that content is actively streaming/updating.
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
- When `isStreaming` is `true`, a special AST node `{ type: 'component', name: 'cursor' }` is inserted at the end of the AST to render the `BlinkingCursor` component. The helper `manageCursor(ast, 'add'|'remove')` handles insertion/removal of this cursor node.
154
+ #### Syntax Highlighting
94
155
 
95
- ## Plugin System
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
- mio-previewer provides a powerful two-tier plugin system:
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
- ### 1. Markdown-it Plugins (Syntax Extension)
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
- Extend Markdown syntax by using standard markdown-it plugins:
214
+ #### Emoji Support
102
215
 
103
- ```js
216
+ ```vue
217
+ <script setup>
104
218
  import { MdRenderer } from 'mio-previewer'
105
- import markdownItSub from 'markdown-it-sub'
106
- import markdownItSup from 'markdown-it-sup'
219
+ import { EmojiPlugin } from 'mio-previewer/plugins/custom'
220
+ import 'mio-previewer/dist/mio-previewer.css'
107
221
 
108
- const markdownItPlugins = [
109
- { plugin: markdownItSub },
110
- { plugin: markdownItSup, options: { /* plugin options */ } }
111
- ]
222
+ const markdown = 'Hello :smile: Welcome! :tada: :rocket:'
112
223
 
113
- // Use in component
114
- <MdRenderer
115
- :md="text"
116
- :markdownItPlugins="markdownItPlugins"
117
- :markdownItOptions="{ html: true, linkify: true }"
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
- ### 2. Custom Plugins (Rendering Extension)
235
+ ### Complete Example with All Plugins
122
236
 
123
- Create custom renderers for specific AST nodes:
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
- ```js
126
- import { AlertPlugin, EmojiPlugin } from 'mio-previewer'
245
+ const markdown = ref(`# Complete Demo :rocket:
127
246
 
128
- // Built-in plugins
129
- const customPlugins = [AlertPlugin, EmojiPlugin]
247
+ ## Alerts
248
+ ::: info
249
+ This is **important** information!
250
+ :::
130
251
 
131
- // Or create your own
132
- const MyPlugin = {
133
- name: 'my-plugin',
134
- priority: 50, // Higher priority executes first
135
- test: (node) => node.type === 'tag' && node.name === 'custom',
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('div', { class: 'my-custom' }, renderChildren())
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
- <MdRenderer :md="text" :customPlugins="[MyPlugin, ...customPlugins]" />
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
- ### Built-in Plugins
369
+ #### MarkdownItPluginConfig
145
370
 
146
- - **AlertPlugin**: Renders custom alert boxes with types (info, warning, error, success)
147
- - **EmojiPlugin**: Converts emoji codes like `:smile:` → 😊
148
- - **CodeBlockPlugin**: Prism syntax highlighting with copy & HTML preview buttons (20+ languages)
149
- - **katexPlugin**: Renders math formulas with KaTeX (supports `$...$`, `$$...$$`, `\(...\)`, `\[...\]` delimiters)
150
- - **mermaidPlugin**: Renders diagrams with Mermaid (flowcharts, sequence diagrams, state diagrams, class diagrams, etc.) with dark/light theme support
371
+ ```typescript
372
+ interface MarkdownItPluginConfig {
373
+ plugin: (md: MarkdownIt, options?: any) => void
374
+ options?: any
375
+ }
376
+ ```
151
377
 
152
- ### Plugin Priority
378
+ ## Built-in Plugins
153
379
 
154
- Plugins are executed in priority order (higher first). Built-in CursorPlugin has priority 100.
380
+ ### Markdown-it Plugins (Syntax)
155
381
 
156
- **Recommended ranges:**
157
- - 100+: System plugins
158
- - 50-99: High priority (containers, alerts)
159
- - 10-49: Medium priority (icons, badges)
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
- ### Documentation
387
+ ### Custom Plugins (Rendering)
163
388
 
164
- See [Plugin Guide](./docs/PLUGIN_GUIDE.md) for detailed documentation, examples, and best practices.
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
- ### Demo
395
+ ## Advanced Usage
167
396
 
168
- Run the plugin demo:
169
- ```bash
170
- pnpm dev
171
- # Open http://localhost:5173/plugin-demo.html
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
- ## Worker contract
417
+ ### Web Worker Mode
175
418
 
176
- When `useWorker` is `true`, `MdRenderer` creates a module Worker with:
419
+ For better performance with large documents:
177
420
 
178
- ```js
179
- worker = new Worker(new URL('/parser.worker.js', import.meta.url), { type: 'module' })
180
- worker.postMessage({ markdownText: newMd })
181
- // worker should respond with: postMessage({ ast })
421
+ ```vue
422
+ <template>
423
+ <MdRenderer
424
+ :md="largeMarkdown"
425
+ :useWorker="true"
426
+ />
427
+ </template>
182
428
  ```
183
429
 
184
- The `ast` must be the same shape as `parseDocument(html).children` so
185
- that `RecursiveRenderer` can consume it directly.
430
+ **Note:** Worker mode requires `public/parser.worker.js` to be accessible.
186
431
 
187
- ## TypeScript migration notes
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
- pnpm add -D vue-tsc @types/htmlparser2 @types/markdown-it
195
- npx vue-tsc --noEmit
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
- Then replace the shim declarations with real types from the installed
199
- packages.
444
+ # Run benchmark
445
+ pnpm benchmark
446
+ ```
200
447
 
201
- ## Development tips
448
+ ## Project Structure
202
449
 
203
- - To debug AST output, add a `console.log(parseDocument(html).children)`
204
- in `MdRenderer.vue` before assigning `ast` — this helps inspect node
205
- shapes for plugin writing.
206
- - If you change streaming logic, ensure `manageCursor` is called to
207
- preserve cursor visibility during incremental updates.
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
- ## Files of interest
470
+ ## Browser Support
210
471
 
211
- - `src/MdRenderer.vue` main parsing & streaming logic
212
- - `src/components/RecursiveRenderer.vue` renderer & plugin system
213
- - `src/components/BlinkingCursor.vue` streaming cursor
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)