UNPKG

vue-renderer-markdown

Version:

Vue 3 Markdown renderer optimized for large docs: progressive Mermaid, streaming diff code blocks, and fast real-time preview.

1,491 lines 417 kB
var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __objRest = (source, exclude) => { var target = {}; for (var prop in source) if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0) target[prop] = source[prop]; if (source != null && __getOwnPropSymbols) for (var prop of __getOwnPropSymbols(source)) { if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop)) target[prop] = source[prop]; } return target; }; var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; import { full } from "markdown-it-emoji"; import markdownItFootnote from "markdown-it-footnote"; import markdownItIns from "markdown-it-ins"; import markdownItMark from "markdown-it-mark"; import markdownItSub from "markdown-it-sub"; import markdownItSup from "markdown-it-sup"; import * as markdownItCheckbox from "markdown-it-task-checkbox"; import MarkdownIt from "markdown-it-ts"; import markdownItContainer from "markdown-it-container"; import { defineComponent, createElementBlock, openBlock, createVNode, unref, createElementVNode, Fragment, renderList, toDisplayString, computed, ref, watch, nextTick, onBeforeUnmount, createBlock, Teleport, Transition, withCtx, withDirectives, normalizeClass, normalizeStyle, vShow, createApp, h, defineAsyncComponent, resolveDynamicComponent, useAttrs, mergeProps, createCommentVNode, renderSlot, onMounted, onUnmounted, withModifiers, createTextVNode, provide, inject } from "vue"; let defaultMathOptions; function setDefaultMathOptions(opts) { defaultMathOptions = opts; } function getDefaultMathOptions() { return defaultMathOptions; } function applyContainers(md) { [ "admonition", "info", "warning", "error", "tip", "danger", "note", "caution" ].forEach((name) => { md.use(markdownItContainer, name, { render(tokens, idx) { if (tokens[idx].nesting === 1) return `<div class="vmr-container vmr-container-${name}">`; else return "</div>\n"; } }); }); md.block.ruler.before("fence", "vmr_container_fallback", (state, startLine, endLine, silent) => { const s = state; const startPos = s.bMarks[startLine] + s.tShift[startLine]; const lineMax = s.eMarks[startLine]; const markerMatch = s.src.slice(startPos, lineMax).match(/^:::\s*(\w+)/); if (!markerMatch) return false; if (silent) return true; const name = markerMatch[1]; let nextLine = startLine + 1; let found = false; while (nextLine <= endLine) { const sPos = s.bMarks[nextLine] + s.tShift[nextLine]; const ePos = s.eMarks[nextLine]; if (s.src.slice(sPos, ePos).trim() === ":::") { found = true; break; } nextLine++; } if (!found) return false; s.push("vmr_container_open", "div", 1).attrSet("class", `vmr-container vmr-container-${name}`); const contentLines = []; for (let i = startLine + 1; i < nextLine; i++) { const sPos = s.bMarks[i] + s.tShift[i]; const ePos = s.eMarks[i]; contentLines.push(s.src.slice(sPos, ePos)); } s.push("paragraph_open", "p", 1); const inlineToken = s.push("inline", "", 0); inlineToken.content = contentLines.join("\n"); inlineToken.map = [startLine + 1, nextLine]; inlineToken.children = []; s.md.inline.parse(inlineToken.content, s.md, s.env, inlineToken.children); s.push("paragraph_close", "p", -1); s.push("vmr_container_close", "div", -1); s.line = nextLine + 1; return true; }); } function applyFixLinkInline(md) { const rule = (state, silent) => { var _a, _b; const s = state; const start = s.pos; if (s.src[start] !== "[") return false; if (start > 0 && s.src[start - 1] === "!") return false; const rest = s.src.slice(start); const m = /^\[([^\]]*)\]\(([^)\s]*)?/.exec(rest); if (!m) return false; if (silent) return true; const text = (_a = m[1]) != null ? _a : ""; const href = (_b = m[2]) != null ? _b : ""; if (text.includes("*") || text.includes(":")) return false; const idxClose = rest.indexOf(")"); const hasClosingParen = idxClose !== -1; const open = s.push("link_open", "a", 1); open.attrs = [["href", href]]; const txt = s.push("text", "", 0); txt.content = text; if (hasClosingParen) { s.push("link_close", "a", -1); s.pos += idxClose + 1; } else s.pos += m[0].length; return true; }; md.inline.ruler.before("link", "fix_link_inline", rule); } function applyFixLinkTokens(md) { md.core.ruler.after("inline", "fix_link_tokens", (state) => { var _a; const toks = (_a = state.tokens) != null ? _a : []; for (let i = 0; i < toks.length; i++) { const t = toks[i]; if (t && t.type === "inline" && Array.isArray(t.children)) try { t.children = fixLinkToken(t.children); } catch (e) { console.error("[applyFixLinkTokens] failed to fix inline children", e); } } }); } function isTextToken(t) { return !!t && t.type === "text" && typeof t.content === "string"; } function fixLinkToken(tokens) { var _a, _b, _c; const tokensAny = tokens; tokens = fixLinkToken4(fixLinkToken3(tokens)); if (tokens.length < 5) return tokens; const first = tokens[tokens.length - 5]; const firstAny = first; const firstContent = String((_a = firstAny.content) != null ? _a : ""); if (first.type !== "text" || !firstContent.endsWith("[")) return fixLinkTokens2(tokens); if (tokens[tokens.length - 4].tag !== "em") return fixLinkTokens2(tokens); const last = tokens[tokens.length - 1]; const lastAny = last; const lastContent = String((_b = lastAny.content) != null ? _b : ""); if ((last == null ? void 0 : last.type) === "text" && !lastContent.startsWith("]")) return fixLinkTokens2(tokens); const thirdAny = tokens[tokens.length - 3]; const thirdContent = String((_c = thirdAny.content) != null ? _c : ""); const href = lastContent.replace(/^\]\(*/, ""); const loading = !lastContent.includes(")"); tokensAny[tokens.length - 5].content = firstContent.replace(/\[$/, ""); tokens.splice(tokens.length - 3, 1, { type: "link", href, text: thirdContent, children: [{ type: "text", content: thirdContent, raw: thirdContent }], loading }); tokens.splice(tokens.length - 1, 1); return tokens; } function fixLinkTokens2(tokens) { var _a, _b, _c, _d, _e; const tokensAny = tokens; if (tokens.length < 8) return tokens; let length = tokens.length; let last = tokens[length - 1]; if (!last) return tokens; if (last.type !== "link_close") { length--; last = tokens[length - 1]; if (last.type !== "link_close") return tokens; } if (tokens[length - 7].type !== "em_open") return tokens; const third = tokens[length - 6]; const first = tokens[length - 8]; if (first.type !== "text") return tokens; let href = String((_b = (_a = tokensAny[length - 2]) == null ? void 0 : _a.content) != null ? _b : ""); let count = 4; if (length !== tokens.length) { href += String((_c = last.content) != null ? _c : ""); count++; } tokens.splice(length - 4, count); const thirdAny = third; const content2 = String((_d = thirdAny.content) != null ? _d : ""); length -= 4; const firstAny = first; tokensAny[length - 8].content = String((_e = firstAny.content) != null ? _e : "").replace(/\[$/, ""); tokens.splice(length - 2, 1, { type: "link", href, text: content2, children: [{ type: "text", content: content2, raw: content2 }], loading: true }); return tokens; } function fixLinkToken3(tokens) { var _a, _b, _c, _d, _e, _f; const tokensAny = tokens; const last = tokens[tokens.length - 1]; const preLast = tokens[tokens.length - 2]; const fixedTokens = [...tokens]; if (!last) return tokens; if (last.type !== "text" || !((_a = last.content) == null ? void 0 : _a.startsWith(")"))) return tokens; if (preLast.type !== "link_close") return tokens; if (isTextToken(tokens[tokens.length - 5]) && String((_b = tokens[tokens.length - 5].content) != null ? _b : "").endsWith("(")) { const a = tokensAny[tokens.length - 5]; const b = tokensAny[tokens.length - 3]; const content2 = String((_c = a.content) != null ? _c : "") + String((_d = b.content) != null ? _d : "") + String((_e = last.content) != null ? _e : ""); fixedTokens.splice(tokens.length - 5, 5, { type: "text", content: content2, raw: content2 }); } else { const lc = ((_f = last.content) != null ? _f : "").slice(1); fixedTokens[fixedTokens.length - 1] = __spreadProps(__spreadValues({}, last), { content: lc }); } return fixedTokens; } function fixLinkToken4(tokens) { var _a, _b, _c, _d, _e, _f, _g, _h, _i; const tokensAny = tokens; const fixedTokens = [...tokens]; for (let i = tokens.length - 1; i >= 3; i--) { const token = tokens[i]; if (token && token.type === "link_close") { if ((_b = (_a = tokens[i - 3]) == null ? void 0 : _a.content) == null ? void 0 : _b.endsWith("(")) { const nextToken = tokens[i + 1]; if (nextToken && (nextToken == null ? void 0 : nextToken.type) === "text") { if (tokens[i - 1].type === "text" && ((_c = tokens[i - 3]) == null ? void 0 : _c.type) === "text") { const nextTokenContent = String((_d = nextToken.content) != null ? _d : ""); const a = tokensAny[i - 3]; const b = tokensAny[i - 1]; const content2 = String((_e = a.content) != null ? _e : "") + String((_f = b.content) != null ? _f : "") + nextTokenContent; fixedTokens.splice(i - 3, 5, { type: "text", content: content2, raw: content2 }); i -= 3; } } else { if (tokens[i - 1].type === "text" && ((_g = tokens[i - 3]) == null ? void 0 : _g.type) === "text") { const a = tokensAny[i - 3]; const b = tokensAny[i - 1]; const content2 = String((_h = a.content) != null ? _h : "") + String((_i = b.content) != null ? _i : ""); fixedTokens.splice(i - 3, 4, { type: "text", content: content2, raw: content2 }); } i -= 3; } } } } return fixedTokens; } function applyFixListItem(md) { md.core.ruler.after("inline", "fix_list_item_tokens", (state) => { var _a; const toks = (_a = state.tokens) != null ? _a : []; for (let i = 0; i < toks.length; i++) { const t = toks[i]; if (t && t.type === "inline" && Array.isArray(t.children)) try { t.children = fixListItem(t.children); } catch (e) { console.error("[applyFixListItem] failed to fix inline children", e); } } }); } function fixListItem(tokens) { var _a, _b; const last = tokens[tokens.length - 1]; const lastContent = String((_a = last == null ? void 0 : last.content) != null ? _a : ""); if ((last == null ? void 0 : last.type) === "text" && /^\s*\d+\.\s*$/.test(lastContent) && ((_b = tokens[tokens.length - 2]) == null ? void 0 : _b.tag) === "br") tokens.splice(tokens.length - 1, 1); return tokens; } function applyFixStrongTokens(md) { md.core.ruler.after("inline", "fix_strong_tokens", (state) => { var _a; const toks = (_a = state.tokens) != null ? _a : []; for (let i = 0; i < toks.length; i++) { const t = toks[i]; if (t && t.type === "inline" && Array.isArray(t.children)) try { t.children = fixStrongTokens(t.children); } catch (e) { console.error("[applyFixStrongTokens] failed to fix inline children", e); } } }); } function fixStrongTokens(tokens) { var _a, _b; const fixedTokens = [...tokens]; if (tokens.length < 4) return fixedTokens; const i = tokens.length - 4; const token = tokens[i]; const nextToken = tokens[i + 1]; const tokenContent = String((_a = token.content) != null ? _a : ""); if (token.type === "text" && tokenContent.endsWith("*") && nextToken.type === "em_open") { const _nextToken = tokens[i + 2]; const count = (_nextToken == null ? void 0 : _nextToken.type) === "text" ? 4 : 3; const insert = [ { type: "strong_open", tag: "strong", attrs: null, map: null, children: null, content: "", markup: "**", info: "", meta: null }, { type: "text", content: (_nextToken == null ? void 0 : _nextToken.type) === "text" ? String((_b = _nextToken.content) != null ? _b : "") : "" }, { type: "strong_close", tag: "strong", attrs: null, map: null, children: null, content: "", markup: "**", info: "", meta: null } ]; const beforeText = tokenContent.slice(0, -1); if (beforeText) insert.unshift({ type: "text", content: beforeText, raw: beforeText }); fixedTokens.splice(i, count, ...insert); return fixedTokens; } return fixedTokens; } function applyFixTableTokens(md) { md.core.ruler.after("block", "fix_table_tokens", (state) => { var _a; const s = state; try { const fixed = fixTableTokens((_a = s.tokens) != null ? _a : []); if (Array.isArray(fixed)) s.tokens = fixed; } catch (e) { console.error("[applyFixTableTokens] failed to fix table tokens", e); } }); } function createStart() { return [ { type: "table_open", tag: "table", attrs: null, map: null, children: null, content: "", markup: "", info: "", level: 0, loading: true, meta: null }, { type: "thead_open", tag: "thead", attrs: null, block: true, level: 1, children: null }, { type: "tr_open", tag: "tr", attrs: null, block: true, level: 2, children: null } ]; } function createEnd() { return [ { type: "tr_close", tag: "tr", attrs: null, block: true, level: 2, children: null }, { type: "thead_close", tag: "thead", attrs: null, block: true, level: 1, children: null }, { type: "table_close", tag: "table", attrs: null, map: null, children: null, content: "", markup: "", info: "", level: 0, meta: null } ]; } function createTh(text) { return [ { type: "th_open", tag: "th", attrs: null, block: true, level: 3, children: null }, { type: "inline", tag: "", children: [{ tag: "", type: "text", block: false, content: text, children: null }], content: text, level: 4, attrs: null, block: true }, { type: "th_close", tag: "th", attrs: null, block: true, level: 3, children: null } ]; } function fixTableTokens(tokens) { var _a, _b, _c, _d; const fixedTokens = [...tokens]; if (tokens.length < 3) return fixedTokens; const i = tokens.length - 2; const token = tokens[i]; if (token.type === "inline") { const tcontent = String((_a = token.content) != null ? _a : ""); const childContent = String((_d = (_c = (_b = token.children) == null ? void 0 : _b[0]) == null ? void 0 : _c.content) != null ? _d : ""); if (/^\|(?:[^|\n]+\|?)+/.test(tcontent)) { const body = childContent.slice(1).split("|").map((i$1) => i$1.trim()).filter(Boolean).flatMap((i$1) => createTh(i$1)); const insert = [ ...createStart(), ...body, ...createEnd() ]; fixedTokens.splice(i - 1, 3, ...insert); } else if (/^\|(?:[^|\n]+\|)+\n\|:?-/.test(tcontent)) { const body = childContent.slice(1, -1).split("|").map((i$1) => i$1.trim()).flatMap((i$1) => createTh(i$1)); const insert = [ ...createStart(), ...body, ...createEnd() ]; fixedTokens.splice(i - 1, 3, ...insert); } else if (/^\|(?:[^|\n:]+\|)+\n\|:?$/.test(tcontent)) { token.content = tcontent.slice(0, -2); token.children.splice(2, 1); } } return fixedTokens; } function findMatchingClose(src, startIdx, open, close) { const len = src.length; if (open === "$$" && close === "$$") { let i$1 = startIdx; while (i$1 < len - 1) { if (src[i$1] === "$" && src[i$1 + 1] === "$") { let k = i$1 - 1; let backslashes = 0; while (k >= 0 && src[k] === "\\") { backslashes++; k--; } if (backslashes % 2 === 0) return i$1; } i$1++; } return -1; } const openChar = open[open.length - 1]; const closeSeq = close; let depth = 0; let i = startIdx; while (i < len) { if (src.slice(i, i + closeSeq.length) === closeSeq) { let k = i - 1; let backslashes = 0; while (k >= 0 && src[k] === "\\") { backslashes++; k--; } if (backslashes % 2 === 0) { if (depth === 0) return i; depth--; i += closeSeq.length; continue; } } const ch = src[i]; if (ch === "\\") { i += 2; continue; } if (ch === openChar) depth++; else if (ch === closeSeq[closeSeq.length - 1]) { if (depth > 0) depth--; } i++; } return -1; } var findMatchingClose_default = findMatchingClose; const TEX_BRACE_COMMANDS = [ "mathbf", "boldsymbol", "mathbb", "mathcal", "mathfrak", "mathrm", "mathit", "mathsf", "vec", "hat", "bar", "tilde", "overline", "underline", "mathscr", "mathnormal", "operatorname", "mathbf*" ]; const ESCAPED_TEX_BRACE_COMMANDS = TEX_BRACE_COMMANDS.map((c) => c.replace(/[.*+?^${}()|[\\]"\]/g, "\\$&")).join("|"); const TEX_CMD_RE = /\\[a-z]+/i; const PREFIX_CLASS = "(?:\\\\|\\u0008)"; const TEX_CMD_WITH_BRACES_RE = new RegExp(`${PREFIX_CLASS}(?:${ESCAPED_TEX_BRACE_COMMANDS})\\s*\\{[^}]+\\}`, "i"); const TEX_BRACE_CMD_START_RE = new RegExp(`(?:${PREFIX_CLASS})?(?:${ESCAPED_TEX_BRACE_COMMANDS})s*{`, "i"); const TEX_SPECIFIC_RE = /\\(?:text|frac|left|right|times)/; const OPS_RE = /* @__PURE__ */ new RegExp("(?<!\\+)\\+(?!\\+)|[=\\-*/^<>]|\\\\times|\\\\pm|\\\\cdot|\\\\le|\\\\ge|\\\\neq"); const FUNC_CALL_RE = /[A-Z]+\s*\([^)]+\)/i; const WORDS_RE = /\b(?:sin|cos|tan|log|ln|exp|sqrt|frac|sum|lim|int|prod)\b/; const DATE_TIME_RE = /\b\d{4}\/\d{1,2}\/\d{1,2}(?:[ T]\d{1,2}:\d{2}(?::\d{2})?)?\b/; function isMathLike(s) { if (!s) return false; const norm = s.replace(/\u0008/g, "\\b"); const stripped = norm.trim(); if (DATE_TIME_RE.test(stripped)) return false; if (stripped.includes("**")) return false; if (stripped.length > 2e3) return true; if (/[./]\s*\D|\D\s*[./]/.test(s)) return false; const texCmd = TEX_CMD_RE.test(norm); const texCmdWithBraces = TEX_CMD_WITH_BRACES_RE.test(norm); const texBraceStart = TEX_BRACE_CMD_START_RE.test(norm); const texSpecific = TEX_SPECIFIC_RE.test(norm); const superSub = /(?:^|[^\w\\])(?:[A-Z]|\\[A-Z]+)_(?:\{[^}]+\}|[A-Z0-9\\])/i.test(norm) || /(?:^|[^\w\\])(?:[A-Z]|\\[A-Z]+)\^(?:\{[^}]+\}|[A-Z0-9\\])/i.test(norm); const ops = OPS_RE.test(norm); const funcCall = FUNC_CALL_RE.test(norm); const words = WORDS_RE.test(norm); return texCmd || texCmdWithBraces || texBraceStart || texSpecific || superSub || ops || funcCall || words; } const KATEX_COMMANDS = [ "ldots", "cdots", "quad", "in", "end", "infty", "perp", "mid", "operatorname", "to", "rightarrow", "leftarrow", "math", "mathrm", "mathbf", "mathit", "mathbb", "mathcal", "mathfrak", "alpha", "beta", "gamma", "delta", "epsilon", "lambda", "sum", "prod", "int", "sqrt", "fbox", "boxed", "color", "rule", "edef", "fcolorbox", "hline", "hdashline", "cdot", "times", "pm", "le", "ge", "neq", "sin", "cos", "tan", "log", "ln", "exp", "lim", "frac", "text", "left", "right" ]; const ESCAPED_KATEX_COMMANDS = KATEX_COMMANDS.slice().sort((a, b) => b.length - a.length).map((c) => c.replace(/[.*+?^${}()|[\\]\\\]/g, "\\$&")).join("|"); const CONTROL_CHARS_CLASS = "[ \r\b\f\v]"; const CONTROL_MAP = { " ": "t", "\r": "r", "\b": "b", "\f": "f", "\v": "v" }; function countUnescapedStrong(s) { const re = /(^|[^\\])(__|\*\*)/g; let c = 0; while (re.exec(s) !== null) c++; return c; } function normalizeStandaloneBackslashT(s, opts) { var _a, _b; const commands = (_a = opts == null ? void 0 : opts.commands) != null ? _a : KATEX_COMMANDS; const escapeExclamation = (_b = opts == null ? void 0 : opts.escapeExclamation) != null ? _b : true; const useDefault = (opts == null ? void 0 : opts.commands) == null; let re; if (useDefault) re = new RegExp(`${CONTROL_CHARS_CLASS}|(?<!\\\\|\\w)(${ESCAPED_KATEX_COMMANDS})\\b`, "g"); else { const commandPattern = `(?:${commands.slice().sort((a, b) => b.length - a.length).map((c) => c.replace(/[.*+?^${}()|[\\]\\"\]/g, "\\$&")).join("|")})`; re = new RegExp(`${CONTROL_CHARS_CLASS}|(?<!\\\\|\\w)(${commandPattern})\\b`, "g"); } let out = s.replace(re, (m, cmd) => { if (CONTROL_MAP[m] !== void 0) return `\\${CONTROL_MAP[m]}`; if (cmd && commands.includes(cmd)) return `\\${cmd}`; return m; }); if (escapeExclamation) out = out.replace(/(^|[^\\])!/g, "$1\\!"); const braceEscaped = useDefault ? [ESCAPED_TEX_BRACE_COMMANDS, ESCAPED_KATEX_COMMANDS].filter(Boolean).join("|") : [commands.map((c) => c.replace(/[.*+?^${}()|[\\]\\\]/g, "\\$&")).join("|"), ESCAPED_TEX_BRACE_COMMANDS].filter(Boolean).join("|"); let result = out; if (braceEscaped) { const braceCmdRe = new RegExp(`(^|[^\\\\\\w])(${braceEscaped})\\s*\\{`, "g"); result = result.replace(braceCmdRe, (_m, p1, p2) => `${p1}\\${p2}{`); } result = result.replace(/span\{([^}]+)\}/, "span\\{$1\\}").replace(/\\operatorname\{span\}\{((?:[^{}]|\{[^}]*\})+)\}/, "\\operatorname{span}\\{$1\\}"); result = result.replace(/(^|[^\\])\\\r?\n/g, "$1\\\\\n"); result = result.replace(/(^|[^\\])\\$/g, "$1\\\\"); return result; } function applyMath(md, mathOpts) { const mathInline = (state, silent) => { const s = state; if (/^\*[^*]+/.test(s.src)) return false; const delimiters = [ ["$$", "$$"], ["\\(", "\\)"], ["(", ")"] ]; let searchPos = 0; let preMathPos = 0; for (const [open, close] of delimiters) { const src = s.src; let foundAny = false; const pushText = (text) => { if (text === "undefined" || text == null) text = ""; if (text === "\\") { s.pos = s.pos + text.length; searchPos = s.pos; return; } if (text === "\\)" || text === "\\(") { const t$1 = s.push("text_special", "", 0); t$1.content = text === "\\)" ? ")" : "("; t$1.markup = text; s.pos = s.pos + text.length; searchPos = s.pos; return; } if (!text) return; const t = s.push("text", "", 0); t.content = text; s.pos = s.pos + text.length; searchPos = s.pos; }; while (true) { if (searchPos >= src.length) break; const index2 = src.indexOf(open, searchPos); if (index2 === -1) break; if (index2 > 0) { let i = index2 - 1; while (i >= 0 && src[i] === " ") i--; if (i >= 0 && src[i] === "]") return false; } const endIdx = findMatchingClose_default(src, index2 + open.length, open, close); if (endIdx === -1) { const content$1 = src.slice(index2 + open.length); if (content$1.includes(open)) { searchPos = src.indexOf(open, index2 + open.length); continue; } if (endIdx === -1) { if (isMathLike(content$1)) { searchPos = index2 + open.length; foundAny = true; if (!silent) { s.pending = ""; const isStrongPrefix = countUnescapedStrong(preMathPos ? src.slice(preMathPos, searchPos) : src.slice(0, searchPos)) % 2 === 1; if (preMathPos) pushText(src.slice(preMathPos, searchPos)); else { let text = src.slice(0, searchPos); if (text.endsWith(open)) text = text.slice(0, text.length - open.length); pushText(text); } if (isStrongPrefix) { const strongToken = s.push("strong_open", "", 0); strongToken.markup = src.slice(0, index2 + 2); const token = s.push("math_inline", "math", 0); token.content = normalizeStandaloneBackslashT(content$1, mathOpts); token.markup = open === "$$" ? "$$" : open === "\\(" ? "\\(\\)" : open === "$" ? "$" : "()"; token.raw = `${open}${content$1}${close}`; token.loading = true; strongToken.content = content$1; s.push("strong_close", "", 0); } else { const token = s.push("math_inline", "math", 0); token.content = normalizeStandaloneBackslashT(content$1, mathOpts); token.markup = open === "$$" ? "$$" : open === "\\(" ? "\\(\\)" : open === "$" ? "$" : "()"; token.raw = `${open}${content$1}${close}`; token.loading = true; } s.pos = src.length; } searchPos = src.length; preMathPos = searchPos; } break; } } const content2 = src.slice(index2 + open.length, endIdx); if (!isMathLike(content2)) { searchPos = endIdx + close.length; const text = src.slice(s.pos, searchPos); if (!s.pending) pushText(text); continue; } foundAny = true; if (!silent) { const before = src.slice(0, index2); let toPushBefore = src.slice(0, searchPos) ? src.slice(preMathPos, index2) : before; const isStrongPrefix = countUnescapedStrong(toPushBefore) % 2 === 1; if (index2 !== s.pos && isStrongPrefix) toPushBefore = s.pending + src.slice(s.pos, index2); if (s.pending !== toPushBefore) { s.pending = ""; if (isStrongPrefix) { const _match = toPushBefore.match(/(\*+)/); const after = toPushBefore.slice(_match.index + _match[0].length); pushText(toPushBefore.slice(0, _match.index)); const strongToken = s.push("strong_open", "", 0); strongToken.markup = _match[0]; const textToken = s.push("text", "", 0); textToken.content = after; s.push("strong_close", "", 0); } else pushText(toPushBefore); } if (isStrongPrefix) { const strongToken = s.push("strong_open", "", 0); strongToken.markup = "**"; const token = s.push("math_inline", "math", 0); token.content = normalizeStandaloneBackslashT(content2, mathOpts); token.markup = open === "$$" ? "$$" : open === "\\(" ? "\\(\\)" : open === "$" ? "$" : "()"; token.raw = `${open}${content2}${close}`; token.loading = false; const raw = src.slice(endIdx + close.length); const isBeforeClose = raw.startsWith("*"); if (isBeforeClose) s.push("strong_close", "", 0); if (raw) { const textContentToken = s.push("text", "", 0); textContentToken.content = (raw == null ? "" : String(raw)).replace(/^\*+/, ""); } if (!isBeforeClose) s.push("strong_close", "", 0); s.pos = src.length; searchPos = src.length; preMathPos = searchPos; continue; } else { const token = s.push("math_inline", "math", 0); token.content = normalizeStandaloneBackslashT(content2, mathOpts); token.markup = open === "$$" ? "$$" : open === "\\(" ? "\\(\\)" : open === "$" ? "$" : "()"; token.raw = `${open}${content2}${close}`; token.loading = false; } } searchPos = endIdx + close.length; preMathPos = searchPos; s.pos = searchPos; } if (foundAny) { if (!silent) { if (searchPos < src.length) pushText(src.slice(searchPos)); s.pos = src.length; } else s.pos = searchPos; return true; } } return false; }; const mathBlock = (state, startLine, endLine, silent) => { const s = state; const delimiters = [ ["\\[", "\\]"], ["[", "]"], ["$$", "$$"] ]; const startPos = s.bMarks[startLine] + s.tShift[startLine]; const lineText = s.src.slice(startPos, s.eMarks[startLine]).trim(); let matched = false; let openDelim = ""; let closeDelim = ""; for (const [open, close] of delimiters) if (lineText === open || lineText.startsWith(open)) if (open.includes("[")) { if (lineText.replace("\\", "") === "[") { if (startLine + 1 < endLine) { matched = true; openDelim = open; closeDelim = close; break; } continue; } } else { matched = true; openDelim = open; closeDelim = close; break; } if (!matched) return false; if (silent) return true; if (lineText.includes(closeDelim) && lineText.indexOf(closeDelim) > openDelim.length) { const startDelimIndex = lineText.indexOf(openDelim); const endDelimIndex = lineText.indexOf(closeDelim, startDelimIndex + openDelim.length); const content$1 = lineText.slice(startDelimIndex + openDelim.length, endDelimIndex); const token$1 = s.push("math_block", "math", 0); token$1.content = normalizeStandaloneBackslashT(content$1); token$1.markup = openDelim === "$$" ? "$$" : openDelim === "[" ? "[]" : "\\[\\]"; token$1.map = [startLine, startLine + 1]; token$1.raw = `${openDelim}${content$1}${closeDelim}`; token$1.block = true; token$1.loading = false; s.line = startLine + 1; return true; } let nextLine = startLine; let content2 = ""; let found = false; const firstLineContent = lineText === openDelim ? "" : lineText.slice(openDelim.length); if (firstLineContent.includes(closeDelim)) { const endIndex = firstLineContent.indexOf(closeDelim); content2 = firstLineContent.slice(0, endIndex); found = true; nextLine = startLine; } else { if (firstLineContent) content2 = firstLineContent; for (nextLine = startLine + 1; nextLine < endLine; nextLine++) { const lineStart = s.bMarks[nextLine] + s.tShift[nextLine]; const lineEnd = s.eMarks[nextLine]; const currentLine = s.src.slice(lineStart - 1, lineEnd); if (currentLine.trim() === closeDelim) { found = true; break; } else if (currentLine.includes(closeDelim)) { found = true; const endIndex = currentLine.indexOf(closeDelim); content2 += (content2 ? "\n" : "") + currentLine.slice(0, endIndex); break; } content2 += (content2 ? "\n" : "") + currentLine; } } const token = s.push("math_block", "math", 0); token.content = normalizeStandaloneBackslashT(content2); token.markup = openDelim === "$$" ? "$$" : openDelim === "[" ? "[]" : "\\[\\]"; token.raw = `${openDelim}${content2}${content2.startsWith("\n") ? "\n" : ""}${closeDelim}`; token.map = [startLine, nextLine + 1]; token.block = true; token.loading = !found; s.line = nextLine + 1; return true; }; md.inline.ruler.before("escape", "math", mathInline); md.block.ruler.before("paragraph", "math_block", mathBlock, { alt: [ "paragraph", "reference", "blockquote", "list" ] }); } function applyRenderRules(md) { const defaultImage = md.renderer.rules.image || function(tokens, idx, options, env, self) { const tokensAny = tokens; const selfShape = self; return selfShape.renderToken ? selfShape.renderToken(tokensAny, idx, options) : ""; }; md.renderer.rules.image = (tokens, idx, options, env, self) => { var _a, _b; const tokensAny = tokens; (_b = (_a = tokensAny[idx]).attrSet) == null ? void 0 : _b.call(_a, "loading", "lazy"); return defaultImage(tokensAny, idx, options, env, self); }; md.renderer.rules.fence = md.renderer.rules.fence || ((tokens, idx) => { var _a, _b; const tokenShape = tokens[idx]; const info = String((_a = tokenShape.info) != null ? _a : "").trim(); return `<pre class="${info ? `language-${md.utils.escapeHtml(info.split(/\s+/g)[0])}` : ""}"><code>${md.utils.escapeHtml(String((_b = tokenShape.content) != null ? _b : ""))}</code></pre>`; }); } function factory(opts = {}) { var _a, _b, _c, _d, _e; const md = new MarkdownIt(__spreadValues({ html: true, linkify: true, typographer: true }, (_a = opts.markdownItOptions) != null ? _a : {})); if ((_b = opts.enableMath) != null ? _b : true) applyMath(md, __spreadValues(__spreadValues({}, (_c = getDefaultMathOptions()) != null ? _c : {}), (_d = opts.mathOptions) != null ? _d : {})); if ((_e = opts.enableContainers) != null ? _e : true) applyContainers(md); applyFixLinkInline(md); applyFixLinkTokens(md); applyFixStrongTokens(md); applyFixListItem(md); applyFixTableTokens(md); applyRenderRules(md); return md; } function parseCheckboxToken(token) { var _a; const tokenMeta = (_a = token.meta) != null ? _a : {}; return { type: "checkbox", checked: tokenMeta.checked === true, raw: tokenMeta.checked ? "[x]" : "[ ]" }; } function parseCheckboxInputToken(token) { const tokenAny = token; const rawAttr = tokenAny.attrGet ? tokenAny.attrGet("checked") : void 0; const checked = rawAttr === "" || rawAttr === "true"; return { type: "checkbox_input", checked, raw: checked ? "[x]" : "[ ]" }; } function parseEmojiToken(token) { var _a, _b; const name = String((_a = token.content) != null ? _a : ""); return { type: "emoji", name, markup: String((_b = token.markup) != null ? _b : ""), raw: `:${name}:` }; } function parseEmphasisToken(tokens, startIndex) { var _a; const children = []; let emText = ""; let i = startIndex + 1; const innerTokens = []; while (i < tokens.length && tokens[i].type !== "em_close") { emText += String((_a = tokens[i].content) != null ? _a : ""); innerTokens.push(tokens[i]); i++; } children.push(...parseInlineTokens(innerTokens)); return { node: { type: "emphasis", children, raw: `*${emText}*` }, nextIndex: i < tokens.length ? i + 1 : tokens.length }; } function splitUnifiedDiff(content2) { const orig = []; const updated = []; for (const rawLine of content2.split(/\r?\n/)) { const line = rawLine; if (/^(?:diff |index |--- |\+\+\+ |@@ )/.test(line)) continue; if (line.startsWith("- ")) orig.push(` ${line.slice(1)}`); else if (line.startsWith("+ ")) updated.push(` ${line.slice(1)}`); else { orig.push(line); updated.push(line); } } return { original: orig.join("\n"), updated: updated.join("\n") }; } function parseFenceToken(token) { var _a, _b, _c, _d; const hasMap = Array.isArray(token.map) && token.map.length === 2; const tokenMeta = (_a = token.meta) != null ? _a : {}; const closed = typeof tokenMeta.closed === "boolean" ? tokenMeta.closed : void 0; const info = String((_b = token.info) != null ? _b : ""); const diff = info.startsWith("diff"); const language = diff ? String((_c = info.split(" ")[1]) != null ? _c : "") : info; let content2 = String((_d = token.content) != null ? _d : ""); const trailingFenceLine = /\r?\n[ \t]*`+\s*$/; if (trailingFenceLine.test(content2)) content2 = content2.replace(trailingFenceLine, ""); if (diff) { const { original, updated } = splitUnifiedDiff(content2); return { type: "code_block", language, code: String(updated != null ? updated : ""), raw: String(content2 != null ? content2 : ""), diff, loading: closed === true ? false : closed === false ? true : !hasMap, originalCode: original, updatedCode: updated }; } return { type: "code_block", language, code: String(content2 != null ? content2 : ""), raw: String(content2 != null ? content2 : ""), diff, loading: closed === true ? false : closed === false ? true : !hasMap }; } function parseFootnoteRefToken(token) { var _a, _b, _c; const tokenMeta = (_a = token.meta) != null ? _a : {}; return { type: "footnote_reference", id: String((_b = tokenMeta.label) != null ? _b : ""), raw: `[^${String((_c = tokenMeta.label) != null ? _c : "")}]` }; } function parseHardbreakToken() { return { type: "hardbreak", raw: "\\\n" }; } function parseHighlightToken(tokens, startIndex) { var _a; const children = []; let markText = ""; let i = startIndex + 1; const innerTokens = []; while (i < tokens.length && tokens[i].type !== "mark_close") { markText += String((_a = tokens[i].content) != null ? _a : ""); innerTokens.push(tokens[i]); i++; } children.push(...parseInlineTokens(innerTokens)); return { node: { type: "highlight", children, raw: `==${markText}==` }, nextIndex: i < tokens.length ? i + 1 : tokens.length }; } function parseHtmlInlineCodeToken(token, tokens, i) { var _a, _b, _c; let code = String((_a = token.content) != null ? _a : "").trim(); const nextToken = tokens[i + 1]; const nnextToken = tokens[i + 2]; const tagMatch = code.match(/^<\s*([\w-]+)/); const tag = tagMatch ? tagMatch[1].toLowerCase() : ""; function extractInner(html) { const m = html.match(/>([\s\S]*?)<\s*\/\s*[\w-]+>/); return m ? m[1] : ""; } if (tag === "a") { let loading = false; if (!nextToken || (nextToken == null ? void 0 : nextToken.type) === "text" && (!nnextToken || nnextToken.type !== "html_inline") || !nextToken) loading = true; if ((nextToken == null ? void 0 : nextToken.type) === "text" && ((nnextToken == null ? void 0 : nnextToken.type) === "html_inline" || !nnextToken)) { const hrefMatch = code.match(/href\s*=\s*"([^"]+)"|href\s*=\s*'([^']+)'|href\s*=\s*([^\s>]+)/i); const href = hrefMatch ? hrefMatch[1] || hrefMatch[2] || hrefMatch[3] : ""; let index2 = i + 1; if (nextToken.type === "text") { code = (_c = (_b = nextToken.content) == null ? void 0 : _b.replace(/<[^>]*$/, "")) != null ? _c : ""; index2 = i + 2; } if ((nnextToken == null ? void 0 : nnextToken.type) === "html_inline" && nextToken.type === "text") index2 = i + 3; const inner = code || href || ""; return [{ type: "link", href: String(href != null ? href : ""), title: null, text: code, children: [{ type: "text", content: inner, raw: inner }], loading, raw: code }, index2]; } } if (tag === "p" || tag === "div") { const inner = extractInner(code) || ""; return [{ type: "paragraph", children: [{ type: "text", content: inner, raw: inner }], raw: code }, i + 1]; } return [{ type: "inline_code", code, raw: code }, i + 1]; } function parseImageToken(token, loading = false) { var _a, _b, _c, _d, _e, _f, _g, _h, _i; let attrs = (_a = token.attrs) != null ? _a : []; let childWithAttrs = null; if ((!attrs || attrs.length === 0) && Array.isArray(token.children)) for (const child of token.children) { const childAttrs = child == null ? void 0 : child.attrs; if (Array.isArray(childAttrs) && childAttrs.length > 0) { attrs = childAttrs; childWithAttrs = child; break; } } const src = String((_c = (_b = attrs.find((attr) => attr[0] === "src")) == null ? void 0 : _b[1]) != null ? _c : ""); const altAttr = (_d = attrs.find((attr) => attr[0] === "alt")) == null ? void 0 : _d[1]; let alt = ""; if (altAttr != null && String(altAttr).length > 0) alt = String(altAttr); else if ((childWithAttrs == null ? void 0 : childWithAttrs.content) != null && String(childWithAttrs.content).length > 0) alt = String(childWithAttrs.content); else if (Array.isArray(childWithAttrs == null ? void 0 : childWithAttrs.children) && ((_e = childWithAttrs.children[0]) == null ? void 0 : _e.content)) alt = String(childWithAttrs.children[0].content); else if (Array.isArray(token.children) && ((_f = token.children[0]) == null ? void 0 : _f.content)) alt = String(token.children[0].content); else if (token.content != null && String(token.content).length > 0) alt = String(token.content); const _title = (_h = (_g = attrs.find((attr) => attr[0] === "title")) == null ? void 0 : _g[1]) != null ? _h : null; const title = _title === null ? null : String(_title); const raw = String((_i = token.content) != null ? _i : ""); return { type: "image", src, alt, title, raw, loading }; } function parseInlineCodeToken(token) { var _a; const code = String((_a = token.content) != null ? _a : ""); return { type: "inline_code", code, raw: code }; } function parseInsertToken(tokens, startIndex) { var _a; const children = []; let insText = ""; let i = startIndex + 1; const innerTokens = []; while (i < tokens.length && tokens[i].type !== "ins_close") { insText += String((_a = tokens[i].content) != null ? _a : ""); innerTokens.push(tokens[i]); i++; } children.push(...parseInlineTokens(innerTokens)); return { node: { type: "insert", children, raw: `++${String(insText)}++` }, nextIndex: i < tokens.length ? i + 1 : tokens.length }; } function parseLinkToken(tokens, startIndex) { var _a, _b, _c, _d, _e; const attrs = (_a = tokens[startIndex].attrs) != null ? _a : []; const href = String((_c = (_b = attrs.find((attr) => attr[0] === "href")) == null ? void 0 : _b[1]) != null ? _c : ""); const _title = (_e = (_d = attrs.find((attr) => attr[0] === "title")) == null ? void 0 : _d[1]) != null ? _e : null; const title = _title === null ? null : String(_title); let i = startIndex + 1; const linkTokens = []; const loading = true; while (i < tokens.length && tokens[i].type !== "link_close") { linkTokens.push(tokens[i]); i++; } const children = parseInlineTokens(linkTokens); const linkText = children.map((node) => { var _a2, _b2; const nodeAny = node; if ("content" in node) return String((_a2 = nodeAny.content) != null ? _a2 : ""); return String((_b2 = nodeAny.raw) != null ? _b2 : ""); }).join(""); return { node: { type: "link", href, title, text: linkText, children, raw: String(`[${linkText}](${href}${title ? ` "${title}"` : ""})`), loading }, nextIndex: i < tokens.length ? i + 1 : tokens.length }; } function parseMathInlineToken(token) { var _a; return { type: "math_inline", content: String((_a = token.content) != null ? _a : ""), loading: !!token.loading, raw: token.raw }; } function parseReferenceToken(token) { var _a, _b, _c; return { type: "reference", id: String((_a = token.content) != null ? _a : ""), raw: String((_c = token.markup) != null ? _c : `[${(_b = token.content) != null ? _b : ""}]`) }; } function parseStrikethroughToken(tokens, startIndex) { var _a; const children = []; let sText = ""; let i = startIndex + 1; const innerTokens = []; while (i < tokens.length && tokens[i].type !== "s_close") { sText += String((_a = tokens[i].content) != null ? _a : ""); innerTokens.push(tokens[i]); i++; } children.push(...parseInlineTokens(innerTokens)); return { node: { type: "strikethrough", children, raw: `~~${sText}~~` }, nextIndex: i < tokens.length ? i + 1 : tokens.length }; } function parseStrongToken(tokens, startIndex, raw) { var _a; const children = []; let strongText = ""; let i = startIndex + 1; const innerTokens = []; while (i < tokens.length && tokens[i].type !== "strong_close") { strongText += String((_a = tokens[i].content) != null ? _a : ""); innerTokens.push(tokens[i]); i++; } children.push(...parseInlineTokens(innerTokens, raw)); return { node: { type: "strong", children, raw: `**${String(strongText)}**` }, nextIndex: i < tokens.length ? i + 1 : tokens.length }; } function parseSubscriptToken(tokens, startIndex) { var _a, _b; const children = []; let subText = ""; let i = startIndex + 1; const innerTokens = []; while (i < tokens.length && tokens[i].type !== "sub_close") { subText += String((_a = tokens[i].content) != null ? _a : ""); innerTokens.push(tokens[i]); i++; } children.push(...parseInlineTokens(innerTokens)); const startContent = String((_b = tokens[startIndex].content) != null ? _b : ""); const display = subText || startContent; return { node: { type: "subscript", children: children.length > 0 ? children : [{ type: "text", content: display, raw: display }], raw: `~${display}~` }, nextIndex: i < tokens.length ? i + 1 : tokens.length }; } function parseSuperscriptToken(tokens, startIndex) { var _a, _b, _c, _d; const children = []; let supText = ""; let i = startIndex + 1; const innerTokens = []; while (i < tokens.length && tokens[i].type !== "sup_close") { supText += String((_a = tokens[i].content) != null ? _a : ""); innerTokens.push(tokens[i]); i++; } children.push(...parseInlineTokens(innerTokens)); return { node: { type: "superscript", children: children.length > 0 ? children : [{ type: "text", content: supText || String((_b = tokens[startIndex].content) != null ? _b : ""), raw: supText || String((_c = tokens[startIndex].content) != null ? _c : "") }], raw: `^${supText || String((_d = tokens[startIndex].content) != null ? _d : "")}^` }, nextIndex: i < tokens.length ? i + 1 : tokens.length }; } function parseTextToken(token) { var _a; const content2 = String((_a = token.content) != null ? _a : ""); return { type: "text", content: content2, raw: content2 }; } const AUTOLINK_PROTOCOL_RE = /^(?:https?:\/\/|mailto:|ftp:\/\/)/i; const AUTOLINK_GENERIC_RE = /:\/\//; function isLikelyUrl(href) { if (!href) return false; return AUTOLINK_PROTOCOL_RE.test(href) || AUTOLINK_GENERIC_RE.test(href); } function parseInlineTokens(tokens, raw, pPreToken) { if (!tokens || tokens.length === 0) return []; const result = []; let currentTextNode = null; let i = 0; function resetCurrentTextNode() { currentTextNode = null; } function handleEmphasisAndStrikethrough(content2, token) { var _a, _b; if (/[^~]*~{2,}[^~]+/.test(content2)) { let idx = content2.indexOf("~~"); if (idx === -1) idx = 0; const _text = content2.slice(0, idx); if (_text) if (currentTextNode) { currentTextNode.content += _text; currentTextNode.raw += _text; } else { currentTextNode = { type: "text", content: String(_text != null ? _text : ""), raw: String((_a = token.content) != null ? _a : "") }; result.push(currentTextNode); } const { node } = parseStrikethroughToken([ { type: "s_open", tag: "s", content: "", markup: "*", info: "", meta: null }, { type: "text", tag: "", content: content2.slice(idx).replace(/~/g, ""), markup: "", info: "", meta: null }, { type: "s_close", tag: "s", content: "", markup: "*", info: "", meta: null } ], 0); resetCurrentTextNode(); pushNode(node); i++; return true; } if (/\*\*/.test(content2)) { const openIdx = content2.indexOf("**"); const beforeText = openIdx > -1 ? c