编辑区域和预览区域¶
Text Only | |
---|---|
一、MarkdownContainer¶
MarkdownContainer.vue 脚本参考
编辑侧进行了三个区域划分,最上面部分是编辑器工具栏,增加常用的格式和图标等的输入。如标题、字体、对齐、数学公式、列表(有序、无序)、超链接、表格、Emoji、特殊字符、mermaid绘图、Plantuml绘图。
下面的部分分为两部分,左侧作为编辑器区域,进行markdown的编辑,右侧增加预览区域。
中间有个分割部分,可以鼠标拖动,以修改编辑区和预览区的显示百分比。
另外,在视图部分,增加编辑框部分的显示模式。编辑器模式、预览模式、编辑/预览模式。
二、编辑器组件¶
这里使用的是monaco-editor编辑器,嵌入vue组件,组件监听编辑器内容变化,然后将新的内容实时渲染到预览区域
MarkdownEditComponent.vue 脚本参考
TypeScript 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
<template>
<div
v-show="isShowEditArea"
id="md-edit-component"
class="md-edit-component"
:style="{ width: monacoEditorWidth }"
>
<MdMonacoEdit
v-model="markdownEditorCode"
:code="initialCodeContent"
:editor-area-width="monacoEditorWidthPx"
@update:code="handleMarkdownCodeUpdate"
/>
</div>
<div
v-show="isShowResizer"
id="resizer-md"
class="resizer-md"
:style="{ left: resizerLeft }"
@mousedown="onEditorResizerMouseDown($event)"
></div>
<div
v-show="isShowPreviewArea"
id="md-preview"
class="md-preview"
:style="{ width: editPreviewAreaWidth, left: editPreviewAreaLeft }"
>
<MdPreview :editor-content="markdownEditorContent" />
</div>
</template>
function onEditorResizerMouseDown(e: MouseEvent) {
editorMouseStart = e.clientX
window.addEventListener('mousemove', onEditorMouseMove)
window.addEventListener('mouseup', onEditorMouseUp)
}
// 编辑器大小调整逻辑(百分比)
function onEditorMouseMove(e: MouseEvent) {
const windowWidthValue = parseInt(windowWidth.value.replace('px', ''), 10)
const moveX = e.clientX - editorMouseStart
// 将当前百分比宽度转换为像素值
const currentWidthPx =
(parseFloat(monacoEditorWidth.value.replace('%', '')) / 100) * windowWidthValue
const newWidthPx = currentWidthPx + moveX
// 转换为百分比
let newWidthPercent = pxToPercent(newWidthPx, windowWidthValue)
// 限制最小和最大宽度(百分比)
const minWidthPercent = '20%'
const maxWidthPercent = '70%'
if (newWidthPercent > maxWidthPercent) {
newWidthPercent = maxWidthPercent
} else if (newWidthPercent < minWidthPercent) {
newWidthPercent = minWidthPercent
}
// 更新 Monaco Editor 宽度
monacoEditorWidth.value = newWidthPercent
editorMouseStart = e.clientX
}
function onEditorMouseUp() {
window.removeEventListener('mousemove', onEditorMouseMove)
window.removeEventListener('mouseup', onEditorMouseUp)
}
function handleMarkdownCodeUpdate(newValue: string) {
window.electron.ipcRenderer.send('update-select-file-content', newValue)
markdownEditorContent.value = newValue
}
function onHandleNewContent(content: string) {
if (content) {
// 编辑区域显示时,传入
if (isShowEditArea.value) {
initialCodeContent.value = content
}
// 预览模式、编辑器/预览模式,才进行渲染
if (isShowPreviewArea.value) {
handleMarkdownCodeUpdate(content)
}
} else {
// console.log('content bull')
handleMarkdownCodeUpdate('\r\n')
}
}
window.electron.ipcRenderer.on('show-selected-file-context', (_, content) => {
EventBus.$emit('plugin-tools-container-show', false)
onHandleNewContent(content)
})
window.electron.ipcRenderer.on('monaco-insert-writing-templates', (_, fileContent: string) => {
onHandleNewContent(fileContent)
})
function onHandleEditorShow(edit: boolean, preview: boolean) {
isShowEditArea.value = edit
isShowPreviewArea.value = preview
if (edit && preview) {
isShowResizer.value = true
monacoEditorWidth.value = '50%'
} else {
isShowResizer.value = false
if (edit) {
monacoEditorWidth.value = '100%'
} else {
monacoEditorWidth.value = '0%'
}
}
}
window.electron.ipcRenderer.on('markdown-edit-model', () => {
onHandleEditorShow(true, false)
})
window.electron.ipcRenderer.on('markdown-preview-model', () => {
onHandleEditorShow(false, true)
})
window.electron.ipcRenderer.on('markdown-edit-preview-model', () => {
onHandleEditorShow(true, true)
})
这里面增加了一些样式控制的东西,可以动态调整编辑区域和预览区域
三、预览区域¶
MarkdownPreviewComponent.vue 脚本参考
这里使用markdown-it进行渲染,因为markdown语法本身是支持html语言的,所以遇到一些特殊的或者自定义的格式,这里就在渲染之前,进行预渲染。比如mermaid绘图、公式、路径、链接、自定义的格式、特殊的字体等。
预渲染之后,再使用markdown-it进行渲染,渲染结束后,再进行后渲染,这里对渲染之后的html再进行特殊的处理,只是这里的会涉及的少一些。