@incremark/core 0.2.6 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +132 -23
- package/dist/MarkedAstBuildter-BsjxZko_.d.ts +72 -0
- package/dist/detector/index.d.ts +118 -1
- package/dist/detector/index.js +196 -118
- package/dist/detector/index.js.map +1 -1
- package/dist/engines/marked/index.d.ts +29 -0
- package/dist/engines/marked/index.js +1541 -0
- package/dist/engines/marked/index.js.map +1 -0
- package/dist/engines/micromark/index.d.ts +106 -0
- package/dist/engines/micromark/index.js +1161 -0
- package/dist/engines/micromark/index.js.map +1 -0
- package/dist/index-mZ7yCqNH.d.ts +225 -0
- package/dist/index.d.ts +68 -54
- package/dist/index.js +1908 -1198
- package/dist/index.js.map +1 -1
- package/dist/types-C_EW5vfp.d.ts +123 -0
- package/dist/utils/index.d.ts +17 -1
- package/dist/utils/index.js +21 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +18 -3
- package/dist/index-BMUkM7mT.d.ts +0 -422
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/extensions/html-extension/index.ts","../../../src/extensions/micromark-reference-extension.ts","../../../src/extensions/micromark-gfm-footnote-incremental.ts","../../../src/parser/ast/types.ts","../../../src/parser/ast/MicromarkAstBuilder.ts","../../../src/engines/micromark/index.ts"],"names":["match","codes","constants","markdownLineEndingOrSpace","children"],"mappings":"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","file":"index.js","sourcesContent":["import type { Parent, RootContent, Root, PhrasingContent, HTML } from 'mdast'\nimport type { Extension as MdastExtension } from 'mdast-util-from-markdown'\n\ndeclare module 'mdast' {\n interface RootContentMap {\n htmlElement: HtmlElementNode\n }\n interface PhrasingContentMap {\n htmlElement: HtmlElementNode\n }\n}\n\n// ============ 类型定义 ============\n\n/**\n * 自定义 HTML 元素节点类型\n */\nexport interface HtmlElementNode extends Parent {\n type: 'htmlElement'\n tagName: string\n attrs: Record<string, string>\n children: RootContent[]\n data?: {\n rawHtml?: string\n parsed?: boolean\n originalType?: string\n }\n}\n\n/**\n * HTML 属性信息\n */\nexport interface HtmlAttrInfo {\n name: string\n value: string\n}\n\n/**\n * 解析后的 HTML 标签信息\n */\nexport interface ParsedHtmlTag {\n tagName: string\n attrs: Record<string, string>\n isClosing: boolean\n isSelfClosing: boolean\n rawHtml: string\n}\n\n/**\n * HTML 树扩展配置\n */\nexport interface HtmlTreeExtensionOptions {\n /**\n * 标签黑名单 - 这些标签会被过滤掉(XSS 防护)\n * 默认包含危险标签:script, style, iframe, object, embed, form, input, button, textarea, select\n */\n tagBlacklist?: string[]\n \n /**\n * 属性黑名单 - 这些属性会被过滤掉(XSS 防护)\n * 默认包含所有 on* 事件属性和 javascript: 协议\n */\n attrBlacklist?: string[]\n \n /**\n * 协议黑名单 - URL 属性中禁止的协议\n * 默认包含 javascript:, vbscript:, data: (允许 data:image/)\n */\n protocolBlacklist?: string[]\n \n /**\n * 是否保留原始 HTML 在 data 中\n * 默认为 true\n */\n preserveRawHtml?: boolean\n \n /**\n * 自定义标签处理器\n * 可以对特定标签进行自定义处理\n */\n tagHandlers?: Record<string, (node: HtmlElementNode) => HtmlElementNode | null>\n}\n\n// ============ 默认配置 ============\n\n/**\n * 危险标签黑名单(XSS 防护)\n */\nexport const DEFAULT_TAG_BLACKLIST = [\n 'script',\n 'style',\n 'iframe',\n 'object',\n 'embed',\n 'form',\n 'input',\n 'button',\n 'textarea',\n 'select',\n 'meta',\n 'link',\n 'base',\n 'frame',\n 'frameset',\n 'applet',\n 'noscript',\n 'template'\n]\n\n/**\n * 危险属性黑名单(XSS 防护)\n * 包含所有 on* 事件属性\n */\nexport const DEFAULT_ATTR_BLACKLIST = [\n // 事件属性通过正则匹配\n 'formaction',\n 'xlink:href',\n 'xmlns',\n 'srcdoc'\n]\n\n/**\n * 危险协议黑名单\n */\nexport const DEFAULT_PROTOCOL_BLACKLIST = [\n 'javascript:',\n 'vbscript:',\n 'data:' // 注意:data:image/ 会被特殊处理允许\n]\n\n/**\n * URL 类属性列表(需要检查协议)\n */\nconst URL_ATTRS = ['href', 'src', 'action', 'formaction', 'poster', 'background']\n\n// ============ HTML 解析工具 ============\n\n/**\n * HTML 内容类型\n */\nexport type HtmlContentType = 'opening' | 'closing' | 'self-closing' | 'fragment' | 'unknown'\n\n/**\n * 自闭合标签列表\n */\nconst VOID_ELEMENTS = ['br', 'hr', 'img', 'input', 'meta', 'link', 'area', 'base', 'col', 'embed', 'source', 'track', 'wbr']\n\n/**\n * 判断 HTML 内容的类型\n * - opening: 单个开标签,如 <span class=\"foo\">\n * - closing: 单个闭标签,如 </span>\n * - self-closing: 自闭合标签,如 <br /> 或 <img src=\"...\">\n * - fragment: 完整的 HTML 片段,包含多个标签\n * - unknown: 无法识别\n */\nexport function detectHtmlContentType(html: string): HtmlContentType {\n const trimmed = html.trim()\n \n // 空内容\n if (!trimmed) return 'unknown'\n \n // 不是以 < 开头\n if (!trimmed.startsWith('<')) return 'unknown'\n \n // 检查是否是单个闭标签: </tagName>\n const closingMatch = trimmed.match(/^<\\/([a-zA-Z][a-zA-Z0-9-]*)\\s*>$/)\n if (closingMatch) {\n return 'closing'\n }\n \n // 检查是否是单个开标签或自闭合标签\n // 单个标签不应该包含其他 < 字符(除了在属性值中)\n // 使用更精确的匹配:从开头到第一个 > 之间不应该有未转义的 <\n const singleTagMatch = trimmed.match(/^<([a-zA-Z][a-zA-Z0-9-]*)(\\s[^]*?)?(\\/?)>$/)\n if (singleTagMatch) {\n const [fullMatch, tagName, attrsString, selfClosingSlash] = singleTagMatch\n \n // 检查属性字符串中是否有未闭合的 < \n // 如果有,说明这可能是一个片段而不是单个标签\n if (attrsString) {\n // 统计属性字符串中的 < 数量(不在引号内的)\n let inQuote = ''\n let hasUnquotedBracket = false\n for (let i = 0; i < attrsString.length; i++) {\n const char = attrsString[i]\n if (inQuote) {\n if (char === inQuote) inQuote = ''\n } else {\n if (char === '\"' || char === \"'\") inQuote = char\n else if (char === '<') {\n hasUnquotedBracket = true\n break\n }\n }\n }\n if (hasUnquotedBracket) {\n return 'fragment'\n }\n }\n \n // 判断是否是自闭合\n const isSelfClosing = selfClosingSlash === '/' || VOID_ELEMENTS.includes(tagName.toLowerCase())\n return isSelfClosing ? 'self-closing' : 'opening'\n }\n \n // 检查是否包含多个标签(片段)\n // 统计 < 的数量\n let bracketCount = 0\n for (const char of trimmed) {\n if (char === '<') bracketCount++\n }\n if (bracketCount > 1) {\n return 'fragment'\n }\n \n return 'unknown'\n}\n\n/**\n * 解析单个 HTML 标签(开标签、闭标签或自闭合标签)\n * 只处理单个标签,不处理完整的 HTML 片段\n */\nexport function parseHtmlTag(html: string): ParsedHtmlTag | null {\n const trimmed = html.trim()\n const contentType = detectHtmlContentType(trimmed)\n \n // 只处理单个标签\n if (contentType !== 'opening' && contentType !== 'closing' && contentType !== 'self-closing') {\n return null\n }\n \n // 闭标签\n if (contentType === 'closing') {\n const match = trimmed.match(/^<\\/([a-zA-Z][a-zA-Z0-9-]*)\\s*>$/)\n if (!match) return null\n return {\n tagName: match[1].toLowerCase(),\n attrs: {},\n isClosing: true,\n isSelfClosing: false,\n rawHtml: html\n }\n }\n \n // 开标签或自闭合标签\n const match = trimmed.match(/^<([a-zA-Z][a-zA-Z0-9-]*)(\\s[^]*?)?(\\/?)>$/)\n if (!match) return null\n \n const [, tagName, attrsString, selfClosingSlash] = match\n const isSelfClosing = selfClosingSlash === '/' || VOID_ELEMENTS.includes(tagName.toLowerCase())\n \n // 解析属性\n const attrs: Record<string, string> = {}\n if (attrsString) {\n // 匹配属性:name=\"value\", name='value', name=value, name\n const attrRegex = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)\\s*(?:=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s\"'=<>`]+)))?/g\n let attrMatch\n while ((attrMatch = attrRegex.exec(attrsString)) !== null) {\n const [, name, doubleQuoted, singleQuoted, unquoted] = attrMatch\n const value = doubleQuoted ?? singleQuoted ?? unquoted ?? ''\n attrs[name.toLowerCase()] = decodeHtmlEntities(value)\n }\n }\n \n return {\n tagName: tagName.toLowerCase(),\n attrs,\n isClosing: false,\n isSelfClosing,\n rawHtml: html\n }\n}\n\n/**\n * 解码 HTML 实体\n */\nfunction decodeHtmlEntities(text: string): string {\n const entities: Record<string, string> = {\n '&': '&',\n '<': '<',\n '>': '>',\n '"': '\"',\n ''': \"'\",\n ''': \"'\",\n ' ': ' '\n }\n \n return text.replace(/&(?:#(\\d+)|#x([a-fA-F0-9]+)|([a-zA-Z]+));/g, (match, dec, hex, name) => {\n if (dec) return String.fromCharCode(parseInt(dec, 10))\n if (hex) return String.fromCharCode(parseInt(hex, 16))\n return entities[`&${name};`] || match\n })\n}\n\n/**\n * 内部函数:直接解析单个 HTML 标签(不进行类型检测)\n * 用于 parseHtmlFragment 中已经通过正则分离出的标签\n */\nfunction parseTagDirect(tag: string): ParsedHtmlTag | null {\n const trimmed = tag.trim()\n \n // 闭标签\n const closingMatch = trimmed.match(/^<\\/([a-zA-Z][a-zA-Z0-9-]*)\\s*>$/)\n if (closingMatch) {\n return {\n tagName: closingMatch[1].toLowerCase(),\n attrs: {},\n isClosing: true,\n isSelfClosing: false,\n rawHtml: tag\n }\n }\n \n // 开标签或自闭合标签(允许多行属性)\n const openMatch = trimmed.match(/^<([a-zA-Z][a-zA-Z0-9-]*)([\\s\\S]*?)(\\/?)>$/)\n if (!openMatch) return null\n \n const [, tagName, attrsString, selfClosingSlash] = openMatch\n const isSelfClosing = selfClosingSlash === '/' || VOID_ELEMENTS.includes(tagName.toLowerCase())\n \n // 解析属性\n const attrs: Record<string, string> = {}\n if (attrsString) {\n // 匹配属性:name=\"value\", name='value', name=value, name\n const attrRegex = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)\\s*(?:=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s\"'=<>`]+)))?/g\n let attrMatch\n while ((attrMatch = attrRegex.exec(attrsString)) !== null) {\n const [, name, doubleQuoted, singleQuoted, unquoted] = attrMatch\n const value = doubleQuoted ?? singleQuoted ?? unquoted ?? ''\n attrs[name.toLowerCase()] = decodeHtmlEntities(value)\n }\n }\n \n return {\n tagName: tagName.toLowerCase(),\n attrs,\n isClosing: false,\n isSelfClosing,\n rawHtml: tag\n }\n}\n\n/**\n * 解析完整的 HTML 片段为 AST\n */\nexport function parseHtmlFragment(html: string, options: HtmlTreeExtensionOptions = {}): HtmlElementNode[] {\n const result: HtmlElementNode[] = []\n const stack: HtmlElementNode[] = []\n \n // 使用正则逐个提取标签和文本\n const tokenRegex = /(<\\/?[a-zA-Z][^>]*>)|([^<]+)/g\n let match\n \n while ((match = tokenRegex.exec(html)) !== null) {\n const [, tag, text] = match\n \n if (tag) {\n // 使用 parseTagDirect 直接解析,避免类型检测误判\n const parsed = parseTagDirect(tag)\n if (!parsed) continue\n \n // 检查标签黑名单\n if (isTagBlacklisted(parsed.tagName, options)) {\n continue\n }\n \n if (parsed.isClosing) {\n // 结束标签:向上查找匹配的开始标签\n let found = false\n for (let i = stack.length - 1; i >= 0; i--) {\n if (stack[i].tagName === parsed.tagName) {\n // 找到匹配,弹出并关闭\n const node = stack.pop()!\n if (stack.length > 0) {\n stack[stack.length - 1].children.push(node)\n } else {\n result.push(node)\n }\n found = true\n break\n }\n }\n // 未找到匹配的开始标签,忽略该结束标签\n if (!found) continue\n } else {\n // 开始标签或自闭合标签\n const sanitizedAttrs = sanitizeAttrs(parsed.attrs, options)\n \n const node: HtmlElementNode = {\n type: 'htmlElement',\n tagName: parsed.tagName,\n attrs: sanitizedAttrs,\n children: [],\n data: options.preserveRawHtml !== false ? {\n rawHtml: tag,\n parsed: true\n } : undefined\n }\n \n if (parsed.isSelfClosing) {\n // 自闭合标签直接添加\n if (stack.length > 0) {\n stack[stack.length - 1].children.push(node)\n } else {\n result.push(node)\n }\n } else {\n // 开始标签,入栈\n stack.push(node)\n }\n }\n } else if (text && text.trim()) {\n // 文本节点\n const textNode: RootContent = {\n type: 'text',\n value: text\n } as RootContent\n \n if (stack.length > 0) {\n stack[stack.length - 1].children.push(textNode)\n }\n // 顶层纯文本不处理(应该已经被 markdown 解析器处理)\n }\n }\n \n // 处理未闭合的标签(从栈中弹出)\n while (stack.length > 0) {\n const node = stack.pop()!\n if (stack.length > 0) {\n stack[stack.length - 1].children.push(node)\n } else {\n result.push(node)\n }\n }\n \n return result\n}\n\n// ============ XSS 防护 ============\n\n/**\n * 检查标签是否在黑名单中\n */\nfunction isTagBlacklisted(tagName: string, options: HtmlTreeExtensionOptions): boolean {\n const blacklist = options.tagBlacklist ?? DEFAULT_TAG_BLACKLIST\n return blacklist.includes(tagName.toLowerCase())\n}\n\n/**\n * 检查属性是否在黑名单中\n */\nfunction isAttrBlacklisted(attrName: string, options: HtmlTreeExtensionOptions): boolean {\n const name = attrName.toLowerCase()\n const blacklist = options.attrBlacklist ?? DEFAULT_ATTR_BLACKLIST\n \n // 检查 on* 事件属性\n if (name.startsWith('on')) return true\n \n return blacklist.includes(name)\n}\n\n/**\n * 检查 URL 是否包含危险协议\n */\nfunction isProtocolDangerous(url: string, options: HtmlTreeExtensionOptions): boolean {\n const protocolBlacklist = options.protocolBlacklist ?? DEFAULT_PROTOCOL_BLACKLIST\n const normalizedUrl = url.trim().toLowerCase()\n \n for (const protocol of protocolBlacklist) {\n if (normalizedUrl.startsWith(protocol)) {\n // 特殊处理:允许 data:image/\n if (protocol === 'data:' && normalizedUrl.startsWith('data:image/')) {\n return false\n }\n return true\n }\n }\n \n return false\n}\n\n/**\n * 清理属性,移除危险属性\n */\nfunction sanitizeAttrs(\n attrs: Record<string, string>,\n options: HtmlTreeExtensionOptions\n): Record<string, string> {\n const result: Record<string, string> = {}\n \n for (const [name, value] of Object.entries(attrs)) {\n // 检查属性黑名单\n if (isAttrBlacklisted(name, options)) continue\n \n // 检查 URL 属性的协议\n if (URL_ATTRS.includes(name.toLowerCase())) {\n if (isProtocolDangerous(value, options)) continue\n }\n \n result[name] = value\n }\n \n return result\n}\n\n// ============ AST 转换器 ============\n\n/**\n * 检查是否是 HTML 节点\n */\nfunction isHtmlNode(node: RootContent): node is HTML {\n return node.type === 'html'\n}\n\n/**\n * 检查节点是否有子节点\n */\nfunction hasChildren(node: RootContent | Root): node is Parent & RootContent {\n return 'children' in node && Array.isArray((node as Parent).children)\n}\n\n/**\n * 预处理:合并被空行分割的 HTML 节点\n *\n * CommonMark 规范中,HTML 块会在空行处被截断,导致:\n * - `<div>\\ncontent` 和 `</div>` 被分成独立的 HTML 节点\n *\n * 此函数通过追踪未闭合的标签,将分散的 HTML 节点合并回完整的片段\n */\nfunction mergeFragmentedHtmlNodes(nodes: RootContent[]): RootContent[] {\n const result: RootContent[] = []\n let i = 0\n\n\n while (i < nodes.length) {\n const node = nodes[i]\n\n if (!isHtmlNode(node)) {\n result.push(node)\n i++\n continue\n }\n\n // 检测当前 HTML 节点中是否有未闭合的标签\n const unclosedTags = findUnclosedTags(node.value)\n\n if (unclosedTags.length === 0) {\n // 没有未闭合标签,直接添加\n result.push(node)\n i++\n continue\n }\n\n // 有未闭合标签,尝试向后查找闭合标签\n const mergedParts: string[] = [node.value]\n let j = i + 1\n let currentUnclosed = [...unclosedTags]\n\n while (j < nodes.length && currentUnclosed.length > 0) {\n const nextNode = nodes[j]\n\n if (isHtmlNode(nextNode)) {\n // 检查这个节点是否包含我们需要的闭合标签\n const closingInfo = checkClosingTags(nextNode.value, currentUnclosed)\n\n if (closingInfo.hasRelevantClosing) {\n mergedParts.push(nextNode.value)\n currentUnclosed = closingInfo.remainingUnclosed\n\n if (currentUnclosed.length === 0) {\n // 所有标签都已闭合,停止合并\n j++\n break\n }\n } else {\n // 这个 HTML 节点不包含我们需要的闭合标签\n // 但可能是中间内容,也需要包含\n mergedParts.push(nextNode.value)\n }\n } else {\n // 非 HTML 节点(可能是 paragraph 等),停止合并\n // 因为这意味着内容结构已经改变\n break\n }\n\n j++\n }\n\n if (mergedParts.length > 1) {\n // 成功合并了多个节点\n const mergedValue = mergedParts.join('\\n')\n const mergedNode: HTML = {\n type: 'html',\n value: mergedValue\n }\n result.push(mergedNode)\n i = j\n } else {\n // 无法合并,保留原节点\n result.push(node)\n i++\n }\n }\n\n return result\n}\n\n/**\n * 查找 HTML 内容中未闭合的标签\n */\nfunction findUnclosedTags(html: string): string[] {\n const tagStack: string[] = []\n\n // 匹配所有标签\n const tagRegex = /<\\/?([a-zA-Z][a-zA-Z0-9-]*)[^>]*\\/?>/g\n let match\n\n while ((match = tagRegex.exec(html)) !== null) {\n const fullTag = match[0]\n const tagName = match[1].toLowerCase()\n\n // 跳过自闭合标签\n if (VOID_ELEMENTS.includes(tagName) || fullTag.endsWith('/>')) {\n continue\n }\n\n if (fullTag.startsWith('</')) {\n // 闭合标签\n const lastIndex = tagStack.lastIndexOf(tagName)\n if (lastIndex !== -1) {\n tagStack.splice(lastIndex, 1)\n }\n } else {\n // 开标签\n tagStack.push(tagName)\n }\n }\n\n return tagStack\n}\n\n/**\n * 检查 HTML 内容中是否包含指定标签的闭合标签\n */\nfunction checkClosingTags(\n html: string,\n unclosedTags: string[]\n): { hasRelevantClosing: boolean; remainingUnclosed: string[] } {\n const remaining = [...unclosedTags]\n let hasRelevant = false\n\n // 匹配闭合标签\n const closeTagRegex = /<\\/([a-zA-Z][a-zA-Z0-9-]*)\\s*>/g\n let match\n\n while ((match = closeTagRegex.exec(html)) !== null) {\n const tagName = match[1].toLowerCase()\n const index = remaining.lastIndexOf(tagName)\n if (index !== -1) {\n remaining.splice(index, 1)\n hasRelevant = true\n }\n }\n\n return {\n hasRelevantClosing: hasRelevant,\n remainingUnclosed: remaining\n }\n}\n\n/**\n * 处理 HTML 节点数组,将开始标签、内容、结束标签合并为结构化节点\n */\nfunction processHtmlNodesInArray(\n nodes: RootContent[],\n options: HtmlTreeExtensionOptions\n): RootContent[] {\n // 预处理:合并被空行分割的 HTML 节点\n const mergedNodes = mergeFragmentedHtmlNodes(nodes)\n\n const result: RootContent[] = []\n let i = 0\n \n while (i < mergedNodes.length) {\n const node = mergedNodes[i]\n \n if (isHtmlNode(node)) {\n // 首先检测 HTML 内容类型\n const contentType = detectHtmlContentType(node.value)\n \n if (contentType === 'fragment') {\n // 完整的 HTML 片段,解析为 HTML 树\n const fragmentNodes = parseHtmlFragment(node.value, options)\n if (fragmentNodes.length > 0) {\n result.push(...fragmentNodes)\n } else {\n // 无法解析,保留原节点\n result.push(node)\n }\n i++\n } else if (contentType === 'self-closing') {\n // 自闭合标签\n const parsed = parseHtmlTag(node.value)\n if (parsed && !isTagBlacklisted(parsed.tagName, options)) {\n const elementNode: HtmlElementNode = {\n type: 'htmlElement',\n tagName: parsed.tagName,\n attrs: sanitizeAttrs(parsed.attrs, options),\n children: [],\n data: options.preserveRawHtml !== false ? {\n rawHtml: node.value,\n parsed: true,\n originalType: 'html'\n } : undefined\n }\n result.push(elementNode)\n }\n i++\n } else if (contentType === 'closing') {\n // 孤立的结束标签,跳过(通常已被开标签处理)\n i++\n } else if (contentType === 'opening') {\n // 开始标签:收集子节点直到找到对应的结束标签\n const parsed = parseHtmlTag(node.value)\n if (!parsed || isTagBlacklisted(parsed.tagName, options)) {\n i++\n continue\n }\n \n const tagName = parsed.tagName\n const contentNodes: RootContent[] = []\n let depth = 1\n let j = i + 1\n let foundClosing = false\n \n while (j < mergedNodes.length && depth > 0) {\n const nextNode = mergedNodes[j]\n \n if (isHtmlNode(nextNode)) {\n const nextType = detectHtmlContentType(nextNode.value)\n \n if (nextType === 'closing') {\n const nextParsed = parseHtmlTag(nextNode.value)\n if (nextParsed && nextParsed.tagName === tagName) {\n depth--\n if (depth === 0) {\n foundClosing = true\n break\n }\n }\n } else if (nextType === 'opening') {\n const nextParsed = parseHtmlTag(nextNode.value)\n if (nextParsed && nextParsed.tagName === tagName) {\n depth++\n }\n }\n // fragment 和 self-closing 不影响深度\n }\n \n contentNodes.push(nextNode)\n j++\n }\n \n // 创建结构化节点\n const elementNode: HtmlElementNode = {\n type: 'htmlElement',\n tagName: parsed.tagName,\n attrs: sanitizeAttrs(parsed.attrs, options),\n children: processHtmlNodesInArray(contentNodes, options),\n data: options.preserveRawHtml !== false ? {\n rawHtml: node.value,\n parsed: true,\n originalType: 'html'\n } : undefined\n }\n \n result.push(elementNode)\n i = foundClosing ? j + 1 : j\n } else {\n // unknown 类型,保留原节点\n result.push(node)\n i++\n }\n } else {\n // 非 HTML 节点,递归处理子节点\n if (hasChildren(node)) {\n const processed = processHtmlNodesInArray(\n (node as Parent).children as RootContent[],\n options\n )\n result.push({\n ...node,\n children: processed\n } as RootContent)\n } else {\n result.push(node)\n }\n i++\n }\n }\n \n return result\n}\n\n/**\n * 转换整个 AST,处理所有 HTML 节点\n */\nexport function transformHtmlNodes(ast: Root, options: HtmlTreeExtensionOptions = {}): Root {\n return {\n ...ast,\n children: processHtmlNodesInArray(ast.children, options) as Root['children']\n }\n}\n\n/**\n * 创建 HTML 树转换器\n * 这是一个 unified 兼容的转换器\n */\nexport function createHtmlTreeTransformer(options: HtmlTreeExtensionOptions = {}) {\n return function transformer(tree: Root): Root {\n return transformHtmlNodes(tree, options)\n }\n}\n\n// ============ mdast 扩展(用于 fromMarkdown) ============\n\n/**\n * mdast-util-from-markdown 扩展\n * 注意:此扩展主要用于类型声明,实际转换在后处理阶段完成\n */\nexport const htmlTreeExtension: MdastExtension = {\n enter: {},\n exit: {}\n}\n\n// ============ 便捷工具函数 ============\n\n/**\n * 判断节点是否是 HtmlElementNode\n */\nexport function isHtmlElementNode(node: RootContent): node is HtmlElementNode {\n return node.type === 'htmlElement'\n}\n\n/**\n * 遍历所有 HTML 元素节点\n */\nexport function walkHtmlElements(\n node: RootContent | Root,\n callback: (node: HtmlElementNode, parent: Parent | Root | null) => void,\n parent: Parent | Root | null = null\n): void {\n if (isHtmlElementNode(node as RootContent)) {\n callback(node as HtmlElementNode, parent)\n }\n \n if (hasChildren(node as RootContent) || node.type === 'root') {\n const children = (node as Parent | Root).children\n for (const child of children) {\n walkHtmlElements(child, callback, node as Parent | Root)\n }\n }\n}\n\n/**\n * 查找特定标签的所有节点\n */\nexport function findHtmlElementsByTag(\n root: Root,\n tagName: string\n): HtmlElementNode[] {\n const result: HtmlElementNode[] = []\n \n walkHtmlElements(root, (node) => {\n if (node.tagName === tagName.toLowerCase()) {\n result.push(node)\n }\n })\n \n return result\n}\n\n/**\n * 将 HtmlElementNode 转回 HTML 字符串\n */\nexport function htmlElementToString(node: HtmlElementNode): string {\n const { tagName, attrs, children } = node\n \n // 构建属性字符串\n const attrsStr = Object.entries(attrs)\n .map(([name, value]) => {\n if (value === '') return name\n return `${name}=\"${escapeHtml(value)}\"`\n })\n .join(' ')\n \n const openTag = attrsStr ? `<${tagName} ${attrsStr}>` : `<${tagName}>`\n \n // 自闭合标签\n if (children.length === 0 && isSelfClosingTag(tagName)) {\n return attrsStr ? `<${tagName} ${attrsStr} />` : `<${tagName} />`\n }\n \n // 递归处理子节点\n const childrenStr = children.map(child => {\n if (child.type === 'text') {\n return (child as { value: string }).value\n }\n if (isHtmlElementNode(child)) {\n return htmlElementToString(child)\n }\n // 其他节点类型保持原样(实际使用中可能需要扩展)\n return ''\n }).join('')\n \n return `${openTag}${childrenStr}</${tagName}>`\n}\n\n/**\n * 检查是否是自闭合标签\n */\nfunction isSelfClosingTag(tagName: string): boolean {\n return ['br', 'hr', 'img', 'input', 'meta', 'link', 'area', 'base', 'col', 'embed', 'source', 'track', 'wbr'].includes(tagName.toLowerCase())\n}\n\n/**\n * HTML 转义\n */\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n}\n\n// ============ 导出 ============\n\nexport {\n DEFAULT_TAG_BLACKLIST as HTML_TAG_BLACKLIST,\n DEFAULT_ATTR_BLACKLIST as HTML_ATTR_BLACKLIST,\n DEFAULT_PROTOCOL_BLACKLIST as HTML_PROTOCOL_BLACKLIST\n}\n","/**\n * @file Micromark 扩展:支持增量解析的 Reference 语法\n * \n * @description\n * 在增量解析场景中,引用式图片/链接(如 `![Alt][id]`)可能在定义(`[id]: url`)之前出现。\n * 标准 micromark 会检查 parser.defined,如果 id 未定义就解析为文本。\n * \n * 本扩展通过覆盖 labelEnd 构造,移除 parser.defined 检查,\n * 使得 reference 语法总是被解析为 reference token,\n * 由渲染层根据实际的 definitionMap 决定如何渲染。\n * \n * @module micromark-reference-extension\n * \n * @features\n * - ✅ 支持所有 resource 语法(带 title 的图片/链接)\n * - ✅ 支持所有 reference 语法(full, collapsed, shortcut)\n * - ✅ 延迟验证:解析时不检查定义是否存在\n * - ✅ 使用官方 factory 函数,保证与 CommonMark 标准一致\n * \n * @dependencies\n * - micromark-factory-destination: 解析 URL(支持尖括号、括号平衡)\n * - micromark-factory-title: 解析 title(支持三种引号,支持多行)\n * - micromark-factory-label: 解析 label(支持转义、长度限制)\n * - micromark-factory-whitespace: 解析空白符(正确生成 lineEnding/linePrefix token)\n * - micromark-util-character: 字符判断工具\n * - micromark-util-symbol: 常量(codes, types, constants)\n * - micromark-util-types: TypeScript 类型定义\n * \n * @see {@link https://github.com/micromark/micromark} - micromark 官方文档\n * @see {@link https://spec.commonmark.org/0.30/#images} - CommonMark 图片规范\n * @see {@link https://spec.commonmark.org/0.30/#links} - CommonMark 链接规范\n * \n * @example\n * ```typescript\n * import { micromarkReferenceExtension } from './micromark-reference-extension'\n * import { fromMarkdown } from 'mdast-util-from-markdown'\n * \n * const extensions = [micromarkReferenceExtension()]\n * const ast = fromMarkdown(text, { extensions })\n * ```\n * \n * @author Incremark Team\n * @license MIT\n */\n\nimport type {\n Code,\n Construct,\n Extension,\n Event,\n Resolver,\n State,\n TokenizeContext,\n Tokenizer,\n Token\n} from 'micromark-util-types'\nimport { codes, types, constants } from 'micromark-util-symbol'\nimport { \n markdownLineEnding, \n markdownSpace, \n markdownLineEndingOrSpace \n} from 'micromark-util-character'\nimport { factoryDestination } from 'micromark-factory-destination'\nimport { factoryTitle } from 'micromark-factory-title'\nimport { factoryLabel } from 'micromark-factory-label'\nimport { factoryWhitespace } from 'micromark-factory-whitespace'\n\n/**\n * 创建支持增量解析的 reference 扩展\n * \n * 这个扩展覆盖了 micromark-core-commonmark 中的 labelEnd 构造,\n * 移除了对 parser.defined 的检查,使得 reference 语法总是被解析为 reference token,\n * 即使对应的 definition 尚未出现。\n * \n * @returns Micromark 扩展对象\n * \n * @remarks\n * - labelEnd 在 text 中注册,键是 `codes.rightSquareBracket`(']')\n * - 我们使用相同的键来覆盖它\n * - 根据 combineExtensions 的逻辑,后添加的扩展会先被尝试\n * \n * @example\n * ```typescript\n * // 在 IncremarkParser 中使用\n * const extensions = [\n * gfm(),\n * micromarkReferenceExtension() // 最后添加,确保覆盖\n * ]\n * const ast = fromMarkdown(text, { extensions })\n * ```\n */\nexport function micromarkReferenceExtension(): Extension {\n // 关键:不使用 disable,直接覆盖\n // 根据 combineExtensions 的逻辑,后添加的扩展会先被尝试(before 数组会被插入到 existing 的开头)\n return {\n // 在 text 中使用 codes.rightSquareBracket 键覆盖 labelEnd\n text: {\n [codes.rightSquareBracket]: {\n name: 'labelEnd',\n resolveAll: resolveAllLabelEnd,\n resolveTo: resolveToLabelEnd,\n tokenize: tokenizeLabelEnd,\n // 添加 add: 'before' 确保先被尝试\n add: 'before'\n } as Construct\n }\n }\n}\n\n/**\n * Resolve all label end events.\n * 从原始代码复制,保持不变。\n */\nfunction resolveAllLabelEnd(events: Event[]): Event[] {\n let index = -1\n const newEvents: Event[] = []\n while (++index < events.length) {\n const token = events[index][1]\n newEvents.push(events[index])\n\n if (\n token.type === types.labelImage ||\n token.type === types.labelLink ||\n token.type === types.labelEnd\n ) {\n // Remove the marker.\n const offset = token.type === types.labelImage ? 4 : 2\n token.type = types.data\n index += offset\n }\n }\n\n // If the events are equal, we don't have to copy newEvents to events\n if (events.length !== newEvents.length) {\n // 简化:直接替换\n events.length = 0\n events.push(...newEvents)\n }\n\n return events\n}\n\n/**\n * Resolve to label end.\n * 这是关键函数,负责将 labelEnd 和 reference 关联到 image/link。\n * 需要完整实现,否则 mdast 无法找到 image/link token。\n */\nfunction resolveToLabelEnd(events: Event[], context: any): Event[] {\n let index = events.length\n let offset = 0\n /** @type {any} */\n let token: any\n /** @type {number | undefined} */\n let open: number | undefined\n /** @type {number | undefined} */\n let close: number | undefined\n /** @type {Array<Event>} */\n let media: Event[]\n\n // Find an opening.\n while (index--) {\n token = events[index][1]\n\n if (open !== undefined) {\n // If we see another link, or inactive link label, we've been here before.\n if (\n token.type === types.link ||\n (token.type === types.labelLink && token._inactive)\n ) {\n break\n }\n\n // Mark other link openings as inactive, as we can't have links in links.\n if (events[index][0] === 'enter' && token.type === types.labelLink) {\n token._inactive = true\n }\n } else if (close !== undefined) {\n if (\n events[index][0] === 'enter' &&\n (token.type === types.labelImage || token.type === types.labelLink) &&\n !token._balanced\n ) {\n open = index\n\n if (token.type !== types.labelLink) {\n offset = 2\n break\n }\n }\n } else if (token.type === types.labelEnd) {\n close = index\n }\n }\n\n if (open === undefined || close === undefined) {\n // 如果没有找到匹配的 open 和 close,直接返回\n return events\n }\n\n const group = {\n type: events[open][1].type === types.labelLink ? types.link : types.image,\n start: {...events[open][1].start},\n end: {...events[events.length - 1][1].end}\n }\n\n const label = {\n type: types.label,\n start: {...events[open][1].start},\n end: {...events[close][1].end}\n }\n\n const text = {\n type: types.labelText,\n start: {...events[open + offset + 2][1].end},\n end: {...events[close - 2][1].start}\n }\n\n media = [\n ['enter', group, context],\n ['enter', label, context]\n ]\n\n // Opening marker.\n media.push(...events.slice(open + 1, open + offset + 3))\n\n // Text open.\n media.push(['enter', text, context])\n\n // Between (label text content)\n // 简化:直接使用 events,不调用 resolveAll\n media.push(...events.slice(open + offset + 4, close - 3))\n\n // Text close, marker close, label close.\n media.push(\n ['exit', text, context],\n events[close - 2],\n events[close - 1],\n ['exit', label, context]\n )\n\n // Reference, resource, or so.\n media.push(...events.slice(close + 1))\n\n // Media close.\n media.push(['exit', group, context])\n\n // 替换 events\n events.splice(open, events.length - open, ...media)\n\n return events\n}\n\n/**\n * Tokenize label end,支持增量解析\n * \n * 关键修改:\n * 1. 移除了对 parser.defined 的检查\n * 2. 在 after 函数中,总是尝试解析为 reference\n * 3. 在 referenceFullAfter 中,总是返回 ok\n * \n * 注意:这是一个简化实现,主要目的是让 reference 语法总是被解析为 reference token。\n * 完整的实现需要 factoryLabel、factoryDestination 等工具函数,但这些不在公共 npm 包中。\n * 这个简化版本应该能够处理基本的 reference 语法。\n */\nfunction tokenizeLabelEnd(\n this: TokenizeContext,\n effects: Parameters<Tokenizer>[0],\n ok: State,\n nok: State\n): State {\n const self = this\n let index = self.events.length\n /** @type {any} */\n let labelStart: any\n\n // Find an opening.\n while (index--) {\n if (\n (self.events[index][1].type === types.labelImage ||\n self.events[index][1].type === types.labelLink) &&\n !self.events[index][1]._balanced\n ) {\n labelStart = self.events[index][1]\n break\n }\n }\n\n return start as State\n\n /**\n * Start of label end.\n */\n function start(code: Code): State | void {\n // If there is not an okay opening.\n if (!labelStart) {\n return nok(code)\n }\n\n // If the corresponding label (link) start is marked as inactive,\n // it means we'd be wrapping a link, like this:\n //\n // ```markdown\n // > | a [b [c](d) e](f) g.\n // ^\n // ```\n //\n // We can't have that, so it's just balanced brackets.\n if (labelStart._inactive) {\n return labelEndNok(code)\n }\n\n // 检测脚注引用:如果标签以 ^ 开头,交给 GFM 脚注扩展处理\n // 注意:这里只检查 labelLink,不检查 labelImage\n // 因为脚注引用是 [^1],不是 ![^1]\n if (labelStart.type === types.labelLink) {\n const labelText = self.sliceSerialize({start: labelStart.end, end: self.now()})\n if (labelText.startsWith('^')) {\n // 这是脚注引用,交给 GFM 脚注扩展处理\n return nok(code)\n }\n }\n\n // 关键修改:移除了对 parser.defined 的检查\n // 原始代码会检查:\n // defined = self.parser.defined.includes(\n // normalizeIdentifier(\n // self.sliceSerialize({start: labelStart.end, end: self.now()})\n // )\n // )\n\n effects.enter(types.labelEnd)\n effects.enter(types.labelMarker)\n effects.consume(code)\n effects.exit(types.labelMarker)\n effects.exit(types.labelEnd)\n return after as State\n }\n\n /**\n * After `]`.\n */\n function after(code: Code): State | void {\n // Resource (`[asd](fgh)`)?\n if (code === codes.leftParenthesis) {\n // 对于 resource,保持原始逻辑(总是尝试解析)\n // 注意:resource 不依赖于 definition,所以应该总是能正确解析\n // 如果解析失败,返回 labelEndNok,避免被错误解析为 shortcut reference\n return effects.attempt(\n {\n tokenize: tokenizeResource,\n partial: false\n },\n labelEndOk as State,\n labelEndNok as State // 修复:resource 解析失败时返回 nok\n )(code)\n }\n\n // Full (`[asd][fgh]`) or collapsed (`[asd][]`) reference?\n if (code === codes.leftSquareBracket) {\n // 关键修改:总是尝试解析为 reference,不检查 defined\n return effects.attempt(\n {\n tokenize: tokenizeReferenceFull,\n partial: false\n },\n labelEndOk as State,\n referenceNotFull as State // 修改:即使不是 full reference,也尝试 collapsed\n )(code)\n }\n\n // Shortcut (`[asd]`) reference?\n // 关键修改:总是返回 ok,让后续处理\n return labelEndOk(code) as State\n }\n\n /**\n * After `]`, at `[`, but not at a full reference.\n */\n function referenceNotFull(code: Code): State | void {\n return effects.attempt(\n {\n tokenize: tokenizeReferenceCollapsed,\n partial: false\n },\n labelEndOk as State,\n labelEndOk as State // 修改:即使失败也返回 ok\n )(code)\n }\n\n /**\n * Done, we found something.\n */\n function labelEndOk(code: Code): State | void {\n return ok(code) as State\n }\n\n /**\n * Done, it's nothing.\n */\n function labelEndNok(code: Code): State | void {\n labelStart._balanced = true\n return nok(code)\n }\n}\n\n/**\n * 解析 resource 语法:[text](url) 或 [text](url \"title\")\n * \n * 支持的语法:\n * - [text](url)\n * - [text](url \"title\")\n * - [text](url 'title')\n * - [text](url (title))\n * - [text](<url with spaces>)\n * - [text](url \"title with \\\"escaped\\\"\")\n * \n * 完整实现:使用官方 factory 函数保证与 CommonMark 标准一致\n * \n * @param effects - Token 生成器\n * @param ok - 成功时的状态函数\n * @param nok - 失败时的状态函数\n * @returns 起始状态函数\n */\nfunction tokenizeResource(\n this: TokenizeContext,\n effects: Parameters<Tokenizer>[0],\n ok: State,\n nok: State\n): State {\n return resourceStart\n\n /**\n * 在 resource 起始位置,期望 '('\n * \n * ```markdown\n * > | [a](b) c\n * ^\n * ```\n * \n * @param code - 当前字符编码\n */\n function resourceStart(code: Code): State | undefined {\n if (code !== codes.leftParenthesis) {\n return nok(code)\n }\n \n effects.enter(types.resource)\n effects.enter(types.resourceMarker)\n effects.consume(code)\n effects.exit(types.resourceMarker)\n return resourceBefore\n }\n\n /**\n * 在 '(' 之后,可能有空白符\n * \n * ```markdown\n * > | [a]( b) c\n * ^\n * ```\n * \n * @param code - 当前字符编码\n */\n function resourceBefore(code: Code): State | undefined {\n return markdownLineEndingOrSpace(code)\n ? factoryWhitespace(effects, resourceOpen)(code)\n : resourceOpen(code)\n }\n\n /**\n * 在空白符之后,期望 destination 或 ')'\n * \n * ```markdown\n * > | [a](b) c\n * ^\n * ```\n * \n * @param code - 当前字符编码\n */\n function resourceOpen(code: Code): State | undefined {\n // 空 resource: [text]()\n if (code === codes.rightParenthesis) {\n return resourceEnd(code)\n }\n\n // 使用官方 factoryDestination 解析 URL\n return factoryDestination(\n effects,\n resourceDestinationAfter,\n resourceDestinationMissing,\n types.resourceDestination,\n types.resourceDestinationLiteral,\n types.resourceDestinationLiteralMarker,\n types.resourceDestinationRaw,\n types.resourceDestinationString,\n constants.linkResourceDestinationBalanceMax\n )(code)\n }\n\n /**\n * 在 destination 之后,可能有空白符或 title\n * \n * ```markdown\n * > | [a](b ) c\n * ^\n * ```\n * \n * @param code - 当前字符编码\n */\n function resourceDestinationAfter(code: Code): State | undefined {\n return markdownLineEndingOrSpace(code)\n ? factoryWhitespace(effects, resourceBetween)(code)\n : resourceEnd(code)\n }\n\n /**\n * Destination 解析失败(格式错误)\n * \n * ```markdown\n * > | [a](<<) b\n * ^\n * ```\n * \n * @param code - 当前字符编码\n */\n function resourceDestinationMissing(code: Code): State | undefined {\n return nok(code)\n }\n\n /**\n * 在 destination 和空白符之后,可能有 title\n * \n * ```markdown\n * > | [a](b \"c\") d\n * ^\n * ```\n * \n * @param code - 当前字符编码\n */\n function resourceBetween(code: Code): State | undefined {\n // 检测 title 起始标记:双引号、单引号或左括号\n if (\n code === codes.quotationMark ||\n code === codes.apostrophe ||\n code === codes.leftParenthesis\n ) {\n // 使用官方 factoryTitle 解析 title\n return factoryTitle(\n effects,\n resourceTitleAfter,\n nok,\n types.resourceTitle,\n types.resourceTitleMarker,\n types.resourceTitleString\n )(code)\n }\n\n // 没有 title,直接结束\n return resourceEnd(code)\n }\n\n /**\n * 在 title 之后,可能有空白符\n * \n * ```markdown\n * > | [a](b \"c\" ) d\n * ^\n * ```\n * \n * @param code - 当前字符编码\n */\n function resourceTitleAfter(code: Code): State | undefined {\n return markdownLineEndingOrSpace(code)\n ? factoryWhitespace(effects, resourceEnd)(code)\n : resourceEnd(code)\n }\n\n /**\n * 在 resource 结束位置,期望 ')'\n * \n * ```markdown\n * > | [a](b) c\n * ^\n * ```\n * \n * @param code - 当前字符编码\n */\n function resourceEnd(code: Code): State | undefined {\n if (code === codes.rightParenthesis) {\n effects.enter(types.resourceMarker)\n effects.consume(code)\n effects.exit(types.resourceMarker)\n effects.exit(types.resource)\n return ok\n }\n\n return nok(code)\n }\n}\n\n/**\n * 解析 full reference:[text][id]\n * \n * 注意:不检查 id 是否已定义(支持增量解析的核心特性)\n * \n * @param effects - Token 生成器\n * @param ok - 成功时的状态函数\n * @param nok - 失败时的状态函数\n * @returns 起始状态函数\n */\nfunction tokenizeReferenceFull(\n this: TokenizeContext,\n effects: Parameters<Tokenizer>[0],\n ok: State,\n nok: State\n): State {\n const self = this\n\n return referenceFull\n\n /**\n * 在 reference 起始位置,期望 '['\n * \n * ```markdown\n * > | [a][b] d\n * ^\n * ```\n * \n * @param code - 当前字符编码\n */\n function referenceFull(code: Code): State | undefined {\n if (code !== codes.leftSquareBracket) {\n return nok(code)\n }\n \n // 使用官方 factoryLabel 解析 [id]\n // 使用 .call() 确保正确的 this 上下文\n return factoryLabel.call(\n self,\n effects,\n referenceFullAfter,\n referenceFullMissing,\n types.reference,\n types.referenceMarker,\n types.referenceString\n )(code)\n }\n\n /**\n * 在 reference 结束后\n * \n * 🔑 核心特性:总是返回 ok,不检查 parser.defined\n * 这使得增量解析场景下,前向引用能够正常工作\n * \n * ```markdown\n * > | [a][b] d\n * ^\n * ```\n * \n * @param code - 当前字符编码\n */\n function referenceFullAfter(code: Code): State | undefined {\n // 关键修改:不检查 parser.defined\n // \n // 原始 micromark-core-commonmark 的代码:\n // return self.parser.defined.includes(\n // normalizeIdentifier(\n // self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1)\n // )\n // ) ? ok(code) : nok(code)\n //\n // 修改后:总是返回 ok,延迟验证到渲染层\n return ok(code)\n }\n\n /**\n * Reference label 格式错误\n * \n * ```markdown\n * > | [a][b d\n * ^\n * ```\n * \n * @param code - 当前字符编码\n */\n function referenceFullMissing(code: Code): State | undefined {\n return nok(code)\n }\n}\n\n/**\n * Tokenize collapsed reference (e.g., `[text][]`).\n */\nfunction tokenizeReferenceCollapsed(\n this: TokenizeContext,\n effects: Parameters<Tokenizer>[0],\n ok: State,\n nok: State\n): State {\n return referenceCollapsedStart as State\n\n function referenceCollapsedStart(code: Code): State | void {\n if (code !== codes.leftSquareBracket) {\n return nok(code)\n }\n effects.enter(types.reference)\n effects.enter(types.referenceMarker)\n effects.consume(code)\n effects.exit(types.referenceMarker)\n return referenceCollapsedOpen as State\n }\n\n function referenceCollapsedOpen(code: Code): State | void {\n if (code === codes.rightSquareBracket) {\n effects.enter(types.referenceMarker)\n effects.consume(code)\n effects.exit(types.referenceMarker)\n effects.exit(types.reference)\n return ok as State\n }\n return nok(code)\n }\n}\n\n","/**\n * @file GFM 脚注扩展的增量解析补丁\n * \n * @description\n * GFM 脚注扩展会检查 parser.gfmFootnotes 来验证定义是否存在。\n * 在增量解析场景下,定义可能在引用之后才出现,导致引用无法被正确解析。\n * \n * 本补丁移除定义检查,使脚注引用总是被解析为 footnoteReference。\n * \n * @module micromark-gfm-footnote-incremental\n * \n * @features\n * - ✅ 移除脚注引用的定义检查(支持前向引用)\n * - ✅ 覆盖 text[91] (`[`) 和 text[93] (`]`) 的处理\n * - ✅ 延迟验证:解析时不检查定义是否存在\n */\n\nimport type { Extension, Code, State, TokenizeContext, Tokenizer } from 'micromark-util-types'\nimport { gfmFootnote } from 'micromark-extension-gfm-footnote'\nimport { normalizeIdentifier } from 'micromark-util-normalize-identifier'\nimport { codes, constants } from 'micromark-util-symbol'\nimport { markdownLineEndingOrSpace } from 'micromark-util-character'\n\n/**\n * 创建支持增量解析的 GFM 脚注扩展\n * \n * 这个扩展基于官方 gfmFootnote(),但移除了定义检查,支持前向引用\n * \n * @returns Micromark 扩展对象\n * \n * @example\n * ```typescript\n * import { gfmFootnoteIncremental } from './micromark-gfm-footnote-incremental'\n * \n * const extensions = [\n * gfm(),\n * micromarkReferenceExtension(),\n * gfmFootnoteIncremental() // 最后添加,确保覆盖\n * ]\n * ```\n */\nexport function gfmFootnoteIncremental(): Extension {\n const original = gfmFootnote()\n \n return {\n ...original,\n text: {\n ...original.text,\n // 覆盖 text[91] (`[` 的处理) - 这是脚注引用解析的起点\n [codes.leftSquareBracket]: {\n ...original.text![codes.leftSquareBracket],\n tokenize: tokenizeGfmFootnoteCallIncremental\n },\n // 覆盖 text[93] (`]` 的处理) - 用于处理 ![^1] 这样的情况\n [codes.rightSquareBracket]: {\n ...original.text![codes.rightSquareBracket],\n tokenize: tokenizePotentialGfmFootnoteCallIncremental\n }\n }\n }\n}\n\n/**\n * Tokenize 脚注引用 `[^id]`,移除定义检查\n * \n * 🔑 关键修改:不检查 parser.gfmFootnotes,总是允许解析脚注引用\n * \n * @param effects - Token 生成器\n * @param ok - 成功时的状态函数\n * @param nok - 失败时的状态函数\n * @returns 起始状态函数\n */\nfunction tokenizeGfmFootnoteCallIncremental(\n this: TokenizeContext,\n effects: Parameters<Tokenizer>[0],\n ok: State,\n nok: State\n): State {\n const self = this\n let size = 0\n let data = false\n\n return start\n\n /**\n * 脚注引用起始位置\n * \n * ```markdown\n * > | a [^b] c\n * ^\n * ```\n */\n function start(code: Code): State | undefined {\n if (code !== codes.leftSquareBracket) {\n return nok(code)\n }\n\n effects.enter('gfmFootnoteCall')\n effects.enter('gfmFootnoteCallLabelMarker')\n effects.consume(code)\n effects.exit('gfmFootnoteCallLabelMarker')\n return callStart\n }\n\n /**\n * 在 `[` 之后,期望 `^`\n * \n * ```markdown\n * > | a [^b] c\n * ^\n * ```\n */\n function callStart(code: Code): State | undefined {\n if (code !== codes.caret) {\n return nok(code)\n }\n\n effects.enter('gfmFootnoteCallMarker')\n effects.consume(code)\n effects.exit('gfmFootnoteCallMarker')\n effects.enter('gfmFootnoteCallString')\n const token = effects.enter('chunkString')\n token.contentType = 'string'\n return callData\n }\n\n /**\n * 在脚注标识符中\n * \n * ```markdown\n * > | a [^b] c\n * ^\n * ```\n */\n function callData(code: Code): State | undefined {\n if (\n // 太长\n size > constants.linkReferenceSizeMax ||\n // 右括号但没有数据\n (code === codes.rightSquareBracket && !data) ||\n // EOF、换行、空格、制表符、左括号不支持\n code === codes.eof ||\n code === codes.leftSquareBracket ||\n markdownLineEndingOrSpace(code)\n ) {\n return nok(code)\n }\n\n if (code === codes.rightSquareBracket) {\n effects.exit('chunkString')\n effects.exit('gfmFootnoteCallString')\n\n // 🔑 关键修改:移除定义检查\n // 原始代码:\n // const token = effects.exit('gfmFootnoteCallString')\n // if (!defined.includes(normalizeIdentifier(self.sliceSerialize(token)))) {\n // return nok(code)\n // }\n\n effects.enter('gfmFootnoteCallLabelMarker')\n effects.consume(code)\n effects.exit('gfmFootnoteCallLabelMarker')\n effects.exit('gfmFootnoteCall')\n return ok\n }\n\n if (!markdownLineEndingOrSpace(code)) {\n data = true\n }\n\n size++\n effects.consume(code)\n return code === codes.backslash ? callEscape : callData\n }\n\n /**\n * 在转义字符之后\n * \n * ```markdown\n * > | a [^b\\c] d\n * ^\n * ```\n */\n function callEscape(code: Code): State | undefined {\n if (\n code === codes.leftSquareBracket ||\n code === codes.backslash ||\n code === codes.rightSquareBracket\n ) {\n effects.consume(code)\n size++\n return callData\n }\n\n return callData(code)\n }\n}\n\n/**\n * Tokenize 潜在的脚注引用 `![^id]`,移除定义检查\n * \n * 用于处理图片标记后的脚注引用(虽然这不是标准语法,但 GFM 会尝试解析)\n * \n * @param effects - Token 生成器\n * @param ok - 成功时的状态函数\n * @param nok - 失败时的状态函数\n * @returns 起始状态函数\n */\nfunction tokenizePotentialGfmFootnoteCallIncremental(\n this: TokenizeContext,\n effects: Parameters<Tokenizer>[0],\n ok: State,\n nok: State\n): State {\n const self = this\n let index = self.events.length\n let labelStart: any\n\n // 查找开始的 labelImage token\n while (index--) {\n const token = self.events[index][1]\n if (token.type === 'labelImage') {\n labelStart = token\n break\n }\n\n // 如果走得太远就退出\n if (\n token.type === 'gfmFootnoteCall' ||\n token.type === 'labelLink' ||\n token.type === 'label' ||\n token.type === 'image' ||\n token.type === 'link'\n ) {\n break\n }\n }\n\n return start\n\n function start(code: Code): State | undefined {\n if (code !== codes.rightSquareBracket) {\n return nok(code)\n }\n\n if (!labelStart || !labelStart._balanced) {\n return nok(code)\n }\n\n const id = normalizeIdentifier(\n self.sliceSerialize({\n start: labelStart.end,\n end: self.now()\n })\n )\n\n // 只检查是否以 ^ 开头,不检查定义是否存在\n if (id.codePointAt(0) !== codes.caret) {\n return nok(code)\n }\n\n // 🔑 关键修改:移除定义检查\n // 原始代码:\n // const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = [])\n // if (!defined.includes(id.slice(1))) {\n // return nok(code)\n // }\n\n effects.enter('gfmFootnoteCallLabelMarker')\n effects.consume(code)\n effects.exit('gfmFootnoteCallLabelMarker')\n return ok(code)\n }\n}\n\n","/**\n * AST 构建器统一接口和类型定义\n *\n * 支持两种引擎:\n * - marked: 极速模式,速度更快\n * - micromark: 稳定模式,更可靠,支持 div 内嵌 markdown\n */\n\nimport type { Root, RootContent } from 'mdast'\nimport type { Extension as MicromarkExtension } from 'micromark-util-types'\nimport type { Extension as MdastExtension } from 'mdast-util-from-markdown'\nimport type { MarkedExtension } from 'marked'\nimport type { ParsedBlock, BlockStatus, ParserOptions, ContainerConfig } from '../../types'\n\n/**\n * 引擎类型\n */\nexport type EngineType = 'marked' | 'micromark'\n\n/**\n * AST 构建器接口\n * 所有引擎实现必须遵循此接口\n */\nexport interface IAstBuilder {\n /** 容器配置(用于边界检测) */\n readonly containerConfig: ContainerConfig | undefined\n\n /**\n * 解析文本为 AST\n * @param text Markdown 文本\n * @returns AST\n */\n parse(text: string): Root\n\n /**\n * 将 AST 节点转换为 ParsedBlock\n */\n nodesToBlocks(\n nodes: RootContent[],\n startOffset: number,\n rawText: string,\n status: BlockStatus,\n generateBlockId: () => string\n ): ParsedBlock[]\n}\n\n/**\n * Marked 引擎扩展配置\n */\nexport interface MarkedEngineExtension {\n /** marked 扩展列表 */\n extensions: MarkedExtension[]\n}\n\n/**\n * Micromark 引擎扩展配置\n */\nexport interface MicromarkEngineExtension {\n /** micromark 语法扩展 */\n extensions: MicromarkExtension[]\n /** mdast 转换扩展 */\n mdastExtensions: MdastExtension[]\n}\n\n/**\n * 统一插件格式\n *\n * 插件可以同时支持多个引擎,运行时会根据当前引擎选择对应配置\n *\n * @example\n * ```ts\n * const myPlugin: IncremarkPlugin = {\n * name: 'my-plugin',\n * type: 'both', // 支持两种引擎\n * marked: {\n * extensions: [myMarkedExtension]\n * },\n * micromark: {\n * extensions: [myMicromarkExt],\n * mdastExtensions: [myMdastExt]\n * }\n * }\n * ```\n */\nexport interface IncremarkPlugin {\n /** 插件名称 */\n name: string\n\n /**\n * 插件支持的引擎类型\n * - 'marked': 仅支持 marked 引擎\n * - 'micromark': 仅支持 micromark 引擎\n * - 'both': 同时支持两种引擎\n */\n type: 'marked' | 'micromark' | 'both'\n\n /**\n * Marked 引擎配置\n * 当 type 为 'marked' 或 'both' 时必须提供\n */\n marked?: MarkedEngineExtension\n\n /**\n * Micromark 引擎配置\n * 当 type 为 'micromark' 或 'both' 时必须提供\n */\n micromark?: MicromarkEngineExtension\n}\n\n/**\n * 引擎特定的解析器选项\n *\n * 注意:不再包含 engine 选项,引擎切换通过注入 astBuilder 类实现\n * 这样可以确保 tree-shaking 正常工作\n */\nexport interface EngineParserOptions extends Omit<ParserOptions, 'extensions' | 'mdastExtensions'> {\n /**\n * 统一插件列表\n * 插件会根据当前引擎自动选择对应的扩展配置\n */\n plugins?: IncremarkPlugin[]\n\n /**\n * Micromark 扩展(仅 micromark 引擎使用)\n * @deprecated 建议使用 plugins 统一配置\n */\n extensions?: MicromarkExtension[]\n\n /**\n * Mdast 扩展(仅 micromark 引擎使用)\n * @deprecated 建议使用 plugins 统一配置\n */\n mdastExtensions?: MdastExtension[]\n\n /**\n * Marked 扩展(仅 marked 引擎使用)\n * @deprecated 建议使用 plugins 统一配置\n */\n markedExtensions?: MarkedExtension[]\n}\n\n/**\n * 从插件列表中提取 marked 扩展\n */\nexport function extractMarkedExtensions(plugins: IncremarkPlugin[]): MarkedExtension[] {\n const extensions: MarkedExtension[] = []\n for (const plugin of plugins) {\n if ((plugin.type === 'marked' || plugin.type === 'both') && plugin.marked) {\n extensions.push(...plugin.marked.extensions)\n }\n }\n return extensions\n}\n\n/**\n * 从插件列表中提取 micromark 扩展\n */\nexport function extractMicromarkExtensions(plugins: IncremarkPlugin[]): {\n extensions: MicromarkExtension[]\n mdastExtensions: MdastExtension[]\n} {\n const extensions: MicromarkExtension[] = []\n const mdastExtensions: MdastExtension[] = []\n\n for (const plugin of plugins) {\n if ((plugin.type === 'micromark' || plugin.type === 'both') && plugin.micromark) {\n extensions.push(...plugin.micromark.extensions)\n mdastExtensions.push(...plugin.micromark.mdastExtensions)\n }\n }\n\n return { extensions, mdastExtensions }\n}\n\n/**\n * 验证插件配置是否与引擎兼容\n */\nexport function validatePluginsForEngine(\n plugins: IncremarkPlugin[],\n engine: EngineType\n): { valid: boolean; incompatible: string[] } {\n const incompatible: string[] = []\n\n for (const plugin of plugins) {\n if (engine === 'marked' && plugin.type === 'micromark') {\n incompatible.push(plugin.name)\n } else if (engine === 'micromark' && plugin.type === 'marked') {\n incompatible.push(plugin.name)\n }\n }\n\n return {\n valid: incompatible.length === 0,\n incompatible\n }\n}\n","/**\n * Micromark AST 构建器(稳定模式)\n *\n * 基于 micromark + mdast-util-from-markdown\n * 特点:\n * - 更稳定可靠\n * - 支持 div 内嵌 markdown\n * - 丰富的扩展生态\n */\n\nimport { fromMarkdown } from 'mdast-util-from-markdown'\nimport { gfmFromMarkdown } from 'mdast-util-gfm'\nimport { gfm } from 'micromark-extension-gfm'\nimport { gfmFootnoteFromMarkdown } from 'mdast-util-gfm-footnote'\nimport { math } from 'micromark-extension-math'\nimport { mathFromMarkdown } from 'mdast-util-math'\nimport { directive } from 'micromark-extension-directive'\nimport { directiveFromMarkdown } from 'mdast-util-directive'\nimport type { Extension as MicromarkExtension } from 'micromark-util-types'\nimport type { Extension as MdastExtension } from 'mdast-util-from-markdown'\nimport type { Root, RootContent, HTML, Text, Paragraph, Parent as MdastParent } from 'mdast'\n\nimport type { ParsedBlock, BlockStatus, ContainerConfig } from '../../types'\nimport { transformHtmlNodes, type HtmlTreeExtensionOptions } from '../../extensions/html-extension'\nimport { micromarkReferenceExtension } from '../../extensions/micromark-reference-extension'\nimport { gfmFootnoteIncremental } from '../../extensions/micromark-gfm-footnote-incremental'\nimport type { IAstBuilder, EngineParserOptions } from './types'\nimport { extractMicromarkExtensions } from './types'\n\n/**\n * 内联容器节点类型\n * 这些节点的 children 包含内联内容(文本、emphasis、strong 等)\n */\nconst INLINE_CONTAINER_TYPES = [\n 'paragraph',\n 'heading',\n 'tableCell',\n 'delete',\n 'emphasis',\n 'strong',\n 'link',\n 'linkReference'\n] as const\n\n/**\n * 判断是否为内联容器节点\n */\nfunction isInlineContainer(node: RootContent): boolean {\n return INLINE_CONTAINER_TYPES.includes(node.type as any)\n}\n\n/**\n * Micromark AST 构建器\n *\n * 使用 micromark + mdast-util-from-markdown 解析 Markdown\n * 适用于需要稳定性和高级特性的场景\n */\nexport class MicromarkAstBuilder implements IAstBuilder {\n private readonly options: EngineParserOptions\n readonly containerConfig: ContainerConfig | undefined\n private readonly htmlTreeConfig: HtmlTreeExtensionOptions | undefined\n /** 缓存的扩展实例,避免每次 parse 都重新创建 */\n private readonly cachedExtensions: MicromarkExtension[] = []\n private readonly cachedMdastExtensions: MdastExtension[] = []\n\n constructor(options: EngineParserOptions = {}) {\n this.options = options\n this.containerConfig = this.computeContainerConfig(options)\n this.htmlTreeConfig = this.computeHtmlTreeConfig(options)\n // 初始化扩展实例\n this.initExtensions()\n }\n\n /**\n * 初始化并缓存扩展实例\n */\n private initExtensions(): void {\n // 先添加 GFM(包含原始的脚注扩展)\n if (this.options.gfm) {\n this.cachedExtensions.push(gfm())\n this.cachedMdastExtensions.push(...gfmFromMarkdown(), gfmFootnoteFromMarkdown())\n }\n\n // 如果启用了数学公式支持,添加 math 扩展\n if (this.options.math) {\n this.cachedExtensions.push(math())\n this.cachedMdastExtensions.push(mathFromMarkdown())\n }\n\n // 如果启用了容器支持,自动添加 directive 扩展\n if (this.containerConfig !== undefined) {\n this.cachedExtensions.push(directive())\n this.cachedMdastExtensions.push(directiveFromMarkdown())\n }\n\n // 处理统一插件\n if (this.options.plugins) {\n const { extensions, mdastExtensions } = extractMicromarkExtensions(this.options.plugins)\n this.cachedExtensions.push(...extensions)\n this.cachedMdastExtensions.push(...mdastExtensions)\n }\n\n // 如果用户传入了自定义扩展(旧 API),添加它们\n if (this.options.extensions) {\n this.cachedExtensions.push(...this.options.extensions)\n }\n if (this.options.mdastExtensions) {\n this.cachedMdastExtensions.push(...this.options.mdastExtensions)\n }\n\n // 添加增量脚注扩展,覆盖 GFM 脚注的定义检查\n // ⚠️ 必须在 micromarkReferenceExtension 之前添加\n if (this.options.gfm) {\n this.cachedExtensions.push(gfmFootnoteIncremental())\n }\n\n // 添加 reference 扩展(支持增量解析),覆盖 commonmark 的 labelEnd\n // ⚠️ 必须最后添加,确保它能拦截 `]` 并正确处理脚注\n this.cachedExtensions.push(micromarkReferenceExtension())\n }\n\n /**\n * 计算容器配置\n */\n private computeContainerConfig(options: EngineParserOptions): ContainerConfig | undefined {\n const containers = options.containers\n if (!containers) return undefined\n return containers === true ? {} : containers\n }\n\n /**\n * 计算 HTML 树配置\n */\n private computeHtmlTreeConfig(options: EngineParserOptions): HtmlTreeExtensionOptions | undefined {\n const htmlTree = options.htmlTree\n if (!htmlTree) return undefined\n return htmlTree === true ? {} : htmlTree\n }\n\n /**\n * 解析文本为 AST\n *\n * @param text Markdown 文本\n * @returns AST\n */\n parse(text: string): Root {\n // 直接使用缓存的扩展实例,避免每次都重新创建\n const ast = fromMarkdown(text, {\n extensions: this.cachedExtensions,\n mdastExtensions: this.cachedMdastExtensions\n })\n\n // 如果启用了 HTML 树转换,应用转换\n if (this.htmlTreeConfig) {\n return transformHtmlNodes(ast, this.htmlTreeConfig)\n } else {\n // 如果未启用 HTML 树,将 HTML 节点转换为纯文本\n return this.convertHtmlToText(ast)\n }\n }\n\n /**\n * 将 HTML 节点转换为纯文本(当未启用 HTML 树转换时)\n *\n * @param ast AST\n * @returns 转换后的 AST\n */\n private convertHtmlToText(ast: Root): Root {\n return {\n ...ast,\n children: this.processBlockChildren(ast.children)\n }\n }\n\n /**\n * 处理块级节点\n */\n private processBlockChildren(children: RootContent[]): RootContent[] {\n return children.map((node) => {\n // 块级 html 节点转换为段落包含纯文本\n if (node.type === 'html') {\n return this.convertBlockHtmlToParagraph(node as HTML)\n }\n\n // 递归处理有 children 的节点\n if ('children' in node && Array.isArray(node.children)) {\n const parent = node as MdastParent\n const children = isInlineContainer(node)\n ? this.processInlineChildren(parent.children)\n : this.processBlockChildren(parent.children as RootContent[])\n\n return {\n ...parent,\n children\n } as RootContent\n }\n\n return node\n })\n }\n\n /**\n * 处理内联节点\n */\n private processInlineChildren(children: unknown[]): unknown[] {\n return children.map((node) => {\n const n = node as RootContent\n\n // 内联 html 节点转换为纯文本节点\n if (n.type === 'html') {\n return this.convertInlineHtmlToText(n as HTML)\n }\n\n // 递归处理有 children 的内联节点\n if ('children' in n && Array.isArray(n.children)) {\n const parent = n as MdastParent\n return {\n ...parent,\n children: this.processInlineChildren(parent.children)\n }\n }\n\n return n\n })\n }\n\n /**\n * 将块级 HTML 节点转换为段落\n */\n private convertBlockHtmlToParagraph(htmlNode: HTML): RootContent {\n const textNode: Text = {\n type: 'text',\n value: htmlNode.value\n }\n\n const paragraphNode: Paragraph = {\n type: 'paragraph',\n children: [textNode],\n position: htmlNode.position\n }\n\n return paragraphNode as RootContent\n }\n\n /**\n * 将内联 HTML 节点转换为纯文本节点\n */\n private convertInlineHtmlToText(htmlNode: HTML): Text {\n return {\n type: 'text',\n value: htmlNode.value,\n position: htmlNode.position\n }\n }\n\n /**\n * 将 AST 节点转换为 ParsedBlock\n *\n * @param nodes AST 节点列表\n * @param startOffset 起始偏移量\n * @param rawText 原始文本\n * @param status 块状态\n * @param generateBlockId 生成块 ID 的函数\n * @returns ParsedBlock 列表\n */\n nodesToBlocks(\n nodes: RootContent[],\n startOffset: number,\n rawText: string,\n status: BlockStatus,\n generateBlockId: () => string\n ): ParsedBlock[] {\n const blocks: ParsedBlock[] = []\n\n for (const node of nodes) {\n // micromark 的 position.offset 是相对于传入文本的(从 0 开始)\n const relativeStart = node.position?.start?.offset ?? 0\n const relativeEnd = node.position?.end?.offset ?? 1\n\n // 使用相对位置截取文本(直接用 relativeStart/End,因为 rawText 也是相对的)\n const nodeText = rawText.substring(relativeStart, relativeEnd)\n\n // 计算绝对位置(用于光标同步等场景)\n const absoluteStart = startOffset + relativeStart\n const absoluteEnd = startOffset + relativeEnd\n\n blocks.push({\n id: generateBlockId(),\n status,\n node,\n startOffset: absoluteStart,\n endOffset: absoluteEnd,\n rawText: nodeText\n })\n }\n\n return blocks\n }\n}\n","/**\n * Micromark 引擎入口(稳定模式)\n *\n * 单独导入此模块可以实现 tree-shaking,避免打包 marked 相关依赖\n *\n * @example\n * ```ts\n * import { createMicromarkParser } from '@incremark/core/engines/micromark'\n *\n * const parser = createMicromarkParser({ gfm: true, math: true })\n * ```\n */\n\nexport { MicromarkAstBuilder } from '../../parser/ast/MicromarkAstBuilder'\nexport type {\n EngineParserOptions,\n IncremarkPlugin,\n MicromarkEngineExtension,\n IAstBuilder\n} from '../../parser/ast/types'\n\n// 导出创建解析器的工厂函数\nimport { MicromarkAstBuilder } from '../../parser/ast/MicromarkAstBuilder'\nimport type { EngineParserOptions } from '../../parser/ast/types'\n\n/**\n * 创建 Micromark 引擎的 AST 构建器\n */\nexport function createMicromarkBuilder(options: EngineParserOptions = {}): MicromarkAstBuilder {\n return new MicromarkAstBuilder(options)\n}\n"]}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { Parent, RootContent, Root, Definition, FootnoteDefinition } from 'mdast';
|
|
2
|
+
import { Extension } from 'micromark-util-types';
|
|
3
|
+
import { Extension as Extension$1 } from 'mdast-util-from-markdown';
|
|
4
|
+
|
|
5
|
+
declare module 'mdast' {
|
|
6
|
+
interface RootContentMap {
|
|
7
|
+
htmlElement: HtmlElementNode;
|
|
8
|
+
}
|
|
9
|
+
interface PhrasingContentMap {
|
|
10
|
+
htmlElement: HtmlElementNode;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 自定义 HTML 元素节点类型
|
|
15
|
+
*/
|
|
16
|
+
interface HtmlElementNode extends Parent {
|
|
17
|
+
type: 'htmlElement';
|
|
18
|
+
tagName: string;
|
|
19
|
+
attrs: Record<string, string>;
|
|
20
|
+
children: RootContent[];
|
|
21
|
+
data?: {
|
|
22
|
+
rawHtml?: string;
|
|
23
|
+
parsed?: boolean;
|
|
24
|
+
originalType?: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* HTML 树扩展配置
|
|
29
|
+
*/
|
|
30
|
+
interface HtmlTreeExtensionOptions {
|
|
31
|
+
/**
|
|
32
|
+
* 标签黑名单 - 这些标签会被过滤掉(XSS 防护)
|
|
33
|
+
* 默认包含危险标签:script, style, iframe, object, embed, form, input, button, textarea, select
|
|
34
|
+
*/
|
|
35
|
+
tagBlacklist?: string[];
|
|
36
|
+
/**
|
|
37
|
+
* 属性黑名单 - 这些属性会被过滤掉(XSS 防护)
|
|
38
|
+
* 默认包含所有 on* 事件属性和 javascript: 协议
|
|
39
|
+
*/
|
|
40
|
+
attrBlacklist?: string[];
|
|
41
|
+
/**
|
|
42
|
+
* 协议黑名单 - URL 属性中禁止的协议
|
|
43
|
+
* 默认包含 javascript:, vbscript:, data: (允许 data:image/)
|
|
44
|
+
*/
|
|
45
|
+
protocolBlacklist?: string[];
|
|
46
|
+
/**
|
|
47
|
+
* 是否保留原始 HTML 在 data 中
|
|
48
|
+
* 默认为 true
|
|
49
|
+
*/
|
|
50
|
+
preserveRawHtml?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* 自定义标签处理器
|
|
53
|
+
* 可以对特定标签进行自定义处理
|
|
54
|
+
*/
|
|
55
|
+
tagHandlers?: Record<string, (node: HtmlElementNode) => HtmlElementNode | null>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Definition 映射类型
|
|
60
|
+
*/
|
|
61
|
+
interface DefinitionMap {
|
|
62
|
+
[identifier: string]: Definition;
|
|
63
|
+
}
|
|
64
|
+
interface FootnoteDefinitionMap {
|
|
65
|
+
[identifier: string]: FootnoteDefinition;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* 解析块的状态
|
|
69
|
+
*/
|
|
70
|
+
type BlockStatus = 'pending' | 'completed';
|
|
71
|
+
/**
|
|
72
|
+
* AST 节点的通用接口(用于遍历)
|
|
73
|
+
* 统一定义,避免各模块重复声明
|
|
74
|
+
*/
|
|
75
|
+
interface AstNode {
|
|
76
|
+
type: string;
|
|
77
|
+
value?: string;
|
|
78
|
+
children?: AstNode[];
|
|
79
|
+
[key: string]: unknown;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* 解析出的块
|
|
83
|
+
*/
|
|
84
|
+
interface ParsedBlock {
|
|
85
|
+
/** 块的唯一 ID */
|
|
86
|
+
id: string;
|
|
87
|
+
/** 块状态 */
|
|
88
|
+
status: BlockStatus;
|
|
89
|
+
/** AST 节点 */
|
|
90
|
+
node: RootContent;
|
|
91
|
+
/** 原始文本起始位置(相对于完整文档) */
|
|
92
|
+
startOffset: number;
|
|
93
|
+
/** 原始文本结束位置 */
|
|
94
|
+
endOffset: number;
|
|
95
|
+
/** 原始文本内容 */
|
|
96
|
+
rawText: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* 增量更新事件
|
|
100
|
+
*/
|
|
101
|
+
interface IncrementalUpdate {
|
|
102
|
+
/** 新完成的块 */
|
|
103
|
+
completed: ParsedBlock[];
|
|
104
|
+
/** 更新的块(内容变化) */
|
|
105
|
+
updated: ParsedBlock[];
|
|
106
|
+
/** 当前正在解析中的块(可能不完整) */
|
|
107
|
+
pending: ParsedBlock[];
|
|
108
|
+
/** 完整的 AST(包含所有已解析的内容) */
|
|
109
|
+
ast: Root;
|
|
110
|
+
/** Definition 映射表(用于引用式图片和链接) */
|
|
111
|
+
definitions: DefinitionMap;
|
|
112
|
+
/** Footnote Definition 映射表 */
|
|
113
|
+
footnoteDefinitions: FootnoteDefinitionMap;
|
|
114
|
+
/** 脚注引用的出现顺序(用于渲染时排序) */
|
|
115
|
+
footnoteReferenceOrder: string[];
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* 容器语法配置
|
|
119
|
+
*/
|
|
120
|
+
interface ContainerConfig {
|
|
121
|
+
/** 容器标记字符,默认 ':' */
|
|
122
|
+
marker?: string;
|
|
123
|
+
/** 最小标记长度,默认 3 */
|
|
124
|
+
minMarkerLength?: number;
|
|
125
|
+
/** 允许的容器名称(如 ['warning', 'info', 'youtube']),undefined 表示允许所有 */
|
|
126
|
+
allowedNames?: string[];
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* 解析器状态变化事件
|
|
130
|
+
*/
|
|
131
|
+
interface ParserState {
|
|
132
|
+
/** 已完成的块 */
|
|
133
|
+
completedBlocks: ParsedBlock[];
|
|
134
|
+
/** 待处理的块 */
|
|
135
|
+
pendingBlocks: ParsedBlock[];
|
|
136
|
+
/** 完整的 Markdown 内容 */
|
|
137
|
+
markdown: string;
|
|
138
|
+
/** 完整的 AST */
|
|
139
|
+
ast: Root;
|
|
140
|
+
definitions: DefinitionMap;
|
|
141
|
+
footnoteDefinitions: FootnoteDefinitionMap;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* 解析器配置
|
|
145
|
+
*/
|
|
146
|
+
interface ParserOptions {
|
|
147
|
+
/** 启用 GFM 扩展(表格、任务列表等) */
|
|
148
|
+
gfm?: boolean;
|
|
149
|
+
/**
|
|
150
|
+
* 启用数学公式支持($..$ 行内公式和 $$...$$ 块级公式)
|
|
151
|
+
* - false/undefined: 禁用(默认)
|
|
152
|
+
* - true: 启用数学公式解析
|
|
153
|
+
*/
|
|
154
|
+
math?: boolean;
|
|
155
|
+
/**
|
|
156
|
+
* 启用 ::: 容器语法支持(用于边界检测)
|
|
157
|
+
* - false: 禁用(默认)
|
|
158
|
+
* - true: 使用默认配置启用
|
|
159
|
+
* - ContainerConfig: 使用自定义配置启用
|
|
160
|
+
*/
|
|
161
|
+
containers?: boolean | ContainerConfig;
|
|
162
|
+
/**
|
|
163
|
+
* 启用 HTML 树转换
|
|
164
|
+
* - false/undefined: 禁用(默认),HTML 节点保持原始 type: 'html' 格式
|
|
165
|
+
* - true: 使用默认配置启用,将 HTML 节点转换为结构化的 htmlElement 节点
|
|
166
|
+
* - HtmlTreeExtensionOptions: 使用自定义配置启用(可配置黑名单等)
|
|
167
|
+
*/
|
|
168
|
+
htmlTree?: boolean | HtmlTreeExtensionOptions;
|
|
169
|
+
/** 自定义块边界检测函数 */
|
|
170
|
+
blockBoundaryDetector?: (content: string, position: number) => boolean;
|
|
171
|
+
/** 自定义 micromark 扩展(如 directive) */
|
|
172
|
+
extensions?: Extension[];
|
|
173
|
+
/** 自定义 mdast 扩展(如 directiveFromMarkdown) */
|
|
174
|
+
mdastExtensions?: Extension$1[];
|
|
175
|
+
/** 状态变化回调 */
|
|
176
|
+
onChange?: (state: ParserState) => void;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* 块上下文
|
|
180
|
+
*/
|
|
181
|
+
interface BlockContext {
|
|
182
|
+
/** 当前是否在代码块中 */
|
|
183
|
+
inFencedCode: boolean;
|
|
184
|
+
/** 代码块的 fence 字符(` 或 ~) */
|
|
185
|
+
fenceChar?: string;
|
|
186
|
+
/** 代码块的 fence 长度 */
|
|
187
|
+
fenceLength?: number;
|
|
188
|
+
/** 当前列表嵌套深度 */
|
|
189
|
+
listDepth: number;
|
|
190
|
+
/** 当前引用嵌套深度 */
|
|
191
|
+
blockquoteDepth: number;
|
|
192
|
+
/** 当前是否在容器块中 */
|
|
193
|
+
inContainer: boolean;
|
|
194
|
+
/** 容器的标记长度 */
|
|
195
|
+
containerMarkerLength?: number;
|
|
196
|
+
/** 容器名称 */
|
|
197
|
+
containerName?: string;
|
|
198
|
+
/** 容器嵌套深度(支持嵌套容器) */
|
|
199
|
+
containerDepth: number;
|
|
200
|
+
/** 当前是否在列表中 */
|
|
201
|
+
inList: boolean;
|
|
202
|
+
/** 当前列表是否是有序列表 */
|
|
203
|
+
listOrdered?: boolean;
|
|
204
|
+
/** 当前列表的基础缩进 */
|
|
205
|
+
listIndent?: number;
|
|
206
|
+
/** 遇到空行后,列表可能结束(等待下一行确认) */
|
|
207
|
+
listMayEnd?: boolean;
|
|
208
|
+
/** 当前是否在脚注定义中 */
|
|
209
|
+
inFootnote?: boolean;
|
|
210
|
+
/** 脚注标识符 */
|
|
211
|
+
footnoteIdentifier?: string;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* 容器检测结果
|
|
215
|
+
*/
|
|
216
|
+
interface ContainerMatch {
|
|
217
|
+
/** 容器名称 */
|
|
218
|
+
name: string;
|
|
219
|
+
/** 标记长度(冒号数量) */
|
|
220
|
+
markerLength: number;
|
|
221
|
+
/** 是否是结束标记 */
|
|
222
|
+
isEnd: boolean;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export type { AstNode as A, BlockStatus as B, ContainerConfig as C, DefinitionMap as D, FootnoteDefinitionMap as F, HtmlTreeExtensionOptions as H, IncrementalUpdate as I, ParsedBlock as P, ParserState as a, ParserOptions as b, BlockContext as c, ContainerMatch as d };
|