UNPKG

md-editor-v3

Version:

Markdown editor for vue3, developed in jsx and typescript, dark theme、beautify content by prettier、render articles directly、paste or clip the picture and upload it...

2,062 lines 52.6 kB
import { useId as He, provide as x, computed as F, reactive as le, watch as E, onMounted as M, ref as z, inject as C, nextTick as W, shallowRef as ee, onBeforeUnmount as te, toRef as Me, defineComponent as de, createVNode as N, Fragment as Pe, h as Le } from "vue"; import { deepMerge as _e, deepClone as Oe, randomId as ie, debounce as Be } from "@vavt/util"; import { p as h, g as L, f as me, s as fe, a as je, b as Ne } from "./config.mjs"; import { b as y, U as De, C as ke, B as X, O as xe, E as Q, g as he, F as pe, h as ge, i as ve, H as ye, j as be, R as se, e as Ve, k as ue, d as Ge, f as ae, P as Ue, T as ze } from "./event-bus.mjs"; import { a as O, u as We, S as qe, c as Ke, z as Ze } from "./dom.mjs"; import Je from "@vavt/copy2clipboard"; import Xe from "markdown-it"; import Ye from "markdown-it-image-figures"; import Qe from "markdown-it-sub"; import et from "markdown-it-sup"; import { a as tt } from "./index5.mjs"; import nt from "medium-zoom"; const P = { hljs: `${h}-hljs`, hlcss: `${h}-hlCss`, prettier: `${h}-prettier`, prettierMD: `${h}-prettierMD`, cropperjs: `${h}-cropper`, croppercss: `${h}-cropperCss`, screenfull: `${h}-screenfull`, mermaidM: `${h}-mermaid-m`, mermaid: `${h}-mermaid`, katexjs: `${h}-katex`, katexcss: `${h}-katexCss`, echarts: `${h}-echarts` }, Qt = (e, t, a) => { const { editorId: n } = a, o = le({ // 是否已编译成html buildFinished: !1, // 存储当前最新的html html: "" }); E( () => e.modelValue, () => { o.buildFinished = !1; } ), M(() => { y.on(n, { name: X, callback(m) { o.buildFinished = !0, o.html = m; } }), y.on(n, { name: xe, callback() { const m = new Promise((c) => { if (o.buildFinished) c(o.html); else { const u = (s) => { c(s), y.remove(n, X, u); }; y.on(n, { name: X, callback: u }); } }); e.onSave ? e.onSave(e.modelValue, m) : t.emit("onSave", e.modelValue, m); } }); }); }, Te = (e, { editorId: t, rootRef: a, setting: n }) => { const o = L.editorExtensions.highlight, m = L.editorExtensionsAttrs.highlight; x("editorId", t), x("rootRef", a), x( "theme", F(() => e.theme) ), x( "language", F(() => e.language) ), x( "highlight", F(() => { const { js: u } = o, s = { ...me, ...o.css }, { js: l, css: i = {} } = m || {}, r = e.codeStyleReverse && e.codeStyleReverseList.includes(e.previewTheme) ? "dark" : e.theme, d = s[e.codeTheme] ? s[e.codeTheme][r] : me.atom[r], f = s[e.codeTheme] && i[e.codeTheme] ? i[e.codeTheme][r] : i.atom ? i.atom[r] : {}; return { js: { src: u, ...l }, css: { href: d, ...f } }; }) ), x("showCodeRowNumber", e.showCodeRowNumber); const c = F(() => { const u = { ...fe, ...L.editorConfig.languageUserDefined }; return _e( Oe(fe["en-US"]), u[e.language] || {} ); }); return x("usedLanguageText", c), x( "previewTheme", F(() => e.previewTheme) ), x( "customIcon", F(() => e.customIcon) ), x( "setting", F(() => n ? { // setting是reactive,不转化是可以直接赋值的 ...n } : { preview: !0, htmlPreview: !1, previewOnly: !1, pageFullscreen: !1, fullscreen: !1 }) ), { editorId: t }; }, en = (e, t) => (x("tabWidth", e.tabWidth), x( "disabled", F(() => e.disabled) ), x( "showToolbarName", F(() => e.showToolbarName) ), x("noUploadImg", e.noUploadImg), x( "tableShape", F(() => e.tableShape) ), x("noPrettier", e.noPrettier), x( "codeTheme", F(() => e.codeTheme) ), x("updateSetting", t.updateSetting), x( "catalogVisible", F(() => t.catalogVisible.value) ), x("defToolbars", t.defToolbars), x( "floatingToolbars", F(() => e.floatingToolbars) ), Te(e, t)), tn = (e) => { const { noPrettier: t, noUploadImg: a } = e, { editorExtensions: n, editorExtensionsAttrs: o } = L, m = t || n.prettier.prettierInstance, c = t || n.prettier.parserMarkdownInstance, u = a || n.cropper.instance; M(() => { if (!u) { const { js: s = {}, css: l = {} } = o.cropper || {}; O("link", { ...l, rel: "stylesheet", href: n.cropper.css, id: P.croppercss }), O("script", { ...s, src: n.cropper.js, id: P.cropperjs }); } if (!m) { const { standaloneJs: s = {} } = o.prettier || {}; O("script", { ...s, src: n.prettier.standaloneJs, id: P.prettier }); } if (!c) { const { parserMarkdownJs: s = {} } = o.prettier || {}; O("script", { ...s, src: n.prettier.parserMarkdownJs, id: P.prettierMD }); } }); }, nn = (e, t, a) => { const { editorId: n } = a; M(() => { y.on(n, { name: Q, callback: (o) => { e.onError?.(o), t.emit("onError", o); } }); }); }, on = (e, t, a) => { const { editorId: n } = a, o = le({ pageFullscreen: e.pageFullscreen, fullscreen: !1, preview: e.preview, htmlPreview: e.preview ? !1 : e.htmlPreview, previewOnly: !1 }), m = le({ ...o }), c = (l, i) => { const r = i === void 0 ? !o[l] : i; switch (l) { case "preview": { o.htmlPreview = !1, o.previewOnly = !1; break; } case "htmlPreview": { o.preview = !1, o.previewOnly = !1; break; } case "previewOnly": { r ? !o.preview && !o.htmlPreview && (o.preview = !0) : (m.preview || (o.preview = !1), m.htmlPreview || (o.htmlPreview = !1)); break; } } m[l] = r, o[l] = r; }; let u = ""; const s = () => { o.pageFullscreen || o.fullscreen ? document.body.style.overflow = "hidden" : document.body.style.overflow = u; }; return E(() => [o.pageFullscreen, o.fullscreen], s), M(() => { y.on(n, { name: De, callback(l, i) { const r = (d) => { y.emit(n, se, "image", { desc: "", urls: d }), i?.(); }; e.onUploadImg ? e.onUploadImg(l, r) : t.emit("onUploadImg", l, r); } }), u = document.body.style.overflow, s(); }), [o, c]; }, an = (e, t) => { const { editorId: a } = t, n = z(!1); return M(() => { y.on(a, { name: ke, callback: (o) => { o === void 0 ? n.value = !n.value : n.value = o; } }); }), n; }, rn = (e, t, a) => { const { editorId: n, catalogVisible: o, setting: m, updateSetting: c, codeRef: u } = a; E( () => m.pageFullscreen, (l) => { y.emit(n, he, l); } ), E( () => m.fullscreen, (l) => { y.emit(n, pe, l); } ), E( () => m.preview, (l) => { y.emit(n, ge, l); } ), E( () => m.previewOnly, (l) => { y.emit(n, ve, l); } ), E( () => m.htmlPreview, (l) => { y.emit(n, ye, l); } ), E(o, (l) => { y.emit(n, be, l); }); const s = { on(l, i) { switch (l) { case "pageFullscreen": { y.on(n, { name: he, callback(r) { i(r); } }); break; } case "fullscreen": { y.on(n, { name: pe, callback(r) { i(r); } }); break; } case "preview": { y.on(n, { name: ge, callback(r) { i(r); } }); break; } case "previewOnly": { y.on(n, { name: ve, callback(r) { i(r); } }); break; } case "htmlPreview": { y.on(n, { name: ye, callback(r) { i(r); } }); break; } case "catalog": { y.on(n, { name: be, callback(r) { i(r); } }); break; } } }, togglePageFullscreen(l) { c("pageFullscreen", l); }, toggleFullscreen(l) { y.emit(n, Ge, l); }, togglePreview(l) { c("preview", l); }, togglePreviewOnly(l) { c("previewOnly", l); }, toggleHtmlPreview(l) { c("htmlPreview", l); }, toggleCatalog(l) { y.emit(n, ke, l); }, triggerSave() { y.emit(n, xe); }, insert(l) { y.emit(n, se, "universal", { generate: l }); }, focus(l) { u.value?.focus(l); }, rerender() { y.emit(n, ue); }, getSelectedText() { return u.value?.getSelectedText(); }, resetHistory() { u.value?.resetHistory(); }, domEventHandlers(l) { y.emit(n, Ve, l); }, execCommand(l) { y.emit(n, se, l); }, getEditorView() { return u.value?.getEditorView(); } }; t.expose(s); }, ot = (e) => { const t = He(); return e.id || e.editorId || `${h}-${t}`; }, at = (e, t, a) => { const n = C("editorId"), o = C("rootRef"), m = C("usedLanguageText"), c = C("setting"), u = () => { o.value.querySelectorAll(`#${n} .${h}-preview .${h}-code`).forEach((i) => { let r = -1; const d = i.querySelector( `.${h}-copy-button:not([data-processed])` ); d && (d.onclick = (f) => { f.preventDefault(), clearTimeout(r); const v = (i.querySelector("input:checked + pre code") || i.querySelector("pre code")).textContent, { text: p, successTips: T, failTips: b } = m.value.copyCode; let $ = T; Je(e.formatCopiedText(v || "")).catch(() => { $ = b; }).finally(() => { d.dataset.isIcon ? d.dataset.tips = $ : d.textContent = $, r = window.setTimeout(() => { d.dataset.isIcon ? d.dataset.tips = p : d.textContent = p; }, 1500); }); }, d.setAttribute("data-processed", "true")); }); }, s = () => { W(u); }, l = (i) => { i && W(u); }; E([t, a], s), E(() => c.value.preview, l), E(() => c.value.htmlPreview, l), M(u); }, rt = (e) => { const t = C("editorId"), a = C("theme"), n = C("rootRef"), { editorExtensions: o, editorExtensionsAttrs: m, echartsConfig: c } = L; let u = o.echarts.instance; const s = ee(-1), l = () => { !e.noEcharts && u && (s.value = s.value + 1); }; E( () => a.value, () => { l(); } ), M(() => { if (e.noEcharts || u) return; const v = o.echarts.js; O( "script", { ...m.echarts?.js, src: v, id: P.echarts, onload() { u = window.echarts, l(); } }, "echarts" ); }); let i = [], r = [], d = []; const f = (v = !1) => { if (!i.length) { v && (r.forEach(($) => { $.dispose?.(); }), d.forEach(($) => { $.disconnect?.(); }), r = [], d = []); return; } const p = [], T = [], b = []; i.forEach(($, S) => { const w = r[S], I = d[S]; if (v || !$ || !$.isConnected || (n?.value ? !n.value.contains($) : !1)) { w?.dispose?.(), I?.disconnect?.(); return; } p.push($), w && T.push(w), I && b.push(I); }), i = p, r = T, d = b; }, g = () => { f(), !e.noEcharts && u && Array.from( n.value.querySelectorAll( `#${t} div.${h}-echarts:not([data-processed])` ) ).forEach((p) => { if (p.dataset.closed === "false") return !1; try { const T = o.echarts.parseOption(p.innerText, { editorId: t, element: p }), b = c(T), $ = u.init(p, a.value); $.setOption(b), p.setAttribute("data-processed", ""), i.push(p), r.push($); const S = new ResizeObserver(() => { $.resize(); }); S.observe(p), d.push(S); } catch (T) { y.emit(t, Q, { name: "echarts", message: T?.message, error: T }); } }); }; return te(() => { f(!0); }), { reRenderEcharts: s, replaceEcharts: g }; }, lt = (e) => { const t = C("highlight"), a = ee(L.editorExtensions.highlight.instance); return M(() => { e.noHighlight || a.value || (O("link", { ...t.value.css, rel: "stylesheet", id: P.hlcss }), O( "script", { ...t.value.js, id: P.hljs, onload() { a.value = window.hljs; } }, "hljs" )); }), E( () => t.value.css, () => { e.noHighlight || L.editorExtensions.highlight.instance || We("link", { ...t.value.css, rel: "stylesheet", id: P.hlcss }); } ), a; }, it = (e) => { const t = ee(L.editorExtensions.katex.instance); return M(() => { if (e.noKatex || t.value) return; const { editorExtensions: a, editorExtensionsAttrs: n } = L; O( "script", { ...n.katex?.js, src: a.katex.js, id: P.katexjs, onload() { t.value = window.katex; } }, "katex" ), O("link", { ...n.katex?.css, rel: "stylesheet", href: a.katex.css, id: P.katexcss }); }), t; }; class st { constructor(t) { this.options = t; } options; cache = /* @__PURE__ */ new Map(); isExpired(t) { return t.expiresAt <= Date.now(); } deleteExpired(t, a) { const n = a ?? this.cache.get(t); return !n || !this.isExpired(n) ? !1 : (this.cache.delete(t), !0); } trim() { for (const [t, a] of this.cache) if (!this.deleteExpired(t, a)) break; for (; this.cache.size > this.options.max; ) { const t = this.cache.keys().next().value; if (t === void 0) break; this.cache.delete(t); } } get(t) { const a = this.cache.get(t); if (!(!a || this.deleteExpired(t, a))) return this.cache.delete(t), this.cache.set(t, a), a.value; } set(t, a) { this.cache.delete(t), this.cache.set(t, { value: a, expiresAt: Date.now() + this.options.ttl }), this.trim(); } clear() { this.cache.clear(); } } const Y = new st({ max: 1e3, // 缓存10分钟 ttl: 6e5 }), ct = (e) => { const t = C("editorId"), a = C("theme"), n = C("rootRef"), { editorExtensions: o, editorExtensionsAttrs: m, mermaidConfig: c } = L; let u = o.mermaid.instance; const s = ee(-1), l = () => { if (!e.noMermaid && u) { const r = a.value === "dark" ? { startOnLoad: !1, theme: "dark" } : { startOnLoad: !1, theme: "base", themeVariables: { background: "#ffffff", primaryColor: "#ffffff", primaryTextColor: "#1f2329", primaryBorderColor: "#b7c0cc", secondaryColor: "#f7f8fa", tertiaryColor: "#f7f8fa", lineColor: "#596273", edgeLabelBackground: "#ffffff", clusterBkg: "#ffffff", clusterBorder: "#b7c0cc" } }; u.initialize(c(r)), s.value = s.value + 1; } }; return E( () => a.value, () => { Y.clear(), l(); } ), M(() => { if (e.noMermaid || u) return; const r = o.mermaid.js; /\.mjs/.test(r) ? (O("link", { ...m.mermaid?.js, rel: "modulepreload", href: r, id: P.mermaidM }), import( /* @vite-ignore */ /* webpackIgnore: true */ r ).then((d) => { u = d.default, l(); }).catch((d) => { y.emit(t, Q, { name: "mermaid", message: `Failed to load mermaid module: ${d.message}`, error: d }); })) : O( "script", { ...m.mermaid?.js, src: r, id: P.mermaid, onload() { u = window.mermaid, l(); } }, "mermaid" ); }), { reRenderRef: s, replaceMermaid: async () => { if (!e.noMermaid && u) { const r = n.value.querySelectorAll( `div.${h}-mermaid` ), d = document.createElement("div"), f = document.body.offsetWidth > 1366 ? document.body.offsetWidth : 1366, g = document.body.offsetHeight > 768 ? document.body.offsetHeight : 768; d.style.width = f + "px", d.style.height = g + "px", d.style.position = "fixed", d.style.zIndex = "-10000", d.style.top = "-10000"; let v = r.length; v > 0 && document.body.appendChild(d), await Promise.allSettled( Array.from(r).map((p) => (async (b) => { if (b.dataset.closed === "false") return !1; const $ = b.innerText; let S = Y.get($); if (!S) { const w = ie(); let I = { svg: "" }; try { I = await u.render(w, $, d), S = await e.sanitizeMermaid(I.svg); const k = document.createElement("p"); k.className = `${h}-mermaid`, k.setAttribute("data-processed", ""), k.setAttribute("data-content", $), k.innerHTML = S, k.children[0]?.removeAttribute("height"), Y.set($, k.innerHTML), b.dataset.line !== void 0 && (k.dataset.line = b.dataset.line), b.replaceWith(k); } catch (k) { y.emit(t, Q, { name: "mermaid", message: k.message, error: k }); } --v === 0 && d.remove(); } })(p)) ); } } }; }, dt = (e, t) => { t = t || {}; const a = 3, n = t.marker || "!", o = n.charCodeAt(0), m = n.length; let c = "", u = ""; const s = (i, r, d, f, g) => { const v = i[r]; return v.type === "admonition_open" ? i[r].attrPush([ "class", `${h}-admonition ${h}-admonition-${v.info}` ]) : v.type === "admonition_title_open" && i[r].attrPush(["class", `${h}-admonition-title`]), g.renderToken(i, r, d); }, l = (i) => { const r = i.trim().split(" ", 2); u = "", c = r[0], r.length > 1 && (u = i.substring(c.length + 2)); }; e.block.ruler.before( "code", "admonition", (i, r, d, f) => { let g, v, p, T = !1, b = i.bMarks[r] + i.tShift[r], $ = i.eMarks[r]; if (o !== i.src.charCodeAt(b)) return !1; for (g = b + 1; g <= $ && n[(g - b) % m] === i.src[g]; g++) ; const S = Math.floor((g - b) / m); if (S !== a) return !1; g -= (g - b) % m; const w = i.src.slice(b, g), I = i.src.slice(g, $); if (l(I), f) return !0; for (v = r; v++, !(v >= d || (b = i.bMarks[v] + i.tShift[v], $ = i.eMarks[v], b < $ && i.sCount[v] < i.blkIndent)); ) if (o === i.src.charCodeAt(b) && !(i.sCount[v] - i.blkIndent >= 4)) { for (g = b + 1; g <= $ && n[(g - b) % m] === i.src[g]; g++) ; if (!(Math.floor((g - b) / m) < S) && (g -= (g - b) % m, g = i.skipSpaces(g), !(g < $))) { T = !0; break; } } const k = i.parentType, R = i.lineMax; return i.parentType = "root", i.lineMax = v, p = i.push("admonition_open", "div", 1), p.markup = w, p.block = !0, p.info = c, p.map = [r, v], u && (p = i.push("admonition_title_open", "p", 1), p.markup = w + " " + c, p.map = [r, v], p = i.push("inline", "", 0), p.content = u, p.map = [r, i.line - 1], p.children = [], p = i.push("admonition_title_close", "p", -1), p.markup = w + " " + c), i.md.block.tokenize(i, r + 1, v), p = i.push("admonition_close", "div", -1), p.markup = i.src.slice(b, g), p.block = !0, i.parentType = k, i.lineMax = R, i.line = v + (T ? 1 : 0), !0; }, { alt: ["paragraph", "reference", "blockquote", "list"] } ), e.renderer.rules.admonition_open = s, e.renderer.rules.admonition_title_open = s, e.renderer.rules.admonition_title_close = s, e.renderer.rules.admonition_close = s; }, ce = (e, t) => { const a = e.attrs ? e.attrs.slice() : []; return t.forEach((n) => { const o = e.attrIndex(n[0]); o < 0 ? a.push(n) : (a[o] = a[o].slice(), a[o][1] += ` ${n[1]}`); }), a; }, ut = (e) => Array.from(e).map( (t) => /[A-Za-z0-9_-]/.test(t) ? t : `_${t.codePointAt(0).toString(16)}_` ).join(""), mt = (e, t) => { const a = e.renderer.rules.fence, n = e.utils.unescapeAll, o = /\[(\w*)(?::([\w ]*))?\]/, m = /::(open|close)/, c = ut(t.editorId), u = (d) => d.info ? n(d.info).trim() : "", s = (d) => { const f = u(d), [g = null, v = ""] = (o.exec(f) || []).slice(1); return [g, v]; }, l = (d) => { const f = u(d); return f ? f.split(/(\s+)/g)[0] : ""; }, i = (d) => { const f = d.info.match(m) || [], g = f[1] === "open" || f[1] !== "close" && t.codeFoldable && d.content.trim().split(` `).length < t.autoFoldThreshold, v = f[1] || t.codeFoldable ? "details" : "div", p = f[1] || t.codeFoldable ? "summary" : "div"; return { open: g, tagContainer: v, tagHeader: p }; }, r = (d, f, g, v, p) => { if (d[f].hidden) return ""; const T = t.usedLanguageTextRef.value?.copyCode.text || "", b = t.customIconRef.value.copy, $ = e.utils.escapeHtml(T), S = b || $, w = !!b, I = `<span class="${h}-collapse-tips">${qe("collapse-tips", t.customIconRef.value)}</span>`, [k] = s(d[f]); if (k === null) { const { open: A, tagContainer: _, tagHeader: J } = i(d[f]), U = [["class", `${h}-code`]]; A && U.push(["open", ""]); const Fe = { attrs: ce(d[f], U) }; d[f].info = d[f].info.replace(m, ""); const Re = a(d, f, g, v, p); return ` <${_} ${p.renderAttrs(Fe)}> <${J} class="${h}-code-head"> <div class="${h}-code-flag"><span></span><span></span><span></span></div> <div class="${h}-code-action"> <span class="${h}-code-lang">${e.utils.escapeHtml(d[f].info.trim())}</span> <span class="${h}-copy-button" data-tips="${$}"${w ? " data-is-icon=true" : ""}>${S}</span> ${t.extraTools instanceof Function ? t.extraTools({ lang: d[f].info.trim() }) : t.extraTools || ""} ${_ === "details" ? I : ""} </div> </${J}> ${Re} </${_}> `; } let R, B, V, j, q = "", K = "", Z = ""; const { open: ne, tagContainer: G, tagHeader: H } = i(d[f]), D = [["class", `${h}-code`]]; ne && D.push(["open", ""]); const oe = { attrs: ce(d[f], D) }; for (let A = f; A < d.length && (R = d[A], [B, V] = s(R), B === k); A++) { R.info = R.info.replace(o, "").replace(m, ""), R.hidden = !0; const _ = `${h}-codetab-${c}-${f}-${A - f}`; j = A - f > 0 ? "" : "checked", q += ` <li> <input type="radio" id="label-${h}-codetab-label-1-${c}-${f}-${A - f}" name="${h}-codetab-label-${c}-${f}" class="${_}" ${j} > <label for="label-${h}-codetab-label-1-${c}-${f}-${A - f}" onclick="this.getRootNode().querySelectorAll('.${_}').forEach(e => e.click())" > ${e.utils.escapeHtml(V || l(R))} </label> </li>`, K += ` <div role="tabpanel"> <input type="radio" name="${h}-codetab-pre-${c}-${f}" class="${_}" ${j} role="presentation"> ${a(d, A, g, v, p)} </div>`, Z += ` <input type="radio" name="${h}-codetab-lang-${c}-${f}" class="${_}" ${j} role="presentation"> <span class=${h}-code-lang role="note">${e.utils.escapeHtml(l(R))}</span>`; } return ` <${G} ${p.renderAttrs(oe)}> <${H} class="${h}-code-head"> <div class="${h}-code-flag"> <ul class="${h}-codetab-label" role="tablist">${q}</ul> </div> <div class="${h}-code-action"> <span class="${h}-codetab-lang">${Z}</span> <span class="${h}-copy-button" data-tips="${$}"${w ? " data-is-icon=true" : ""}>${S}</span> ${t.extraTools instanceof Function ? t.extraTools({ lang: d[f].info.trim() }) : t.extraTools || ""} ${G === "details" ? I : ""} </div> </${H}> ${K} </${G}> `; }; e.renderer.rules.fence = r, e.renderer.rules.code_block = r; }, ft = (e, t) => { const a = e.renderer.rules.fence.bind(e.renderer.rules); e.renderer.rules.fence = (n, o, m, c, u) => { const s = n[o], l = s.content.trim(); if (s.info === "echarts") { if (s.attrSet("class", `${h}-echarts`), s.attrSet("data-echarts-theme", t.themeRef.value), s.map && s.level === 0) { const i = s.map[1] - 1, d = !!c.srcLines[i]?.trim()?.startsWith("```"); s.attrSet("data-closed", `${d}`), s.attrSet("data-line", String(s.map[0])); } return `<div ${u.renderAttrs(s)} style="width: 100%; aspect-ratio: 4 / 3;">${e.utils.escapeHtml(l)}</div>`; } return a(n, o, m, c, u); }; }, ht = (e, t) => { e.renderer.rules.heading_open = (a, n) => { const o = a[n], m = a[n + 1].children?.reduce((u, s) => u + (["text", "code_inline", "math_inline"].includes(s.type) && s.content || ""), "") || "", c = o.markup.length; return t.headsRef.value.push({ text: m, level: c, line: o.map[0], currentToken: o, nextToken: a[n + 1] }), o.map && o.level === 0 && o.attrSet( "id", t.mdHeadingId({ text: m, level: c, index: t.headsRef.value.length, currentToken: o, nextToken: a[n + 1] }) ), e.renderer.renderToken(a, n, t); }, e.renderer.rules.heading_close = (a, n, o, m, c) => c.renderToken(a, n, o); }, $e = { block: [ { open: "$$", close: "$$" }, { open: "\\[", close: "\\]" } ], inline: [ { open: "$$", close: "$$" }, { open: "$", close: "$" }, { open: "\\[", close: "\\]" }, { open: "\\(", close: "\\)" } ] }, pt = (e) => (t, a) => { const n = e.delimiters; for (const o of n) { if (!t.src.startsWith(o.open, t.pos)) continue; const m = t.pos + o.open.length; let c = m; for (; (c = t.src.indexOf(o.close, c)) !== -1; ) { let u = 0, s = c - 1; for (; s >= 0 && t.src[s] === "\\"; ) u++, s--; if (u % 2 === 0) break; c += o.close.length; } if (c !== -1) { if (c - m === 0) return a || (t.pending += o.open + o.close), t.pos = c + o.close.length, !0; if (!a) { const u = t.push("math_inline", "math", 0); u.markup = o.open, u.content = t.src.slice(m, c); } return t.pos = c + o.close.length, !0; } } return !1; }, gt = (e) => (t, a, n, o) => { const m = e.delimiters, c = t.bMarks[a] + t.tShift[a], u = t.eMarks[a], s = (l, i, r) => { t.line = i; const d = t.push("math_block", "math", 0); return d.block = !0, d.content = l, d.map = [a, t.line], d.markup = r, !0; }; for (const l of m) { const i = c; if (t.src.slice(i, i + l.open.length) !== l.open) continue; const r = i + l.open.length, d = t.src.slice(r, u).trim(), f = d === "", g = d === l.close, v = d.endsWith(l.close); if (!f && !g && !v) continue; if (o) return !0; if (g) return s("", a + 1, l.open); if (!f && v) { const w = d.slice(0, -l.close.length); return s(w, a + 1, l.open); } let p = a + 1, T = !1, b = ""; for (; p < n; p++) { const w = t.bMarks[p] + t.tShift[p], I = t.eMarks[p]; if (w < I && t.tShift[p] < t.blkIndent) break; if (t.src.slice(w, I).trim().endsWith(l.close)) { const R = t.src.slice(0, I).lastIndexOf(l.close); b = t.src.slice(w, R), T = !0; break; } } if (!T) continue; const S = t.getLines(a + 1, p, t.tShift[a], !0) + (b.trim() ? b : ""); return s(S, p + 1, l.open); } return !1; }, vt = (e, { katexRef: t, inlineDelimiters: a, blockDelimiters: n }) => { const o = (u, s, l, i, r = !1) => { const d = { attrs: ce(u, [["class", s]]) }, f = i.renderAttrs(d); if (!t.value) return `<${l} ${f}>${u.content}</${l}>`; const g = t.value.renderToString( u.content, L.katexConfig({ throwOnError: !1, displayMode: r }) ); return `<${l} ${f} data-processed>${g}</${l}>`; }, m = (u, s, l, i, r) => o(u[s], `${h}-katex-inline`, "span", r), c = (u, s, l, i, r) => o(u[s], `${h}-katex-block`, "p", r, !0); e.inline.ruler.before( "escape", "math_inline", pt({ delimiters: a || $e.inline }) ), e.block.ruler.after( "blockquote", "math_block", gt({ delimiters: n || $e.block }), { alt: ["paragraph", "reference", "blockquote", "list"] } ), e.renderer.rules.math_inline = m, e.renderer.rules.math_block = c; }, yt = (e, t) => { const a = e.renderer.rules.fence.bind(e.renderer.rules); e.renderer.rules.fence = (n, o, m, c, u) => { const s = n[o], l = s.content.trim(); if (s.info === "mermaid") { if (s.attrSet("class", `${h}-mermaid`), s.attrSet("data-mermaid-theme", t.themeRef.value), s.map && s.level === 0) { const r = s.map[1] - 1, f = !!c.srcLines[r]?.trim()?.startsWith("```"); s.attrSet("data-closed", `${f}`), s.attrSet("data-line", String(s.map[0])); } const i = Y.get(l); return i ? (s.attrSet("data-processed", ""), s.attrSet("data-content", l), `<p ${u.renderAttrs(s)}>${i}</p>`) : `<div ${u.renderAttrs(s)}>${e.utils.escapeHtml(l)}</div>`; } return a(n, o, m, c, u); }; }, we = (e, t, a) => { const n = e.attrIndex(t), o = [t, a]; n < 0 ? e.attrPush(o) : (e.attrs = e.attrs || [], e.attrs[n] = o); }, bt = (e) => e.type === "inline", $t = (e) => e.type === "paragraph_open", wt = (e) => e.type === "list_item_open", Ct = (e) => e.content.indexOf("[ ] ") === 0 || e.content.indexOf("[x] ") === 0 || e.content.indexOf("[X] ") === 0, Et = (e, t) => bt(e[t]) && $t(e[t - 1]) && wt(e[t - 2]) && Ct(e[t]), kt = (e, t) => { const a = e[t].level - 1; for (let n = t - 1; n >= 0; n--) if (e[n].level === a) return n; return -1; }, xt = (e) => { const t = new e("html_inline", "", 0); return t.content = "<label>", t; }, Tt = (e) => { const t = new e("html_inline", "", 0); return t.content = "</label>", t; }, St = (e, t, a) => { const n = new a("html_inline", "", 0); return n.content = '<label class="task-list-item-label" for="' + t + '">' + e + "</label>", n.attrs = [["for", t]], n; }, It = (e, t, a) => { const n = new t("html_inline", "", 0), o = a.enabled ? " " : ' disabled="" '; return e.content.indexOf("[ ] ") === 0 ? n.content = '<input class="task-list-item-checkbox"' + o + 'type="checkbox">' : (e.content.indexOf("[x] ") === 0 || e.content.indexOf("[X] ") === 0) && (n.content = '<input class="task-list-item-checkbox" checked=""' + o + 'type="checkbox">'), n; }, At = (e, t, a) => { if (e.children = e.children || [], e.children.unshift(It(e, t, a)), e.children[1].content = e.children[1].content.slice(3), e.content = e.content.slice(3), a.label) if (a.labelAfter) { e.children.pop(); const n = "task-item-" + Math.ceil(Math.random() * (1e4 * 1e3) - 1e3); e.children[0].content = e.children[0].content.slice(0, -1) + ' id="' + n + '">', e.children.push(St(e.content, n, t)); } else e.children.unshift(xt(t)), e.children.push(Tt(t)); }, Ft = (e, t = {}) => { e.core.ruler.after("inline", "github-task-lists", (a) => { const n = a.tokens; for (let o = 2; o < n.length; o++) Et(n, o) && (At(n[o], a.Token, t), we( n[o - 2], "class", "task-list-item" + (t.enabled ? " enabled" : " ") ), we(n[kt(n, o - 2)], "class", "contains-task-list")); }); }, Rt = (e) => { e.core.ruler.push("init-line-number", (t) => (t.tokens.forEach((a) => { a.map && (a.attrs || (a.attrs = []), a.attrs.push(["data-line", a.map[0].toString()])); }), !0)); }, Ht = (e, t) => { const { editorConfig: a, markdownItConfig: n, markdownItPlugins: o, editorExtensions: m } = L, c = C("editorId"), u = C("language"), s = C( "usedLanguageText" ), l = C("showCodeRowNumber"), i = C("theme"), r = C("customIcon"), d = C("rootRef"), f = C("setting"), g = z([]), v = lt(e), p = it(e), { reRenderRef: T, replaceMermaid: b } = ct(e), { reRenderEcharts: $, replaceEcharts: S } = rt(e), w = Xe({ html: !0, breaks: !0, linkify: !0 }); n(w, { editorId: c }); const I = [ { type: "image", plugin: Ye, options: { figcaption: !0, classes: "md-zoom" } }, { type: "admonition", plugin: dt, options: {} }, { type: "taskList", plugin: Ft, options: {} }, { type: "heading", plugin: ht, options: { mdHeadingId: e.mdHeadingId, headsRef: g } }, { type: "code", plugin: mt, options: { editorId: c, usedLanguageTextRef: s, // showCodeRowNumber, codeFoldable: e.codeFoldable, autoFoldThreshold: e.autoFoldThreshold, customIconRef: r } }, { type: "sub", plugin: Qe, options: {} }, { type: "sup", plugin: et, options: {} } ]; e.noKatex || I.push({ type: "katex", plugin: vt, options: { katexRef: p } }), e.noMermaid || I.push({ type: "mermaid", plugin: yt, options: { themeRef: i } }), e.noEcharts || I.push({ type: "echarts", plugin: ft, options: { themeRef: i } }), o(I, { editorId: c }).forEach((H) => { w.use(H.plugin, H.options); }); const k = w.options.highlight; w.set({ highlight: (H, D, oe) => { if (k) { const U = k(H, D, oe); if (U) return U; } let A; !e.noHighlight && v.value ? v.value.getLanguage(D) ? A = v.value.highlight(H, { language: D, ignoreIllegals: !0 }).value : A = v.value.highlightAuto(H).value : A = w.utils.escapeHtml(H); const _ = w.utils.escapeHtml(D), J = l ? tt( A.replace(/^\n+|\n+$/g, ""), H.replace(/^\n+|\n+$/g, "") ) : `<span class="${h}-code-block">${A.replace(/^\n+|\n+$/g, "")}</span>`; return `<pre><code class="language-${_}" language="${_}">${J}</code></pre>`; } }), Rt(w); const R = z(`_article-key_${ie()}`), B = z( e.sanitize( w.render(e.modelValue, { srcLines: e.modelValue.split(` `) }) ) ); let V = () => { }, j = () => { }; const q = () => { const H = d.value?.querySelectorAll( `#${c} p.${h}-mermaid:not([data-closed=false])` ); j(), j = Ke(H, { customIcon: r.value }), m.mermaid?.enableZoom && (V(), V = Ze(H, { customIcon: r.value })); }, K = () => { y.emit(c, X, B.value), e.onHtmlChanged(B.value), e.onGetCatalog(g.value), y.emit(c, ae, g.value), W(() => { b().then(q), S(); }); }, Z = () => { g.value = [], B.value = e.sanitize( w.render(e.modelValue, { srcLines: e.modelValue.split(` `) }) ); }, ne = F(() => (e.noKatex || !!p.value) && (e.noHighlight || !!v.value)); let G = -1; return E([Me(e, "modelValue"), ne, T, u], () => { G = window.setTimeout( () => { Z(); }, t ? 0 : a.renderDelay ); }), E( () => f.value.preview, () => { f.value.preview && W(() => { b().then(q), S(), y.emit(c, ae, g.value); }); } ), E([B, $], () => { K(); }), M(K), M(() => { y.on(c, { name: Ue, callback() { y.emit(c, ae, g.value); } }), y.on(c, { name: ue, callback: () => { R.value = `_article-key_${ie()}`, Z(); } }); }), te(() => { V(), j(), clearTimeout(G); }), { html: B, key: R }; }, Mt = (e, t) => { const a = C("editorId"), n = C("setting"), { noImgZoomIn: o } = e, m = Be(() => { const c = document.querySelectorAll( `#${a}-preview img:not(.not-zoom):not(.medium-zoom-image)` ); c.length !== 0 && nt(c, { background: "#00000073" }); }); M(async () => { !o && n.value.preview && await m(); }), E([t, () => n.value.preview], async () => { !o && n.value.preview && await m(); }); }, Ce = { checked: { regexp: /- \[x\]/, value: "- [ ]" }, unChecked: { regexp: /- \[\s\]/, value: "- [x]" } }, Pt = (e, t) => { const a = C("editorId"), n = C("rootRef"); let o = () => { }; const m = () => { if (!n.value) return !1; const c = n.value.querySelectorAll(".task-list-item.enabled"), u = (s) => { s.preventDefault(); const l = s.target.checked ? "unChecked" : "checked", i = s.target.parentElement?.dataset.line; if (!i) return; const r = Number(i), d = e.modelValue.split(` `), f = d[Number(r)].replace( Ce[l].regexp, Ce[l].value ); e.previewOnly ? (d[Number(r)] = f, e.onChange(d.join(` `))) : y.emit(a, ze, r + 1, f); }; c.forEach((s) => { s.addEventListener("click", u); }), o = () => { c.forEach((s) => { s.removeEventListener("click", u); }); }; }; te(() => { o(); }), E( [t], () => { o(), W(m); }, { immediate: !0 } ); }, Lt = (e, t, a) => { const n = C("setting"), o = () => { W(() => { e.onRemount?.(); }); }, m = (c) => { c && o(); }; E([t, a], o), E(() => n.value.preview, m), E(() => n.value.htmlPreview, m), M(o); }, Se = { modelValue: { type: String, default: "" }, onChange: { type: Function, default: () => { } }, onHtmlChanged: { type: Function, default: () => { } }, onGetCatalog: { type: Function, default: () => { } }, mdHeadingId: { type: Function, default: () => "" }, noMermaid: { type: Boolean, default: !1 }, sanitize: { type: Function, default: (e) => e }, // 不使用该函数功能 noKatex: { type: Boolean, default: !1 }, formatCopiedText: { type: Function, default: (e) => e }, noHighlight: { type: Boolean, default: !1 }, previewOnly: { type: Boolean, default: !1 }, noImgZoomIn: { type: Boolean }, sanitizeMermaid: { type: Function }, codeFoldable: { type: Boolean }, autoFoldThreshold: { type: Number }, onRemount: { type: Function }, noEcharts: { type: Boolean }, previewComponent: { type: [Object, Function], default: void 0 } }, ln = { ...Se, updateModelValue: { type: Function, default: () => { } }, placeholder: { type: String, default: "" }, scrollAuto: { type: Boolean }, autofocus: { type: Boolean }, readonly: { type: Boolean }, maxlength: { type: Number }, autoDetectCode: { type: Boolean }, /** * 输入框失去焦点时触发事件 */ onBlur: { type: Function, default: () => { } }, /** * 输入框获得焦点时触发事件 */ onFocus: { type: Function, default: () => { } }, completions: { type: Array }, onInput: { type: Function }, onDrop: { type: Function, default: () => { } }, inputBoxWidth: { type: String }, oninputBoxWidthChange: { type: Function }, transformImgUrl: { type: Function, default: (e) => e }, catalogLayout: { type: String }, catalogMaxDepth: { type: Number } }, Ee = (e) => { const a = new DOMParser().parseFromString(e, "text/html"); return Array.from(a.body.childNodes); }, _t = (e, t) => e.nodeType !== t.nodeType ? !1 : e.nodeType === Node.TEXT_NODE || e.nodeType === Node.COMMENT_NODE ? e.textContent === t.textContent : e.nodeType === Node.ELEMENT_NODE ? e.outerHTML === t.outerHTML : e.isEqualNode ? e.isEqualNode(t) : !1, Ot = /* @__PURE__ */ de({ name: "UpdateOnDemand", props: { id: { type: String, required: !0 }, class: { type: [String, Array, Object], required: !0 }, html: { type: String, required: !0 } }, setup(e) { const t = z(), a = e.html, n = (o, m) => { if (!t.value) return; const c = t.value, u = Array.from(c.childNodes), s = Math.min(o.length, m.length); let l = -1; for (let r = 0; r < s; r++) if (!_t(o[r], m[r])) { l = r; break; } if (l === -1) if (m.length > o.length) l = o.length; else if (o.length > m.length) l = m.length; else return; const i = Math.min(l, u.length); for (let r = u.length - 1; r >= i; r--) u[r].remove(); for (let r = l; r < o.length; r++) c.appendChild(o[r].cloneNode(!0)); }; return E(() => e.html, (o, m) => { const c = Ee(o), u = Ee(m || ""); n(c, u); }), () => N("div", { id: e.id, class: e.class, innerHTML: a, ref: t }, null); } }), Bt = /* @__PURE__ */ de({ name: "ContentPreview", props: Se, setup(e) { const t = C("editorId"), a = C("setting"), n = C("previewTheme"), o = C("showCodeRowNumber"), { html: m, key: c } = Ht(e, e.previewOnly); at(e, m, c), Mt(e, m), Pt(e, m), Lt(e, m, c); const u = F(() => [`${h}-preview`, `${n?.value}-theme`, o && `${h}-scrn`].filter(Boolean)), s = () => { const l = `${t}-preview`; return e.previewComponent ? Le(e.previewComponent, { key: c.value, html: m.value, id: l, class: u.value }) : N(Ot, { key: c.value, html: m.value, id: l, class: u.value }, null); }; return () => N(Pe, null, [a.value.preview && (e.previewOnly ? s() : N("div", { id: `${t}-preview-wrapper`, class: `${h}-preview-wrapper`, key: "content-preview-wrapper" }, [s()])), a.value.htmlPreview && N("div", { id: `${t}-html-wrapper`, class: `${h}-preview-wrapper`, key: "html-preview-wrapper" }, [N("div", { class: `${h}-html` }, [m.value])])]); } }), jt = ({ text: e }) => e, Ie = { /** * markdown content. * * @default '' */ modelValue: { type: String, default: "" }, /** * input回调事件 */ onChange: { type: Function, default: void 0 }, /** * 主题,支持light和dark * * @default 'light' */ theme: { type: String, default: "light" }, /** * 外层类名 * * @default '' */ class: { type: String, default: "" }, /** * 预设语言名称 * * @default 'zh-CN' */ language: { type: String, default: "zh-CN" }, /** * html变化事件 */ onHtmlChanged: { type: Function, default: void 0 }, /** * 获取目录结构 */ onGetCatalog: { type: Function, default: void 0 }, /** * 编辑器唯一标识 * * @default 'md-editor-v3' * @deprecated 5.x版本开始使用 id 替换 */ editorId: { type: String, default: void 0 }, /** * 5.x版本开始 editorId 的替换 * * @default 'md-editor-v3' */ id: { type: String, default: void 0 }, /** * 预览中代码是否显示行号 * * @default true */ showCodeRowNumber: { type: Boolean, default: !0 }, /** * 预览内容样式 * * @default 'default' */ previewTheme: { type: String, default: "default" }, /** * 编辑器样式 */ style: { type: Object, default: () => ({}) }, /** * 标题的id生成方式 * * @default (text: string) => text */ mdHeadingId: { type: Function, default: jt }, /** * * 不能保证文本正确的情况,在marked编译md文本后通过该方法处理 * 推荐DOMPurify、sanitize-html * * @default (text: string) => text */ sanitize: { type: Function, default: (e) => e }, /** * 不使用该mermaid * * @default false */ noMermaid: { type: Boolean, default: !1 }, /** * 不使用katex * * @default false */ noKatex: { type: Boolean, default: !1 }, /** * 代码主题 * * @default 'atom' */ codeTheme: { type: String, default: "atom" }, /** * 复制代码格式化方法 * * @default (text) => text */ formatCopiedText: { type: Function, default: (e) => e }, /** * 某些预览主题的代码模块背景是暗色系 * 将这个属性设置为true,会自动在该主题下的light模式下使用暗色系的代码风格 * * @default true */ codeStyleReverse: { type: Boolean, default: !0 }, /** * 需要自动调整的预览主题 * * @default ['default', 'mk-cute'] */ codeStyleReverseList: { type: Array, default: ["default", "mk-cute"] }, noHighlight: { type: Boolean, default: !1 }, /** * 是否关闭编辑器默认的放大缩小功能 */ noImgZoomIn: { type: Boolean, default: !1 }, /** * 自定义的图标 */ customIcon: { type: Object, default: {} }, sanitizeMermaid: { type: Function, default: (e) => Promise.resolve(e) }, /** * 是否开启折叠代码功能 * 不开启会使用div标签替代details标签 * * @default true */ codeFoldable: { type: Boolean, default: !0 }, /** * 触发自动折叠代码的行数阈值 * * @default 30 */ autoFoldThreshold: { type: Number, default: 30 }, /** * 内容重新挂载事件 * * 相比起onHtmlChanged,onRemount会在重新挂载后触发 */ onRemount: { type: Function, default: void 0 }, /** * 不使用 echarts */ noEcharts: { type: Boolean, default: !1 }, previewComponent: { type: [Object, Function], default: void 0 } }, sn = { ...Ie, /** * input回调事件 */ onSave: { type: Function, default: void 0 }, /** * 上传图片事件 */ onUploadImg: { type: Function, default: void 0 }, /** * 是否页面内全屏 * * @default false */ pageFullscreen: { type: Boolean, default: !1 }, /** * 是否展开预览 * * @default true */ preview: { type: Boolean, default: !0 }, /** * 是否展开html预览 * * @default false */ htmlPreview: { type: Boolean, default: !1 }, /** * 仅预览模式,不显示toolbar和编辑框 * * @4.0.0开始移除该设置,使用组件MdPreview替换 * * @default false */ // previewOnly: { // type: Boolean as PropType<boolean>, // default: false // }, /** * 工具栏选择显示 * * @default allToolbar */ toolbars: { type: Array, default: Ne }, /** * 浮动工具栏 * * @version 6.0.0 * @default [] */ floatingToolbars: { type: Array, default: [] }, /** * 工具栏选择不显示 * * @default [] */ toolbarsExclude: { type: Array, default: [] }, /** * 格式化md * * @default true */ noPrettier: { type: Boolean, default: !1 }, /** * 一个tab等于空格数 * * @default 2 */ tabWidth: { type: Number, default: 2 }, /** * 表格预设格子数 * * 也可以是[6, 4, 10, 8] * * @default [6, 4] */ tableShape: { type: Array, default: [6, 4] }, /** * 空提示 * * @default '' */ placeholder: { type: String, default: "" }, /** * 自定义的工具栏列表 */ defToolbars: { type: [String, Object], default: void 0 }, /** * 内部错误捕获 */ onError: { type: Function, default: void 0 }, /** * 页脚列表显示顺序 */ footers: { type: Array, default: je }, /** * 是否默认激活输入框和预览框同步滚动 * * @default true */ scrollAuto: { type: Boolean, default: !0 }, /** * 自定义的也叫工具组件列表 */ defFooters: { type: [String, Object], default: void 0 }, /** * 是否禁用上传图片 * * @default false */ noUploadImg: { type: Boolean, default: !1 }, /** * 文本区域自动获得焦点 * * @default false */ autoFocus: { type: Boolean, default: !1 }, /** * 禁用文本区域 * * @default false */ disabled: { type: Boolean, default: !1 }, /** * 文本区域为只读 * * @default false */ readOnly: { type: Boolean, default: !1 }, /** * 文本区域允许的最大字符数 */ maxLength: { type: Number, default: void 0 }, /** * 是否启用自动识别粘贴代码类别 * 目前支持 vscode 复制的代码识别 * * @default false */ autoDetectCode: { type: Boolean, default: !1 }, /** * 输入框失去焦点时触发事件 */ onBlur: { type: Function, default: void 0 }, /** * 输入框获得焦点时触发事件 */ onFocus: { type: Function, default: void 0 }, /** * @codemirror/autocomplete匹配关键词的方法列表 * * 它会被像下面这样嵌入编辑器 * * import { autocompletion } from '@codemirror/autocomplete'; * autocompletion({ * override: [...completions] * }) */ completions: { type: Array, default: void 0 }, /** * 是否在工具栏下面显示对应的文字名称 * * @default false */ showToolbarName: { type: Boolean, default: !1 }, /** * 字符输入事件 */ onInput: { type: Function, default: void 0 }, onDrop: { type: Function, default: void 0 }, /** * 输入框的默认宽度 * * @example '100px'/'50%' * @default '50% */ inputBoxWidth: { type: String, default: "50%" }, /** * 输入框宽度变化事件 */ oninputBoxWidthChange: { type: Function, default: void 0 }, /** * 替换粘贴的图片链接 * * @param t 图片链接 * @returns */ transformImgUrl: { type: Function, default: (e) => e }, /** * 内置的目录显示的状态 * * 'fixed': 悬浮在内容上方 * 'flat': 展示在右侧 * * \>=5.3.0 * * @default 'fixed' */ catalogLayout: { type: String, default: "fixed" }, /** * 控制最大显示的目录层级 */ catalogMaxDepth: { type: Number, default: void 0 } }, Ae = [ "onHtmlChanged", "onGetCatalog", "onChange", "onRemount", "update:modelValue" ], cn = [ ...Ae, "onSave", "onUploadImg", "onError", "onBlur", "onFocus", "onInput", "onDrop", "oninputBoxWidthChange" ], Nt = (e, t, a) => { const { editorId: n } = a, o = { rerender() { y.emit(n, ue); } }; t.expose(o); }, re = /* @__PURE__ */ de({ name: "MdPreview", props: Ie, emits: Ae, setup(e, t) { const { noKatex: a, noMermaid: n, noHighlight: o } = e, m = z(), c = ot(e); Te(e, { rootRef: m, editorId: c }), Nt(e, t, { editorId: c }), te(() => { y.clear(c); }); const u = (r) => {