UNPKG

vditor

Version:

♏ 易于使用的 Markdown 编辑器,为适配不同的应用场景而生

170 lines (163 loc) 6.93 kB
import {Constants} from "../constants"; import {setContentTheme} from "../ui/setContentTheme"; import {addScript} from "../util/addScript"; import {hasClosestByClassName, hasClosestByMatchTag} from "../util/hasClosest"; import {merge} from "../util/merge"; import {abcRender} from "./abcRender"; import {anchorRender} from "./anchorRender"; import {chartRender} from "./chartRender"; import {codeRender} from "./codeRender"; import {flowchartRender} from "./flowchartRender"; import {graphvizRender} from "./graphvizRender"; import {highlightRender} from "./highlightRender"; import {lazyLoadImageRender} from "./lazyLoadImageRender"; import {mathRender} from "./mathRender"; import {mediaRender} from "./mediaRender"; import {mermaidRender} from "./mermaidRender"; import {markmapRender} from "./markmapRender"; import {SMILESRender} from "./SMILESRender"; import {mindmapRender} from "./mindmapRender"; import {plantumlRender} from "./plantumlRender"; import {setLute} from "./setLute"; import {speechRender} from "./speechRender"; const mergeOptions = (options?: IPreviewOptions) => { const defaultOption: IPreviewOptions = { anchor: 0, cdn: Constants.CDN, customEmoji: {}, emojiPath: `${Constants.CDN}/dist/images/emoji`, hljs: Constants.HLJS_OPTIONS, icon: "ant", lang: "zh_CN", markdown: Constants.MARKDOWN_OPTIONS, math: Constants.MATH_OPTIONS, mode: "light", speech: { enable: false, }, render: { media: { enable: true, } }, theme: Constants.THEME_OPTIONS, }; if (options.cdn) { if (!options.theme?.path) { defaultOption.theme.path = `${options.cdn}/dist/css/content-theme` } if (!options.emojiPath) { defaultOption.emojiPath = `${options.cdn}/dist/images/emoji`; } } return merge(defaultOption, options); }; export const md2html = (mdText: string, options?: IPreviewOptions) => { const mergedOptions = mergeOptions(options); return addScript(`${mergedOptions.cdn}/dist/js/lute/lute.min.js`, "vditorLuteScript").then(() => { const lute = setLute({ autoSpace: mergedOptions.markdown.autoSpace, gfmAutoLink: mergedOptions.markdown.gfmAutoLink, codeBlockPreview: mergedOptions.markdown.codeBlockPreview, emojiSite: mergedOptions.emojiPath, emojis: mergedOptions.customEmoji, fixTermTypo: mergedOptions.markdown.fixTermTypo, footnotes: mergedOptions.markdown.footnotes, headingAnchor: mergedOptions.anchor !== 0, inlineMathDigit: mergedOptions.math.inlineDigit, lazyLoadImage: mergedOptions.lazyLoadImage, linkBase: mergedOptions.markdown.linkBase, linkPrefix: mergedOptions.markdown.linkPrefix, listStyle: mergedOptions.markdown.listStyle, mark: mergedOptions.markdown.mark, mathBlockPreview: mergedOptions.markdown.mathBlockPreview, paragraphBeginningSpace: mergedOptions.markdown.paragraphBeginningSpace, sanitize: mergedOptions.markdown.sanitize, toc: mergedOptions.markdown.toc, }); if (options?.renderers) { lute.SetJSRenderers({ renderers: { Md2HTML: options.renderers, }, }); } lute.SetHeadingID(true); return lute.Md2HTML(mdText); }); }; export const previewRender = async (previewElement: HTMLDivElement, markdown: string, options?: IPreviewOptions) => { const mergedOptions: IPreviewOptions = mergeOptions(options); let html = await md2html(markdown, mergedOptions); if (mergedOptions.transform) { html = mergedOptions.transform(html); } previewElement.innerHTML = html; previewElement.classList.add("vditor-reset"); if (!mergedOptions.i18n) { if (!["de_DE", "en_US", "fr_FR", "pt_BR", "ja_JP", "ko_KR", "ru_RU", "sv_SE", "zh_CN", "zh_TW"].includes(mergedOptions.lang)) { throw new Error( "options.lang error, see https://ld246.com/article/1549638745630#options", ); } else { const i18nScriptPrefix = "vditorI18nScript"; const i18nScriptID = i18nScriptPrefix + mergedOptions.lang; document.querySelectorAll(`head script[id^="${i18nScriptPrefix}"]`).forEach((el) => { if (el.id !== i18nScriptID) { document.head.removeChild(el); } }); await addScript(`${mergedOptions.cdn}/dist/js/i18n/${mergedOptions.lang}.js`, i18nScriptID); } } else { window.VditorI18n = mergedOptions.i18n; } if (mergedOptions.icon) { await addScript(`${mergedOptions.cdn}/dist/js/icons/${mergedOptions.icon}.js`, "vditorIconScript"); } setContentTheme(mergedOptions.theme.current, mergedOptions.theme.path); if (mergedOptions.anchor === 1) { previewElement.classList.add("vditor-reset--anchor"); } codeRender(previewElement, mergedOptions.hljs); highlightRender(mergedOptions.hljs, previewElement, mergedOptions.cdn); mathRender(previewElement, { cdn: mergedOptions.cdn, math: mergedOptions.math, }); mermaidRender(previewElement, mergedOptions.cdn, mergedOptions.mode); SMILESRender(previewElement, mergedOptions.cdn, mergedOptions.mode); markmapRender(previewElement, mergedOptions.cdn); flowchartRender(previewElement, mergedOptions.cdn); graphvizRender(previewElement, mergedOptions.cdn); chartRender(previewElement, mergedOptions.cdn, mergedOptions.mode); mindmapRender(previewElement, mergedOptions.cdn, mergedOptions.mode); plantumlRender(previewElement, mergedOptions.cdn); abcRender(previewElement, mergedOptions.cdn); if (mergedOptions.render.media.enable) { mediaRender(previewElement); } if (mergedOptions.speech.enable) { speechRender(previewElement); } if (mergedOptions.anchor !== 0) { anchorRender(mergedOptions.anchor); } if (mergedOptions.after) { mergedOptions.after(); } if (mergedOptions.lazyLoadImage) { lazyLoadImageRender(previewElement); } previewElement.addEventListener("click", (event: MouseEvent & { target: HTMLElement }) => { const spanElement = hasClosestByMatchTag(event.target, "SPAN"); if (spanElement && hasClosestByClassName(spanElement, "vditor-toc")) { const headingElement = previewElement.querySelector("#" + spanElement.getAttribute("data-target-id")) as HTMLElement; if (headingElement) { window.scrollTo(window.scrollX, headingElement.offsetTop); } return; } }); };