11<template >
22 <div class =" markdown markdown-body" >
33 <PerfectScrollbar >
4- <div v-html =" renderer " />
4+ <div v-html =" renderedHtml " />
55 </PerfectScrollbar >
66 </div >
77</template >
@@ -11,11 +11,14 @@ import { useAppStore } from '@/store/app'
1111import { useSnippetStore } from ' @/store/snippets'
1212import sanitizeHtml from ' sanitize-html'
1313import hljs from ' highlight.js'
14- import { computed , onBeforeUnmount , onMounted , ref , watch } from ' vue'
14+ import { computed , onBeforeUnmount , onMounted , ref , watch , nextTick } from ' vue'
1515import { ipc , store } from ' @/electron'
1616import { marked } from ' marked'
1717import mermaid from ' mermaid'
1818import { useHljsTheme } from ' @/composable'
19+ import { useCodemirror } from ' @/composable/codemirror'
20+
21+ import { nanoid } from ' nanoid'
1922
2023const isDev = import .meta .env .DEV
2124
@@ -24,28 +27,51 @@ interface Props {
2427 scale? : number
2528}
2629
30+ interface Editors {
31+ id: string
32+ value: string
33+ lang: string
34+ }
35+
2736const props = withDefaults (defineProps <Props >(), {
2837 scale: 1
2938})
3039
3140const appStore = useAppStore ()
3241const snippetStore = useSnippetStore ()
3342
43+ const renderedHtml = ref ()
44+
45+ const editors: Editors [] = []
46+
3447const forceRefresh = ref ()
3548const preTagBg = computed (() =>
3649 appStore .isLightTheme ? ' #fff' : ' var(--color-contrast-high)'
3750)
51+ const fontFamily = computed (() => appStore .editor .fontFamily )
3852
3953const init = () => {
4054 const renderer: marked .RendererObject = {
4155 code (code : string , lang : string ) {
4256 if (lang === ' mermaid' ) {
4357 return ` <div class="mermaid">${code }</div><br> `
4458 } else {
45- const language = hljs .getLanguage (lang ) ? lang : ' plaintext'
46- return ` <pre><code class="language-${lang }">${
47- hljs .highlight (code , { language }).value
48- }</code></pre> `
59+ if (appStore .markdown .codeRenderer === ' highlight.js' ) {
60+ const language = hljs .getLanguage (lang ) ? lang : ' plaintext'
61+ return ` <pre><code class="language-${lang }">${
62+ hljs .highlight (code , { language }).value
63+ }</code></pre> `
64+ } else {
65+ const id = nanoid (6 )
66+
67+ editors .push ({
68+ id ,
69+ value: code ,
70+ lang
71+ })
72+
73+ return ` <div id="${id }"></div> `
74+ }
4975 }
5076 },
5177 link (href : string , title : string , text : string ) {
@@ -69,10 +95,12 @@ const initMermaid = () => {
6995
7096onMounted (() => {
7197 initMermaid ()
98+ render ()
7299})
73100
74- const getRenderer = () => {
101+ const render = () => {
75102 const raw = marked .parse (props .value )
103+
76104 let html = sanitizeHtml (raw , {
77105 allowedTags: [
78106 ' h1' ,
@@ -152,7 +180,8 @@ const getRenderer = () => {
152180 ' class' ,
153181 ' type' ,
154182 ' checked' ,
155- ' disabled'
183+ ' disabled' ,
184+ ' id'
156185 ]
157186 }
158187 })
@@ -164,11 +193,9 @@ const getRenderer = () => {
164193 ? html .replace (re , ` src="file://${path }/ ` )
165194 : html .replace (re , ` src="${path }/ ` )
166195
167- return html
196+ renderedHtml . value = html
168197}
169198
170- const renderer = computed (() => getRenderer ())
171-
172199const openExternal = (e : Event ) => {
173200 const el = e .target as HTMLAnchorElement
174201 e .preventDefault ()
@@ -209,6 +236,24 @@ watch(
209236 { immediate: true }
210237)
211238
239+ watch (renderedHtml , () => {
240+ nextTick (() => {
241+ editors .forEach (i => {
242+ useCodemirror (i .id , {
243+ value: i .value ,
244+ mode: i .lang
245+ })
246+ })
247+ })
248+ })
249+
250+ watch (
251+ () => props .value ,
252+ () => {
253+ render ()
254+ }
255+ )
256+
212257init ()
213258
214259onMounted (() => {
@@ -238,5 +283,20 @@ window.addEventListener('resize', () => {
238283 :deep(.ps ) {
239284 height : v-bind (height );
240285 }
286+ :deep(.CodeMirror ) {
287+ height : 100% ;
288+ padding : var (--spacing-xs );
289+ font-size : 0.85em ;
290+ font-family : v-bind (fontFamily );
291+ }
292+ :deep(.CodeMirror-line ) {
293+ padding : 0 var (--spacing-sm );
294+ & :first-child {
295+ padding-top : var (--spacing-xs );
296+ }
297+ & :last-child {
298+ padding-bottom : var (--spacing-xs );
299+ }
300+ }
241301}
242302 </style >
0 commit comments