UNPKG

vue-renderer-markdown

Version:

A Vue 3 component that renders Markdown string content as HTML, supporting custom components and advanced markdown features.

1,604 lines 255 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __getProtoOf = Object.getPrototypeOf; 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 __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod2, isNodeMode, target) => (target = mod2 != null ? __create(__getProtoOf(mod2)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod2 || !mod2.__esModule ? __defProp(target, "default", { value: mod2, enumerable: true }) : target, mod2 )); 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()); }); }; Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } }); const vue = require("vue"); const katex = require("katex"); const MarkdownIt = require("markdown-it"); const markdownItEmoji = require("markdown-it-emoji"); const markdownItFootnote = require("markdown-it-footnote"); const markdownItIns = require("markdown-it-ins"); const markdownItMark = require("markdown-it-mark"); const markdownItSub = require("markdown-it-sub"); const markdownItSup = require("markdown-it-sup"); const markdownItCheckbox = require("markdown-it-task-checkbox"); const markdownItContainer = require("markdown-it-container"); const mathjax3 = require("markdown-it-mathjax3"); const mermaid = require("./components/MermaidBlockNode/mermaid"); function _interopNamespaceDefault(e) { const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } }); if (e) { for (const k in e) { if (k !== "default") { const d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: () => e[k] }); } } } n.default = e; return Object.freeze(n); } const markdownItCheckbox__namespace = /* @__PURE__ */ _interopNamespaceDefault(markdownItCheckbox); const mathjax3__namespace = /* @__PURE__ */ _interopNamespaceDefault(mathjax3); function humanizeKey(key) { const s = key.split(".").pop() || key; return s.replace(/[_-]/g, " ").replace(/([A-Z])/g, " $1").replace(/\s+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()).trim(); } const defaultMap = { "common.copy": "Copy", "common.copySuccess": "Copied", "common.decrease": "Decrease", "common.reset": "Reset", "common.increase": "Increase", "common.expand": "Expand", "common.collapse": "Collapse", "common.preview": "Preview" }; function useSafeI18n() { try { const possible = globalThis.$vueI18nUse || null; if (possible && typeof possible === "function") { try { const i18n = possible(); if (i18n && typeof i18n.t === "function") { return { t: i18n.t.bind(i18n) }; } } catch (e) { } } } catch (e) { } const fallbackT = (key) => { var _a; return (_a = defaultMap[key]) != null ? _a : humanizeKey(key); }; (() => __async(null, null, function* () { try { const mod2 = yield import("vue-i18n"); const useI18n = mod2.useI18n || mod2.default && mod2.default.useI18n; if (useI18n && typeof useI18n === "function") { try { const i18n = useI18n(); if (i18n && typeof i18n.t === "function") { try { globalThis.$vueI18nUse = () => i18n; } catch (e) { } } } catch (e) { } } } catch (e) { } }))(); return { t: fallbackT }; } function parseCheckboxToken(token) { var _a, _b; return { type: "checkbox", checked: ((_a = token.meta) == null ? void 0 : _a.checked) === true, raw: ((_b = token.meta) == null ? void 0 : _b.checked) ? "[x]" : "[ ]" }; } function parseEmojiToken(token) { return { type: "emoji", name: token.content || "", raw: `:${token.content || ""}:` }; } function parseEmphasisToken(tokens, startIndex) { const children = []; let emText = ""; let i = startIndex + 1; const innerTokens = []; while (i < tokens.length && tokens[i].type !== "em_close") { emText += tokens[i].content || ""; innerTokens.push(tokens[i]); i++; } children.push(...parseInlineTokens(innerTokens)); const node = { type: "emphasis", children, raw: `*${emText}*` }; const nextIndex = i < tokens.length ? i + 1 : tokens.length; return { node, nextIndex }; } function parseFenceToken(token) { const hasMap = Array.isArray(token.map) && token.map.length === 2; const meta = token.meta; const closed = typeof (meta == null ? void 0 : meta.closed) === "boolean" ? meta.closed : void 0; return { type: "code_block", language: token.info || "", code: token.content || "", raw: token.content || "", loading: closed === true ? false : closed === false ? true : !hasMap }; } function parseFootnoteRefToken(token) { var _a, _b; return { type: "footnote_reference", id: ((_a = token.meta) == null ? void 0 : _a.label) || "", raw: `[^${((_b = token.meta) == null ? void 0 : _b.label) || ""}]` }; } function parseHardbreakToken() { return { type: "hardbreak", raw: "\\\n" }; } function parseHighlightToken(tokens, startIndex) { const children = []; let markText = ""; let i = startIndex + 1; const innerTokens = []; while (i < tokens.length && tokens[i].type !== "mark_close") { markText += tokens[i].content || ""; innerTokens.push(tokens[i]); i++; } children.push(...parseInlineTokens(innerTokens)); const node = { type: "highlight", children, raw: `==${markText}==` }; const nextIndex = i < tokens.length ? i + 1 : tokens.length; return { node, nextIndex }; } function parseImageToken(token) { var _a, _b, _c, _d, _e, _f; return { type: "image", src: ((_b = (_a = token.attrs) == null ? void 0 : _a.find((attr) => attr[0] === "src")) == null ? void 0 : _b[1]) || "", alt: ((_d = (_c = token.attrs) == null ? void 0 : _c.find((attr) => attr[0] === "alt")) == null ? void 0 : _d[1]) || "", title: ((_f = (_e = token.attrs) == null ? void 0 : _e.find((attr) => attr[0] === "title")) == null ? void 0 : _f[1]) || null, raw: token.content || "" }; } function parseInlineCodeToken(token) { return { type: "inline_code", code: token.content || "", raw: token.content || "" }; } function parseInsertToken(tokens, startIndex) { const children = []; let insText = ""; let i = startIndex + 1; const innerTokens = []; while (i < tokens.length && tokens[i].type !== "ins_close") { insText += tokens[i].content || ""; innerTokens.push(tokens[i]); i++; } children.push(...parseInlineTokens(innerTokens)); const node = { type: "insert", children, raw: `++${insText}++` }; const nextIndex = i < tokens.length ? i + 1 : tokens.length; return { node, nextIndex }; } function parseLinkToken(tokens, startIndex) { var _a, _b, _c, _d; const openToken = tokens[startIndex]; const href = ((_b = (_a = openToken.attrs) == null ? void 0 : _a.find((attr) => attr[0] === "href")) == null ? void 0 : _b[1]) || ""; const title = ((_d = (_c = openToken.attrs) == null ? void 0 : _c.find((attr) => attr[0] === "title")) == null ? void 0 : _d[1]) || null; let i = startIndex + 1; const linkTokens = []; while (i < tokens.length && tokens[i].type !== "link_close") { linkTokens.push(tokens[i]); i++; } const children = parseInlineTokens(linkTokens); const linkText = children.map((node2) => { if ("content" in node2) return node2.content; return node2.raw; }).join(""); const node = { type: "link", href, title, text: linkText, children, raw: `[${linkText}](${href}${title ? ` "${title}"` : ""})` }; const nextIndex = i < tokens.length ? i + 1 : tokens.length; return { node, nextIndex }; } function parseMathInlineToken(token) { return { type: "math_inline", content: token.content || "", raw: token.markup === "\\(\\)" ? `\\(${token.content}\\)` : `$$${token.content}$$` }; } function parseReferenceToken(token) { return { type: "reference", id: token.content || "", raw: token.markup || `[${token.content}]` }; } function parseStrikethroughToken(tokens, startIndex) { const children = []; let sText = ""; let i = startIndex + 1; const innerTokens = []; while (i < tokens.length && tokens[i].type !== "s_close") { sText += tokens[i].content || ""; innerTokens.push(tokens[i]); i++; } children.push(...parseInlineTokens(innerTokens)); const node = { type: "strikethrough", children, raw: `~~${sText}~~` }; const nextIndex = i < tokens.length ? i + 1 : tokens.length; return { node, nextIndex }; } function parseStrongToken(tokens, startIndex) { const children = []; let strongText = ""; let i = startIndex + 1; const innerTokens = []; while (i < tokens.length && tokens[i].type !== "strong_close") { strongText += tokens[i].content || ""; innerTokens.push(tokens[i]); i++; } children.push(...parseInlineTokens(innerTokens)); const node = { type: "strong", children, raw: `**${strongText}**` }; const nextIndex = i < tokens.length ? i + 1 : tokens.length; return { node, nextIndex }; } function parseSubscriptToken(tokens, startIndex) { const children = []; let subText = ""; let i = startIndex + 1; const innerTokens = []; while (i < tokens.length && tokens[i].type !== "sub_close") { subText += tokens[i].content || ""; innerTokens.push(tokens[i]); i++; } children.push(...parseInlineTokens(innerTokens)); const node = { type: "subscript", children: children.length > 0 ? children : [ { type: "text", content: tokens[startIndex].content || "", raw: tokens[startIndex].content || "" } ], raw: `~${subText || tokens[startIndex].content || ""}~` }; const nextIndex = i < tokens.length ? i + 1 : tokens.length; return { node, nextIndex }; } function parseSuperscriptToken(tokens, startIndex) { const children = []; let supText = ""; let i = startIndex + 1; const innerTokens = []; while (i < tokens.length && tokens[i].type !== "sup_close") { supText += tokens[i].content || ""; innerTokens.push(tokens[i]); i++; } children.push(...parseInlineTokens(innerTokens)); const node = { type: "superscript", children: children.length > 0 ? children : [ { type: "text", content: tokens[startIndex].content || "", raw: tokens[startIndex].content || "" } ], raw: `^${supText || tokens[startIndex].content || ""}^` }; const nextIndex = i < tokens.length ? i + 1 : tokens.length; return { node, nextIndex }; } function parseTextToken(token) { return { type: "text", content: token.content || "", raw: token.content || "" }; } function parseInlineTokens(tokens) { if (!tokens || tokens.length === 0) return []; const result = []; let currentTextNode = null; let i = 0; while (i < tokens.length) { const token = tokens[i]; switch (token.type) { case "text": { const textNode = parseTextToken(token); if (currentTextNode) { currentTextNode.content += textNode.content; currentTextNode.raw += textNode.raw; } else { currentTextNode = textNode; result.push(currentTextNode); } i++; break; } case "softbreak": if (currentTextNode) { currentTextNode.content += "\n"; currentTextNode.raw += "\n"; } i++; break; case "code_inline": currentTextNode = null; result.push(parseInlineCodeToken(token)); i++; break; case "link_open": { currentTextNode = null; const { node, nextIndex } = parseLinkToken(tokens, i); result.push(node); i = nextIndex; break; } case "image": currentTextNode = null; result.push(parseImageToken(token)); i++; break; case "strong_open": { currentTextNode = null; const { node, nextIndex } = parseStrongToken(tokens, i); result.push(node); i = nextIndex; break; } case "em_open": { currentTextNode = null; const { node, nextIndex } = parseEmphasisToken(tokens, i); result.push(node); i = nextIndex; break; } case "s_open": { currentTextNode = null; const { node, nextIndex } = parseStrikethroughToken(tokens, i); result.push(node); i = nextIndex; break; } case "mark_open": { currentTextNode = null; const { node, nextIndex } = parseHighlightToken(tokens, i); result.push(node); i = nextIndex; break; } case "ins_open": { currentTextNode = null; const { node, nextIndex } = parseInsertToken(tokens, i); result.push(node); i = nextIndex; break; } case "sub_open": { currentTextNode = null; const { node, nextIndex } = parseSubscriptToken(tokens, i); result.push(node); i = nextIndex; break; } case "sup_open": { currentTextNode = null; const { node, nextIndex } = parseSuperscriptToken(tokens, i); result.push(node); i = nextIndex; break; } case "sub": currentTextNode = null; result.push({ type: "subscript", children: [ { type: "text", content: token.content || "", raw: token.content || "" } ], raw: `~${token.content || ""}~` }); i++; break; case "sup": currentTextNode = null; result.push({ type: "superscript", children: [ { type: "text", content: token.content || "", raw: token.content || "" } ], raw: `^${token.content || ""}^` }); i++; break; case "emoji": currentTextNode = null; result.push(parseEmojiToken(token)); i++; break; case "checkbox": currentTextNode = null; result.push(parseCheckboxToken(token)); i++; break; case "footnote_ref": currentTextNode = null; result.push(parseFootnoteRefToken(token)); i++; break; case "hardbreak": currentTextNode = null; result.push(parseHardbreakToken()); i++; break; case "fence": { currentTextNode = null; result.push(parseFenceToken(tokens[i])); i++; break; } case "math_inline": { currentTextNode = null; result.push(parseMathInlineToken(token)); i++; break; } case "reference": { currentTextNode = null; result.push(parseReferenceToken(token)); i++; break; } default: currentTextNode = null; i++; break; } } return result; } function parseBlockquote(tokens, index2) { const blockquoteChildren = []; let j = index2 + 1; while (j < tokens.length && tokens[j].type !== "blockquote_close") { if (tokens[j].type === "paragraph_open") { const contentToken = tokens[j + 1]; blockquoteChildren.push({ type: "paragraph", children: parseInlineTokens(contentToken.children || []), raw: contentToken.content || "" }); j += 3; } else if (tokens[j].type === "bullet_list_open" || tokens[j].type === "ordered_list_open") { const [listNode, newIndex] = parseList(tokens, j); blockquoteChildren.push(listNode); j = newIndex; } else { j++; } } const blockquoteNode = { type: "blockquote", children: blockquoteChildren, raw: blockquoteChildren.map((child) => child.raw).join("\n") }; return [blockquoteNode, j + 1]; } function parseCodeBlock(token) { const match = token.content.match(/ type="application\/vnd\.ant\.([^"]+)"/); if (match == null ? void 0 : match[1]) { token.content = token.content.replace(/<antArtifact[^>]*>/g, "").replace(/<\/antArtifact>/g, ""); } const hasMap = Array.isArray(token.map) && token.map.length === 2; return { type: "code_block", language: match ? match[1] : token.info || "", code: token.content || "", raw: token.content || "", loading: !hasMap }; } function parseDefinitionList(tokens, index2) { const items = []; let j = index2 + 1; let termNodes = []; let definitionNodes = []; while (j < tokens.length && tokens[j].type !== "dl_close") { if (tokens[j].type === "dt_open") { const termToken = tokens[j + 1]; termNodes = parseInlineTokens(termToken.children || []); j += 3; } else if (tokens[j].type === "dd_open") { let k = j + 1; definitionNodes = []; while (k < tokens.length && tokens[k].type !== "dd_close") { if (tokens[k].type === "paragraph_open") { const contentToken = tokens[k + 1]; definitionNodes.push({ type: "paragraph", children: parseInlineTokens(contentToken.children || []), raw: contentToken.content || "" }); k += 3; } else { k++; } } if (termNodes.length > 0) { items.push({ type: "definition_item", term: termNodes, definition: definitionNodes, raw: `${termNodes.map((term) => term.raw).join("")}: ${definitionNodes.map((def) => def.raw).join("\n")}` }); termNodes = []; } j = k + 1; } else { j++; } } const definitionListNode = { type: "definition_list", items, raw: items.map((item) => item.raw).join("\n") }; return [definitionListNode, j + 1]; } function parseFootnote(tokens, index2) { var _a, _b; const token = tokens[index2]; const id = (_b = (_a = token.meta) == null ? void 0 : _a.label) != null ? _b : 0; const footnoteChildren = []; let j = index2 + 1; while (j < tokens.length && tokens[j].type !== "footnote_close") { if (tokens[j].type === "paragraph_open") { const contentToken = tokens[j + 1]; footnoteChildren.push({ type: "paragraph", children: parseInlineTokens(contentToken.children || []), raw: contentToken.content || "" }); j += 3; } else { j++; } } const footnoteNode = { type: "footnote", id, children: footnoteChildren, raw: `[^${id}]: ${footnoteChildren.map((child) => child.raw).join("\n")}` }; return [footnoteNode, j + 1]; } function parseHeading(tokens, index2) { var _a; const token = tokens[index2]; const headingLevel = Number.parseInt(((_a = token.tag) == null ? void 0 : _a.substring(1)) || "1"); const headingContentToken = tokens[index2 + 1]; const headingContent = headingContentToken.content || ""; return { type: "heading", level: headingLevel, text: headingContent, children: parseInlineTokens(headingContentToken.children || []), raw: headingContent }; } function parseMathBlock(token) { return { type: "math_block", content: token.content || "", raw: token.markup === "\\[\\]" ? `\\[${token.content}\\]` : `$$${token.content}$$` }; } function parseTable(tokens, index2) { let j = index2 + 1; let headerRow = null; const rows = []; let isHeader = false; while (j < tokens.length && tokens[j].type !== "table_close") { if (tokens[j].type === "thead_open") { isHeader = true; j++; } else if (tokens[j].type === "thead_close") { isHeader = false; j++; } else if (tokens[j].type === "tbody_open" || tokens[j].type === "tbody_close") { j++; } else if (tokens[j].type === "tr_open") { const cells = []; let k = j + 1; while (k < tokens.length && tokens[k].type !== "tr_close") { if (tokens[k].type === "th_open" || tokens[k].type === "td_open") { const isHeaderCell = tokens[k].type === "th_open"; const contentToken = tokens[k + 1]; const content2 = contentToken.content || ""; cells.push({ type: "table_cell", header: isHeaderCell || isHeader, children: parseInlineTokens(contentToken.children || []), raw: content2 }); k += 3; } else { k++; } } const rowNode = { type: "table_row", cells, raw: cells.map((cell) => cell.raw).join("|") }; if (isHeader) { headerRow = rowNode; } else { rows.push(rowNode); } j = k + 1; } else { j++; } } if (!headerRow) { headerRow = { type: "table_row", cells: [], raw: "" }; } const tableNode = { type: "table", header: headerRow, rows, raw: [headerRow, ...rows].map((row) => row.raw).join("\n") }; return [tableNode, j + 1]; } function parseThematicBreak() { return { type: "thematic_break", raw: "---" }; } function parseList(tokens, index2) { const token = tokens[index2]; const listItems = []; let j = index2 + 1; while (j < tokens.length && tokens[j].type !== "bullet_list_close" && tokens[j].type !== "ordered_list_close") { if (tokens[j].type === "list_item_open") { const itemChildren = []; let k = j + 1; while (k < tokens.length && tokens[k].type !== "list_item_close") { if (tokens[k].type === "paragraph_open") { const contentToken = tokens[k + 1]; itemChildren.push({ type: "paragraph", children: parseInlineTokens(contentToken.children || []), raw: contentToken.content || "" }); k += 3; } else if (tokens[k].type === "blockquote_open") { const [blockquoteNode, newIndex] = parseBlockquote(tokens, k); itemChildren.push(blockquoteNode); k = newIndex; } else if (tokens[k].type === "bullet_list_open" || tokens[k].type === "ordered_list_open") { const [nestedListNode, newIndex] = parseNestedList(tokens, k); itemChildren.push(nestedListNode); k = newIndex; } else if (tokens[k].type === "code_block") { itemChildren.push(parseCodeBlock(tokens[k])); k += 1; } else if (tokens[k].type === "fence") { itemChildren.push(parseFenceToken(tokens[k])); k += 1; } else if (tokens[k].type === "math_block") { itemChildren.push(parseMathBlock(tokens[k])); k += 1; } else if (tokens[k].type === "table_open") { const [tableNode, newIndex] = parseTable(tokens, k); itemChildren.push(tableNode); k = newIndex; } else if (tokens[k].type === "dl_open") { const [defListNode, newIndex] = parseDefinitionList(tokens, k); itemChildren.push(defListNode); k = newIndex; } else if (tokens[k].type === "footnote_open") { const [footnoteNode, newIndex] = parseFootnote(tokens, k); itemChildren.push(footnoteNode); k = newIndex; } else if (tokens[k].type === "heading_open") { const headingNode = parseHeading(tokens, k); itemChildren.push(headingNode); k += 3; } else if (tokens[k].type === "hr") { itemChildren.push(parseThematicBreak()); k += 1; } else if (tokens[k].type === "container_open") { const match = /^::: ?(warning|info|note|tip|danger|caution) ?(.*)$/.exec( tokens[k].info || "" ); if (match) { const [admonitionNode, newIndex] = parseAdmonition(tokens, k, match); itemChildren.push(admonitionNode); k = newIndex; } else { k += 1; } } else { k += 1; } } listItems.push({ type: "list_item", children: itemChildren, raw: itemChildren.map((child) => child.raw).join("") }); j = k + 1; } else { j += 1; } } const listNode = { type: "list", ordered: token.type === "ordered_list_open", items: listItems, raw: listItems.map((item) => item.raw).join("\n") }; return [listNode, j + 1]; } function parseNestedList(tokens, index2) { const nestedToken = tokens[index2]; const nestedItems = []; let j = index2 + 1; while (j < tokens.length && tokens[j].type !== "bullet_list_close" && tokens[j].type !== "ordered_list_close") { if (tokens[j].type === "list_item_open") { const itemChildren = []; let k = j + 1; while (k < tokens.length && tokens[k].type !== "list_item_close") { if (tokens[k].type === "paragraph_open") { const contentToken = tokens[k + 1]; itemChildren.push({ type: "paragraph", children: parseInlineTokens(contentToken.children || []), raw: contentToken.content || "" }); k += 3; } else if (tokens[k].type === "bullet_list_open" || tokens[k].type === "ordered_list_open") { const [deeperNestedListNode, newIndex] = parseNestedList(tokens, k); itemChildren.push(deeperNestedListNode); k = newIndex; } else if (tokens[k].type === "code_block") { itemChildren.push(parseCodeBlock(tokens[k])); k += 1; } else if (tokens[k].type === "fence") { itemChildren.push(parseFenceToken(tokens[k])); k += 1; } else if (tokens[k].type === "math_block") { itemChildren.push(parseMathBlock(tokens[k])); k += 1; } else { k += 1; } } nestedItems.push({ type: "list_item", children: itemChildren, raw: itemChildren.map((child) => child.raw).join("") }); j = k + 1; } else { j += 1; } } const nestedListNode = { type: "list", ordered: nestedToken.type === "ordered_list_open", items: nestedItems, raw: nestedItems.map((item) => item.raw).join("\n") }; return [nestedListNode, j + 1]; } function parseAdmonition(tokens, index2, match) { const kind = match[1] || "note"; const title = match[2] || kind.charAt(0).toUpperCase() + kind.slice(1); const admonitionChildren = []; let j = index2 + 1; while (j < tokens.length && tokens[j].type !== "container_close") { if (tokens[j].type === "paragraph_open") { const contentToken = tokens[j + 1]; admonitionChildren.push({ type: "paragraph", children: parseInlineTokens(contentToken.children || []), raw: contentToken.content || "" }); j += 3; } else if (tokens[j].type === "bullet_list_open" || tokens[j].type === "ordered_list_open") { const [listNode, newIndex] = parseList(tokens, j); admonitionChildren.push(listNode); j = newIndex; } else { j++; } } const admonitionNode = { type: "admonition", kind, title, children: admonitionChildren, raw: `:::${kind} ${title} ${admonitionChildren.map((child) => child.raw).join("\n")} :::` }; return [admonitionNode, j + 1]; } function parseContainer(tokens, index2) { const openToken = tokens[index2]; let kind = "note"; let title = ""; const typeMatch = openToken.type.match(/^container_(\w+)_open$/); if (typeMatch) { kind = typeMatch[1]; const info = (openToken.info || "").trim(); if (info && !info.startsWith(":::")) { const maybe = info.replace(new RegExp(`^${kind}`), "").trim(); if (maybe) title = maybe; } } else { const info = (openToken.info || "").trim(); const match = /^:{1,3}\s*(warning|info|note|tip|danger|caution)\s*(.*)$/i.exec(info); if (match) { kind = match[1]; title = match[2] || ""; } } if (!title) title = kind.charAt(0).toUpperCase() + kind.slice(1); const children = []; let j = index2 + 1; const closeType = new RegExp(`^container_${kind}_close$`); while (j < tokens.length && tokens[j].type !== "container_close" && !closeType.test(tokens[j].type)) { if (tokens[j].type === "paragraph_open") { const contentToken = tokens[j + 1]; children.push({ type: "paragraph", children: parseInlineTokens(contentToken.children || []), raw: contentToken.content || "" }); j += 3; } else if (tokens[j].type === "bullet_list_open" || tokens[j].type === "ordered_list_open") { const [listNode, newIndex] = parseList(tokens, j); children.push(listNode); j = newIndex; } else { j++; } } const admonitionNode = { type: "admonition", kind, title, children, raw: `:::${kind} ${title} ${children.map((c) => c.raw).join("\n")} :::` }; const closingIndex = j; return [admonitionNode, closingIndex + 1]; } function parseHardBreak() { return { type: "hardbreak", raw: "\\\n" }; } function parseParagraph(tokens, index2) { const paragraphContentToken = tokens[index2 + 1]; const paragraphContent = paragraphContentToken.content || ""; return { type: "paragraph", children: parseInlineTokens(paragraphContentToken.children || []), raw: paragraphContent }; } function parseMarkdownToStructure(markdown, md) { const tokens = md.parse(markdown, {}); const result = processTokens(tokens); return result; } function processTokens(tokens) { const result = []; let i = 0; while (i < tokens.length) { const token = tokens[i]; switch (token.type) { case "container_warning_open": case "container_info_open": case "container_note_open": case "container_tip_open": case "container_danger_open": case "container_caution_open": { const [warningNode, newIndex] = parseContainer(tokens, i); result.push(warningNode); i = newIndex; break; } case "heading_open": result.push(parseHeading(tokens, i)); i += 3; break; case "paragraph_open": result.push(parseParagraph(tokens, i)); i += 3; break; case "html_block": case "code_block": result.push(parseCodeBlock(tokens[i])); i += 1; break; case "fence": result.push(parseFenceToken(tokens[i])); i += 1; break; case "bullet_list_open": case "ordered_list_open": { const [listNode, newIndex] = parseList(tokens, i); result.push(listNode); i = newIndex; break; } case "hr": result.push(parseThematicBreak()); i += 1; break; case "blockquote_open": { const [blockquoteNode, newIndex] = parseBlockquote(tokens, i); result.push(blockquoteNode); i = newIndex; break; } case "table_open": { const [tableNode, newIndex] = parseTable(tokens, i); result.push(tableNode); i = newIndex; break; } case "dl_open": { const [definitionListNode, newIndex] = parseDefinitionList(tokens, i); result.push(definitionListNode); i = newIndex; break; } case "footnote_open": { const [footnoteNode, newIndex] = parseFootnote(tokens, i); result.push(footnoteNode); i = newIndex; break; } case "container_open": { const match = /^::: ?(warning|info|note|tip|danger|caution) ?(.*)$/.exec( token.info || "" ); if (match) { const [admonitionNode, newIndex] = parseAdmonition(tokens, i, match); result.push(admonitionNode); i = newIndex; } else { i += 1; } break; } case "hardbreak": result.push(parseHardBreak()); i++; break; case "math_block": result.push(parseMathBlock(tokens[i])); i += 1; break; default: i += 1; break; } } return result; } function applyContainers(md) { [ "admonition", "info", "warning", "tip", "danger", "note", "caution" ].forEach((name) => { md.use(markdownItContainer, name, { render(tokens, idx) { const token = tokens[idx]; if (token.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 startPos = state.bMarks[startLine] + state.tShift[startLine]; const lineMax = state.eMarks[startLine]; const markerMatch = state.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 = state.bMarks[nextLine] + state.tShift[nextLine]; const ePos = state.eMarks[nextLine]; if (state.src.slice(sPos, ePos).trim() === ":::") { found = true; break; } nextLine++; } if (!found) return false; const tokenOpen = state.push("vmr_container_open", "div", 1); tokenOpen.attrSet("class", `vmr-container vmr-container-${name}`); const contentLines = []; for (let i = startLine + 1; i < nextLine; i++) { const sPos = state.bMarks[i] + state.tShift[i]; const ePos = state.eMarks[i]; contentLines.push(state.src.slice(sPos, ePos)); } const inline = state.push("inline", "", 0); inline.content = contentLines.join("\n"); inline.map = [startLine + 1, nextLine]; state.push("paragraph_close", "p", -1); state.push("vmr_container_close", "div", -1); state.line = nextLine + 1; return true; } ); } function applyMath(md) { var _a; const mathInline = (state, silent) => { const delimiters = [ ["\\(", "\\)", true], ["$$", "$$", true] ]; for (const [open, close] of delimiters) { const start = state.pos; if (state.src.slice(start, start + open.length) !== open) continue; const end = state.src.indexOf(close, start + open.length); if (end === -1) continue; if (!silent) { const token = state.push("math_inline", "math", 0); token.content = state.src.slice(start + open.length, end); token.markup = open === "$$" ? "$$" : "\\(\\)"; } state.pos = end + close.length; return true; } return false; }; const mathBlock = (state, startLine, endLine, silent) => { const delimiters = [ ["\\[", "\\]"], ["$$", "$$"], ["[", "]"] ]; const startPos = state.bMarks[startLine] + state.tShift[startLine]; const lineText = state.src.slice(startPos, state.eMarks[startLine]).trim(); let matched = false; let openDelim = ""; let closeDelim = ""; for (const [open, close] of delimiters) { if (lineText === open || lineText.startsWith(open)) { if (open === "[") { if (lineText === "[") { if (startLine + 1 < endLine) { const nextLineStart = state.bMarks[startLine + 1] + state.tShift[startLine + 1]; const nextLineText = state.src.slice( nextLineStart, state.eMarks[startLine + 1] ); const hasMathContent = /\\text|\\frac|\\left|\\right|\\times/.test(nextLineText); if (hasMathContent) { 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 content22 = lineText.slice( startDelimIndex + openDelim.length, endDelimIndex ); const token2 = state.push("math_block", "math", 0); token2.content = normalizeStandaloneBackslashT(content22); token2.markup = openDelim === "$$" ? "$$" : openDelim === "[" ? "[]" : "\\[\\]"; token2.map = [startLine, startLine + 1]; token2.block = true; state.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 = state.bMarks[nextLine] + state.tShift[nextLine] - 1; const lineEnd = state.eMarks[nextLine]; const currentLine = state.src.slice(lineStart, 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; } } if (!found) return false; const token = state.push("math_block", "math", 0); token.content = normalizeStandaloneBackslashT(content2); token.markup = openDelim === "$$" ? "$$" : openDelim === "[" ? "[]" : "\\[\\]"; token.map = [startLine, nextLine + 1]; token.block = true; state.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"] }); md.renderer.rules.math_inline = (tokens, idx) => { const token = tokens[idx]; return `<span class="math-inline">${escapeHtml(token.content)}</span>`; }; md.renderer.rules.math_block = (tokens, idx) => { const token = tokens[idx]; return `<div class="math-block">${escapeHtml(token.content)}</div>`; }; const mathjaxPlugin = (_a = mathjax3__namespace.default) != null ? _a : mathjax3__namespace; md.use(mathjaxPlugin, { tex: { inlineMath: [ ["\\(", "\\)"], ["$", "$"] ], displayMath: [ ["$$", "$$"], ["\\[", "\\]"], ["[", "]"] ], processEscapes: true, processEnvironments: true, processRefs: true } }); function escapeHtml(str) { return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"); } function normalizeStandaloneBackslashT(s) { return s.replace(/(^|[^\\])\t/g, (_m, p1) => `${p1}\\t`).replace(/!/g, "\\!"); } } function applyRenderRules(md) { const defaultImage = md.renderer.rules.image || function(tokens, idx, options, env, self) { return self.renderToken(tokens, idx, options); }; md.renderer.rules.image = (tokens, idx, options, env, self) => { var _a; const token = tokens[idx]; (_a = token.attrSet) == null ? void 0 : _a.call(token, "loading", "lazy"); return defaultImage(tokens, idx, options, env, self); }; md.renderer.rules.fence = md.renderer.rules.fence || ((tokens, idx) => { const token = tokens[idx]; const info = token.info ? token.info.trim() : ""; const langClass = info ? `language-${md.utils.escapeHtml(info.split(/\s+/g)[0])}` : ""; const code = md.utils.escapeHtml(token.content); return `<pre class="${langClass}"><code>${code}</code></pre>`; }); } function getMarkdown$1(opts = {}) { var _a, _b, _c; 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); if ((_c = opts.enableContainers) != null ? _c : true) applyContainers(md); applyRenderRules(md); return md; } function getMarkdown(msgId = `editor-${Date.now()}`, options = {}) { var _a; const md = getMarkdown$1({}); if (Array.isArray(options.plugin)) { for (const p of options.plugin) { if (Array.isArray(p)) md.use(p[0], p[1]); else md.use(p); } } if (Array.isArray(options.apply)) { for (const fn of options.apply) { try { fn(md); } catch (e) { console.error("[getMarkdown] apply function threw an error", e); } } } md.use(markdownItSub); md.use(markdownItSup); md.use(markdownItMark); md.use(markdownItEmoji.full); const markdownItCheckboxPlugin = (_a = markdownItCheckbox__namespace.default) != null ? _a : markdownItCheckbox__namespace; md.use(markdownItCheckboxPlugin); md.use(markdownItIns); md.use(markdownItFootnote); md.core.ruler.after("block", "mark_fence_closed", (state) => { var _a2; const src = state.src; const lines = src.split(/\r?\n/); for (const token of state.tokens) { if (token.type !== "fence" || !token.map || !token.markup) continue; const openLine = token.map[0]; const endLine = token.map[1]; const markup = token.markup; const marker = markup[0]; const minLen = markup.length; const lineIdx = Math.max(0, endLine - 1); const line = (_a2 = lines[lineIdx]) != null ? _a2 : ""; let i = 0; while (i < line.length && (line[i] === " " || line[i] === " ")) i++; let count = 0; while (i + count < line.length && line[i + count] === marker) count++; let j = i + count; while (j < line.length && (line[j] === " " || line[j] === " ")) j++; const closed = endLine > openLine + 1 && count >= minLen && j === line.length; token.meta = token.meta || {}; token.meta.unclosed = !closed; token.meta.closed = !!closed; } }); md.inline.ruler.before( "emphasis", "strong", (state, silent) => { let found = false; let token; let pos = state.pos; const max2 = state.posMax; const start = pos; const marker = state.src.charCodeAt(pos); if (silent) return false; if (marker !== 42 && marker !== 95) return false; let scan = pos; const mem = pos; while (scan < max2 && state.src.charCodeAt(scan) === marker) scan++; const len = scan - pos; if (len < 2) return false; pos = scan; const markerCount = len; while (pos < max2) { if (state.src.charCodeAt(pos) === marker) { if (state.src.slice(pos, pos + markerCount).length === markerCount) { found = true; break; } } pos++; } if (!found) { state.pos = mem; return false; } if (!silent) { state.pos = start + markerCount; token = state.push("strong_open", "strong", 1); token.markup = marker === 42 ? "**" : "__"; token = state.push("text", "", 0); token.content = state.src.slice(start + markerCount, pos); token = state.push("strong_close", "strong", -1); token.markup = marker === 42 ? "**" : "__"; } state.pos = pos + markerCount; return true; } ); const waveRule = (state, silent) => { const start = state.pos; if (state.src[start] !== "~") return false; const prevChar = state.src[start - 1]; const nextChar = state.src[start + 1]; if (/\d/.test(prevChar) && /\d/.test(nextChar)) { if (!silent) { const token = state.push("text", "", 0); token.content = "~"; } state.pos += 1; return true; } return false; }; md.inline.ruler.before("sub", "wave", waveRule); md.renderer.rules.fence = (tokens, idx) => { const { t } = useSafeI18n(); const token = tokens[idx]; const info = token.info ? token.info.trim() : ""; const str = token.content; const encodedCode = btoa(unescape(encodeURIComponent(str))); const language = info || "text"; const uniqueId = `editor-${msgId}-${idx}-${language}`; return `<div class="code-block" data-code="${encodedCode}" data-lang="${language}" id="${uniqueId}"> <div class="code-header"> <span class="code-lang">${language.toUpperCase()}</span> <button class="copy-button" data-code="${encodedCode}">${t( "common.copy" )}</button> </div> <div class="code-editor"></div> </div>`; }; const referenceInline = (state, silent) => { if (state.src[state.pos] !== "[") return false; const match = /^\[(\d+)\]/.exec(state.src.slice(state.pos)); if (!match) return false; if (!silent) { const id = match[1]; const token = state.push("reference", "span", 0); token.content = id; token.markup = match[0]; } state.pos += match[0].length; return true; }; md.inline.ruler.before("escape", "reference", referenceInline); md.renderer.rules.reference = (tokens, idx) => { const id = tokens[idx].content; return `<span class="reference-link" data-reference-id="${id}" role="button" tabindex="0" title="Click to view reference">${id}</span>`; }; return md; } function getCommonMarkdown() { const md = new MarkdownIt({ html: true, linkify: true, typographer: true, breaks: false }); return md; } function renderMarkdown(md, content2) { const html = md.render(content2); const newHTML = html.replace(/\([^)]*\)/g, (match) => { const latex = match.slice(1, -1); try { const data = katex.renderToString(latex, { throwOnError: true, displayMode: false }); return data; } catch (e) { return match; } }); return newHTML; } let nodeComponents = null; function getNodeComponents() { return nodeComponents; } function setNodeComponents(component) { nodeComponents = component; } const _hoisted_1$p = { class: "blockquote", dir: "auto" }; const _sfc_main$v = /* @__PURE__ */ vue.defineComponent({ __name: "BlockquoteNode", props: { node: {} }, emits: ["copy"], setup(__props) { return (_ctx, _cache) => { return vue.openBlock(), vue.createElementBlock("blockquote", _hoisted_1$p, [ vue.createVNode(vue.unref(NodeRenderer), { nodes: _ctx.node.children, onCopy: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("copy", $event)) }, null, 8, ["nodes"]) ]); }; } }); const _export_sfc = (sfc, props) => { const target = sfc.__vccOpts || sfc; for (const [key, val] of props) { target[key] = val; } return target; }; const BlockquoteNode = /* @__PURE__ */ _export_sfc(_sfc_main$v, [["__scopeId", "data-v-ac155173"]]); BlockquoteNode.install = (app) => { a