md2ui 1.0.18 → 1.0.20
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 +51 -58
- package/bin/build.js +95 -9
- package/bin/md2ui.js +102 -13
- package/package.json +24 -10
- package/public/docs/00-/345/277/253/351/200/237/345/274/200/345/247/213.md +48 -28
- package/public/docs/01-/345/212/237/350/203/275/347/211/271/346/200/247.md +55 -40
- package/public/docs/02-Markdown/346/270/262/346/237/223/00-/345/237/272/347/241/200/350/257/255/346/263/225.md +88 -0
- package/public/docs/02-Markdown/346/270/262/346/237/223/01-/344/273/243/347/240/201/345/235/227.md +91 -0
- package/public/docs/02-Markdown/346/270/262/346/237/223/02-/350/241/250/346/240/274.md +187 -0
- package/public/docs/02-Markdown/346/270/262/346/237/223/03-Mermaid/345/233/276/350/241/250.md +101 -0
- package/public/docs/02-Markdown/346/270/262/346/237/223/04-Frontmatter.md +32 -0
- package/public/docs/02-Markdown/346/270/262/346/237/223/05-/346/225/260/345/255/246/345/205/254/345/274/217.md +47 -0
- package/public/docs/02-Markdown/346/270/262/346/237/223/06-Mermaid/345/244/215/346/235/202/345/233/276/350/241/250/346/265/213/350/257/225.md +1376 -0
- package/public/docs/02-Markdown/346/270/262/346/237/223/assets/img-1777383093712.png +0 -0
- package/public/docs/03-/345/257/274/350/210/252/344/270/216/345/270/203/345/261/200/00-/344/270/211/346/240/217/345/270/203/345/261/200.md +33 -0
- package/public/docs/03-/345/257/274/350/210/252/344/270/216/345/270/203/345/261/200/01-/347/233/256/345/275/225/346/240/221/345/257/274/350/210/252.md +43 -0
- package/public/docs/03-/345/257/274/350/210/252/344/270/216/345/270/203/345/261/200/02-/346/226/207/346/241/243/345/244/247/347/272/262.md +51 -0
- package/public/docs/03-/345/257/274/350/210/252/344/270/216/345/270/203/345/261/200/03-/344/270/212/344/270/213/347/257/207/345/257/274/350/210/252.md +29 -0
- package/public/docs/03-/345/257/274/350/210/252/344/270/216/345/270/203/345/261/200/04-/347/253/231/345/206/205/351/223/276/346/216/245.md +39 -0
- package/public/docs/03-/345/257/274/350/210/252/344/270/216/345/270/203/345/261/200/05-/345/244/247/347/272/262/345/216/213/345/212/233/346/265/213/350/257/225.md +340 -0
- package/public/docs/04-/346/220/234/347/264/242/345/212/237/350/203/275/00-/345/205/250/346/226/207/346/220/234/347/264/242.md +46 -0
- package/public/docs/05-/347/274/226/350/276/221/345/212/237/350/203/275/00-/347/274/226/350/276/221/345/231/250/345/237/272/347/241/200.md +65 -0
- package/public/docs/05-/347/274/226/350/276/221/345/212/237/350/203/275/01-/350/207/252/345/212/250/344/277/235/345/255/230.md +38 -0
- package/public/docs/06-/351/230/205/350/257/273/344/275/223/351/252/214/00-/351/230/205/350/257/273/350/277/233/345/272/246.md +43 -0
- package/public/docs/06-/351/230/205/350/257/273/344/275/223/351/252/214/01-/345/233/276/347/211/207/346/224/276/345/244/247.md +40 -0
- package/public/docs/06-/351/230/205/350/257/273/344/275/223/351/252/214/02-/350/277/224/345/233/236/351/241/266/351/203/250.md +38 -0
- package/public/docs/06-/351/230/205/350/257/273/344/275/223/351/252/214/assets/img-1777261394722.png +0 -0
- package/public/docs/07-/347/247/273/345/212/250/347/253/257/351/200/202/351/205/215/00-/345/223/215/345/272/224/345/274/217/345/270/203/345/261/200.md +37 -0
- package/public/docs/08-/346/226/207/346/241/243/347/256/241/347/220/206/00-/346/226/260/345/273/272/344/270/216/345/210/240/351/231/244.md +47 -0
- package/public/docs/09-/345/257/274/345/207/272/345/212/237/350/203/275/00-/345/257/274/345/207/272Word.md +77 -0
- package/public/docs/10-/351/203/250/347/275/262/344/270/216/351/205/215/347/275/256/00-CLI/345/267/245/345/205/267.md +52 -0
- package/public/docs/10-/351/203/250/347/275/262/344/270/216/351/205/215/347/275/256/01-SSG/351/235/231/346/200/201/346/236/204/345/273/272.md +44 -0
- package/public/docs/10-/351/203/250/347/275/262/344/270/216/351/205/215/347/275/256/02-/350/207/252/345/256/232/344/271/211/351/205/215/347/275/256.md +58 -0
- package/public/docs/11-/345/244/232/347/272/247/347/233/256/345/275/225/346/265/213/350/257/225/00-/344/270/200/347/272/247/346/226/207/346/241/243.md +20 -0
- package/public/docs/11-/345/244/232/347/272/247/347/233/256/345/275/225/346/265/213/350/257/225/01-/345/255/220/347/233/256/345/275/225/00-/344/272/214/347/272/247/346/226/207/346/241/243.md +13 -0
- package/public/docs/11-/345/244/232/347/272/247/347/233/256/345/275/225/346/265/213/350/257/225/01-/345/255/220/347/233/256/345/275/225/01-/346/267/261/345/261/202/345/265/214/345/245/227/00-/344/270/211/347/272/247/346/226/207/346/241/243.md +23 -0
- package/src/App.vue +111 -12
- package/src/components/AppSidebar.vue +181 -21
- package/src/components/CodeBlockNodeView.vue +72 -0
- package/src/components/DocContent.vue +25 -14
- package/src/components/EditorContent.vue +257 -0
- package/src/components/EditorToolbar.vue +264 -0
- package/src/components/ImageZoom.vue +88 -5
- package/src/components/MathBlockNodeView.vue +160 -0
- package/src/components/MathInlineNodeView.vue +145 -0
- package/src/components/MermaidNodeView.vue +157 -0
- package/src/components/MobileSearch.vue +97 -0
- package/src/components/TableOfContents.vue +174 -32
- package/src/components/TopBar.vue +69 -4
- package/src/components/TreeNode.vue +232 -39
- package/src/components/WelcomePage.vue +2 -2
- package/src/composables/useDocHash.js +9 -1
- package/src/composables/useDocManager.js +452 -105
- package/src/composables/useDocTree.js +33 -2
- package/src/composables/useExportWord.js +73 -10
- package/src/composables/useFileWatcher.js +45 -0
- package/src/composables/useFrontmatter.js +2 -2
- package/src/composables/useMarkdown.js +450 -52
- package/src/composables/useMermaidCache.js +15 -0
- package/src/composables/useScroll.js +354 -27
- package/src/composables/useSearch.js +12 -11
- package/src/config.js +1 -4
- package/src/extensions/CodeBlockCustom.js +113 -0
- package/src/extensions/MathBlock.js +107 -0
- package/src/extensions/MathInline.js +100 -0
- package/src/extensions/MermaidBlock.js +73 -0
- package/src/extensions/TableControls.js +670 -0
- package/src/services/DocService.js +168 -0
- package/src/style.css +2416 -36
- package/src/utils/imageConverter.js +129 -0
- package/vite-plugin-doc-api.js +369 -0
- package/vite.config.js +7 -2
- package/public/docs/02-Mermaid/345/233/276/350/241/250.md +0 -102
- package/public/docs/03-/350/277/233/351/230/266/346/214/207/345/215/227/01-/347/233/256/345/275/225/347/273/223/346/236/204.md +0 -55
- package/public/docs/03-/350/277/233/351/230/266/346/214/207/345/215/227/02-/350/207/252/345/256/232/344/271/211/351/205/215/347/275/256.md +0 -63
- package/public/docs/03-/350/277/233/351/230/266/346/214/207/345/215/227/03-/351/203/250/347/275/262/346/226/271/346/241/210.md +0 -73
- package/public/docs/04-API/345/217/202/350/200/203/01-/347/273/204/344/273/266API.md +0 -80
- package/public/docs/04-API/345/217/202/350/200/203/02-Composables.md +0 -92
- package/src/api/docs.js +0 -106
- package/src/components/SearchPanel.vue +0 -90
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { Node, mergeAttributes, VueNodeViewRenderer } from '@tiptap/vue-3'
|
|
2
|
+
import MathInlineNodeView from '../components/MathInlineNodeView.vue'
|
|
3
|
+
|
|
4
|
+
// HTML 属性转义
|
|
5
|
+
function escapeAttr(str) {
|
|
6
|
+
return str.replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>')
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 行内数学公式扩展($...$)
|
|
11
|
+
* 编辑模式下渲染为 inline NodeView
|
|
12
|
+
*/
|
|
13
|
+
export const MathInline = Node.create({
|
|
14
|
+
name: 'mathInline',
|
|
15
|
+
group: 'inline',
|
|
16
|
+
inline: true,
|
|
17
|
+
atom: true,
|
|
18
|
+
|
|
19
|
+
addAttributes() {
|
|
20
|
+
return {
|
|
21
|
+
latex: { default: '' },
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
parseHTML() {
|
|
26
|
+
return [
|
|
27
|
+
{
|
|
28
|
+
tag: 'span.math-inline-node',
|
|
29
|
+
getAttrs: (node) => {
|
|
30
|
+
const latex = node.getAttribute('data-latex') || node.textContent.trim()
|
|
31
|
+
return latex ? { latex } : false
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
renderHTML({ node, HTMLAttributes }) {
|
|
38
|
+
return ['span', mergeAttributes(HTMLAttributes, {
|
|
39
|
+
class: 'math-inline-node',
|
|
40
|
+
'data-latex': node.attrs.latex,
|
|
41
|
+
}), node.attrs.latex]
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
addNodeView() {
|
|
45
|
+
return VueNodeViewRenderer(MathInlineNodeView)
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
addInputRules() {
|
|
49
|
+
return [
|
|
50
|
+
{
|
|
51
|
+
find: /(?<!\$)\$([^$\n]+)\$$/,
|
|
52
|
+
handler: ({ state, range, match }) => {
|
|
53
|
+
const latex = match[1]
|
|
54
|
+
if (!latex || !latex.trim()) return
|
|
55
|
+
const node = state.schema.nodes.mathInline.create({ latex: latex.trim() })
|
|
56
|
+
const tr = state.tr.replaceWith(range.from, range.to, node)
|
|
57
|
+
tr.insertText(' ', range.from + 1)
|
|
58
|
+
return tr
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
addStorage() {
|
|
65
|
+
return {
|
|
66
|
+
markdown: {
|
|
67
|
+
serialize(state, node) {
|
|
68
|
+
state.write('$' + (node.attrs.latex || '') + '$')
|
|
69
|
+
},
|
|
70
|
+
parse: {
|
|
71
|
+
// 给 markdown-it 注册行内公式规则
|
|
72
|
+
setup(md) {
|
|
73
|
+
md.inline.ruler.after('escape', 'math_inline', (state, silent) => {
|
|
74
|
+
if (state.src[state.pos] !== '$') return false
|
|
75
|
+
if (state.src[state.pos + 1] === '$') return false // 跳过 $$
|
|
76
|
+
const start = state.pos + 1
|
|
77
|
+
let end = start
|
|
78
|
+
while (end < state.posMax) {
|
|
79
|
+
if (state.src[end] === '$' && state.src[end - 1] !== '\\') break
|
|
80
|
+
end++
|
|
81
|
+
}
|
|
82
|
+
if (end >= state.posMax) return false
|
|
83
|
+
if (end === start) return false // 空公式
|
|
84
|
+
if (silent) return true
|
|
85
|
+
const latex = state.src.slice(start, end).trim()
|
|
86
|
+
const token = state.push('math_inline', 'span', 0)
|
|
87
|
+
token.content = latex
|
|
88
|
+
state.pos = end + 1
|
|
89
|
+
return true
|
|
90
|
+
})
|
|
91
|
+
md.renderer.rules.math_inline = (tokens, idx) => {
|
|
92
|
+
const latex = tokens[idx].content
|
|
93
|
+
return '<span class="math-inline-node" data-latex="' + escapeAttr(latex) + '">' + escapeAttr(latex) + '</span>'
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
})
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Node, mergeAttributes, VueNodeViewRenderer } from '@tiptap/vue-3'
|
|
2
|
+
import MermaidNodeView from '../components/MermaidNodeView.vue'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Tiptap Mermaid 扩展
|
|
6
|
+
* 编辑模式下将 mermaid 代码块渲染为图表预览,右上角提供编辑按钮
|
|
7
|
+
*/
|
|
8
|
+
export const MermaidBlock = Node.create({
|
|
9
|
+
name: 'mermaidBlock',
|
|
10
|
+
group: 'block',
|
|
11
|
+
content: 'text*',
|
|
12
|
+
marks: '',
|
|
13
|
+
defining: true,
|
|
14
|
+
isolating: true,
|
|
15
|
+
code: true,
|
|
16
|
+
|
|
17
|
+
addAttributes() {
|
|
18
|
+
return {
|
|
19
|
+
language: {
|
|
20
|
+
default: 'mermaid',
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
parseHTML() {
|
|
26
|
+
return [
|
|
27
|
+
{
|
|
28
|
+
tag: 'pre',
|
|
29
|
+
preserveWhitespace: 'full',
|
|
30
|
+
getAttrs: (node) => {
|
|
31
|
+
const code = node.querySelector('code')
|
|
32
|
+
if (!code) return false
|
|
33
|
+
const isMermaid = code.classList.contains('language-mermaid')
|
|
34
|
+
return isMermaid ? {} : false
|
|
35
|
+
},
|
|
36
|
+
// 优先级高于默认 codeBlock
|
|
37
|
+
priority: 60,
|
|
38
|
+
},
|
|
39
|
+
]
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
renderHTML({ HTMLAttributes }) {
|
|
43
|
+
return [
|
|
44
|
+
'pre',
|
|
45
|
+
mergeAttributes(HTMLAttributes),
|
|
46
|
+
['code', { class: 'language-mermaid' }, 0],
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
addNodeView() {
|
|
51
|
+
return VueNodeViewRenderer(MermaidNodeView)
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
// tiptap-markdown 序列化/解析规则
|
|
55
|
+
addStorage() {
|
|
56
|
+
return {
|
|
57
|
+
markdown: {
|
|
58
|
+
serialize(state, node) {
|
|
59
|
+
state.write('```mermaid\n')
|
|
60
|
+
state.text(node.textContent, false)
|
|
61
|
+
state.ensureNewLine()
|
|
62
|
+
state.write('```')
|
|
63
|
+
state.closeBlock(node)
|
|
64
|
+
},
|
|
65
|
+
parse: {
|
|
66
|
+
// 不需要额外的 parse 配置,
|
|
67
|
+
// Markdown 解析后会生成 <pre><code class="language-mermaid"> 结构,
|
|
68
|
+
// 由 parseHTML 规则匹配
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
})
|