@incremark/core 0.3.1 → 0.3.2
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/dist/{MarkedAstBuildter-DDP1An5M.d.ts → MarkedAstBuildter-B2QhLKKy.d.ts} +2 -2
- package/dist/engines/marked/index.d.ts +4 -4
- package/dist/engines/marked/index.js +1 -1
- package/dist/engines/marked/index.js.map +1 -1
- package/dist/engines/micromark/index.d.ts +4 -4
- package/dist/engines/micromark/index.js +2 -2
- package/dist/engines/micromark/index.js.map +1 -1
- package/dist/index.d.ts +33 -6
- package/dist/index.js +151 -16
- package/dist/index.js.map +1 -1
- package/dist/{types-N1b99kYB.d.ts → types-B7GTGJc2.d.ts} +2 -1
- package/dist/utils/index.d.ts +8 -1
- package/dist/utils/index.js +15 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/detector/index.ts","../src/parser/boundary/BoundaryDetector.ts","../src/utils/index.ts","../src/parser/manager/DefinitionManager.ts","../src/parser/manager/FootnoteManager.ts","../src/extensions/html-extension/index.ts","../src/parser/ast/types.ts","../src/extensions/marked-extensions/explicitDefinitionExtension.ts","../src/extensions/marked-extensions/optimisticReferenceExtension.ts","../src/extensions/marked-extensions/mathExtension.ts","../src/extensions/marked-extensions/footnoteDefinitionExtension.ts","../src/extensions/marked-extensions/inlineHtmlExtension.ts","../src/parser/ast/markedHelpers.ts","../src/parser/ast/MarkedAstBuildter.ts","../src/parser/IncremarkParser.ts","../src/transformer/utils.ts","../src/transformer/BlockTransformer.ts","../src/transformer/plugins.ts"],"names":["node","match","Lexer","mergedLast"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * 块类型检测与边界判断\n *\n * Markdown 块级元素的识别规则\n */\n\nimport type { BlockContext, ContainerConfig, ContainerMatch } from '../types'\n\n// ============ 预编译正则表达式(性能优化) ============\n\nconst RE_FENCE_START = /^(\\s*)((`{3,})|(~{3,}))/\nconst RE_EMPTY_LINE = /^\\s*$/\nconst RE_HEADING = /^#{1,6}\\s/\nconst RE_THEMATIC_BREAK = /^(\\*{3,}|-{3,}|_{3,})\\s*$/\nconst RE_UNORDERED_LIST = /^(\\s*)([-*+])\\s/\nconst RE_ORDERED_LIST = /^(\\s*)(\\d{1,9})[.)]\\s/\nconst RE_BLOCKQUOTE = /^\\s{0,3}>/\nconst RE_HTML_BLOCK_1 = /^\\s{0,3}<(script|pre|style|textarea|!--|!DOCTYPE|\\?|!\\[CDATA\\[)/i\nconst RE_HTML_BLOCK_2 = /^\\s{0,3}<\\/?[a-zA-Z][a-zA-Z0-9-]*(\\s|>|$)/\nconst RE_TABLE_DELIMITER = /^\\|?\\s*:?-{3,}:?\\s*(\\|\\s*:?-{3,}:?\\s*)*\\|?$/\nconst RE_ESCAPE_SPECIAL = /[.*+?^${}()|[\\]\\\\]/g\nconst RE_FOOTNOTE_DEFINITION = /^\\[\\^([^\\]]+)\\]:\\s/\nconst RE_FOOTNOTE_CONTINUATION = /^(?: |\\t)/\n\n/** fence 结束模式缓存 */\nconst fenceEndPatternCache = new Map<string, RegExp>()\n\n/** 容器模式缓存 */\nconst containerPatternCache = new Map<string, RegExp>()\n\n// ============ 代码块检测 ============\n\n/**\n * 检测行是否是代码块 fence 开始\n */\nexport function detectFenceStart(line: string): { char: string; length: number } | null {\n const match = line.match(RE_FENCE_START)\n if (match) {\n const fence = match[2]\n const char = fence[0]\n return { char, length: fence.length }\n }\n return null\n}\n\n/**\n * 检测行是否是代码块 fence 结束\n */\nexport function detectFenceEnd(line: string, context: BlockContext): boolean {\n if (!context.inFencedCode || !context.fenceChar || !context.fenceLength) {\n return false\n }\n\n // 使用缓存的正则表达式\n const cacheKey = `${context.fenceChar}-${context.fenceLength}`\n let pattern = fenceEndPatternCache.get(cacheKey)\n if (!pattern) {\n pattern = new RegExp(`^\\\\s{0,3}${context.fenceChar}{${context.fenceLength},}\\\\s*$`)\n fenceEndPatternCache.set(cacheKey, pattern)\n }\n return pattern.test(line)\n}\n\n// ============ 行类型检测 ============\n\n/**\n * 检测是否是空行或仅包含空白字符\n */\nexport function isEmptyLine(line: string): boolean {\n return RE_EMPTY_LINE.test(line)\n}\n\n/**\n * 检测是否是 Setext 标题下划线(=== 或 ---)\n * @param line 当前行\n * @param prevLine 前一行\n * @returns 是否是 Setext 标题下划线\n */\nexport function isSetextHeadingUnderline(line: string, prevLine?: string): boolean {\n const trimmed = line.trim()\n\n // 检查是否是 === 或 --- 形式的下划线\n if (!/^={3,}$|^-{3,}$/.test(trimmed)) {\n return false\n }\n\n // 如果没有前一行,不能判断\n if (!prevLine) {\n return false\n }\n\n const trimmedPrev = prevLine.trim()\n\n // 前一行是空行,不是 Setext 标题\n if (trimmedPrev === '') {\n return false\n }\n\n // 前一行是 ATX 标题或 thematic break,不是 Setext 标题\n if (/^#{1,6}\\s/.test(trimmedPrev) || /^(\\*{3,}|-{3,}|_{3,})\\s*$/.test(trimmedPrev)) {\n return false\n }\n\n // 前一行是列表项,不是 Setext 标题\n if (/^(\\s*)([-*+])\\s/.test(trimmedPrev) || /^(\\s*)(\\d{1,9})[.)]\\s/.test(trimmedPrev)) {\n return false\n }\n\n // 前一行是引用块,不是 Setext 标题\n if (/^\\s{0,3}>/.test(trimmedPrev)) {\n return false\n }\n\n // 前一行是代码块 fence,不是 Setext 标题\n if (/^(\\s*)(`{3,}|~{3,})/.test(trimmedPrev)) {\n return false\n }\n\n // 检查下划线行的缩进(不超过3个空格)\n const underlineIndent = line.match(/^(\\s*)/)?.[1].length ?? 0\n if (underlineIndent > 3) {\n return false\n }\n\n // 检查前一行缩进(不超过3个空格)\n const contentIndent = prevLine.match(/^(\\s*)/)?.[1].length ?? 0\n if (contentIndent > 3) {\n return false\n }\n\n return true\n}\n\n/**\n * 检测是否是标题行\n */\nexport function isHeading(line: string): boolean {\n return RE_HEADING.test(line)\n}\n\n/**\n * 检测是否是 thematic break(水平线)\n */\nexport function isThematicBreak(line: string): boolean {\n return RE_THEMATIC_BREAK.test(line.trim())\n}\n\n/**\n * 检测是否是列表项开始\n *\n * CommonMark 规范:列表项可以是以下形式:\n * - `- text`(无缩进)\n * - `1. text`(有序列表)\n * - ` - text`(缩进4个空格,作为上一个列表项的延续)\n *\n * 注意:` - text` 这种形式,虽然 `-` 后面没有空格,\n * 但因为前面有4个空格的缩进,所以是列表项的有效形式。\n */\nexport function isListItemStart(line: string): { ordered: boolean; indent: number } | null {\n // 先检查是否以列表标记开头(-、*、+、数字)\n const hasListMarker = /^(\\s*)([-*+]|\\d{1,9}[.)])/.test(line)\n \n if (!hasListMarker) {\n return null\n }\n \n // 如果有列表标记,检查是否是列表项的延续(缩进4+个空格)\n const match = line.match(/^(\\s*)([-*+]|\\d{1,9}[.)])(.*)/)\n if (match) {\n const indent = match[1].length\n const marker = match[2]\n const rest = match[3]\n \n // 如果标记后有内容,检查是否是有效的列表项\n if (rest.trim()) {\n const isOrdered = /^\\d{1,9}[.)]/.test(marker)\n return { ordered: isOrdered, indent }\n }\n \n // 标记后只有空格,可能是缩进的列表项\n // 如 \" - text\" 或 \" 1. text\"\n if (/^\\s+$/.test(rest)) {\n const isOrdered = /^\\d{1,9}[.)]/.test(marker)\n return { ordered: isOrdered, indent }\n }\n }\n \n return null\n}\n\n/**\n * 检测是否是引用块开始\n */\nexport function isBlockquoteStart(line: string): boolean {\n return RE_BLOCKQUOTE.test(line)\n}\n\n/**\n * 检测是否是 HTML 块\n */\nexport function isHtmlBlock(line: string): boolean {\n return RE_HTML_BLOCK_1.test(line) || RE_HTML_BLOCK_2.test(line)\n}\n\n/**\n * 检测表格分隔行\n */\nexport function isTableDelimiter(line: string): boolean {\n return RE_TABLE_DELIMITER.test(line.trim())\n}\n\n// ============ 脚注检测 ============\n\n/**\n * 检测是否是脚注定义的起始行\n * 格式: [^id]: content\n * \n * @example\n * isFootnoteDefinitionStart('[^1]: 脚注内容') // true\n * isFootnoteDefinitionStart('[^note]: 内容') // true\n * isFootnoteDefinitionStart(' 缩进内容') // false\n */\nexport function isFootnoteDefinitionStart(line: string): boolean {\n return RE_FOOTNOTE_DEFINITION.test(line)\n}\n\n/**\n * 检测是否是脚注定义的延续行(缩进行)\n * 至少4个空格或1个tab\n * \n * @example\n * isFootnoteContinuation(' 第二行') // true\n * isFootnoteContinuation('\\t第二行') // true\n * isFootnoteContinuation(' 两个空格') // false\n */\nexport function isFootnoteContinuation(line: string): boolean {\n return RE_FOOTNOTE_CONTINUATION.test(line)\n}\n\n// ============ 容器检测 ============\n\n/**\n * 检测容器开始或结束\n *\n * 支持格式:\n * - ::: name 开始\n * - ::: name attr 开始(带属性)\n * - ::: 结束\n * - :::::: name 开始(更长的标记,用于嵌套)\n */\nexport function detectContainer(line: string, config?: ContainerConfig): ContainerMatch | null {\n const marker = config?.marker || ':'\n const minLength = config?.minMarkerLength || 3\n\n // 使用缓存的正则表达式\n const cacheKey = `${marker}-${minLength}`\n let pattern = containerPatternCache.get(cacheKey)\n if (!pattern) {\n const escapedMarker = marker.replace(RE_ESCAPE_SPECIAL, '\\\\$&')\n // 支持两种格式:\n // 1. ::: name attr (有空格分隔)\n // 2. :::name{...} (directive 语法,无空格)\n pattern = new RegExp(\n `^(\\\\s*)(${escapedMarker}{${minLength},})(?:\\\\s*(\\\\w[\\\\w-]*))?(?:\\\\{[^}]*\\\\})?(?:\\\\s+(.*))?\\\\s*$`\n )\n containerPatternCache.set(cacheKey, pattern)\n }\n\n const match = line.match(pattern)\n if (!match) {\n return null\n }\n\n const markerLength = match[2].length\n const name = match[3] || ''\n const isEnd = !name && !match[4]\n\n if (!isEnd && config?.allowedNames && config.allowedNames.length > 0) {\n if (!config.allowedNames.includes(name)) {\n return null\n }\n }\n\n return { name, markerLength, isEnd }\n}\n\n/**\n * 检测容器结束\n */\nexport function detectContainerEnd(\n line: string,\n context: BlockContext,\n config?: ContainerConfig\n): boolean {\n if (!context.inContainer || !context.containerMarkerLength) {\n return false\n }\n\n const result = detectContainer(line, config)\n if (!result) {\n return false\n }\n\n return result.isEnd && result.markerLength >= context.containerMarkerLength\n}\n\n// ============ 边界检测 ============\n\n/**\n * 判断两行之间是否构成块边界\n */\nexport function isBlockBoundary(\n prevLine: string,\n currentLine: string,\n context: BlockContext\n): boolean {\n if (context.inFencedCode) {\n return detectFenceEnd(currentLine, context)\n }\n\n if (isEmptyLine(prevLine) && !isEmptyLine(currentLine)) {\n return true\n }\n\n if (isHeading(currentLine) && !isEmptyLine(prevLine)) {\n return true\n }\n\n if (isThematicBreak(currentLine)) {\n return true\n }\n\n if (detectFenceStart(currentLine)) {\n return true\n }\n\n return false\n}\n\n// ============ 上下文管理 ============\n\n/**\n * 上下文更新器接口\n */\ninterface ContextUpdater {\n /**\n * 尝试更新上下文\n * @param line 当前行\n * @param context 当前上下文\n * @returns 更新后的上下文,如果不处理返回 null\n */\n update(line: string, context: BlockContext, config?: ContainerConfig): BlockContext | null\n}\n\n/**\n * 代码块上下文更新器\n * 优先级:1(最高)\n */\nclass CodeContextUpdater implements ContextUpdater {\n update(line: string, context: BlockContext): BlockContext | null {\n const newContext = { ...context }\n\n if (context.inFencedCode) {\n if (detectFenceEnd(line, context)) {\n newContext.inFencedCode = false\n newContext.fenceChar = undefined\n newContext.fenceLength = undefined\n return newContext\n }\n return null // 在代码块内,不处理其他逻辑\n }\n\n const fence = detectFenceStart(line)\n if (fence) {\n newContext.inFencedCode = true\n newContext.fenceChar = fence.char\n newContext.fenceLength = fence.length\n return newContext\n }\n\n return null\n }\n}\n\n/**\n * 容器上下文更新器\n * 优先级:2\n */\nclass ContainerContextUpdater implements ContextUpdater {\n update(line: string, context: BlockContext, config?: ContainerConfig): BlockContext | null {\n if (config === undefined) {\n return null\n }\n\n const newContext = { ...context }\n\n if (context.inContainer) {\n // 检查是否是容器结束\n if (detectContainerEnd(line, context, config)) {\n newContext.containerDepth = context.containerDepth - 1\n if (newContext.containerDepth === 0) {\n newContext.inContainer = false\n newContext.containerMarkerLength = undefined\n newContext.containerName = undefined\n }\n return newContext\n }\n\n // 检查是否是嵌套容器开始\n const nested = detectContainer(line, config)\n if (nested && !nested.isEnd) {\n newContext.containerDepth = context.containerDepth + 1\n return newContext\n }\n\n // ⚠️ 关键:在容器内,无论是什么内容(空行、列表、段落等),都保持 inContainer = true\n // 只有容器结束标记才能改变容器状态\n // 这里不需要做任何操作,因为 newContext 已经复制了 context,inContainer 已经是 true\n return newContext\n } else {\n // 不在容器内,检查是否是容器开始\n const container = detectContainer(line, config)\n if (container && !container.isEnd) {\n newContext.inContainer = true\n newContext.containerMarkerLength = container.markerLength\n newContext.containerName = container.name\n newContext.containerDepth = 1\n return newContext\n }\n }\n\n return null\n }\n}\n\n/**\n * 脚注上下文更新器\n * 优先级:3\n */\nclass FootnoteContextUpdater implements ContextUpdater {\n update(line: string, context: BlockContext): BlockContext | null {\n const newContext = { ...context }\n\n // 脚注定义开始(不在脚注中)\n if (!context.inFootnote && isFootnoteDefinitionStart(line)) {\n const identifier = line.match(RE_FOOTNOTE_DEFINITION)?.[1]\n newContext.inFootnote = true\n newContext.footnoteIdentifier = identifier\n return newContext\n }\n\n // 在脚注中\n if (context.inFootnote) {\n // 遇到新脚注定义:前一个脚注结束,新脚注开始\n if (isFootnoteDefinitionStart(line)) {\n const identifier = line.match(RE_FOOTNOTE_DEFINITION)?.[1]\n newContext.footnoteIdentifier = identifier\n return newContext\n }\n\n // 空行:保持脚注状态(支持脚注内部的多段落)\n // 返回当前上下文,阻止责任链继续\n if (isEmptyLine(line)) {\n return { ...context }\n }\n\n // 列表项处理\n const listItem = isListItemStart(line)\n if (listItem) {\n // 无缩进列表项:脚注结束\n // 缩进列表项:脚注的延续内容(包含嵌套列表)\n if (listItem.indent === 0) {\n newContext.inFootnote = false\n newContext.footnoteIdentifier = undefined\n } else {\n // 缩进列表项:脚注的延续内容,返回当前上下文阻止责任链\n return { ...context }\n }\n return null // 让列表处理器处理无缩进情况\n }\n\n // 其他块结束脚注\n if (isHeading(line) || detectFenceStart(line) || isBlockquoteStart(line)) {\n newContext.inFootnote = false\n newContext.footnoteIdentifier = undefined\n return newContext\n }\n\n // 脚注延续:以4+空格开头\n if (isFootnoteContinuation(line)) {\n return { ...context }\n }\n\n // 其他内容(普通文本、表格等),脚注结束\n newContext.inFootnote = false\n newContext.footnoteIdentifier = undefined\n return newContext\n }\n\n return null\n }\n}\n\n/**\n * 列表上下文更新器\n * 优先级:4\n */\nclass ListContextUpdater implements ContextUpdater {\n /**\n * 检测是否是列表项的延续内容(缩进内容或空行)\n */\n private isListContinuation(line: string, listIndent: number): boolean {\n // 空行可能是列表内部的段落分隔\n if (isEmptyLine(line)) {\n return true\n }\n\n // 检查是否有足够的缩进\n const contentIndent = line.match(/^(\\s*)/)?.[1].length ?? 0\n return contentIndent > listIndent\n }\n\n update(line: string, context: BlockContext): BlockContext | null {\n const newContext = { ...context }\n const listItem = isListItemStart(line)\n\n if (context.inList) {\n // 已经在列表中\n if (context.listMayEnd) {\n // 上一行是空行,需要确认列表是否结束\n if (listItem) {\n // 遇到新的列表项\n // 检查是否是同类型列表的延续\n if (listItem.ordered === context.listOrdered && listItem.indent === context.listIndent) {\n // 同类型同级别列表项,列表继续\n newContext.listMayEnd = false\n return newContext\n }\n // 不同类型或不同级别,列表结束,新列表开始\n newContext.listOrdered = listItem.ordered\n newContext.listIndent = listItem.indent\n newContext.listMayEnd = false\n return newContext\n } else if (this.isListContinuation(line, context.listIndent ?? 0)) {\n // 缩进内容或空行,列表继续\n newContext.listMayEnd = isEmptyLine(line)\n return newContext\n } else {\n // 非列表内容,列表结束\n newContext.inList = false\n newContext.listOrdered = undefined\n newContext.listIndent = undefined\n newContext.listMayEnd = false\n return newContext\n }\n } else {\n // 上一行不是空行\n if (listItem) {\n // 新列表项(可能是同级或嵌套)\n return null\n } else if (isEmptyLine(line)) {\n // 遇到空行,列表可能结束\n newContext.listMayEnd = true\n return newContext\n } else if (this.isListContinuation(line, context.listIndent ?? 0)) {\n // 缩进内容,列表继续\n return null\n } else {\n // 非缩进非列表内容,列表结束\n newContext.inList = false\n newContext.listOrdered = undefined\n newContext.listIndent = undefined\n newContext.listMayEnd = false\n return newContext\n }\n }\n } else {\n // 不在列表中\n if (listItem) {\n // 列表开始\n newContext.inList = true\n newContext.listOrdered = listItem.ordered\n newContext.listIndent = listItem.indent\n newContext.listMayEnd = false\n return newContext\n }\n }\n\n return null\n }\n}\n\n/**\n * 创建初始上下文\n */\nexport function createInitialContext(): BlockContext {\n return {\n inFencedCode: false,\n listDepth: 0,\n blockquoteDepth: 0,\n inContainer: false,\n containerDepth: 0,\n inList: false,\n inFootnote: false,\n footnoteIdentifier: undefined\n }\n}\n\n/**\n * 上下文管理器\n * 使用责任链模式更新上下文\n */\nclass ContextManager {\n private readonly updaters: ContextUpdater[] = [\n new CodeContextUpdater(),\n new ContainerContextUpdater(),\n new FootnoteContextUpdater(),\n new ListContextUpdater()\n ]\n\n /**\n * 更新上下文(处理一行后)\n *\n * @param line 当前行\n * @param context 当前上下文\n * @param containerConfig 容器配置\n * @returns 更新后的上下文\n */\n update(line: string, context: BlockContext, containerConfig?: ContainerConfig | boolean): BlockContext {\n // 规范化容器配置\n const config = containerConfig === true ? {} : containerConfig === false ? undefined : containerConfig\n\n // 依次调用上下文更新器\n for (const updater of this.updaters) {\n const result = updater.update(line, context, config)\n if (result !== null) {\n return result\n }\n }\n\n // 没有任何更新器处理,返回原上下文\n return { ...context }\n }\n}\n\n// 上下文管理器单例\nconst contextManager = new ContextManager()\n\n/**\n * 更新上下文(处理一行后)\n *\n * @param line 当前行\n * @param context 当前上下文\n * @param containerConfig 容器配置\n * @returns 更新后的上下文\n */\nexport function updateContext(\n line: string,\n context: BlockContext,\n containerConfig?: ContainerConfig | boolean\n): BlockContext {\n return contextManager.update(line, context, containerConfig)\n}\n\n","/**\n * 边界检测器\n *\n * 职责:\n * - 检测 Markdown 文档中的稳定边界\n * - 判断哪些块已经完成,不会再改变\n * - 支持代码块、引用块、列表、脚注、容器等边界检测\n *\n * 此类是直接从 IncremarkParser 中提取的边界检测逻辑,未做任何优化。\n */\n\nimport type { BlockContext, ContainerConfig } from '../../types'\nimport {\n updateContext,\n isEmptyLine,\n isHeading,\n isThematicBreak,\n isBlockquoteStart,\n isListItemStart,\n detectContainer,\n detectContainerEnd,\n isFootnoteDefinitionStart,\n isFootnoteContinuation,\n detectFenceStart,\n isSetextHeadingUnderline\n} from '../../detector'\n\n/**\n * 稳定边界结果\n */\nexport interface StableBoundaryResult {\n /** 稳定边界行号 */\n line: number\n /** 该行对应的上下文 */\n context: BlockContext\n}\n\n/**\n * 边界检测器配置\n */\nexport interface BoundaryDetectorConfig {\n /** 容器配置 */\n containers?: ContainerConfig\n}\n\n/**\n * 稳定性检查接口\n */\ninterface StabilityChecker {\n /**\n * 检查是否为稳定边界\n * @param lineIndex 行索引\n * @param context 当前上下文\n * @param lines 所有行\n * @returns 稳定边界行号,如果不是稳定边界返回 -1\n */\n check(lineIndex: number, context: BlockContext, lines: string[]): number\n}\n\n/**\n * 容器内边界检查器\n */\nclass ContainerBoundaryChecker implements StabilityChecker {\n constructor(private containerConfig: ContainerConfig | undefined) {}\n\n check(lineIndex: number, context: BlockContext, lines: string[]): number {\n const line = lines[lineIndex]\n\n if (!context.inContainer) {\n return -1\n }\n\n // 检查当前行是否是容器结束\n if (this.containerConfig !== undefined) {\n const containerEnd = detectContainerEnd(line, context, this.containerConfig)\n if (containerEnd) {\n // 容器结束,返回前一行作为稳定边界\n return lineIndex - 1\n }\n }\n\n // 容器内且不是容器结束,不判断为稳定边界\n return -1\n }\n}\n\n/**\n * 列表边界检查器\n */\nclass ListBoundaryChecker implements StabilityChecker {\n check(lineIndex: number, context: BlockContext, lines: string[]): number {\n if (!context.inList) {\n return -1\n }\n\n // 列表还没有确认结束(listMayEnd 为 false 或 undefined)\n // 不应该在列表中间创建稳定边界\n if (!context.listMayEnd) {\n return -1\n }\n\n const line = lines[lineIndex]\n\n // 如果 listMayEnd 为 true,说明上一行是空行\n // 需要检查当前行是否是列表延续或新列表项\n const listItem = isListItemStart(line)\n\n // 检查当前行是否有足够的缩进以作为列表内容\n const contentIndent = line.match(/^(\\s*)/)?.[1].length ?? 0\n const isListContent = contentIndent > (context.listIndent ?? 0)\n\n // 只有当当前行不是列表内容且不是空行时,列表才算结束\n if (!listItem && !isListContent && !isEmptyLine(line)) {\n // 当前行不是列表内容且不是空行,列表在上一行的空行处结束\n return lineIndex - 1\n }\n\n return -1\n }\n}\n\n/**\n * 脚注边界检查器\n */\nclass FootnoteBoundaryChecker implements StabilityChecker {\n check(lineIndex: number, context: BlockContext, lines: string[]): number {\n const line = lines[lineIndex]\n const prevLine = lines[lineIndex - 1]\n\n // 情况 1: 前一行是脚注定义开始\n if (isFootnoteDefinitionStart(prevLine)) {\n // 当前行是空行或缩进行,脚注可能继续(不稳定)\n if (isEmptyLine(line) || isFootnoteContinuation(line)) {\n return -1\n }\n // 当前行是新脚注定义,前一个脚注完成\n if (isFootnoteDefinitionStart(line)) {\n return lineIndex - 1\n }\n }\n\n // 情况 2: 前一行是缩进行,可能是脚注延续\n // 注意:这个逻辑已经在 updateContext() 中通过 inFootnote 标志处理\n // 这里不需要重复判断,统一使用 updateContext() 的结果\n if (!isEmptyLine(prevLine) && isFootnoteContinuation(prevLine)) {\n // 在脚注中的缩进行或空行,保持不稳定\n // 实际的脚注边界判断由 updateContext() 中的 inFootnote 标志控制\n return -1\n }\n\n // 前一行非空时,新脚注定义开始(排除连续脚注定义)\n if (!isEmptyLine(prevLine) && isFootnoteDefinitionStart(line) && !isFootnoteDefinitionStart(prevLine)) {\n return lineIndex - 1\n }\n\n return -1\n }\n}\n\n/**\n * 新块边界检查器\n */\nclass NewBlockBoundaryChecker implements StabilityChecker {\n check(lineIndex: number, context: BlockContext, lines: string[]): number {\n const line = lines[lineIndex]\n const prevLine = lines[lineIndex - 1]\n\n if (isEmptyLine(prevLine)) {\n return -1\n }\n\n // 检测 Setext 标题下划线\n if (isSetextHeadingUnderline(line, prevLine)) {\n return lineIndex - 1\n }\n\n // 新标题开始\n if (isHeading(line)) {\n return lineIndex - 1\n }\n\n // 新代码块开始\n if (detectFenceStart(line)) {\n return lineIndex - 1\n }\n\n // 新引用块开始(排除连续引用)\n if (isBlockquoteStart(line) && !isBlockquoteStart(prevLine)) {\n return lineIndex - 1\n }\n\n // 新列表开始(排除连续列表项)\n // ⚠️ 修改:只有在不在列表中时才触发这个逻辑\n if (!context.inList && isListItemStart(line) && !isListItemStart(prevLine)) {\n return lineIndex - 1\n }\n\n return -1\n }\n}\n\n/**\n * 空行边界检查器\n */\nclass EmptyLineBoundaryChecker implements StabilityChecker {\n check(lineIndex: number, context: BlockContext, lines: string[]): number {\n const line = lines[lineIndex]\n const prevLine = lines[lineIndex - 1]\n\n // 空行标志段落结束\n // ⚠️ 修改:如果在列表中,空行不作为稳定边界\n if (isEmptyLine(line) && !isEmptyLine(prevLine) && !context.inList) {\n return lineIndex\n }\n\n return -1\n }\n}\n\n/**\n * 边界检测器\n */\nexport class BoundaryDetector {\n private readonly containerConfig: ContainerConfig | undefined\n private readonly checkers: StabilityChecker[]\n /** 缓存每一行结束时对应的 Context,避免重复计算 */\n private contextCache: Map<number, BlockContext> = new Map()\n\n constructor(config: BoundaryDetectorConfig = {}) {\n this.containerConfig = config.containers\n // 初始化稳定性检查器链\n this.checkers = [\n new ContainerBoundaryChecker(this.containerConfig),\n new ListBoundaryChecker(),\n new FootnoteBoundaryChecker(),\n new NewBlockBoundaryChecker(),\n new EmptyLineBoundaryChecker()\n ]\n }\n\n /**\n * 清空上下文缓存\n * 当 pendingStartLine 推进后调用,释放不再需要的缓存\n */\n clearContextCache(beforeLine: number): void {\n for (const key of this.contextCache.keys()) {\n if (key < beforeLine) {\n this.contextCache.delete(key)\n }\n }\n }\n\n /**\n * 查找稳定边界\n * 返回稳定边界行号和该行对应的上下文(用于后续更新,避免重复计算)\n *\n * @param lines 所有行\n * @param startLine 起始行\n * @param context 当前上下文\n * @returns 稳定边界结果\n */\n findStableBoundary(\n lines: string[],\n startLine: number,\n context: BlockContext\n ): StableBoundaryResult {\n let stableLine = -1\n let stableContext: BlockContext = context\n\n // 尝试从缓存获取 startLine - 1 的 context,如果匹配则直接用,否则用传入的 context\n let tempContext = startLine > 0 && this.contextCache.has(startLine - 1)\n ? { ...this.contextCache.get(startLine - 1)! }\n : { ...context }\n\n for (let i = startLine; i < lines.length; i++) {\n const line = lines[i]\n const wasInFencedCode = tempContext.inFencedCode\n const wasInContainer = tempContext.inContainer\n const wasContainerDepth = tempContext.containerDepth\n\n tempContext = updateContext(line, tempContext, this.containerConfig)\n\n // 写入缓存:第 i 行结束后的 context\n this.contextCache.set(i, { ...tempContext })\n\n if (wasInFencedCode && !tempContext.inFencedCode) {\n if (i < lines.length - 1) {\n stableLine = i\n stableContext = { ...tempContext }\n }\n continue\n }\n\n if (tempContext.inFencedCode) {\n continue\n }\n\n if (wasInContainer && wasContainerDepth === 1 && !tempContext.inContainer) {\n if (i < lines.length - 1) {\n stableLine = i\n stableContext = { ...tempContext }\n }\n continue\n }\n\n // ⚠️ 关键:如果当前在容器内,跳过所有稳定性检查\n // 容器内的所有内容(包括空行、列表等)都应该被视为容器的一部分\n // 只有容器结束标记才能作为稳定边界\n if (tempContext.inContainer) {\n continue\n }\n\n // 使用检查器链检查稳定性\n const stablePoint = this.checkStability(i, tempContext, lines)\n if (stablePoint >= 0) {\n stableLine = stablePoint\n stableContext = { ...tempContext }\n }\n }\n\n return { line: stableLine, context: stableContext }\n }\n\n /**\n * 检查指定行是否是稳定边界\n * 使用责任链模式,依次调用各个检查器\n *\n * @param lineIndex 行索引\n * @param context 当前上下文\n * @param lines 所有行\n * @returns 稳定边界行号,如果不是稳定边界返回 -1\n */\n private checkStability(\n lineIndex: number,\n context: BlockContext,\n lines: string[]\n ): number {\n // 第一行永远不稳定\n if (lineIndex === 0) {\n return -1\n }\n\n const line = lines[lineIndex]\n const prevLine = lines[lineIndex - 1]\n\n // ⚠️ 脚注特殊处理:在脚注中,空行是段落分隔,不是稳定边界\n // 只有脚注定义开始才算脚注的稳定边界\n if (context.inFootnote) {\n // ⚠️ 关键修复:在脚注中,不应该检测到代码块作为稳定边界\n // 因为脚注内容的缩进(4个空格)可能被误判为代码块 fence\n // 检查前一行是否是脚注定义的开始(脚注单行内容的情况)\n if (isFootnoteDefinitionStart(prevLine) && !isEmptyLine(line)) {\n // ⚠️ 关键:如果当前行是脚注延续(缩进),则不应该作为稳定边界\n // 因为这是脚注内容的一部分,而不是新块\n if (isFootnoteContinuation(line)) {\n return -1\n }\n return lineIndex - 1\n }\n // ⚠️ 另一个关键修复:如果前一行在脚注中(缩进或延续),\n // 且当前行也是缩进或延续,则不应该作为稳定边界\n // 这样可以避免脚注的多行内容被错误分割\n if (isEmptyLine(prevLine) && (isEmptyLine(line) || isFootnoteContinuation(line))) {\n return -1\n }\n // 其他情况(包括空行)都不作为脚注的稳定边界\n return -1\n }\n\n // 前一行是独立块(标题、分割线),该块已完成\n if (isHeading(prevLine) || isThematicBreak(prevLine)) {\n return lineIndex - 1\n }\n\n // 前一行是 Setext 标题下划线,该标题已完成\n if (isSetextHeadingUnderline(prevLine, lines[lineIndex - 2])) {\n return lineIndex - 1\n }\n\n // 最后一行不稳定(可能还有更多内容)\n if (lineIndex >= lines.length - 1) {\n return -1\n }\n\n // 依次调用检查器链,返回第一个匹配的稳定边界\n for (const checker of this.checkers) {\n const stablePoint = checker.check(lineIndex, context, lines)\n if (stablePoint >= 0) {\n return stablePoint\n }\n }\n\n return -1\n }\n}\n\n","/**\n * 工具函数\n */\n\nimport type { Definition, FootnoteDefinition, RootContent } from \"mdast\"\n\n/**\n * 生成唯一 ID\n */\nlet idCounter = 0\nexport function generateId(prefix = 'block'): string {\n return `${prefix}-${++idCounter}`\n}\n\n/**\n * 重置 ID 计数器(用于测试)\n */\nexport function resetIdCounter(): void {\n idCounter = 0\n}\n\n/**\n * 计算行的偏移量\n */\nexport function calculateLineOffset(lines: string[], lineIndex: number): number {\n let offset = 0\n for (let i = 0; i < lineIndex && i < lines.length; i++) {\n offset += lines[i].length + 1 // +1 for newline\n }\n return offset\n}\n\n/**\n * 将文本按行分割\n */\nexport function splitLines(text: string): string[] {\n return text.split('\\n')\n}\n\n/**\n * 合并行为文本\n */\nexport function joinLines(lines: string[], start: number, end: number): string {\n return lines.slice(start, end + 1).join('\\n')\n}\n\nexport function isDefinitionNode(node: RootContent): node is Definition {\n return node.type === 'definition'\n}\n\nexport function isFootnoteDefinitionNode(node: RootContent): node is FootnoteDefinition {\n return node.type === 'footnoteDefinition'\n}\n\n/**\n * AST 节点遍历器\n * 深度优先遍历 AST 节点\n *\n * @param node 起始节点\n * @param visitor 访问者函数,返回 true 可以提前终止遍历\n */\nexport function traverseAst(\n node: RootContent,\n visitor: (node: RootContent) => boolean | void\n): void {\n // 访问当前节点\n const stopEarly = visitor(node)\n if (stopEarly === true) {\n return\n }\n\n // 递归遍历子节点\n if ('children' in node && Array.isArray(node.children)) {\n for (const child of node.children) {\n traverseAst(child as RootContent, visitor)\n }\n }\n}\n\n/**\n * 从 AST 节点中收集指定类型的节点\n *\n * @param node 起始节点\n * @param predicate 匹配谓词\n * @returns 匹配的节点列表\n */\nexport function collectAstNodes<T extends RootContent>(\n node: RootContent,\n predicate: (node: RootContent) => node is T\n): T[] {\n const results: T[] = []\n\n traverseAst(node, (node) => {\n if (predicate(node)) {\n results.push(node)\n }\n })\n\n return results\n}","/**\n * Definition 管理器\n *\n * 职责:\n * - 从 AST 节点中提取 definitions\n * - 管理 Definition 映射表\n * - 提供访问 Definition 的方法\n */\n\nimport type { ParsedBlock, DefinitionMap } from '../../types'\nimport { collectAstNodes, isDefinitionNode } from '../../utils'\n\n/**\n * Definition 管理器\n */\nexport class DefinitionManager {\n private definitions: DefinitionMap = {}\n\n /**\n * 从已完成的 blocks 中提取 definitions\n *\n * @param blocks 已完成的块\n */\n extractFromBlocks(blocks: ParsedBlock[]): void {\n for (const block of blocks) {\n const newDefinitions = this.findDefinitions(block)\n this.definitions = {\n ...this.definitions,\n ...newDefinitions\n }\n }\n }\n\n /**\n * 从 block 中提取 definitions\n *\n * @param block 解析块\n * @returns Definition 映射表\n */\n private findDefinitions(block: ParsedBlock): DefinitionMap {\n // 使用通用遍历工具收集 definition 节点\n const definitions = collectAstNodes(block.node, isDefinitionNode)\n\n return definitions.reduce<DefinitionMap>((acc, node) => {\n acc[node.identifier] = node\n return acc\n }, {})\n }\n\n /**\n * 获取所有 definitions\n *\n * @returns Definition 映射表\n */\n getAll(): DefinitionMap {\n return this.definitions\n }\n\n /**\n * 清空所有 definitions\n */\n clear(): void {\n this.definitions = {}\n }\n}\n\n","/**\n * Footnote 管理器\n *\n * 职责:\n * - 从 AST 节点中提取 footnote definitions\n * - 收集脚注引用顺序\n * - 管理 Footnote Definition 映射表\n * - 提供访问 Footnote 的方法\n */\n\nimport type { RootContent, FootnoteDefinition } from 'mdast'\nimport type { FootnoteDefinitionMap, ParsedBlock } from '../../types'\nimport { collectAstNodes, isFootnoteDefinitionNode, traverseAst } from '../../utils'\n\n/**\n * Footnote 管理器\n */\nexport class FootnoteManager {\n private definitions: FootnoteDefinitionMap = {}\n /** 已完成部分的脚注引用顺序(缓存) */\n private completedReferenceOrder: string[] = []\n /** 所有脚注引用顺序(包括 pending 部分) */\n private referenceOrder: string[] = []\n\n /**\n * 从已完成的 blocks 中提取 footnote definitions\n *\n * @param blocks 已完成的块\n */\n extractDefinitionsFromBlocks(blocks: ParsedBlock[]): void {\n for (const block of blocks) {\n const newDefinitions = this.findFootnoteDefinitions(block)\n this.definitions = {\n ...this.definitions,\n ...newDefinitions\n }\n }\n }\n\n /**\n * 从 block 中提取 footnote definitions\n *\n * @param block 解析块\n * @returns Footnote Definition 映射表\n */\n private findFootnoteDefinitions(block: ParsedBlock): FootnoteDefinitionMap {\n // 使用通用遍历工具收集 footnote definition 节点\n const definitions = collectAstNodes(block.node, isFootnoteDefinitionNode)\n\n return definitions.reduce<FootnoteDefinitionMap>((acc, node) => {\n acc[node.identifier] = node\n return acc\n }, {})\n }\n\n /**\n * 从已完成的 blocks 中收集脚注引用(增量更新)\n * 只收集新完成的 blocks 中的引用,并缓存结果\n *\n * @param blocks 新完成的 blocks\n */\n collectReferencesFromCompletedBlocks(blocks: ParsedBlock[]): void {\n const newReferences = new Set<string>()\n blocks.forEach((block) => {\n traverseAst(block.node, (n) => {\n if (n.type === 'footnoteReference') {\n const identifier = n.identifier\n // 只在已完成部分没出现过的引用才添加\n if (!this.completedReferenceOrder.includes(identifier)) {\n newReferences.add(identifier)\n }\n }\n })\n })\n // 更新已完成部分的引用顺序\n this.completedReferenceOrder.push(...Array.from(newReferences))\n }\n\n /**\n * 收集 pending blocks 中的脚注引用\n * 返回完整的引用顺序(已完成 + pending)\n *\n * @param pendingBlocks pending blocks\n * @returns 完整的脚注引用顺序\n */\n collectReferencesFromPending(pendingBlocks: ParsedBlock[]): string[] {\n // 收集 pending 部分的新引用\n const pendingReferences = new Set<string>()\n pendingBlocks.forEach((block) => {\n traverseAst(block.node, (n) => {\n if (n.type === 'footnoteReference') {\n const identifier = n.identifier\n // 只记录在已完成部分没出现过的引用\n if (!this.completedReferenceOrder.includes(identifier)) {\n pendingReferences.add(identifier)\n }\n }\n })\n })\n // 合并已完成和 pending 的引用顺序\n this.referenceOrder = [...this.completedReferenceOrder, ...Array.from(pendingReferences)]\n return this.referenceOrder\n }\n\n /**\n * 收集 AST 中的脚注引用(按出现顺序)\n *\n * @deprecated 使用 collectReferencesFromCompletedBlocks 和 collectReferencesFromPending 代替\n * @param nodes AST 节点列表\n */\n collectReferences(nodes: RootContent[]): void {\n nodes.forEach((node) => {\n traverseAst(node, (n) => {\n // 检查是否是脚注引用\n if (n.type === 'footnoteReference') {\n const identifier = n.identifier\n // 去重:只记录第一次出现的位置\n if (!this.referenceOrder.includes(identifier)) {\n this.referenceOrder.push(identifier)\n }\n }\n })\n })\n }\n\n /**\n * 获取所有 footnote definitions\n *\n * @returns Footnote Definition 映射表\n */\n getDefinitions(): FootnoteDefinitionMap {\n return this.definitions\n }\n\n /**\n * 获取脚注引用顺序\n *\n * @returns 脚注引用顺序\n */\n getReferenceOrder(): string[] {\n return this.referenceOrder\n }\n\n /**\n * 清空所有 footnote definitions 和引用顺序\n */\n clear(): void {\n this.definitions = {}\n this.completedReferenceOrder = []\n this.referenceOrder = []\n }\n}\n\n","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 * 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 * @param options 部分配置选项\n */\n updateOptions(options: Partial<EngineParserOptions>): void\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 * 显式 Definition 扩展\n *\n * 作用:捕获 [id]: ... 整行,手动解析,并立即注册到 marked 的 links 表中。\n * 这能让 marked 原生逻辑正确识别后续的引用图片。\n *\n * 注意:start 函数必须严格匹配 definition 格式 [id]:,否则会干扰 ![alt][id] 的解析\n */\n\nimport type { TokenizerExtension } from 'marked'\nimport type { ExplicitDefinitionToken } from './types'\n\n/**\n * 创建显式定义扩展\n *\n * @returns marked 扩展对象\n */\nexport function createExplicitDefinitionExtension(): TokenizerExtension {\n return {\n name: 'explicitDefinition',\n level: 'block',\n // 🔑 关键修复:start 必须匹配完整的 definition 模式 [id]:,\n // 而不能只匹配 [,否则会把 ![alt][id] 中的 [alt] 误认为是 definition 开头\n // 同时排除脚注定义 [^id]:\n start(src: string): number | undefined {\n // 匹配 [id]: 但不匹配 [^id]:(脚注定义)\n const match = src.match(/^ {0,3}\\[(?!\\^)[^\\]]+\\]:/m)\n return match?.index\n },\n tokenizer(this: any, src: string): ExplicitDefinitionToken | undefined {\n // 匹配整行:[id]: ... 直到换行,但排除脚注定义 [^id]:\n const rule = /^ {0,3}\\[(?!\\^)[^\\]]+\\]:.*?(?:\\n+|$)/\n const match = rule.exec(src)\n\n if (match) {\n const raw = match[0]\n // 手动解析内部结构:提取 identifier, url, title\n // 使用 \\S+ 匹配 URL,防止被怪异空格截断\n const contentMatch = raw.match(\n /^ {0,3}\\[([^\\]]+)\\]:\\s*(\\S+)(?:\\s+[\"'(](.*?)[\"')])?/\n )\n\n if (contentMatch) {\n const identifier = contentMatch[1].toLowerCase()\n const url = contentMatch[2]\n const title = contentMatch[3]\n\n // ⚡️ 关键步骤:立即注册到 marked 上下文\n // 这样 marked 在解析后续的 ![Alt][id] 时就能找到定义,从而生成正确的 Image Token\n if (this.lexer?.tokens?.links) {\n this.lexer.tokens.links[identifier] = { href: url, title }\n }\n\n return {\n type: 'explicitDefinition',\n raw,\n identifier,\n url,\n title\n }\n }\n\n // 如果捕获了行但解析失败,依然返回 raw Token,防止它漏到 paragraph 里被 Reference 误伤\n return { type: 'explicitDefinition', raw, identifier: '', url: '' }\n }\n return undefined\n },\n renderer(): string {\n return ''\n }\n } as TokenizerExtension\n}\n\n","/**\n * 乐观引用解析扩展\n *\n * 作用:仅当 marked 原生无法解析(即 ID 不存在)时,强制生成引用节点。\n * 注意:需要排除脚注引用 [^id],让脚注处理逻辑来处理\n */\n\nimport type { TokenizerExtension } from 'marked'\nimport type { OptimisticRefToken } from './types'\n\n/**\n * 创建乐观引用扩展\n *\n * @returns marked 扩展对象\n */\nexport function createOptimisticReferenceExtension(): TokenizerExtension {\n return {\n name: 'optimisticReference',\n level: 'inline',\n start(src: string): number | undefined {\n return src.match(/!?\\[/)?.index\n },\n tokenizer(this: any, src: string): OptimisticRefToken | undefined {\n // 匹配 ![...][...] 或 [...][...]\n const rule =\n /^(!?)\\[((?:\\[[^\\]]*\\]|[^\\[\\]]|\\](?=[^\\[]*\\]))*)\\](?:\\s*\\[((?:\\[[^\\]]*\\]|[^\\[\\]]|\\](?=[^\\[]*\\]))*)\\])?/\n const match = rule.exec(src)\n\n if (match) {\n const fullMatch = match[0]\n\n // 1. 如果是标准链接 [text](url),跳过\n if (src.length > fullMatch.length && src[fullMatch.length] === '(') {\n return undefined\n }\n\n // 2. ⚡️ 防抢断:如果后面紧跟 ':',说明这是 Definition 的一部分,坚决不碰\n if (src.length > fullMatch.length && src[fullMatch.length] === ':') {\n return undefined\n }\n\n const isImage = match[1] === '!'\n const text = match[2]\n const refRaw = match[3]\n\n // 3. ⚡️ 排除脚注引用:如果文本以 ^ 开头,这是脚注引用 [^id],交给脚注处理逻辑\n if (text.startsWith('^')) {\n return undefined\n }\n\n let identifier = ''\n let referenceType: 'shortcut' | 'collapsed' | 'full' = 'shortcut'\n\n if (refRaw !== undefined) {\n if (refRaw === '') {\n referenceType = 'collapsed'\n identifier = text\n } else {\n referenceType = 'full'\n identifier = refRaw\n }\n } else {\n referenceType = 'shortcut'\n identifier = text\n // 排除 Checkbox\n if (text.match(/^[ xX]$/)) {\n return undefined\n }\n }\n\n return {\n type: 'optimisticReference',\n raw: fullMatch,\n isImage,\n text,\n identifier: identifier.toLowerCase(),\n label: identifier,\n referenceType\n }\n }\n return undefined\n },\n renderer(): string {\n return ''\n }\n } as TokenizerExtension\n}\n\n","/**\n * 数学公式扩展\n *\n * 提供块级和行内数学公式的支持\n *\n * 块级公式(display math):\n * - $$...$$ 格式(Markdown 标准,默认支持)\n * - \\[...\\] 格式(TeX 风格,需要配置开启)\n *\n * 行内公式(inline math):\n * - $...$ 格式(Markdown 标准,默认支持)\n * - \\(...\\) 格式(TeX 风格,需要配置开启)\n *\n * 这两种格式都是 MathJax/KaTeX 支持的标准分隔符\n */\n\nimport type { TokenizerExtension } from 'marked'\nimport type { BlockMathToken, InlineMathToken } from './types'\n\n/**\n * 数学公式扩展配置选项\n */\nexport interface MathExtensionOptions {\n /**\n * 启用 TeX 风格的公式分隔符 (default: `false`)\n *\n * 开启后同时支持:\n * - 行内公式:\\(...\\)\n * - 块级公式:\\[...\\]\n *\n * 这是 LaTeX/TeX 原生语法,MathJax 和 KaTeX 都支持。\n */\n tex?: boolean\n}\n\n/**\n * 解析后的配置(所有选项都有默认值)\n */\ninterface ResolvedMathExtensionOptions {\n tex: boolean\n}\n\n/**\n * 解析配置,填充默认值\n */\nfunction resolveOptions(options?: MathExtensionOptions): ResolvedMathExtensionOptions {\n return {\n tex: options?.tex ?? false,\n }\n}\n\n/**\n * 创建块级数学公式扩展\n *\n * 支持两种格式:\n * - $$...$$ 格式(Markdown 标准,默认支持)\n * - \\[...\\] 格式(TeX 风格,需要配置开启)\n *\n * @param options - 配置选项\n * @returns marked 扩展对象\n */\nexport function createBlockMathExtension(options?: MathExtensionOptions): TokenizerExtension {\n const resolved = resolveOptions(options)\n\n return {\n name: 'blockMath',\n level: 'block',\n start(src: string): number | undefined {\n // 匹配行首的 $$ (允许前面有空格)\n const dollarMatch = src.match(/^ {0,3}\\$\\$/m)\n\n // 如果开启了 TeX 风格,也匹配 \\[\n let bracketMatch: RegExpMatchArray | null = null\n if (resolved.tex) {\n bracketMatch = src.match(/^ {0,3}\\\\\\[/m)\n }\n\n // 返回最先出现的位置\n if (dollarMatch && bracketMatch) {\n return Math.min(dollarMatch.index!, bracketMatch.index!)\n }\n return dollarMatch?.index ?? bracketMatch?.index\n },\n tokenizer(src: string): BlockMathToken | undefined {\n // 匹配 $$...$$ 块级公式(支持多行,允许行首空格)\n const dollarRule = /^ {0,3}\\$\\$([\\s\\S]*?)\\$\\$ *(?:\\n+|$)/\n const dollarMatch = dollarRule.exec(src)\n if (dollarMatch) {\n return {\n type: 'blockMath',\n raw: dollarMatch[0],\n text: dollarMatch[1].trim(),\n }\n }\n\n // 如果开启了 TeX 风格,匹配 \\[...\\] 块级公式\n if (resolved.tex) {\n const bracketRule = /^ {0,3}\\\\\\[([\\s\\S]*?)\\\\\\] *(?:\\n+|$)/\n const bracketMatch = bracketRule.exec(src)\n if (bracketMatch) {\n return {\n type: 'blockMath',\n raw: bracketMatch[0],\n text: bracketMatch[1].trim(),\n }\n }\n }\n\n return undefined\n },\n renderer(): string {\n return ''\n },\n } as TokenizerExtension\n}\n\n/**\n * 创建行内数学公式扩展\n *\n * 支持两种格式:\n * - $...$ 格式(Markdown 标准,默认支持)\n * - \\(...\\) 格式(TeX 风格,需要配置开启)\n *\n * @param options - 配置选项\n * @returns marked 扩展对象\n */\nexport function createInlineMathExtension(options?: MathExtensionOptions): TokenizerExtension {\n const resolved = resolveOptions(options)\n\n return {\n name: 'inlineMath',\n level: 'inline',\n start(src: string): number | undefined {\n // 查找 $ 分隔符\n const dollarIndex = src.indexOf('$')\n\n // 排除 $$ 开头(那是块级公式)\n const validDollarIndex =\n dollarIndex !== -1 && src[dollarIndex + 1] !== '$' ? dollarIndex : -1\n\n // 如果开启了 TeX 风格,也查找 \\( 分隔符\n let parenIndex = -1\n if (resolved.tex) {\n parenIndex = src.indexOf('\\\\(')\n }\n\n // 返回最先出现的位置\n if (validDollarIndex !== -1 && parenIndex !== -1) {\n return Math.min(validDollarIndex, parenIndex)\n }\n if (validDollarIndex !== -1) return validDollarIndex\n if (parenIndex !== -1) return parenIndex\n return undefined\n },\n tokenizer(src: string): InlineMathToken | undefined {\n // 匹配 $...$ 行内公式(不匹配 $$)\n // 使用非贪婪匹配,支持转义的 \\$\n const dollarRule = /^\\$(?!\\$)((?:\\\\.|[^\\\\\\n$])+?)\\$(?!\\d)/\n const dollarMatch = dollarRule.exec(src)\n if (dollarMatch) {\n return {\n type: 'inlineMath',\n raw: dollarMatch[0],\n text: dollarMatch[1].trim(),\n }\n }\n\n // 如果开启了 TeX 风格,匹配 \\(...\\) 行内公式\n if (resolved.tex) {\n const parenRule = /^\\\\\\(([\\s\\S]*?)\\\\\\)/\n const parenMatch = parenRule.exec(src)\n if (parenMatch) {\n return {\n type: 'inlineMath',\n raw: parenMatch[0],\n text: parenMatch[1].trim(),\n }\n }\n }\n\n return undefined\n },\n renderer(): string {\n return ''\n },\n } as TokenizerExtension\n}\n","/**\n * 脚注定义扩展\n *\n * 解析 [^id]: content 格式的脚注定义\n * 支持多行脚注(后续行需要 4 空格缩进)\n */\n\nimport type { TokenizerExtension } from 'marked'\nimport type { FootnoteDefinitionBlockToken } from './types'\n\n/**\n * 创建脚注定义扩展\n *\n * @returns marked 扩展对象\n */\nexport function createFootnoteDefinitionExtension(): TokenizerExtension {\n return {\n name: 'footnoteDefinitionBlock',\n level: 'block',\n start(src: string): number | undefined {\n // 匹配 [^id]: 格式的开头\n const match = src.match(/^ {0,3}\\[\\^[^\\]]+\\]:/m)\n return match?.index\n },\n tokenizer(src: string): FootnoteDefinitionBlockToken | undefined {\n // 匹配脚注定义的第一行:[^id]: content\n // 脚注标识符可以包含字母、数字、下划线、连字符\n const firstLineRule = /^ {0,3}\\[\\^([a-zA-Z0-9_-]+)\\]:\\s*(.*)/\n const firstLineMatch = firstLineRule.exec(src)\n\n if (!firstLineMatch) return undefined\n\n const identifier = firstLineMatch[1]\n let content = firstLineMatch[2]\n let raw = firstLineMatch[0]\n\n // 计算第一行后剩余的内容\n const remaining = src.slice(raw.length)\n\n // 处理多行脚注:后续行需要至少 4 空格缩进,或者是空行后的缩进行\n // 使用 lines 数组来简化处理\n const lines = remaining.split('\\n')\n let lineIndex = 0\n\n // 跳过第一个空字符串(如果 remaining 以 \\n 开头)\n if (lines[0] === '' && remaining.startsWith('\\n')) {\n lineIndex = 1\n raw += '\\n'\n content += '\\n'\n }\n\n while (lineIndex < lines.length) {\n const line = lines[lineIndex]\n\n // 空行:继续检查下一行是否有缩进\n if (line.trim() === '') {\n // 预检查:空行后是否有缩进行?\n let hasIndentedLineAfter = false\n for (let j = lineIndex + 1; j < lines.length; j++) {\n const nextLine = lines[j]\n if (nextLine.trim() === '') continue // 跳过连续空行\n if (nextLine.match(/^( |\\t)/)) {\n hasIndentedLineAfter = true\n }\n break\n }\n\n if (hasIndentedLineAfter) {\n raw += line + (lineIndex < lines.length - 1 ? '\\n' : '')\n content += '\\n' + line\n lineIndex++\n continue\n } else {\n // 空行后没有缩进行,结束脚注\n break\n }\n }\n\n // 检查是否有 4 空格缩进(脚注延续行)\n if (line.match(/^( |\\t)/)) {\n raw += line + (lineIndex < lines.length - 1 ? '\\n' : '')\n content += '\\n' + line\n lineIndex++\n continue\n }\n\n // 遇到新的脚注定义,结束当前脚注\n if (line.match(/^ {0,3}\\[\\^[^\\]]+\\]:/)) {\n break\n }\n\n // 遇到非缩进非空行,结束脚注\n break\n }\n\n // 如果最后有尾随空行,移除它们(不影响 raw,只影响 content)\n const trimmedContent = content.replace(/\\n+$/, '')\n\n return {\n type: 'footnoteDefinitionBlock',\n raw,\n identifier,\n content: trimmedContent\n }\n },\n renderer(): string {\n return ''\n }\n } as TokenizerExtension\n}\n\n","/**\n * 内联 HTML 扩展\n *\n * 解析内联 HTML 标签(如 <span>text</span>)\n * 用于与 Micromark 保持一致的 HTML 处理行为\n */\n\nimport type { TokenizerExtension } from 'marked'\nimport type { InlineHtmlToken } from './types'\n\n/**\n * HTML 标签正则表达式\n *\n * 匹配:\n * - 开标签: <tag> 或 <tag attr=\"value\">\n * - 闭标签: </tag>\n * - 自闭合: <tag /> 或 <br>\n */\nconst SELF_CLOSING_TAGS = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\n 'link', 'meta', 'param', 'source', 'track', 'wbr'\n])\n\n/**\n * 创建内联 HTML 扩展\n *\n * @returns marked 扩展对象\n */\nexport function createInlineHtmlExtension(): TokenizerExtension {\n return {\n name: 'inlineHtml',\n level: 'inline',\n start(src: string): number | undefined {\n // 查找 < 字符,但排除转义和特殊情况\n const index = src.indexOf('<')\n if (index === -1) return undefined\n\n // 检查是否是有效的 HTML 标签开始\n const afterLt = src.slice(index + 1)\n // 必须是字母开头(开标签)或 / 后跟字母(闭标签)\n if (!/^[a-zA-Z\\/]/.test(afterLt)) return undefined\n\n return index\n },\n tokenizer(src: string): InlineHtmlToken | undefined {\n // 尝试匹配完整的 HTML 元素(开标签 + 内容 + 闭标签)\n const completeTagMatch = matchCompleteHtmlElement(src)\n if (completeTagMatch) {\n return {\n type: 'inlineHtml',\n raw: completeTagMatch,\n text: completeTagMatch\n }\n }\n\n // 尝试匹配自闭合标签\n const selfClosingMatch = matchSelfClosingTag(src)\n if (selfClosingMatch) {\n return {\n type: 'inlineHtml',\n raw: selfClosingMatch,\n text: selfClosingMatch\n }\n }\n\n return undefined\n },\n renderer(): string {\n return ''\n }\n } as TokenizerExtension\n}\n\n/**\n * 匹配完整的 HTML 元素(开标签 + 内容 + 闭标签)\n *\n * 支持嵌套,但限制深度以避免性能问题\n */\nfunction matchCompleteHtmlElement(src: string): string | null {\n // 匹配开标签\n const openTagMatch = /^<([a-zA-Z][a-zA-Z0-9]*)((?:\\s+[a-zA-Z_:][a-zA-Z0-9_.:-]*(?:\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s\"'=<>`]+))?)*)\\s*>/.exec(src)\n if (!openTagMatch) return null\n\n const tagName = openTagMatch[1].toLowerCase()\n const openTag = openTagMatch[0]\n\n // 如果是自闭合标签,不需要找闭标签\n if (SELF_CLOSING_TAGS.has(tagName)) {\n return openTag\n }\n\n // 查找对应的闭标签\n const afterOpenTag = src.slice(openTag.length)\n\n // 简单的嵌套计数\n let depth = 1\n let pos = 0\n const openPattern = new RegExp(`<${tagName}(?:\\\\s[^>]*)?>`, 'gi')\n const closePattern = new RegExp(`</${tagName}>`, 'gi')\n\n while (depth > 0 && pos < afterOpenTag.length) {\n // 重置 lastIndex\n openPattern.lastIndex = pos\n closePattern.lastIndex = pos\n\n const nextOpen = openPattern.exec(afterOpenTag)\n const nextClose = closePattern.exec(afterOpenTag)\n\n if (!nextClose) {\n // 没有找到闭标签,说明 HTML 不完整\n return null\n }\n\n if (nextOpen && nextOpen.index < nextClose.index) {\n // 先遇到开标签,深度 +1\n depth++\n pos = nextOpen.index + nextOpen[0].length\n } else {\n // 先遇到闭标签,深度 -1\n depth--\n pos = nextClose.index + nextClose[0].length\n }\n }\n\n if (depth === 0) {\n return src.slice(0, openTag.length + pos)\n }\n\n return null\n}\n\n/**\n * 匹配自闭合标签\n */\nfunction matchSelfClosingTag(src: string): string | null {\n // 匹配 <tag /> 格式\n const explicitSelfClosing = /^<([a-zA-Z][a-zA-Z0-9]*)((?:\\s+[a-zA-Z_:][a-zA-Z0-9_.:-]*(?:\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s\"'=<>`]+))?)*)\\s*\\/>/.exec(src)\n if (explicitSelfClosing) {\n return explicitSelfClosing[0]\n }\n\n // 匹配隐式自闭合标签(如 <br>、<img src=\"...\">)\n const implicitSelfClosing = /^<([a-zA-Z][a-zA-Z0-9]*)((?:\\s+[a-zA-Z_:][a-zA-Z0-9_.:-]*(?:\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s\"'=<>`]+))?)*)\\s*>/.exec(src)\n if (implicitSelfClosing && SELF_CLOSING_TAGS.has(implicitSelfClosing[1].toLowerCase())) {\n return implicitSelfClosing[0]\n }\n\n return null\n}\n\n","/**\n * Marked Token 到 MDAST 节点转换助手\n *\n * 将 marked 解析产生的 Token 转换为标准的 mdast 节点\n * 严格遵循 marked 类型定义和 mdast 规范\n *\n * 支持通过 TransformContext 扩展自定义 token 类型的转换\n */\n\nimport { Lexer, type Token, type Tokens } from 'marked'\nimport type {\n RootContent,\n PhrasingContent,\n Heading,\n Paragraph,\n Code,\n Blockquote,\n List,\n ListItem,\n Table,\n TableRow,\n TableCell,\n ThematicBreak,\n HTML,\n Text,\n Link,\n Image,\n Strong,\n Emphasis,\n InlineCode,\n Break,\n Delete,\n FootnoteReference,\n FootnoteDefinition,\n Definition,\n ImageReference,\n LinkReference\n} from 'mdast'\n// 从 mdast 插件导入扩展类型\nimport type { Math, InlineMath } from 'mdast-util-math'\nimport type { ContainerDirective } from 'mdast-util-directive'\nimport type {\n ContainerToken,\n FootnoteDefToken,\n OptimisticRefToken,\n ExplicitDefinitionToken,\n BlockMathToken,\n InlineMathToken,\n FootnoteDefinitionBlockToken,\n ExtendedToken,\n InlineHtmlToken\n} from '../../extensions/marked-extensions'\nimport { parseHtmlFragment, type HtmlElementNode } from '../../extensions/html-extension'\n\n// ============ 类型定义 ============\n\n/**\n * 扩展的 ListItem,包含 spread 属性\n */\ninterface ExtendedListItem extends ListItem {\n spread?: boolean\n}\n\n/**\n * 块级 Token 转换函数类型\n *\n * 用于自定义扩展的 token 转换\n */\nexport type BlockTokenTransformer = (\n token: ExtendedToken,\n ctx: TransformContext\n) => RootContent | null | undefined\n\n/**\n * 行内 Token 转换函数类型\n *\n * 用于自定义扩展的 token 转换\n */\nexport type InlineTokenTransformer = (\n token: ExtendedToken,\n ctx: TransformContext\n) => PhrasingContent | PhrasingContent[] | null | undefined\n\n// ============ 转换上下文 ============\n\n/**\n * 转换上下文,用于递归转换时传递信息\n *\n * 支持通过 customBlockTransformers 和 customInlineTransformers 扩展自定义类型\n */\nexport interface TransformContext {\n /**\n * 转换块级 tokens(递归)\n */\n transformTokens: (tokens: Tokens.Generic[] | undefined) => RootContent[]\n\n /**\n * 转换带位置信息的 tokens\n */\n transformTokensWithPosition: (tokens: Tokens.Generic[] | undefined) => RootContent[]\n\n /**\n * 转换行内 tokens\n */\n transformInline: (tokens: Token[] | undefined) => PhrasingContent[]\n\n /**\n * 解析脚注内容为 AST 节点\n */\n parseFootnoteContent: (content: string) => RootContent[]\n\n /**\n * 自定义块级 token 转换器映射\n *\n * key 为 token.type,value 为转换函数\n * 优先于内置转换器执行\n *\n * @example\n * ```ts\n * customBlockTransformers: {\n * myCustomBlock: (token, ctx) => ({\n * type: 'myCustomNode',\n * data: token.data\n * })\n * }\n * ```\n */\n customBlockTransformers?: Record<string, BlockTokenTransformer>\n\n /**\n * 自定义行内 token 转换器映射\n *\n * key 为 token.type,value 为转换函数\n * 优先于内置转换器执行\n */\n customInlineTransformers?: Record<string, InlineTokenTransformer>\n}\n\n// ============ 块级转换 ============\n\n/**\n * 转换块级数学公式\n *\n * 生成 mdast-util-math 兼容的 Math 节点\n */\nexport function transformBlockMath(token: BlockMathToken): Math {\n return {\n type: 'math',\n value: token.text,\n meta: null\n }\n}\n\n/**\n * 转换脚注定义块\n */\nexport function transformFootnoteDefinitionBlock(\n token: FootnoteDefinitionBlockToken,\n ctx: TransformContext\n): FootnoteDefinition {\n // 类型断言说明:parseFootnoteContent 返回 RootContent[]\n // 而 FootnoteDefinition['children'] 要求 (BlockContent | DefinitionContent)[]\n // 实际上脚注内容解析后确实是块级内容,类型安全\n const children = ctx.parseFootnoteContent(token.content) as FootnoteDefinition['children']\n return {\n type: 'footnoteDefinition',\n identifier: token.identifier,\n label: token.identifier,\n children\n }\n}\n\n/**\n * 转换显式定义\n */\nexport function transformExplicitDefinition(token: ExplicitDefinitionToken): Definition | null {\n if (!token.identifier || !token.url) return null\n return {\n type: 'definition',\n identifier: token.identifier,\n label: token.identifier,\n url: token.url,\n title: token.title ?? null\n }\n}\n\n/**\n * 转换 marked 原生的 def token\n */\nexport function transformDef(token: Tokens.Def): Definition | FootnoteDefinition {\n // 检查是否是脚注定义 [^id]: content\n if (token.tag.startsWith('^')) {\n const footnoteId = token.tag.slice(1)\n return {\n type: 'footnoteDefinition',\n identifier: footnoteId,\n label: footnoteId,\n children: [\n {\n type: 'paragraph',\n children: [{ type: 'text', value: token.href }]\n }\n ]\n }\n }\n return {\n type: 'definition',\n identifier: token.tag,\n label: token.tag,\n url: token.href,\n title: token.title ?? null\n }\n}\n\n/**\n * 转换容器指令\n *\n * 生成 mdast-util-directive 兼容的 ContainerDirective 节点\n */\nexport function transformContainer(\n token: ContainerToken,\n ctx: TransformContext\n): ContainerDirective {\n const attributes: Record<string, string> = {}\n const attrRegex = /([a-zA-Z0-9_-]+)=?(\"([^\"]*)\"|'([^']*)'|([^ ]*))?/g\n let match\n while ((match = attrRegex.exec(token.attrs)) !== null) {\n attributes[match[1]] = match[3] || match[4] || match[5] || ''\n }\n // 类型断言说明:transformTokensWithPosition 返回 RootContent[]\n // 而 ContainerDirective['children'] 要求 (BlockContent | DefinitionContent)[]\n // 实际上容器内容确实是块级内容,类型安全\n const children = ctx.transformTokensWithPosition(token.tokens) as ContainerDirective['children']\n return {\n type: 'containerDirective',\n name: token.name,\n attributes,\n children\n }\n}\n\n/**\n * 转换脚注定义(预处理阶段生成的)\n */\nexport function transformFootnoteDefToken(\n token: FootnoteDefToken,\n ctx: TransformContext\n): FootnoteDefinition {\n return {\n type: 'footnoteDefinition',\n identifier: token.identifier,\n label: token.identifier,\n children: [\n {\n type: 'paragraph',\n children: ctx.transformInline(token.tokens)\n }\n ]\n }\n}\n\n/**\n * 转换标题\n */\nexport function transformHeading(token: Tokens.Heading, ctx: TransformContext): Heading {\n return {\n type: 'heading',\n depth: token.depth as 1 | 2 | 3 | 4 | 5 | 6,\n children: ctx.transformInline(token.tokens)\n }\n}\n\n/**\n * 转换段落\n */\nexport function transformParagraph(token: Tokens.Paragraph, ctx: TransformContext): Paragraph {\n return {\n type: 'paragraph',\n children: ctx.transformInline(token.tokens)\n }\n}\n\n/**\n * 转换代码块\n */\nexport function transformCode(token: Tokens.Code): Code {\n return {\n type: 'code',\n lang: token.lang || null,\n meta: null, // 对齐 micromark 输出\n value: token.text\n }\n}\n\n/**\n * 转换引用块\n */\nexport function transformBlockquote(\n token: Tokens.Blockquote,\n ctx: TransformContext\n): Blockquote {\n // 类型断言说明:\n // 1. token.tokens 是 Token[],需转为 Tokens.Generic[](marked 内部类型差异)\n // 2. transformTokens 返回 RootContent[],而 Blockquote['children'] 要求 (BlockContent | DefinitionContent)[]\n // 实际上引用块内容确实是块级内容,类型安全\n const children = ctx.transformTokens(token.tokens as Tokens.Generic[]) as Blockquote['children']\n return {\n type: 'blockquote',\n children\n }\n}\n\n/**\n * 转换列表\n */\nexport function transformList(token: Tokens.List, ctx: TransformContext): List {\n // 类型断言说明:\n // 1. item.tokens 是 Token[],需转为 Tokens.Generic[](marked 内部类型差异)\n // 2. transformTokens 返回 RootContent[],而 ListItem['children'] 要求 (BlockContent | DefinitionContent)[]\n // 实际上列表项内容确实是块级内容,类型安全\n const children: ListItem[] = token.items.map((item) => ({\n type: 'listItem' as const,\n spread: item.loose,\n checked: item.checked ?? null, // 对齐 micromark 输出(GFM 任务列表)\n children: ctx.transformTokens(item.tokens as Tokens.Generic[]) as ListItem['children']\n }))\n return {\n type: 'list',\n ordered: token.ordered,\n start: token.ordered ? (token.start || 1) : null, // 对齐 micromark:有序列表有 start,无序列表为 null\n spread: token.loose,\n children\n }\n}\n\n/**\n * 转换表格\n */\nexport function transformTable(token: Tokens.Table, ctx: TransformContext): Table {\n const headerCells: TableCell[] = token.header.map((cell) => ({\n type: 'tableCell',\n children: ctx.transformInline(cell.tokens)\n }))\n\n const bodyRows: TableRow[] = token.rows.map((row) => ({\n type: 'tableRow',\n children: row.map((cell) => ({\n type: 'tableCell',\n children: ctx.transformInline(cell.tokens)\n }))\n }))\n\n return {\n type: 'table',\n align: token.align as ('left' | 'right' | 'center' | null)[] | undefined,\n children: [{ type: 'tableRow', children: headerCells }, ...bodyRows]\n }\n}\n\n/**\n * 转换分隔线\n */\nexport function transformHr(): ThematicBreak {\n return { type: 'thematicBreak' }\n}\n\n/**\n * 转换 HTML\n */\nexport function transformHtml(token: Tokens.HTML): HTML {\n return {\n type: 'html',\n value: token.text\n }\n}\n\n/**\n * 转换文本块(顶级)\n */\nexport function transformTextBlock(token: Tokens.Text, ctx: TransformContext): Paragraph {\n if (token.tokens) {\n return {\n type: 'paragraph',\n children: ctx.transformInline(token.tokens)\n }\n }\n return {\n type: 'paragraph',\n children: [{ type: 'text', value: token.text }]\n }\n}\n\n// ============ 行内转换 ============\n\n/**\n * 转换行内数学公式\n *\n * 生成 mdast-util-math 兼容的 InlineMath 节点\n */\nexport function transformInlineMath(token: InlineMathToken): InlineMath {\n return {\n type: 'inlineMath',\n value: token.text\n }\n}\n\n/**\n * 转换乐观引用\n */\nexport function transformOptimisticReference(\n token: OptimisticRefToken,\n ctx: TransformContext\n): ImageReference | LinkReference {\n if (token.isImage) {\n return {\n type: 'imageReference',\n identifier: token.identifier,\n label: token.label,\n referenceType: token.referenceType,\n alt: token.text\n }\n }\n const labelChildren = ctx.transformInline(new Lexer().inlineTokens(token.text))\n return {\n type: 'linkReference',\n identifier: token.identifier,\n label: token.label,\n referenceType: token.referenceType,\n children: labelChildren.length ? labelChildren : [{ type: 'text', value: token.text }]\n }\n}\n\n/**\n * 转换链接\n */\nexport function transformLink(token: Tokens.Link, ctx: TransformContext): FootnoteReference | Link {\n // 检查是否是脚注引用:text 以 ^ 开头(如 [^1])\n if (token.text.startsWith('^') && token.text.length > 1) {\n const footnoteId = token.text.slice(1)\n return {\n type: 'footnoteReference',\n identifier: footnoteId,\n label: footnoteId\n }\n }\n return {\n type: 'link',\n url: token.href,\n title: token.title || null, // 对齐 micromark 输出\n children: ctx.transformInline(token.tokens)\n }\n}\n\n/**\n * 转换图片\n */\nexport function transformImage(token: Tokens.Image): Image {\n return {\n type: 'image',\n url: token.href,\n title: token.title || null, // 对齐 micromark 输出\n alt: token.text\n }\n}\n\n/**\n * 转换文本(包含脚注引用提取)\n */\nexport function transformText(token: Tokens.Text | Tokens.Escape): (Text | FootnoteReference)[] {\n const results: (Text | FootnoteReference)[] = []\n const text = token.text\n const footnoteRegex = /\\[\\^([a-zA-Z0-9_-]+)\\]/g\n let lastIndex = 0\n let match\n\n while ((match = footnoteRegex.exec(text)) !== null) {\n if (match.index > lastIndex) {\n results.push({\n type: 'text',\n value: text.substring(lastIndex, match.index)\n })\n }\n results.push({\n type: 'footnoteReference',\n identifier: match[1],\n label: match[1]\n })\n lastIndex = match.index + match[0].length\n }\n\n if (lastIndex < text.length) {\n results.push({\n type: 'text',\n value: text.substring(lastIndex)\n })\n }\n\n return results\n}\n\n/**\n * 转换加粗\n */\nexport function transformStrong(token: Tokens.Strong, ctx: TransformContext): Strong {\n return {\n type: 'strong',\n children: ctx.transformInline(token.tokens)\n }\n}\n\n/**\n * 转换斜体\n */\nexport function transformEmphasis(token: Tokens.Em, ctx: TransformContext): Emphasis {\n return {\n type: 'emphasis',\n children: ctx.transformInline(token.tokens)\n }\n}\n\n/**\n * 转换行内代码\n */\nexport function transformCodespan(token: Tokens.Codespan): InlineCode {\n return {\n type: 'inlineCode',\n value: token.text\n }\n}\n\n/**\n * 转换换行\n */\nexport function transformBreak(): Break {\n return { type: 'break' }\n}\n\n/**\n * 转换删除线\n */\nexport function transformDelete(token: Tokens.Del, ctx: TransformContext): Delete {\n return {\n type: 'delete',\n children: ctx.transformInline(token.tokens)\n }\n}\n\n/**\n * 转换内联 HTML\n *\n * 将内联 HTML token 转换为 HtmlElementNode 节点\n * 如果解析失败,回退为普通文本节点\n */\nexport function transformInlineHtml(\n token: InlineHtmlToken\n): PhrasingContent | PhrasingContent[] {\n // 使用 html-extension 的解析器\n const parsed = parseHtmlFragment(token.text)\n\n if (parsed.length > 0) {\n // 成功解析为 HtmlElementNode\n return parsed as unknown as PhrasingContent[]\n }\n\n // 解析失败,回退为文本节点\n return { type: 'text', value: token.text }\n}\n\n// ============ 主转换函数 ============\n\n// ============ 类型守卫 ============\n\n/**\n * 检查 token 是否为指定类型\n * 通过 type 字段判断,避免 as unknown as 的类型断言\n */\nfunction isTokenType<T extends ExtendedToken>(\n token: ExtendedToken,\n type: T['type']\n): token is T {\n return token.type === type\n}\n\n/**\n * 内置块级转换器映射\n *\n * 注意:由于 TypeScript 的类型系统限制,在回调中需要使用类型断言\n * 这是因为 Record 的 value 类型是统一的 BlockTokenTransformer\n * 而每个具体的转换函数需要特定的 token 类型\n */\nconst builtinBlockTransformers: Record<string, BlockTokenTransformer> = {\n blockMath: (token) => {\n if (isTokenType<BlockMathToken>(token, 'blockMath')) return transformBlockMath(token)\n return null\n },\n footnoteDefinitionBlock: (token, ctx) => {\n if (isTokenType<FootnoteDefinitionBlockToken>(token, 'footnoteDefinitionBlock'))\n return transformFootnoteDefinitionBlock(token, ctx)\n return null\n },\n explicitDefinition: (token) => {\n if (isTokenType<ExplicitDefinitionToken>(token, 'explicitDefinition'))\n return transformExplicitDefinition(token)\n return null\n },\n def: (token) => {\n if (isTokenType<Tokens.Def>(token, 'def')) return transformDef(token)\n return null\n },\n container: (token, ctx) => {\n if (isTokenType<ContainerToken>(token, 'container')) return transformContainer(token, ctx)\n return null\n },\n footnoteDefinition: (token, ctx) => {\n if (isTokenType<FootnoteDefToken>(token, 'footnoteDefinition'))\n return transformFootnoteDefToken(token, ctx)\n return null\n },\n heading: (token, ctx) => {\n if (isTokenType<Tokens.Heading>(token, 'heading')) return transformHeading(token, ctx)\n return null\n },\n paragraph: (token, ctx) => {\n if (isTokenType<Tokens.Paragraph>(token, 'paragraph')) return transformParagraph(token, ctx)\n return null\n },\n code: (token) => {\n if (isTokenType<Tokens.Code>(token, 'code')) return transformCode(token)\n return null\n },\n blockquote: (token, ctx) => {\n if (isTokenType<Tokens.Blockquote>(token, 'blockquote')) return transformBlockquote(token, ctx)\n return null\n },\n list: (token, ctx) => {\n if (isTokenType<Tokens.List>(token, 'list')) return transformList(token, ctx)\n return null\n },\n table: (token, ctx) => {\n if (isTokenType<Tokens.Table>(token, 'table')) return transformTable(token, ctx)\n return null\n },\n hr: () => transformHr(),\n html: (token) => {\n if (isTokenType<Tokens.HTML>(token, 'html')) return transformHtml(token)\n return null\n },\n space: () => null,\n text: (token, ctx) => {\n if (isTokenType<Tokens.Text>(token, 'text')) return transformTextBlock(token, ctx)\n return null\n }\n}\n\n/**\n * 内置行内转换器映射\n */\nconst builtinInlineTransformers: Record<string, InlineTokenTransformer> = {\n inlineMath: (token) => {\n if (isTokenType<InlineMathToken>(token, 'inlineMath')) return transformInlineMath(token)\n return null\n },\n optimisticReference: (token, ctx) => {\n if (isTokenType<OptimisticRefToken>(token, 'optimisticReference'))\n return transformOptimisticReference(token, ctx)\n return null\n },\n link: (token, ctx) => {\n if (isTokenType<Tokens.Link>(token, 'link')) return transformLink(token, ctx)\n return null\n },\n image: (token) => {\n if (isTokenType<Tokens.Image>(token, 'image')) return transformImage(token)\n return null\n },\n text: (token) => {\n if (isTokenType<Tokens.Text>(token, 'text')) return transformText(token)\n return null\n },\n escape: (token) => {\n if (isTokenType<Tokens.Escape>(token, 'escape')) return transformText(token)\n return null\n },\n strong: (token, ctx) => {\n if (isTokenType<Tokens.Strong>(token, 'strong')) return transformStrong(token, ctx)\n return null\n },\n em: (token, ctx) => {\n if (isTokenType<Tokens.Em>(token, 'em')) return transformEmphasis(token, ctx)\n return null\n },\n codespan: (token) => {\n if (isTokenType<Tokens.Codespan>(token, 'codespan')) return transformCodespan(token)\n return null\n },\n br: () => transformBreak(),\n del: (token, ctx) => {\n if (isTokenType<Tokens.Del>(token, 'del')) return transformDelete(token, ctx)\n return null\n },\n inlineHtml: (token) => {\n if (isTokenType<InlineHtmlToken>(token, 'inlineHtml')) return transformInlineHtml(token)\n return null\n }\n}\n\n/**\n * 转换单个块级 Token 为 MDAST 节点\n *\n * 转换优先级:\n * 1. 自定义转换器(customBlockTransformers)\n * 2. 内置转换器\n * 3. 回退处理(带 text 属性的 token 转为段落)\n *\n * @param token 要转换的 token\n * @param ctx 转换上下文\n * @returns MDAST 节点或 null\n */\nexport function transformBlockToken(token: ExtendedToken, ctx: TransformContext): RootContent | null {\n const tokenType = token.type\n\n // 1. 优先使用自定义转换器\n if (ctx.customBlockTransformers?.[tokenType]) {\n const result = ctx.customBlockTransformers[tokenType](token, ctx)\n if (result !== undefined) return result\n }\n\n // 2. 使用内置转换器\n if (builtinBlockTransformers[tokenType]) {\n const result = builtinBlockTransformers[tokenType](token, ctx)\n if (result !== undefined) return result\n }\n\n // 3. 回退处理:带 text 属性的 token 转为段落\n if ('text' in token && typeof token.text === 'string') {\n const paragraph: Paragraph = {\n type: 'paragraph',\n children: [{ type: 'text', value: token.text }]\n }\n return paragraph\n }\n\n return null\n}\n\n/**\n * 转换单个行内 Token 为 MDAST 节点\n *\n * 转换优先级:\n * 1. 自定义转换器(customInlineTransformers)\n * 2. 内置转换器\n * 3. 回退处理(带 text 属性的 token 转为文本节点)\n *\n * @param token 要转换的 token\n * @param ctx 转换上下文\n * @returns MDAST 节点或 null\n */\nexport function transformInlineToken(\n token: ExtendedToken,\n ctx: TransformContext\n): PhrasingContent | PhrasingContent[] | null {\n const tokenType = token.type\n\n // 1. 优先使用自定义转换器\n if (ctx.customInlineTransformers?.[tokenType]) {\n const result = ctx.customInlineTransformers[tokenType](token, ctx)\n if (result !== undefined) return result\n }\n\n // 2. 使用内置转换器\n if (builtinInlineTransformers[tokenType]) {\n const result = builtinInlineTransformers[tokenType](token, ctx)\n if (result !== undefined) return result\n }\n\n // 3. 回退处理:带 text 属性的 token 转为文本节点\n if ('text' in token && typeof token.text === 'string') {\n const text: Text = { type: 'text', value: token.text }\n return text\n }\n\n return null\n}\n\n/**\n * 获取内置块级转换器(用于扩展或覆盖)\n */\nexport function getBuiltinBlockTransformers(): Readonly<Record<string, BlockTokenTransformer>> {\n return builtinBlockTransformers\n}\n\n/**\n * 获取内置行内转换器(用于扩展或覆盖)\n */\nexport function getBuiltinInlineTransformers(): Readonly<Record<string, InlineTokenTransformer>> {\n return builtinInlineTransformers\n}\n","/**\n * Marked AST 构建器(极速模式)\n *\n * 基于 marked 解析器\n * 特点:\n * - 速度更快\n * - 适合流式渲染场景\n *\n */\n\nimport { lexer, Lexer, type Tokens, type Token, type MarkedExtension } from 'marked'\nimport type {\n Root,\n RootContent,\n PhrasingContent\n} from 'mdast'\nimport type { ParsedBlock, BlockStatus, ContainerConfig } from '../../types'\nimport { transformHtmlNodes, type HtmlTreeExtensionOptions } from '../../extensions/html-extension'\nimport type { IAstBuilder, EngineParserOptions } from './types'\nimport { extractMarkedExtensions } from './types'\n\n// 导入扩展\nimport {\n createExplicitDefinitionExtension,\n createOptimisticReferenceExtension,\n createBlockMathExtension,\n createInlineMathExtension,\n createFootnoteDefinitionExtension,\n createInlineHtmlExtension,\n type ContainerToken,\n type FootnoteDefToken\n} from '../../extensions/marked-extensions'\n\n// 导入转换助手\nimport {\n transformBlockToken,\n transformInlineToken,\n type TransformContext\n} from './markedHelpers'\n\n// ============ 类型定义 ============\ntype LinkDefinitions = Record<string, { href: string; title?: string }>\n\n/**\n * Marked AST 构建器\n *\n * 使用 marked 解析 Markdown,速度更快\n * 适用于流式渲染和高性能场景\n */\nexport class MarkedAstBuilder implements IAstBuilder {\n readonly containerConfig: ContainerConfig | undefined\n readonly htmlTreeOptions: HtmlTreeExtensionOptions | undefined\n private globalLinks: LinkDefinitions = {}\n /** 用户传入的 marked 扩展 */\n private readonly userExtensions: MarkedExtension[] = []\n /** 转换上下文(用于递归转换) */\n private readonly transformContext: TransformContext\n\n constructor(private options: EngineParserOptions = {}) {\n this.containerConfig = typeof options.containers === 'object'\n ? options.containers\n : (options.containers === true ? {} : undefined)\n\n this.htmlTreeOptions = typeof options.htmlTree === 'object'\n ? options.htmlTree\n : (options.htmlTree === true ? {} : undefined)\n\n // 收集用户扩展\n if (options.plugins) {\n this.userExtensions.push(...extractMarkedExtensions(options.plugins))\n }\n if (options.markedExtensions) {\n this.userExtensions.push(...options.markedExtensions)\n }\n\n // 初始化转换上下文\n this.transformContext = {\n transformTokens: this.transformTokens.bind(this),\n transformTokensWithPosition: this.transformTokensWithPosition.bind(this),\n transformInline: this.transformInline.bind(this),\n parseFootnoteContent: this.parseFootnoteContent.bind(this)\n }\n }\n\n parse(text: string): Root {\n // 1. 文本清洗:这是解决 URL 截断的第一道防线\n const normalizedText = text.replace(/[\\u00A0\\u200b\\u202f]/g, ' ')\n\n // 2. 构造 Extensions\n const optimisticRefExt = createOptimisticReferenceExtension()\n const explicitDefExt = createExplicitDefinitionExtension()\n const footnoteDefExt = createFootnoteDefinitionExtension()\n\n // 收集用户扩展中的 block/inline tokenizers\n const userBlockExts: any[] = []\n const userBlockStartExts: any[] = []\n const userInlineExts: any[] = []\n const userInlineStartExts: any[] = []\n\n for (const ext of this.userExtensions) {\n if ((ext as any).level === 'block') {\n if ((ext as any).tokenizer) userBlockExts.push((ext as any).tokenizer)\n if ((ext as any).start) userBlockStartExts.push((ext as any).start)\n } else if ((ext as any).level === 'inline') {\n if ((ext as any).tokenizer) userInlineExts.push((ext as any).tokenizer)\n if ((ext as any).start) userInlineStartExts.push((ext as any).start)\n }\n }\n\n // 脚注定义扩展需要在 explicitDefinitionExtension 之前,确保 [^id]: 优先被脚注扩展处理\n const blockExts: any[] = [\n footnoteDefExt.tokenizer,\n explicitDefExt.tokenizer,\n ...userBlockExts\n ]\n const blockStartExts: any[] = [\n footnoteDefExt.start,\n explicitDefExt.start,\n ...userBlockStartExts\n ]\n const inlineExts: any[] = [optimisticRefExt.tokenizer, ...userInlineExts]\n const inlineStartExts: any[] = [optimisticRefExt.start, ...userInlineStartExts]\n\n // Math 扩展(仅当 options.math 启用时)\n if (this.options.math) {\n // 解析 math 配置\n const mathOptions = typeof this.options.math === 'object'\n ? this.options.math\n : {}\n\n const blockMathExt = createBlockMathExtension(mathOptions)\n const inlineMathExt = createInlineMathExtension(mathOptions)\n blockExts.unshift(blockMathExt.tokenizer)\n blockStartExts.unshift(blockMathExt.start)\n inlineExts.unshift(inlineMathExt.tokenizer)\n inlineStartExts.unshift(inlineMathExt.start)\n }\n\n // 内联 HTML 扩展(仅当 options.htmlTree 启用时)\n // 这使得内联 HTML 能够被识别为完整的 token,与 Micromark 行为一致\n if (this.htmlTreeOptions) {\n const inlineHtmlExt = createInlineHtmlExtension()\n inlineExts.unshift(inlineHtmlExt.tokenizer)\n inlineStartExts.unshift(inlineHtmlExt.start)\n }\n\n const lexerOptions: any = {\n gfm: true,\n breaks: false, // 关闭软换行转 break,与 Micromark 保持一致\n ...this.options,\n extensions: {\n inline: inlineExts,\n startInline: inlineStartExts,\n block: blockExts,\n startBlock: blockStartExts\n }\n }\n\n const lexerInstance = new Lexer(lexerOptions)\n\n // 3. 注入历史 Links\n if (lexerInstance.tokens && (lexerInstance.tokens as any).links) {\n Object.assign((lexerInstance.tokens as any).links, this.globalLinks)\n }\n\n // 4. 执行解析\n let tokens = lexerInstance.lex(normalizedText) as Token[]\n\n // 5. 保存 Links\n if (lexerInstance.tokens && (lexerInstance.tokens as any).links) {\n Object.assign(this.globalLinks, (lexerInstance.tokens as any).links)\n }\n\n // 6. 预处理\n tokens = this.preprocessTokens(tokens)\n\n // 7. 转换 AST\n let children = this.transformTokensWithPosition(tokens)\n\n // 8. HTML 后处理\n if (this.htmlTreeOptions) {\n children = this.processHtmlNodes(children)\n }\n\n return {\n type: 'root',\n children\n }\n }\n\n /**\n * 预处理 tokens\n *\n * 处理容器指令和遗留的脚注定义(从 paragraph 中提取)\n */\n private preprocessTokens(tokens: Token[]): Token[] {\n const result: Token[] = []\n let i = 0\n\n while (i < tokens.length) {\n const token = tokens[i]\n\n if (token.type === 'paragraph') {\n const text = (token as Tokens.Paragraph).text\n\n // 处理遗留的脚注定义(从 paragraph 中提取)\n const footnoteMatch = text.match(/^\\[\\^([a-zA-Z0-9_-]+)\\]:\\s+([\\s\\S]*)$/)\n if (footnoteMatch) {\n const defToken: FootnoteDefToken = {\n type: 'footnoteDefinition',\n identifier: footnoteMatch[1],\n text: footnoteMatch[2],\n tokens: new Lexer().inlineTokens(footnoteMatch[2]),\n raw: token.raw\n }\n result.push(defToken as unknown as Token)\n i++\n continue\n }\n\n // 处理容器指令\n const containerStartMatch = text.match(/^:::(\\s*)([a-zA-Z0-9_-]+)(.*?)(\\n|$)/)\n if (containerStartMatch) {\n const name = containerStartMatch[2]\n const attrs = containerStartMatch[3].trim()\n let rawAccumulator = ''\n let j = i\n let depth = 0\n let foundEnd = false\n let contentRaw = ''\n\n while (j < tokens.length) {\n const currentToken = tokens[j]\n rawAccumulator += currentToken.raw\n const lines = rawAccumulator.split('\\n')\n depth = 0\n let startLineIndex = -1\n let endLineIndex = -1\n\n for (let k = 0; k < lines.length; k++) {\n const line = lines[k]\n if (line.match(/^:::(\\s*)([a-zA-Z0-9_-]+)/)) {\n if (depth === 0 && startLineIndex === -1) startLineIndex = k\n depth++\n } else if (line.trim() === ':::') {\n depth--\n if (depth === 0) {\n endLineIndex = k\n foundEnd = true\n break\n }\n }\n }\n\n if (foundEnd) {\n const contentLines = lines.slice(startLineIndex + 1, endLineIndex)\n contentRaw = contentLines.join('\\n')\n const remainingLines = lines.slice(endLineIndex + 1)\n const remainingText = remainingLines.join('\\n')\n\n const containerToken: ContainerToken = {\n type: 'container',\n name,\n attrs,\n tokens: this.preprocessTokens(lexer(contentRaw)),\n raw: rawAccumulator\n }\n result.push(containerToken as unknown as Token)\n\n if (remainingText.trim()) {\n const remainingTokens = this.preprocessTokens(lexer(remainingText))\n result.push(...remainingTokens)\n }\n\n i = j + 1\n break\n }\n j++\n }\n\n if (foundEnd) continue\n }\n }\n\n result.push(token)\n i++\n }\n\n return result\n }\n\n /**\n * 转换 tokens 为 MDAST 节点(带位置信息)\n */\n private transformTokensWithPosition(tokens: Tokens.Generic[] | undefined): RootContent[] {\n if (!tokens) return []\n\n const results: RootContent[] = []\n let currentOffset = 0\n\n for (const token of tokens) {\n const rawLength = token.raw?.length ?? 0\n const node = transformBlockToken(token as Token, this.transformContext)\n\n if (node) {\n node.position = {\n start: { line: 0, column: 0, offset: currentOffset },\n end: { line: 0, column: 0, offset: currentOffset + rawLength }\n }\n results.push(node)\n }\n\n currentOffset += rawLength\n }\n\n return results\n }\n\n /**\n * 转换 tokens 为 MDAST 节点(不带位置信息)\n */\n private transformTokens(tokens: Tokens.Generic[] | undefined): RootContent[] {\n if (!tokens) return []\n return tokens\n .map((t) => transformBlockToken(t as Token, this.transformContext))\n .filter(Boolean) as RootContent[]\n }\n\n /**\n * 转换行内 tokens\n */\n private transformInline(tokens: Token[] | undefined): PhrasingContent[] {\n if (!tokens) return []\n\n const results: PhrasingContent[] = []\n\n for (const token of tokens) {\n const result = transformInlineToken(token, this.transformContext)\n if (result) {\n if (Array.isArray(result)) {\n results.push(...result)\n } else {\n results.push(result)\n }\n }\n }\n\n return results\n }\n\n /**\n * 解析脚注内容为 AST 节点\n */\n private parseFootnoteContent(content: string): RootContent[] {\n if (!content.trim()) {\n return []\n }\n\n // 移除脚注延续行的前导缩进(4 空格或 1 tab)\n const normalizedContent = content\n .split('\\n')\n .map((line, index) => {\n // 第一行不需要移除缩进\n if (index === 0) return line\n // 后续行移除 4 空格或 1 tab 的缩进\n if (line.startsWith(' ')) return line.slice(4)\n if (line.startsWith('\\t')) return line.slice(1)\n return line\n })\n .join('\\n')\n\n // 使用简单的 Lexer 解析内容\n const contentLexer = new Lexer({ gfm: true, breaks: true })\n const tokens = contentLexer.lex(normalizedContent)\n\n return this.transformTokens(tokens)\n }\n\n /**\n * 处理 HTML 节点\n *\n * 使用 html-extension 的 transformHtmlNodes 来处理:\n * - 合并被空行分割的 HTML 节点\n * - 将 HTML 解析为 HtmlElementNode 树结构\n */\n private processHtmlNodes(nodes: RootContent[]): RootContent[] {\n // 构造一个临时的 Root 节点,使用 transformHtmlNodes 处理\n const tempRoot: Root = {\n type: 'root',\n children: nodes as Root['children']\n }\n\n const transformed = transformHtmlNodes(tempRoot, this.htmlTreeOptions)\n return transformed.children as RootContent[]\n }\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 const blocks: ParsedBlock[] = []\n\n for (const node of nodes) {\n const relativeStart = node.position?.start?.offset ?? 0\n const relativeEnd = node.position?.end?.offset ?? rawText.length\n const nodeText = rawText.substring(relativeStart, relativeEnd)\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 * 更新配置选项\n * @param options 部分配置选项\n */\n updateOptions(options: Partial<EngineParserOptions>): void {\n // 合并选项\n Object.assign(this.options, options)\n\n // 更新容器配置\n if ('containers' in options) {\n ;(this as any).containerConfig = typeof options.containers === 'object'\n ? options.containers\n : (options.containers === true ? {} : undefined)\n }\n\n // 更新 HTML Tree 配置\n if ('htmlTree' in options) {\n ;(this as any).htmlTreeOptions = typeof options.htmlTree === 'object'\n ? options.htmlTree\n : (options.htmlTree === true ? {} : undefined)\n }\n\n // 更新用户扩展(如果有)\n if (options.plugins || options.markedExtensions) {\n this.userExtensions.length = 0\n if (options.plugins) {\n this.userExtensions.push(...extractMarkedExtensions(options.plugins))\n }\n if (options.markedExtensions) {\n this.userExtensions.push(...options.markedExtensions)\n }\n }\n }\n}\n\n/**\n * AstBuilder 别名(向后兼容)\n */\nexport const AstBuilder = MarkedAstBuilder\n","/**\n * 增量 Markdown 解析器\n *\n * 设计思路:\n * 1. 维护一个文本缓冲区,接收流式输入\n * 2. 识别\"稳定边界\"(如空行、标题等),将已完成的块标记为 completed\n * 3. 对于正在接收的块,每次重新解析,但只解析该块的内容\n * 4. 复杂嵌套节点(如列表、引用)作为整体处理,直到确认完成\n *\n * 引擎选择:\n * - 默认使用 marked(极速模式),只打包 marked 依赖\n * - 如需使用 micromark,通过 astBuilder 选项注入 MicromarkAstBuilder\n *\n * Tree-shaking 说明:\n * - 默认只打包 marked 引擎\n * - micromark 引擎需要从 '@incremark/core/engines/micromark' 单独导入\n */\n\nimport type {\n Root,\n ParsedBlock,\n IncrementalUpdate,\n BlockContext,\n ParserState,\n DefinitionMap,\n FootnoteDefinitionMap\n} from '../types'\n\nimport {\n createInitialContext,\n} from '../detector'\nimport { BoundaryDetector } from './boundary'\nimport { DefinitionManager } from './manager'\nimport { FootnoteManager } from './manager'\nimport type { IAstBuilder, EngineParserOptions } from './ast/types'\n// 只默认导入 MarkedAstBuilder,实现 tree-shaking\nimport { MarkedAstBuilder } from './ast/MarkedAstBuildter'\n\n/**\n * AST 构建器类型(用于注入)\n */\nexport type AstBuilderClass = new (options: EngineParserOptions) => IAstBuilder\n\n/**\n * 扩展的解析器选项(支持注入自定义 AstBuilder)\n */\nexport interface IncremarkParserOptions extends EngineParserOptions {\n /**\n * 自定义 AST 构建器类\n *\n * 用于注入不同的引擎实现,实现 tree-shaking\n *\n * @example\n * ```ts\n * // 使用 micromark 引擎\n * import { MicromarkAstBuilder } from '@incremark/core/engines/micromark'\n * const parser = createIncremarkParser({\n * astBuilder: MicromarkAstBuilder\n * })\n * ```\n */\n astBuilder?: AstBuilderClass\n}\n\n// ============ 解析器类 ============\n\nexport class IncremarkParser {\n private lines: string[] = []\n /** 行偏移量前缀和:lineOffsets[i] = 第i行起始位置的偏移量 */\n private lineOffsets: number[] = [0]\n private completedBlocks: ParsedBlock[] = []\n private pendingStartLine = 0\n private blockIdCounter = 0\n private context: BlockContext\n private options: IncremarkParserOptions\n /** 边界检测器 */\n private readonly boundaryDetector: BoundaryDetector\n /** AST 构建器 */\n private astBuilder: IAstBuilder\n /** Definition 管理器 */\n private readonly definitionManager: DefinitionManager\n /** Footnote 管理器 */\n private readonly footnoteManager: FootnoteManager\n /** 上次 append 返回的 pending blocks,用于 getAst 复用 */\n private lastPendingBlocks: ParsedBlock[] = []\n\n constructor(options: IncremarkParserOptions = {}) {\n this.options = {\n gfm: true,\n ...options\n }\n this.context = createInitialContext()\n\n // 初始化 AST 构建器\n // 默认使用 MarkedAstBuilder(极速模式),支持注入自定义构建器\n const BuilderClass = options.astBuilder || MarkedAstBuilder\n this.astBuilder = new BuilderClass(this.options)\n\n // 初始化边界检测器\n this.boundaryDetector = new BoundaryDetector({ containers: this.astBuilder.containerConfig })\n // 初始化 Definition 和 Footnote 管理器\n this.definitionManager = new DefinitionManager()\n this.footnoteManager = new FootnoteManager()\n }\n\n private generateBlockId(): string {\n return `block-${++this.blockIdCounter}`\n }\n\n /**\n * 更新已完成的 blocks 中的 definitions 和 footnote definitions\n */\n private updateDefinitionsFromCompletedBlocks(blocks: ParsedBlock[]): void {\n this.definitionManager.extractFromBlocks(blocks)\n this.footnoteManager.extractDefinitionsFromBlocks(blocks)\n }\n\n /**\n * 增量更新 lines 和 lineOffsets\n * 优化策略:只 split 新增的 chunk,不拼接旧字符串,避免长行性能劣化\n */\n private updateLines(chunk: string): void {\n const prevLineCount = this.lines.length\n\n // 1. 初始化情况\n if (prevLineCount === 0) {\n this.lines = chunk.split('\\n')\n this.lineOffsets = [0]\n // 计算后续行的 offset\n for (let i = 0; i < this.lines.length - 1; i++) {\n this.lineOffsets.push(this.lineOffsets[i] + this.lines[i].length + 1)\n }\n return\n }\n\n // 2. 增量更新情况\n // 关键优化:只对 chunk 进行 split,不触碰 oldText\n const chunkLines = chunk.split('\\n')\n const lastLineIndex = prevLineCount - 1\n\n // 步骤 A: 将 chunk 的第一部分追加到当前最后一行\n // 注意:这一步只会改变最后一行的内容长度,不会改变它的【起始偏移量】\n this.lines[lastLineIndex] += chunkLines[0]\n\n // 步骤 B: 如果 chunk 包含换行,处理新增的行\n for (let i = 1; i < chunkLines.length; i++) {\n // 这里的上一行(prevLine)可能是刚刚被追加过的 lastLine,也可能是 chunk 中间的新行\n // 我们需要根据\"上一行\"的 offset 和 length 来计算\"当前新行\"的 offset\n const prevLineIndex = this.lines.length - 1 // 总是取当前数组最后一行作为基准\n const prevLineStart = this.lineOffsets[prevLineIndex]\n const prevLineLength = this.lines[prevLineIndex].length\n\n // 计算新行的 offset = 上一行起始 + 上一行长度 + 1个换行符\n const newOneOffset = prevLineStart + prevLineLength + 1\n\n this.lineOffsets.push(newOneOffset)\n this.lines.push(chunkLines[i])\n }\n }\n\n /**\n * O(1) 获取行偏移量\n */\n private getLineOffset(lineIndex: number): number {\n return this.lineOffsets[lineIndex] ?? 0\n }\n\n /**\n * 查找稳定边界\n * 返回稳定边界行号和该行对应的上下文(用于后续更新,避免重复计算)\n */\n private findStableBoundary(): { line: number; contextAtLine: BlockContext } {\n const result = this.boundaryDetector.findStableBoundary(\n this.lines,\n this.pendingStartLine,\n this.context\n )\n return { line: result.line, contextAtLine: result.context }\n }\n\n /**\n * 追加新的 chunk 并返回增量更新\n */\n append(chunk: string): IncrementalUpdate {\n this.updateLines(chunk)\n\n const { line: stableBoundary, contextAtLine } = this.findStableBoundary()\n\n const update: IncrementalUpdate = {\n completed: [],\n updated: [],\n pending: [],\n ast: { type: 'root', children: [] },\n definitions: {},\n footnoteDefinitions: {},\n footnoteReferenceOrder: []\n }\n\n if (stableBoundary >= this.pendingStartLine && stableBoundary >= 0) {\n const stableText = this.lines.slice(this.pendingStartLine, stableBoundary + 1).join('\\n')\n const stableOffset = this.getLineOffset(this.pendingStartLine)\n\n const ast = this.astBuilder.parse(stableText)\n // 使用绝对偏移量,确保 Block 的位置信息正确\n const newBlocks = this.astBuilder.nodesToBlocks(ast.children, stableOffset, stableText, 'completed', () => this.generateBlockId())\n\n this.completedBlocks.push(...newBlocks)\n update.completed = newBlocks\n\n // 更新 definitions 从新完成的 blocks\n this.updateDefinitionsFromCompletedBlocks(newBlocks)\n\n // 增量收集脚注引用(只扫描新完成的 blocks)\n this.footnoteManager.collectReferencesFromCompletedBlocks(newBlocks)\n\n // 清理不再需要的上下文缓存\n this.boundaryDetector.clearContextCache(this.pendingStartLine)\n\n // 直接使用 findStableBoundary 计算好的上下文,避免重复遍历\n this.context = contextAtLine\n this.pendingStartLine = stableBoundary + 1\n }\n\n if (this.pendingStartLine < this.lines.length) {\n const pendingText = this.lines.slice(this.pendingStartLine).join('\\n')\n\n if (pendingText.trim()) {\n const pendingOffset = this.getLineOffset(this.pendingStartLine)\n const ast = this.astBuilder.parse(pendingText)\n // 使用绝对偏移量,确保 Block 的位置信息正确\n update.pending = this.astBuilder.nodesToBlocks(ast.children, pendingOffset, pendingText, 'pending', () => this.generateBlockId())\n }\n }\n\n // 缓存 pending blocks 供 getAst 使用\n this.lastPendingBlocks = update.pending\n\n update.ast = {\n type: 'root',\n children: [...this.completedBlocks.map((b) => b.node), ...update.pending.map((b) => b.node)]\n }\n\n // 使用优化的脚注引用收集(只扫描 pending 部分)\n update.footnoteReferenceOrder = this.footnoteManager.collectReferencesFromPending(update.pending)\n\n // 填充 definitions 和 footnote 相关数据\n update.definitions = this.getDefinitionMap()\n update.footnoteDefinitions = this.getFootnoteDefinitionMap()\n\n // 触发状态变化回调\n this.emitChange(update.pending)\n\n return update\n }\n\n /**\n * 触发状态变化回调\n */\n private emitChange(pendingBlocks: ParsedBlock[] = []): void {\n if (this.options.onChange) {\n const state: ParserState = {\n completedBlocks: this.completedBlocks,\n pendingBlocks,\n markdown: this.lines.join('\\n'),\n ast: {\n type: 'root',\n children: [\n ...this.completedBlocks.map((b) => b.node),\n ...pendingBlocks.map((b) => b.node)\n ]\n },\n definitions: { ...this.getDefinitionMap() },\n footnoteDefinitions: { ...this.getFootnoteDefinitionMap() }\n }\n this.options.onChange(state)\n }\n }\n\n /**\n * 标记解析完成,处理剩余内容\n * 也可用于强制中断时(如用户点击停止),将 pending 内容标记为 completed\n */\n finalize(): IncrementalUpdate {\n const update: IncrementalUpdate = {\n completed: [],\n updated: [],\n pending: [],\n ast: { type: 'root', children: [] },\n definitions: this.getDefinitionMap(),\n footnoteDefinitions: this.getFootnoteDefinitionMap(),\n footnoteReferenceOrder: this.getFootnoteReferenceOrder()\n }\n\n if (this.pendingStartLine < this.lines.length) {\n const remainingText = this.lines.slice(this.pendingStartLine).join('\\n')\n\n if (remainingText.trim()) {\n const remainingOffset = this.getLineOffset(this.pendingStartLine)\n const ast = this.astBuilder.parse(remainingText)\n // 使用绝对偏移量,确保 Block 的位置信息正确\n const finalBlocks = this.astBuilder.nodesToBlocks(\n ast.children,\n remainingOffset,\n remainingText,\n 'completed',\n () => this.generateBlockId()\n )\n\n this.completedBlocks.push(...finalBlocks)\n update.completed = finalBlocks\n\n // 更新 definitions 从最终完成的 blocks\n this.updateDefinitionsFromCompletedBlocks(finalBlocks)\n\n // 增量收集脚注引用(只扫描新完成的 blocks)\n this.footnoteManager.collectReferencesFromCompletedBlocks(finalBlocks)\n\n // 清理不再需要的上下文缓存\n this.boundaryDetector.clearContextCache(this.pendingStartLine)\n }\n }\n\n // 清空 pending 缓存\n this.lastPendingBlocks = []\n this.pendingStartLine = this.lines.length\n\n update.ast = {\n type: 'root',\n children: this.completedBlocks.map((b) => b.node)\n }\n\n // 填充 definitions 和 footnote 相关数据\n update.definitions = this.getDefinitionMap()\n update.footnoteDefinitions = this.getFootnoteDefinitionMap()\n update.footnoteReferenceOrder = this.getFootnoteReferenceOrder()\n\n // 触发状态变化回调\n this.emitChange([])\n\n return update\n }\n\n /**\n * 强制中断解析,将所有待处理内容标记为完成\n * @deprecated 请使用 finalize() 代替,功能完全相同\n */\n abort(): IncrementalUpdate {\n return this.finalize()\n }\n\n /**\n * 获取当前完整的 AST\n * 复用上次 append 的 pending 结果,避免重复解析\n */\n getAst(): Root {\n const children = [\n ...this.completedBlocks.map((b) => b.node),\n ...this.lastPendingBlocks.map((b) => b.node)\n ]\n\n // 使用优化的脚注引用收集\n this.footnoteManager.collectReferencesFromPending(this.lastPendingBlocks)\n\n return {\n type: 'root',\n children\n }\n }\n\n /**\n * 获取所有已完成的块\n */\n getCompletedBlocks(): ParsedBlock[] {\n return [...this.completedBlocks]\n }\n\n /**\n * 获取当前缓冲区内容\n */\n getBuffer(): string {\n return this.lines.join('\\n')\n }\n\n /**\n * 获取 Definition 映射表(用于引用式图片和链接)\n */\n getDefinitionMap(): DefinitionMap {\n return this.definitionManager.getAll()\n }\n\n /**\n * 获取 Footnote Definition 映射表\n */\n getFootnoteDefinitionMap(): FootnoteDefinitionMap {\n return this.footnoteManager.getDefinitions()\n }\n\n /**\n * 获取脚注引用的出现顺序\n */\n getFootnoteReferenceOrder(): string[] {\n return this.footnoteManager.getReferenceOrder()\n }\n\n /**\n * 设置状态变化回调(用于 DevTools 等)\n */\n setOnChange(callback: ((state: import('../types').ParserState) => void) | undefined): void {\n const originalOnChange = this.options.onChange;\n this.options.onChange = (state: ParserState) => {\n originalOnChange?.(state);\n callback?.(state);\n }\n }\n\n /**\n * 重置解析器状态\n */\n reset(): void {\n this.lines = []\n this.lineOffsets = [0]\n this.completedBlocks = []\n this.pendingStartLine = 0\n this.blockIdCounter = 0\n this.context = createInitialContext()\n this.lastPendingBlocks = []\n // 清空 definition 和 footnote 映射\n this.definitionManager.clear()\n this.footnoteManager.clear()\n\n // 触发状态变化回调\n this.emitChange([])\n }\n\n /**\n * 一次性渲染完整 Markdown(reset + append + finalize)\n * @param content 完整的 Markdown 内容\n * @returns 解析结果\n */\n render(content: string): IncrementalUpdate {\n this.reset()\n this.append(content)\n return this.finalize()\n }\n\n /**\n * 更新解析器配置(动态更新,不需要重建 parser 实例)\n *\n * 注意:更新配置后会自动调用 reset() 重置状态\n *\n * @param options 部分配置选项\n *\n * @example\n * ```ts\n * // 动态启用 TeX 数学公式语法\n * parser.updateOptions({ math: { tex: true } })\n *\n * // 禁用 GFM\n * parser.updateOptions({ gfm: false })\n *\n * // 切换引擎\n * import { MicromarkAstBuilder } from '@incremark/core/engines/micromark'\n * parser.updateOptions({ astBuilder: MicromarkAstBuilder })\n * ```\n */\n updateOptions(options: Partial<IncremarkParserOptions>): void {\n // 重置状态\n this.reset()\n\n // 合并选项\n Object.assign(this.options, options)\n\n if (options.astBuilder) {\n const BuilderClass = options.astBuilder\n if (!(this.astBuilder instanceof BuilderClass)) {\n this.astBuilder = new BuilderClass(this.options)\n } else {\n this.astBuilder.updateOptions(options)\n }\n } else {\n this.astBuilder.updateOptions(options)\n }\n }\n}\n\n/**\n * 创建 Incremark 解析器实例\n *\n * @param options 解析器配置\n * @param options.astBuilder 自定义 AST 构建器类(用于切换引擎)\n * @param options.plugins 统一插件列表\n *\n * @example\n * ```ts\n * // 使用默认的 marked 引擎(极速模式)\n * const parser = createIncremarkParser({ gfm: true, math: true })\n *\n * // 使用 micromark 引擎(需要单独导入,支持 tree-shaking)\n * import { MicromarkAstBuilder } from '@incremark/core/engines/micromark'\n * const parser = createIncremarkParser({\n * astBuilder: MicromarkAstBuilder,\n * gfm: true\n * })\n * ```\n */\nexport function createIncremarkParser(options?: IncremarkParserOptions): IncremarkParser {\n return new IncremarkParser(options)\n}\n","import type { RootContent, Text } from 'mdast'\nimport type { AstNode } from '../types'\n\n/**\n * 文本块片段(用于渐入动画)\n */\nexport interface TextChunk {\n /** 文本内容 */\n text: string\n /** 创建时间戳 */\n createdAt: number\n}\n\n/**\n * 扩展的文本节点(支持 chunks)\n */\nexport interface TextNodeWithChunks extends Text {\n /** 稳定部分的长度(不需要动画) */\n stableLength?: number\n /** 临时的文本片段,用于渐入动画 */\n chunks?: TextChunk[]\n}\n\n/**\n * 计算 AST 节点的总字符数\n */\nexport function countChars(node: RootContent): number {\n return countCharsInNode(node as AstNode)\n}\n\n/**\n * 计算单个 AST 节点的字符数(内部辅助函数)\n */\nfunction countCharsInNode(n: AstNode): number {\n if (n.value && typeof n.value === 'string') {\n return n.value.length\n }\n if (n.children && Array.isArray(n.children)) {\n let count = 0\n for (const child of n.children) {\n count += countCharsInNode(child)\n }\n return count\n }\n // 其他节点(如 thematicBreak, image)算作 1 个字符\n return 1\n}\n\n/**\n * 累积的 chunks 信息\n */\nexport interface AccumulatedChunks {\n /** 已经稳定显示的字符数(不需要动画) */\n stableChars: number\n /** 累积的 chunk 列表 */\n chunks: TextChunk[]\n}\n\n/** chunk 范围信息 */\ninterface ChunkRange {\n start: number\n end: number\n chunk: TextChunk\n}\n\n/**\n * 截断 AST 节点,只保留前 maxChars 个字符\n * 支持 chunks(用于渐入动画)\n * \n * 性能说明:\n * - 此函数每次调用都会从头遍历 AST 节点\n * - 但由于 BlockTransformer 是按 block 处理的,每次只遍历单个 block 的 AST\n * - 单个 block(如一个段落、一个代码块)通常只有几百个字符,性能开销很小\n * - 对于整个文档的渲染,已完成的 blocks 不会重新遍历\n * \n * @param node 原始节点(单个 block 的 AST)\n * @param maxChars 最大字符数\n * @param accumulatedChunks 累积的 chunks 信息(用于渐入动画)\n * @returns 截断后的节点,如果 maxChars <= 0 返回 null\n */\nexport function sliceAst(\n node: RootContent, \n maxChars: number,\n accumulatedChunks?: AccumulatedChunks\n): RootContent | null {\n if (maxChars <= 0) return null\n\n let remaining = maxChars\n let charIndex = 0\n \n // 计算 chunks 在文本中的范围\n const chunkRanges: ChunkRange[] = []\n if (accumulatedChunks && accumulatedChunks.chunks.length > 0) {\n let chunkStart = accumulatedChunks.stableChars\n for (const chunk of accumulatedChunks.chunks) {\n chunkRanges.push({\n start: chunkStart,\n end: chunkStart + chunk.text.length,\n chunk\n })\n chunkStart += chunk.text.length\n }\n }\n\n function process(n: AstNode): AstNode | null {\n if (remaining <= 0) return null\n\n // 文本类节点:截断 value,可能添加 chunks\n if (n.value && typeof n.value === 'string') {\n const nodeStart = charIndex\n const nodeEnd = charIndex + n.value.length\n \n const take = Math.min(n.value.length, remaining)\n remaining -= take\n charIndex = nodeEnd\n\n const slicedValue = n.value.slice(0, take)\n \n const result: AstNode & { stableLength?: number; chunks?: TextChunk[] } = { \n ...n, \n value: slicedValue \n }\n \n // 检查是否有 chunks 落在这个节点范围内\n if (chunkRanges.length > 0 && accumulatedChunks) {\n const nodeChunks: TextChunk[] = []\n let firstChunkLocalStart = take // 第一个 chunk 在节点中的起始位置\n \n for (const range of chunkRanges) {\n // 计算 chunk 与当前节点的交集\n const overlapStart = Math.max(range.start, nodeStart)\n const overlapEnd = Math.min(range.end, nodeStart + take)\n \n if (overlapStart < overlapEnd) {\n // 有交集,提取对应的文本(相对于 slicedValue)\n const localStart = overlapStart - nodeStart\n const localEnd = overlapEnd - nodeStart\n const chunkText = slicedValue.slice(localStart, localEnd)\n \n if (chunkText.length > 0) {\n // 记录第一个 chunk 的起始位置\n if (nodeChunks.length === 0) {\n firstChunkLocalStart = localStart\n }\n nodeChunks.push({\n text: chunkText,\n createdAt: range.chunk.createdAt\n })\n }\n }\n }\n \n if (nodeChunks.length > 0) {\n result.stableLength = firstChunkLocalStart\n result.chunks = nodeChunks\n }\n }\n \n return result\n }\n\n // 容器节点:递归处理 children\n if (n.children && Array.isArray(n.children)) {\n const newChildren: AstNode[] = []\n \n for (const child of n.children) {\n if (remaining <= 0) break\n \n const processed = process(child)\n \n if (processed) {\n newChildren.push(processed)\n }\n }\n \n if (newChildren.length === 0) {\n return null\n }\n return { ...n, children: newChildren }\n }\n\n // 其他节点(如 thematicBreak, image)\n remaining -= 1\n charIndex += 1\n return { ...n }\n }\n\n return process(node as AstNode) as RootContent | null\n}\n\n/**\n * 追加到 AST:将源节点截断到指定字符数,并与基础节点合并\n *\n * 实现说明:\n * - 完整截断 sourceNode 到 endChars,然后通过 smartMergeAst 复用已有节点引用\n * - 虽然每次都重新遍历,但由于只处理单个 block,性能开销很小\n * - smartMergeAst 确保前面已稳定的子节点引用被复用,减少 React/Vue 的重渲染\n *\n * @param baseNode 已截断的基础节点(稳定的部分)\n * @param sourceNode 原始完整节点(单个 block)\n * @param endChars 结束字符位置(新的进度)\n * @param accumulatedChunks 累积的 chunks 信息(用于渐入动画)\n * @returns 合并后的完整节点\n */\nexport function appendToAst(\n baseNode: RootContent,\n sourceNode: RootContent,\n endChars: number,\n accumulatedChunks?: AccumulatedChunks\n): RootContent {\n // 完整截断到 endChars,保留完整的结构信息\n const fullSlice = sliceAst(sourceNode, endChars, accumulatedChunks)\n\n // 如果截断失败,返回 baseNode\n if (!fullSlice) {\n return baseNode\n }\n\n // 智能合并:复用 baseNode 中已有的稳定节点引用\n return smartMergeAst(baseNode, fullSlice)\n}\n\n/**\n * 合并 AST 节点:复用已稳定的子节点引用\n *\n * 目的:\n * - 虽然 sliceAst 已经创建了新的节点对象,但通过复用 baseNode 中的子节点引用\n * - 可以让 React/Vue/Svelte 的 diff 算法识别出未变化的部分,减少 DOM 更新\n *\n * 策略:\n * - 容器节点:复用前面已完成的子节点引用,只替换最后一个(正在增长的)子节点\n * - 文本节点:直接使用 fullSlice(因为文本内容在变化)\n * - 这是一个\"事后优化\",不减少遍历开销,但减少框架层面的重渲染\n */\nfunction smartMergeAst(baseNode: RootContent, fullSlice: RootContent): RootContent {\n // 类型不同,直接返回 fullSlice\n if (baseNode.type !== fullSlice.type) {\n return fullSlice\n }\n\n const base = baseNode as AstNode\n const full = fullSlice as AstNode\n\n // 文本节点:直接使用 fullSlice(chunks 信息在 fullSlice 中)\n if (full.value !== undefined) {\n return fullSlice\n }\n\n // 容器节点:智能合并 children\n if (base.children && Array.isArray(base.children) && full.children && Array.isArray(full.children)) {\n // 如果 fullSlice 的 children 更少(不应该发生),直接返回 fullSlice\n if (full.children.length < base.children.length) {\n return fullSlice\n }\n\n // 如果 children 数量相同,只有最后一个 child 可能变化\n if (full.children.length === base.children.length) {\n if (base.children.length === 0) {\n return fullSlice\n }\n // 复用前面的稳定节点,只递归处理最后一个\n const lastIndex = base.children.length - 1\n const mergedLast = smartMergeAst(\n base.children[lastIndex] as RootContent,\n full.children[lastIndex] as RootContent\n )\n return {\n ...full,\n children: [\n ...base.children.slice(0, lastIndex),\n mergedLast as AstNode\n ]\n } as RootContent\n }\n\n // fullSlice 的 children 更多,说明有新的 child 被添加\n // 复用 base 的前 (base.children.length - 1) 个节点\n // 递归处理 base 的最后一个和 full 对应位置的节点\n // 然后追加 full 的新节点\n const baseLastIndex = base.children.length - 1\n const mergedLast = smartMergeAst(\n base.children[baseLastIndex] as RootContent,\n full.children[baseLastIndex] as RootContent\n )\n return {\n ...full,\n children: [\n ...base.children.slice(0, baseLastIndex),\n mergedLast as AstNode,\n ...full.children.slice(base.children.length)\n ]\n } as RootContent\n }\n\n // 其他情况,直接返回 fullSlice\n return fullSlice\n}\n\n/**\n * 深拷贝 AST 节点\n * 使用递归浅拷贝实现,比 JSON.parse/stringify 更高效\n * 且保持对象结构完整性\n */\nexport function cloneNode<T extends RootContent>(node: T): T {\n // 优先使用 structuredClone(Node 17+ / 现代浏览器)\n if (typeof structuredClone === 'function') {\n return structuredClone(node)\n }\n \n // 回退到递归拷贝\n return deepClone(node) as T\n}\n\n/**\n * 递归深拷贝对象\n */\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') {\n return obj\n }\n\n if (Array.isArray(obj)) {\n return obj.map(item => deepClone(item)) as T\n }\n\n const cloned = {} as T\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n cloned[key] = deepClone(obj[key])\n }\n }\n return cloned\n}\n","import type { RootContent } from 'mdast'\nimport type { AstNode } from '../types'\nimport type {\n SourceBlock,\n DisplayBlock,\n TransformerOptions,\n TransformerState,\n TransformerPlugin,\n AnimationEffect\n} from './types'\nimport { countChars as defaultCountChars, sliceAst as defaultSliceAst, appendToAst, type TextChunk, type AccumulatedChunks } from './utils'\n\n/**\n * Block Transformer\n *\n * 用于控制 blocks 的逐步显示(打字机效果)\n * 作为解析器和渲染器之间的中间层\n *\n * 特性:\n * - 使用 requestAnimationFrame 实现流畅动画\n * - 支持随机步长,模拟真实打字效果\n * - 支持 typing 动画效果\n * - 页面不可见时自动暂停,节省资源\n * - 插件系统支持自定义节点处理\n *\n * @example\n * ```typescript\n * const transformer = new BlockTransformer({\n * charsPerTick: [1, 3], // 随机 1-3 个字符\n * tickInterval: 30,\n * effect: 'typing',\n * onChange: (displayBlocks) => {\n * // 更新 UI\n * }\n * })\n *\n * // 推入新 blocks\n * transformer.push(blocks)\n *\n * // 获取当前显示状态\n * const displayBlocks = transformer.getDisplayBlocks()\n * ```\n */\nexport class BlockTransformer<T = unknown> {\n private state: TransformerState<T>\n private options: {\n charsPerTick: number | [number, number]\n tickInterval: number\n effect: AnimationEffect\n plugins: TransformerPlugin[]\n onChange: (displayBlocks: DisplayBlock<T>[]) => void\n onAllComplete: (() => void) | null\n pauseOnHidden: boolean\n }\n private rafId: number | null = null\n private lastTickTime = 0\n private isRunning = false\n private isPaused = false\n private chunks: TextChunk[] = [] // 累积的 chunks(用于 fade-in 动画)\n private visibilityHandler: (() => void) | null = null\n \n // ============ 性能优化:缓存机制 ============\n /** 缓存的已截断 displayNode(稳定的部分,避免重复遍历) */\n private cachedDisplayNode: RootContent | null = null\n /** 缓存的字符数(避免重复计算) */\n private cachedTotalChars: number | null = null\n /** 当前缓存的进度(对应 cachedDisplayNode) */\n private cachedProgress: number = 0\n\n constructor(options: TransformerOptions = {}) {\n this.options = {\n charsPerTick: options.charsPerTick ?? 1,\n tickInterval: options.tickInterval ?? 20,\n effect: options.effect ?? 'none',\n plugins: options.plugins ?? [],\n onChange: options.onChange ?? (() => {}),\n onAllComplete: options.onAllComplete ?? null,\n pauseOnHidden: options.pauseOnHidden ?? true\n }\n\n this.state = {\n completedBlocks: [],\n currentBlock: null,\n currentProgress: 0,\n pendingBlocks: []\n }\n\n // 设置页面可见性监听\n if (this.options.pauseOnHidden && typeof document !== 'undefined') {\n this.setupVisibilityHandler()\n }\n }\n\n /**\n * 推入新的 blocks\n * 会自动过滤已存在的 blocks\n */\n push(blocks: SourceBlock<T>[]): void {\n const existingIds = this.getAllBlockIds()\n\n // 找出新增的 blocks\n const newBlocks = blocks.filter((b) => !existingIds.has(b.id))\n\n if (newBlocks.length > 0) {\n this.state.pendingBlocks.push(...newBlocks)\n this.startIfNeeded()\n }\n\n // 如果当前正在显示的 block 内容更新了(pending block 变化)\n if (this.state.currentBlock) {\n const updated = blocks.find((b) => b.id === this.state.currentBlock!.id)\n if (updated && updated.node !== this.state.currentBlock.node) {\n // 使用统一的方法处理内容变化\n this.handleContentChange(this.state.currentBlock.node, updated.node, true)\n // 更新引用\n this.state.currentBlock = updated\n }\n }\n }\n\n /**\n * 更新指定 block(用于 pending block 内容增加时)\n */\n update(block: SourceBlock<T>): void {\n if (this.state.currentBlock?.id === block.id) {\n // 使用统一的方法处理内容变化\n this.handleContentChange(this.state.currentBlock.node, block.node, false)\n this.state.currentBlock = block\n }\n }\n\n /**\n * 跳过所有动画,直接显示全部内容\n */\n skip(): void {\n this.stop()\n\n const allBlocks = [\n ...this.state.completedBlocks,\n ...(this.state.currentBlock ? [this.state.currentBlock] : []),\n ...this.state.pendingBlocks\n ]\n\n this.state = {\n completedBlocks: allBlocks,\n currentBlock: null,\n currentProgress: 0,\n pendingBlocks: []\n }\n this.chunks = []\n this.clearCache()\n\n this.emit()\n // 跳过动画也视为完成\n this.options.onAllComplete?.()\n }\n\n /**\n * 重置状态\n */\n reset(): void {\n this.stop()\n this.state = {\n completedBlocks: [],\n currentBlock: null,\n currentProgress: 0,\n pendingBlocks: []\n }\n this.chunks = []\n this.clearCache()\n this.emit()\n }\n\n /**\n * 暂停动画\n */\n pause(): void {\n this.isPaused = true\n this.cancelRaf()\n }\n\n /**\n * 恢复动画\n */\n resume(): void {\n if (this.isPaused) {\n this.isPaused = false\n this.startIfNeeded()\n }\n }\n\n /**\n * 获取用于渲染的 display blocks\n * 优化:使用缓存的 displayNode,避免重复遍历已稳定的节点\n */\n getDisplayBlocks(): DisplayBlock<T>[] {\n const result: DisplayBlock<T>[] = []\n\n // 已完成的 blocks\n for (const block of this.state.completedBlocks) {\n result.push({\n ...block,\n displayNode: block.node,\n progress: 1,\n isDisplayComplete: true\n })\n }\n\n // 当前正在显示的 block\n if (this.state.currentBlock) {\n // 使用缓存的字符数\n const total = this.getTotalChars()\n \n // 如果进度变化了或缓存无效,更新缓存的 displayNode\n if (this.state.currentProgress !== this.cachedProgress || !this.cachedDisplayNode) {\n this.updateCachedDisplayNode()\n }\n\n result.push({\n ...this.state.currentBlock,\n displayNode: this.cachedDisplayNode || { type: 'paragraph', children: [] },\n progress: total > 0 ? this.state.currentProgress / total : 1,\n isDisplayComplete: false\n })\n }\n\n return result\n }\n\n /**\n * 是否正在处理中\n */\n isProcessing(): boolean {\n return this.isRunning || this.state.currentBlock !== null || this.state.pendingBlocks.length > 0\n }\n\n /**\n * 是否已暂停\n */\n isPausedState(): boolean {\n return this.isPaused\n }\n\n /**\n * 获取内部状态(用于调试)\n */\n getState(): Readonly<TransformerState<T>> {\n return { ...this.state }\n }\n\n /**\n * 动态更新配置\n */\n setOptions(options: Partial<Pick<TransformerOptions, 'charsPerTick' | 'tickInterval' | 'effect' | 'pauseOnHidden'>>): void {\n if (options.charsPerTick !== undefined) {\n this.options.charsPerTick = options.charsPerTick\n }\n if (options.tickInterval !== undefined) {\n this.options.tickInterval = options.tickInterval\n }\n if (options.effect !== undefined) {\n this.options.effect = options.effect\n }\n if (options.pauseOnHidden !== undefined) {\n this.options.pauseOnHidden = options.pauseOnHidden\n if (options.pauseOnHidden && typeof document !== 'undefined') {\n this.setupVisibilityHandler()\n } else {\n this.removeVisibilityHandler()\n }\n }\n }\n\n /**\n * 获取当前配置\n */\n getOptions(): { \n charsPerTick: number | [number, number]\n tickInterval: number\n effect: AnimationEffect\n } {\n return {\n charsPerTick: this.options.charsPerTick,\n tickInterval: this.options.tickInterval,\n effect: this.options.effect\n }\n }\n\n /**\n * 获取当前动画效果\n */\n getEffect(): AnimationEffect {\n return this.options.effect\n }\n\n /**\n * 销毁,清理资源\n */\n destroy(): void {\n this.stop()\n this.removeVisibilityHandler()\n }\n\n // ============ 私有方法 ============\n\n /**\n * 处理 block 内容更新时的字符数变化和进度调整\n * 统一 push 和 update 方法中的重复逻辑\n */\n private handleContentChange(\n oldNode: RootContent,\n newNode: RootContent,\n isUpdateFromPush?: boolean\n ): void {\n const oldTotal = this.cachedTotalChars ?? this.countChars(oldNode)\n const newTotal = this.countChars(newNode)\n\n // 如果字符数减少了(AST 结构变化,如 **xxx 变成 **xxx**)\n // 重新计算进度,保持相对位置,并清除 chunks\n if (newTotal < oldTotal || newTotal < this.state.currentProgress) {\n this.state.currentProgress = Math.min(this.state.currentProgress, newTotal)\n // AST 结构变化,chunks 可能错位,需要清除\n this.chunks = []\n }\n\n // 内容变化,清除缓存\n this.clearCache()\n\n // 如果是 push 方法调用的更新,可能需要重新开始动画\n if (isUpdateFromPush) {\n // 如果之前暂停了(因为到达末尾),重新开始\n if (!this.rafId && !this.isPaused) {\n if (this.state.currentProgress < newTotal) {\n this.startIfNeeded()\n }\n }\n } else {\n // 如果是 update 方法调用的更新,内容增加了且之前暂停了,继续\n if (newTotal > oldTotal && !this.rafId && !this.isPaused && this.state.currentProgress >= oldTotal) {\n this.startIfNeeded()\n }\n }\n }\n\n private getAllBlockIds(): Set<string> {\n return new Set([\n ...this.state.completedBlocks.map((b) => b.id),\n this.state.currentBlock?.id,\n ...this.state.pendingBlocks.map((b) => b.id)\n ].filter((id): id is string => id !== undefined))\n }\n\n private setupVisibilityHandler(): void {\n if (this.visibilityHandler) return\n\n this.visibilityHandler = () => {\n if (document.hidden) {\n this.pause()\n } else {\n this.resume()\n }\n }\n\n document.addEventListener('visibilitychange', this.visibilityHandler)\n }\n\n private removeVisibilityHandler(): void {\n if (this.visibilityHandler) {\n document.removeEventListener('visibilitychange', this.visibilityHandler)\n this.visibilityHandler = null\n }\n }\n\n private startIfNeeded(): void {\n if (this.rafId || this.isPaused) return\n\n if (!this.state.currentBlock && this.state.pendingBlocks.length > 0) {\n this.state.currentBlock = this.state.pendingBlocks.shift()!\n this.state.currentProgress = 0\n this.clearCache() // 新 block,清除缓存\n }\n\n if (this.state.currentBlock) {\n this.isRunning = true\n this.lastTickTime = 0\n this.scheduleNextFrame()\n }\n }\n\n private scheduleNextFrame(): void {\n this.rafId = requestAnimationFrame((time) => this.animationFrame(time))\n }\n\n private animationFrame(time: number): void {\n this.rafId = null\n\n // 计算是否应该执行 tick\n if (this.lastTickTime === 0) {\n this.lastTickTime = time\n }\n\n const elapsed = time - this.lastTickTime\n\n if (elapsed >= this.options.tickInterval) {\n this.lastTickTime = time\n this.tick()\n }\n\n // 如果还在运行,继续调度\n if (this.isRunning && !this.isPaused) {\n this.scheduleNextFrame()\n }\n }\n\n private tick(): void {\n const block = this.state.currentBlock\n if (!block) {\n this.processNext()\n return\n }\n\n // 使用缓存的字符数,避免重复计算\n const total = this.getTotalChars()\n const step = this.getStep()\n const prevProgress = this.state.currentProgress\n \n this.state.currentProgress = Math.min(prevProgress + step, total)\n\n // 如果是 fade-in 效果,添加新的 chunk\n if (this.options.effect === 'fade-in' && this.state.currentProgress > prevProgress) {\n // 从 block.node 中提取新增的字符\n const newText = this.extractText(block.node, prevProgress, this.state.currentProgress)\n if (newText.length > 0) {\n this.chunks.push({\n text: newText,\n createdAt: Date.now()\n })\n }\n }\n\n this.emit()\n\n if (this.state.currentProgress >= total) {\n // 当前 block 完成,清空 chunks 和缓存\n this.notifyComplete(block.node)\n this.state.completedBlocks.push(block)\n this.state.currentBlock = null\n this.state.currentProgress = 0\n this.chunks = []\n this.clearCache()\n this.processNext()\n }\n }\n\n /**\n * 从 AST 节点中提取指定范围的文本\n *\n * 优化说明:\n * - 提前终止:当 charIndex >= end 时立即返回,避免不必要的遍历\n * - 局部更新:charIndex 只在需要时更新,减少计算\n * - 早期返回:发现足够的文本后可以提前退出(当前未实现,可作为未来优化)\n *\n * @param node 要提取文本的 AST 节点\n * @param start 起始字符索引(包含)\n * @param end 结束字符索引(不包含)\n * @returns 提取的文本\n */\n private extractText(node: RootContent, start: number, end: number): string {\n // 快速路径:空范围或无效范围\n if (start >= end) {\n return ''\n }\n\n let result = ''\n let charIndex = 0\n\n function traverse(n: AstNode): boolean {\n // 提前终止:已达到目标范围\n if (charIndex >= end) return false\n\n if (n.value && typeof n.value === 'string') {\n const nodeStart = charIndex\n const nodeEnd = charIndex + n.value.length\n const overlapStart = Math.max(start, nodeStart)\n const overlapEnd = Math.min(end, nodeEnd)\n\n // 只有当节点与目标范围有交集时才处理\n if (overlapStart < overlapEnd) {\n result += n.value.slice(overlapStart - nodeStart, overlapEnd - nodeStart)\n }\n\n // 更新索引(仅在处理文本节点后)\n charIndex = nodeEnd\n return charIndex < end\n }\n\n if (n.children && Array.isArray(n.children)) {\n for (const child of n.children) {\n if (!traverse(child)) return false\n }\n }\n\n return true\n }\n\n traverse(node as AstNode)\n return result\n }\n\n private getStep(): number {\n const { charsPerTick } = this.options\n if (typeof charsPerTick === 'number') {\n return charsPerTick\n }\n // 随机步长\n const [min, max] = charsPerTick\n return Math.floor(Math.random() * (max - min + 1)) + min\n }\n\n private processNext(): void {\n if (this.state.pendingBlocks.length > 0) {\n this.state.currentBlock = this.state.pendingBlocks.shift()!\n this.state.currentProgress = 0\n this.chunks = []\n this.clearCache() // 新 block,清除缓存\n this.emit()\n // 继续运行(rAF 已经在调度中)\n } else {\n this.isRunning = false\n this.cancelRaf()\n this.emit()\n // 所有动画完成,触发回调\n this.options.onAllComplete?.()\n }\n }\n\n private cancelRaf(): void {\n if (this.rafId) {\n cancelAnimationFrame(this.rafId)\n this.rafId = null\n }\n }\n\n private stop(): void {\n this.cancelRaf()\n this.isRunning = false\n this.isPaused = false\n }\n\n private emit(): void {\n this.options.onChange(this.getDisplayBlocks())\n }\n\n // ============ 插件调用 ============\n\n private countChars(node: RootContent): number {\n // 先找匹配的插件\n for (const plugin of this.options.plugins) {\n if (plugin.match?.(node) && plugin.countChars) {\n const result = plugin.countChars(node)\n if (result !== undefined) return result\n }\n }\n // 默认计算\n return defaultCountChars(node)\n }\n\n private sliceNode(node: RootContent, chars: number, accumulatedChunks?: AccumulatedChunks): RootContent | null {\n // 先找匹配的插件\n for (const plugin of this.options.plugins) {\n if (plugin.match?.(node) && plugin.sliceNode) {\n const total = this.countChars(node)\n const result = plugin.sliceNode(node, chars, total)\n if (result !== null) return result\n }\n }\n // 默认截断,传入累积的 chunks\n return defaultSliceAst(node, chars, accumulatedChunks)\n }\n\n private notifyComplete(node: RootContent): void {\n for (const plugin of this.options.plugins) {\n if (plugin.match?.(node) && plugin.onComplete) {\n plugin.onComplete(node)\n }\n }\n }\n\n // ============ 缓存管理方法 ============\n\n /**\n * 更新缓存的 displayNode\n * 使用真正的增量追加模式:只处理新增部分,不重复遍历已稳定的节点\n */\n private updateCachedDisplayNode(): void {\n const block = this.state.currentBlock\n if (!block) {\n this.cachedDisplayNode = null\n this.cachedProgress = 0\n return\n }\n\n const currentProgress = this.state.currentProgress\n\n // 如果进度减少了(内容更新导致),需要重新截断\n if (currentProgress < this.cachedProgress) {\n this.cachedDisplayNode = this.sliceNode(\n block.node,\n currentProgress,\n this.getAccumulatedChunks()\n )\n this.cachedProgress = currentProgress\n return\n }\n\n // 如果进度增加了,使用追加模式\n if (currentProgress > this.cachedProgress && this.cachedDisplayNode) {\n // 截断并合并:复用已稳定的节点引用,减少框架重渲染\n this.cachedDisplayNode = appendToAst(\n this.cachedDisplayNode,\n block.node,\n currentProgress,\n this.getAccumulatedChunks()\n )\n this.cachedProgress = currentProgress\n } else if (!this.cachedDisplayNode) {\n // 首次截断\n this.cachedDisplayNode = this.sliceNode(\n block.node,\n currentProgress,\n this.getAccumulatedChunks()\n )\n this.cachedProgress = currentProgress\n }\n }\n\n /**\n * 获取总字符数(带缓存)\n *\n * 缓存策略:\n * - 首次调用时计算并缓存\n * - 内容更新时通过 clearCache() 清除缓存,下次重新计算\n * - 切换到新 block 时也会清除缓存\n */\n private getTotalChars(): number {\n // 没有当前 block 时返回 0\n if (!this.state.currentBlock) {\n this.cachedTotalChars = null\n return 0\n }\n\n // 缓存为空时计算\n if (this.cachedTotalChars === null) {\n this.cachedTotalChars = this.countChars(this.state.currentBlock.node)\n }\n\n return this.cachedTotalChars\n }\n\n /**\n * 清除缓存(当 block 切换或内容更新时)\n */\n private clearCache(): void {\n this.cachedDisplayNode = null\n this.cachedTotalChars = null\n this.cachedProgress = 0\n }\n\n /**\n * 获取累积的 chunks(用于 fade-in 效果)\n * stableChars 表示在 chunks 之前的稳定字符数\n */\n private getAccumulatedChunks(): AccumulatedChunks | undefined {\n if (this.options.effect === 'fade-in' && this.chunks.length > 0) {\n // 计算 chunks 之前的稳定字符数\n // 当前进度 = stableChars + 所有 chunks 的长度\n const chunksLength = this.chunks.reduce((sum, c) => sum + c.text.length, 0)\n const stableChars = this.state.currentProgress - chunksLength\n return { stableChars: Math.max(0, stableChars), chunks: this.chunks }\n }\n return undefined\n }\n}\n\n/**\n * 创建 BlockTransformer 实例的工厂函数\n */\nexport function createBlockTransformer<T = unknown>(\n options?: TransformerOptions\n): BlockTransformer<T> {\n return new BlockTransformer<T>(options)\n}\n\n\n\n","import type { RootContent, Code } from 'mdast'\nimport type { TransformerPlugin } from './types'\n\n/**\n * 代码块插件:整体出现,不逐字符显示\n * \n * 注意:默认不启用,代码块默认参与打字机效果\n * 如需整体显示代码块,可手动添加此插件\n */\nexport const codeBlockPlugin: TransformerPlugin = {\n name: 'code-block',\n match: (node: RootContent) => node.type === 'code',\n countChars: () => 1, // 算作 1 个字符,整体出现\n sliceNode: (node, displayedChars, totalChars) => {\n // 要么全部显示,要么不显示\n return displayedChars >= totalChars ? node : null\n }\n}\n\n/**\n * Mermaid 图表插件:整体出现\n * \n * 注意:默认不启用,mermaid 默认参与打字机效果\n * 如需整体显示 mermaid,可手动添加此插件\n */\nexport const mermaidPlugin: TransformerPlugin = {\n name: 'mermaid',\n match: (node: RootContent) => {\n if (node.type !== 'code') return false\n const codeNode = node as Code\n return codeNode.lang === 'mermaid'\n },\n countChars: () => 1,\n sliceNode: (node, displayedChars) => (displayedChars > 0 ? node : null)\n}\n\n/**\n * 图片插件:立即显示(不参与打字机效果)\n * 图片没有文本内容,应立即显示\n */\nexport const imagePlugin: TransformerPlugin = {\n name: 'image',\n match: (node: RootContent) => node.type === 'image',\n countChars: () => 0 // 0 字符,立即显示\n}\n\n/**\n * 数学公式插件:整体出现\n * \n * 注意:默认不启用,数学公式默认参与打字机效果\n * 如需整体显示公式,可手动添加此插件\n */\nexport const mathPlugin: TransformerPlugin = {\n name: 'math',\n match: (node: RootContent) => {\n const type = node.type as string\n return type === 'math' || type === 'inlineMath'\n },\n countChars: () => 1,\n sliceNode: (node, displayedChars) => (displayedChars > 0 ? node : null)\n}\n\n/**\n * 分割线插件:立即显示\n * 分隔线没有文本内容,应立即显示\n */\nexport const thematicBreakPlugin: TransformerPlugin = {\n name: 'thematic-break',\n match: (node: RootContent) => node.type === 'thematicBreak',\n countChars: () => 0\n}\n\n/**\n * 默认插件集合\n * \n * 只包含确实需要特殊处理的节点:\n * - 图片:无文本内容,立即显示\n * - 分隔线:无文本内容,立即显示\n * \n * 代码块、mermaid、数学公式默认参与打字机效果\n * 如需整体显示,可手动添加对应插件\n */\nexport const defaultPlugins: TransformerPlugin[] = [\n imagePlugin,\n thematicBreakPlugin\n]\n\n/**\n * 完整插件集合(所有特殊节点整体显示)\n * 包含代码块、mermaid、数学公式等的整体显示\n */\nexport const allPlugins: TransformerPlugin[] = [\n mermaidPlugin, // mermaid 优先于普通 code block\n codeBlockPlugin,\n imagePlugin,\n mathPlugin,\n thematicBreakPlugin\n]\n\n/**\n * 创建自定义插件的辅助函数\n */\nexport function createPlugin(\n name: string,\n matcher: (node: RootContent) => boolean,\n options: Partial<Omit<TransformerPlugin, 'name' | 'match'>> = {}\n): TransformerPlugin {\n return {\n name,\n match: matcher,\n ...options\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/detector/index.ts","../src/parser/boundary/BoundaryDetector.ts","../src/utils/index.ts","../src/parser/manager/DefinitionManager.ts","../src/parser/manager/FootnoteManager.ts","../src/extensions/html-extension/index.ts","../src/parser/ast/types.ts","../src/extensions/marked-extensions/explicitDefinitionExtension.ts","../src/extensions/marked-extensions/optimisticReferenceExtension.ts","../src/extensions/marked-extensions/mathExtension.ts","../src/extensions/marked-extensions/footnoteDefinitionExtension.ts","../src/extensions/marked-extensions/inlineHtmlExtension.ts","../src/parser/ast/markedHelpers.ts","../src/parser/ast/MarkedAstBuildter.ts","../src/parser/IncremarkParser.ts","../src/transformer/utils.ts","../src/transformer/BlockTransformer.ts","../src/transformer/plugins.ts"],"names":["node","match","Lexer","mergedLast"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * 块类型检测与边界判断\n *\n * Markdown 块级元素的识别规则\n */\n\nimport type { BlockContext, ContainerConfig, ContainerMatch } from '../types'\n\n// ============ 预编译正则表达式(性能优化) ============\n\nconst RE_FENCE_START = /^(\\s*)((`{3,})|(~{3,}))/\nconst RE_EMPTY_LINE = /^\\s*$/\nconst RE_HEADING = /^#{1,6}\\s/\nconst RE_THEMATIC_BREAK = /^(\\*{3,}|-{3,}|_{3,})\\s*$/\nconst RE_UNORDERED_LIST = /^(\\s*)([-*+])\\s/\nconst RE_ORDERED_LIST = /^(\\s*)(\\d{1,9})[.)]\\s/\nconst RE_BLOCKQUOTE = /^\\s{0,3}>/\nconst RE_HTML_BLOCK_1 = /^\\s{0,3}<(script|pre|style|textarea|!--|!DOCTYPE|\\?|!\\[CDATA\\[)/i\nconst RE_HTML_BLOCK_2 = /^\\s{0,3}<\\/?[a-zA-Z][a-zA-Z0-9-]*(\\s|>|$)/\nconst RE_TABLE_DELIMITER = /^\\|?\\s*:?-{3,}:?\\s*(\\|\\s*:?-{3,}:?\\s*)*\\|?$/\nconst RE_ESCAPE_SPECIAL = /[.*+?^${}()|[\\]\\\\]/g\nconst RE_FOOTNOTE_DEFINITION = /^\\[\\^([^\\]]+)\\]:\\s/\nconst RE_FOOTNOTE_CONTINUATION = /^(?: |\\t)/\n\n/** fence 结束模式缓存 */\nconst fenceEndPatternCache = new Map<string, RegExp>()\n\n/** 容器模式缓存 */\nconst containerPatternCache = new Map<string, RegExp>()\n\n// ============ 代码块检测 ============\n\n/**\n * 检测行是否是代码块 fence 开始\n */\nexport function detectFenceStart(line: string): { char: string; length: number } | null {\n const match = line.match(RE_FENCE_START)\n if (match) {\n const fence = match[2]\n const char = fence[0]\n return { char, length: fence.length }\n }\n return null\n}\n\n/**\n * 检测行是否是代码块 fence 结束\n */\nexport function detectFenceEnd(line: string, context: BlockContext): boolean {\n if (!context.inFencedCode || !context.fenceChar || !context.fenceLength) {\n return false\n }\n\n // 使用缓存的正则表达式\n const cacheKey = `${context.fenceChar}-${context.fenceLength}`\n let pattern = fenceEndPatternCache.get(cacheKey)\n if (!pattern) {\n pattern = new RegExp(`^\\\\s{0,3}${context.fenceChar}{${context.fenceLength},}\\\\s*$`)\n fenceEndPatternCache.set(cacheKey, pattern)\n }\n return pattern.test(line)\n}\n\n// ============ 行类型检测 ============\n\n/**\n * 检测是否是空行或仅包含空白字符\n */\nexport function isEmptyLine(line: string): boolean {\n return RE_EMPTY_LINE.test(line)\n}\n\n/**\n * 检测是否是 Setext 标题下划线(=== 或 ---)\n * @param line 当前行\n * @param prevLine 前一行\n * @returns 是否是 Setext 标题下划线\n */\nexport function isSetextHeadingUnderline(line: string, prevLine?: string): boolean {\n const trimmed = line.trim()\n\n // 检查是否是 === 或 --- 形式的下划线\n if (!/^={3,}$|^-{3,}$/.test(trimmed)) {\n return false\n }\n\n // 如果没有前一行,不能判断\n if (!prevLine) {\n return false\n }\n\n const trimmedPrev = prevLine.trim()\n\n // 前一行是空行,不是 Setext 标题\n if (trimmedPrev === '') {\n return false\n }\n\n // 前一行是 ATX 标题或 thematic break,不是 Setext 标题\n if (/^#{1,6}\\s/.test(trimmedPrev) || /^(\\*{3,}|-{3,}|_{3,})\\s*$/.test(trimmedPrev)) {\n return false\n }\n\n // 前一行是列表项,不是 Setext 标题\n if (/^(\\s*)([-*+])\\s/.test(trimmedPrev) || /^(\\s*)(\\d{1,9})[.)]\\s/.test(trimmedPrev)) {\n return false\n }\n\n // 前一行是引用块,不是 Setext 标题\n if (/^\\s{0,3}>/.test(trimmedPrev)) {\n return false\n }\n\n // 前一行是代码块 fence,不是 Setext 标题\n if (/^(\\s*)(`{3,}|~{3,})/.test(trimmedPrev)) {\n return false\n }\n\n // 检查下划线行的缩进(不超过3个空格)\n const underlineIndent = line.match(/^(\\s*)/)?.[1].length ?? 0\n if (underlineIndent > 3) {\n return false\n }\n\n // 检查前一行缩进(不超过3个空格)\n const contentIndent = prevLine.match(/^(\\s*)/)?.[1].length ?? 0\n if (contentIndent > 3) {\n return false\n }\n\n return true\n}\n\n/**\n * 检测是否是标题行\n */\nexport function isHeading(line: string): boolean {\n return RE_HEADING.test(line)\n}\n\n/**\n * 检测是否是 thematic break(水平线)\n */\nexport function isThematicBreak(line: string): boolean {\n return RE_THEMATIC_BREAK.test(line.trim())\n}\n\n/**\n * 检测是否是列表项开始\n *\n * CommonMark 规范:列表项可以是以下形式:\n * - `- text`(无缩进)\n * - `1. text`(有序列表)\n * - ` - text`(缩进4个空格,作为上一个列表项的延续)\n *\n * 注意:` - text` 这种形式,虽然 `-` 后面没有空格,\n * 但因为前面有4个空格的缩进,所以是列表项的有效形式。\n */\nexport function isListItemStart(line: string): { ordered: boolean; indent: number } | null {\n // 先检查是否以列表标记开头(-、*、+、数字)\n const hasListMarker = /^(\\s*)([-*+]|\\d{1,9}[.)])/.test(line)\n \n if (!hasListMarker) {\n return null\n }\n \n // 如果有列表标记,检查是否是列表项的延续(缩进4+个空格)\n const match = line.match(/^(\\s*)([-*+]|\\d{1,9}[.)])(.*)/)\n if (match) {\n const indent = match[1].length\n const marker = match[2]\n const rest = match[3]\n \n // 如果标记后有内容,检查是否是有效的列表项\n if (rest.trim()) {\n const isOrdered = /^\\d{1,9}[.)]/.test(marker)\n return { ordered: isOrdered, indent }\n }\n \n // 标记后只有空格,可能是缩进的列表项\n // 如 \" - text\" 或 \" 1. text\"\n if (/^\\s+$/.test(rest)) {\n const isOrdered = /^\\d{1,9}[.)]/.test(marker)\n return { ordered: isOrdered, indent }\n }\n }\n \n return null\n}\n\n/**\n * 检测是否是引用块开始\n */\nexport function isBlockquoteStart(line: string): boolean {\n return RE_BLOCKQUOTE.test(line)\n}\n\n/**\n * 检测是否是 HTML 块\n */\nexport function isHtmlBlock(line: string): boolean {\n return RE_HTML_BLOCK_1.test(line) || RE_HTML_BLOCK_2.test(line)\n}\n\n/**\n * 检测表格分隔行\n */\nexport function isTableDelimiter(line: string): boolean {\n return RE_TABLE_DELIMITER.test(line.trim())\n}\n\n// ============ 脚注检测 ============\n\n/**\n * 检测是否是脚注定义的起始行\n * 格式: [^id]: content\n * \n * @example\n * isFootnoteDefinitionStart('[^1]: 脚注内容') // true\n * isFootnoteDefinitionStart('[^note]: 内容') // true\n * isFootnoteDefinitionStart(' 缩进内容') // false\n */\nexport function isFootnoteDefinitionStart(line: string): boolean {\n return RE_FOOTNOTE_DEFINITION.test(line)\n}\n\n/**\n * 检测是否是脚注定义的延续行(缩进行)\n * 至少4个空格或1个tab\n * \n * @example\n * isFootnoteContinuation(' 第二行') // true\n * isFootnoteContinuation('\\t第二行') // true\n * isFootnoteContinuation(' 两个空格') // false\n */\nexport function isFootnoteContinuation(line: string): boolean {\n return RE_FOOTNOTE_CONTINUATION.test(line)\n}\n\n// ============ 容器检测 ============\n\n/**\n * 检测容器开始或结束\n *\n * 支持格式:\n * - ::: name 开始\n * - ::: name attr 开始(带属性)\n * - ::: 结束\n * - :::::: name 开始(更长的标记,用于嵌套)\n */\nexport function detectContainer(line: string, config?: ContainerConfig): ContainerMatch | null {\n const marker = config?.marker || ':'\n const minLength = config?.minMarkerLength || 3\n\n // 使用缓存的正则表达式\n const cacheKey = `${marker}-${minLength}`\n let pattern = containerPatternCache.get(cacheKey)\n if (!pattern) {\n const escapedMarker = marker.replace(RE_ESCAPE_SPECIAL, '\\\\$&')\n // 支持两种格式:\n // 1. ::: name attr (有空格分隔)\n // 2. :::name{...} (directive 语法,无空格)\n pattern = new RegExp(\n `^(\\\\s*)(${escapedMarker}{${minLength},})(?:\\\\s*(\\\\w[\\\\w-]*))?(?:\\\\{[^}]*\\\\})?(?:\\\\s+(.*))?\\\\s*$`\n )\n containerPatternCache.set(cacheKey, pattern)\n }\n\n const match = line.match(pattern)\n if (!match) {\n return null\n }\n\n const markerLength = match[2].length\n const name = match[3] || ''\n const isEnd = !name && !match[4]\n\n if (!isEnd && config?.allowedNames && config.allowedNames.length > 0) {\n if (!config.allowedNames.includes(name)) {\n return null\n }\n }\n\n return { name, markerLength, isEnd }\n}\n\n/**\n * 检测容器结束\n */\nexport function detectContainerEnd(\n line: string,\n context: BlockContext,\n config?: ContainerConfig\n): boolean {\n if (!context.inContainer || !context.containerMarkerLength) {\n return false\n }\n\n const result = detectContainer(line, config)\n if (!result) {\n return false\n }\n\n return result.isEnd && result.markerLength >= context.containerMarkerLength\n}\n\n// ============ 边界检测 ============\n\n/**\n * 判断两行之间是否构成块边界\n */\nexport function isBlockBoundary(\n prevLine: string,\n currentLine: string,\n context: BlockContext\n): boolean {\n if (context.inFencedCode) {\n return detectFenceEnd(currentLine, context)\n }\n\n if (isEmptyLine(prevLine) && !isEmptyLine(currentLine)) {\n return true\n }\n\n if (isHeading(currentLine) && !isEmptyLine(prevLine)) {\n return true\n }\n\n if (isThematicBreak(currentLine)) {\n return true\n }\n\n if (detectFenceStart(currentLine)) {\n return true\n }\n\n return false\n}\n\n// ============ 上下文管理 ============\n\n/**\n * 上下文更新器接口\n */\ninterface ContextUpdater {\n /**\n * 尝试更新上下文\n * @param line 当前行\n * @param context 当前上下文\n * @returns 更新后的上下文,如果不处理返回 null\n */\n update(line: string, context: BlockContext, config?: ContainerConfig): BlockContext | null\n}\n\n/**\n * 代码块上下文更新器\n * 优先级:1(最高)\n */\nclass CodeContextUpdater implements ContextUpdater {\n update(line: string, context: BlockContext): BlockContext | null {\n const newContext = { ...context }\n\n if (context.inFencedCode) {\n if (detectFenceEnd(line, context)) {\n newContext.inFencedCode = false\n newContext.fenceChar = undefined\n newContext.fenceLength = undefined\n return newContext\n }\n return null // 在代码块内,不处理其他逻辑\n }\n\n const fence = detectFenceStart(line)\n if (fence) {\n newContext.inFencedCode = true\n newContext.fenceChar = fence.char\n newContext.fenceLength = fence.length\n return newContext\n }\n\n return null\n }\n}\n\n/**\n * 容器上下文更新器\n * 优先级:2\n */\nclass ContainerContextUpdater implements ContextUpdater {\n update(line: string, context: BlockContext, config?: ContainerConfig): BlockContext | null {\n if (config === undefined) {\n return null\n }\n\n const newContext = { ...context }\n\n if (context.inContainer) {\n // 检查是否是容器结束\n if (detectContainerEnd(line, context, config)) {\n newContext.containerDepth = context.containerDepth - 1\n if (newContext.containerDepth === 0) {\n newContext.inContainer = false\n newContext.containerMarkerLength = undefined\n newContext.containerName = undefined\n }\n return newContext\n }\n\n // 检查是否是嵌套容器开始\n const nested = detectContainer(line, config)\n if (nested && !nested.isEnd) {\n newContext.containerDepth = context.containerDepth + 1\n return newContext\n }\n\n // ⚠️ 关键:在容器内,无论是什么内容(空行、列表、段落等),都保持 inContainer = true\n // 只有容器结束标记才能改变容器状态\n // 这里不需要做任何操作,因为 newContext 已经复制了 context,inContainer 已经是 true\n return newContext\n } else {\n // 不在容器内,检查是否是容器开始\n const container = detectContainer(line, config)\n if (container && !container.isEnd) {\n newContext.inContainer = true\n newContext.containerMarkerLength = container.markerLength\n newContext.containerName = container.name\n newContext.containerDepth = 1\n return newContext\n }\n }\n\n return null\n }\n}\n\n/**\n * 脚注上下文更新器\n * 优先级:3\n */\nclass FootnoteContextUpdater implements ContextUpdater {\n update(line: string, context: BlockContext): BlockContext | null {\n const newContext = { ...context }\n\n // 脚注定义开始(不在脚注中)\n if (!context.inFootnote && isFootnoteDefinitionStart(line)) {\n const identifier = line.match(RE_FOOTNOTE_DEFINITION)?.[1]\n newContext.inFootnote = true\n newContext.footnoteIdentifier = identifier\n return newContext\n }\n\n // 在脚注中\n if (context.inFootnote) {\n // 遇到新脚注定义:前一个脚注结束,新脚注开始\n if (isFootnoteDefinitionStart(line)) {\n const identifier = line.match(RE_FOOTNOTE_DEFINITION)?.[1]\n newContext.footnoteIdentifier = identifier\n return newContext\n }\n\n // 空行:保持脚注状态(支持脚注内部的多段落)\n // 返回当前上下文,阻止责任链继续\n if (isEmptyLine(line)) {\n return { ...context }\n }\n\n // 列表项处理\n const listItem = isListItemStart(line)\n if (listItem) {\n // 无缩进列表项:脚注结束\n // 缩进列表项:脚注的延续内容(包含嵌套列表)\n if (listItem.indent === 0) {\n newContext.inFootnote = false\n newContext.footnoteIdentifier = undefined\n } else {\n // 缩进列表项:脚注的延续内容,返回当前上下文阻止责任链\n return { ...context }\n }\n return null // 让列表处理器处理无缩进情况\n }\n\n // 其他块结束脚注\n if (isHeading(line) || detectFenceStart(line) || isBlockquoteStart(line)) {\n newContext.inFootnote = false\n newContext.footnoteIdentifier = undefined\n return newContext\n }\n\n // 脚注延续:以4+空格开头\n if (isFootnoteContinuation(line)) {\n return { ...context }\n }\n\n // 其他内容(普通文本、表格等),脚注结束\n newContext.inFootnote = false\n newContext.footnoteIdentifier = undefined\n return newContext\n }\n\n return null\n }\n}\n\n/**\n * 列表上下文更新器\n * 优先级:4\n */\nclass ListContextUpdater implements ContextUpdater {\n /**\n * 检测是否是列表项的延续内容(缩进内容或空行)\n */\n private isListContinuation(line: string, listIndent: number): boolean {\n // 空行可能是列表内部的段落分隔\n if (isEmptyLine(line)) {\n return true\n }\n\n // 检查是否有足够的缩进\n const contentIndent = line.match(/^(\\s*)/)?.[1].length ?? 0\n return contentIndent > listIndent\n }\n\n update(line: string, context: BlockContext): BlockContext | null {\n const newContext = { ...context }\n const listItem = isListItemStart(line)\n\n if (context.inList) {\n // 已经在列表中\n if (context.listMayEnd) {\n // 上一行是空行,需要确认列表是否结束\n if (listItem) {\n // 遇到新的列表项\n // 检查是否是同类型列表的延续\n if (listItem.ordered === context.listOrdered && listItem.indent === context.listIndent) {\n // 同类型同级别列表项,列表继续\n newContext.listMayEnd = false\n return newContext\n }\n // 不同类型或不同级别,列表结束,新列表开始\n newContext.listOrdered = listItem.ordered\n newContext.listIndent = listItem.indent\n newContext.listMayEnd = false\n return newContext\n } else if (this.isListContinuation(line, context.listIndent ?? 0)) {\n // 缩进内容或空行,列表继续\n newContext.listMayEnd = isEmptyLine(line)\n return newContext\n } else {\n // 非列表内容,列表结束\n newContext.inList = false\n newContext.listOrdered = undefined\n newContext.listIndent = undefined\n newContext.listMayEnd = false\n return newContext\n }\n } else {\n // 上一行不是空行\n if (listItem) {\n // 新列表项(可能是同级或嵌套)\n return null\n } else if (isEmptyLine(line)) {\n // 遇到空行,列表可能结束\n newContext.listMayEnd = true\n return newContext\n } else if (this.isListContinuation(line, context.listIndent ?? 0)) {\n // 缩进内容,列表继续\n return null\n } else {\n // 非缩进非列表内容,列表结束\n newContext.inList = false\n newContext.listOrdered = undefined\n newContext.listIndent = undefined\n newContext.listMayEnd = false\n return newContext\n }\n }\n } else {\n // 不在列表中\n if (listItem) {\n // 列表开始\n newContext.inList = true\n newContext.listOrdered = listItem.ordered\n newContext.listIndent = listItem.indent\n newContext.listMayEnd = false\n return newContext\n }\n }\n\n return null\n }\n}\n\n/**\n * 创建初始上下文\n */\nexport function createInitialContext(): BlockContext {\n return {\n inFencedCode: false,\n listDepth: 0,\n blockquoteDepth: 0,\n inContainer: false,\n containerDepth: 0,\n inList: false,\n inFootnote: false,\n footnoteIdentifier: undefined\n }\n}\n\n/**\n * 上下文管理器\n * 使用责任链模式更新上下文\n */\nclass ContextManager {\n private readonly updaters: ContextUpdater[] = [\n new CodeContextUpdater(),\n new ContainerContextUpdater(),\n new FootnoteContextUpdater(),\n new ListContextUpdater()\n ]\n\n /**\n * 更新上下文(处理一行后)\n *\n * @param line 当前行\n * @param context 当前上下文\n * @param containerConfig 容器配置\n * @returns 更新后的上下文\n */\n update(line: string, context: BlockContext, containerConfig?: ContainerConfig | boolean): BlockContext {\n // 规范化容器配置\n const config = containerConfig === true ? {} : containerConfig === false ? undefined : containerConfig\n\n // 依次调用上下文更新器\n for (const updater of this.updaters) {\n const result = updater.update(line, context, config)\n if (result !== null) {\n return result\n }\n }\n\n // 没有任何更新器处理,返回原上下文\n return { ...context }\n }\n}\n\n// 上下文管理器单例\nconst contextManager = new ContextManager()\n\n/**\n * 更新上下文(处理一行后)\n *\n * @param line 当前行\n * @param context 当前上下文\n * @param containerConfig 容器配置\n * @returns 更新后的上下文\n */\nexport function updateContext(\n line: string,\n context: BlockContext,\n containerConfig?: ContainerConfig | boolean\n): BlockContext {\n return contextManager.update(line, context, containerConfig)\n}\n\n","/**\n * 边界检测器\n *\n * 职责:\n * - 检测 Markdown 文档中的稳定边界\n * - 判断哪些块已经完成,不会再改变\n * - 支持代码块、引用块、列表、脚注、容器等边界检测\n *\n * 此类是直接从 IncremarkParser 中提取的边界检测逻辑,未做任何优化。\n */\n\nimport type { BlockContext, ContainerConfig } from '../../types'\nimport {\n updateContext,\n isEmptyLine,\n isHeading,\n isThematicBreak,\n isBlockquoteStart,\n isListItemStart,\n detectContainer,\n detectContainerEnd,\n isFootnoteDefinitionStart,\n isFootnoteContinuation,\n detectFenceStart,\n isSetextHeadingUnderline\n} from '../../detector'\n\n/**\n * 稳定边界结果\n */\nexport interface StableBoundaryResult {\n /** 稳定边界行号 */\n line: number\n /** 该行对应的上下文 */\n context: BlockContext\n}\n\n/**\n * 边界检测器配置\n */\nexport interface BoundaryDetectorConfig {\n /** 容器配置 */\n containers?: ContainerConfig\n}\n\n/**\n * 稳定性检查接口\n */\ninterface StabilityChecker {\n /**\n * 检查是否为稳定边界\n * @param lineIndex 行索引\n * @param context 当前上下文\n * @param lines 所有行\n * @returns 稳定边界行号,如果不是稳定边界返回 -1\n */\n check(lineIndex: number, context: BlockContext, lines: string[]): number\n}\n\n/**\n * 容器内边界检查器\n */\nclass ContainerBoundaryChecker implements StabilityChecker {\n constructor(private containerConfig: ContainerConfig | undefined) {}\n\n check(lineIndex: number, context: BlockContext, lines: string[]): number {\n const line = lines[lineIndex]\n\n if (!context.inContainer) {\n return -1\n }\n\n // 检查当前行是否是容器结束\n if (this.containerConfig !== undefined) {\n const containerEnd = detectContainerEnd(line, context, this.containerConfig)\n if (containerEnd) {\n // 容器结束,返回前一行作为稳定边界\n return lineIndex - 1\n }\n }\n\n // 容器内且不是容器结束,不判断为稳定边界\n return -1\n }\n}\n\n/**\n * 列表边界检查器\n */\nclass ListBoundaryChecker implements StabilityChecker {\n check(lineIndex: number, context: BlockContext, lines: string[]): number {\n if (!context.inList) {\n return -1\n }\n\n // 列表还没有确认结束(listMayEnd 为 false 或 undefined)\n // 不应该在列表中间创建稳定边界\n if (!context.listMayEnd) {\n return -1\n }\n\n const line = lines[lineIndex]\n\n // 如果 listMayEnd 为 true,说明上一行是空行\n // 需要检查当前行是否是列表延续或新列表项\n const listItem = isListItemStart(line)\n\n // 检查当前行是否有足够的缩进以作为列表内容\n const contentIndent = line.match(/^(\\s*)/)?.[1].length ?? 0\n const isListContent = contentIndent > (context.listIndent ?? 0)\n\n // 只有当当前行不是列表内容且不是空行时,列表才算结束\n if (!listItem && !isListContent && !isEmptyLine(line)) {\n // 当前行不是列表内容且不是空行,列表在上一行的空行处结束\n return lineIndex - 1\n }\n\n return -1\n }\n}\n\n/**\n * 脚注边界检查器\n */\nclass FootnoteBoundaryChecker implements StabilityChecker {\n check(lineIndex: number, context: BlockContext, lines: string[]): number {\n const line = lines[lineIndex]\n const prevLine = lines[lineIndex - 1]\n\n // 情况 1: 前一行是脚注定义开始\n if (isFootnoteDefinitionStart(prevLine)) {\n // 当前行是空行或缩进行,脚注可能继续(不稳定)\n if (isEmptyLine(line) || isFootnoteContinuation(line)) {\n return -1\n }\n // 当前行是新脚注定义,前一个脚注完成\n if (isFootnoteDefinitionStart(line)) {\n return lineIndex - 1\n }\n }\n\n // 情况 2: 前一行是缩进行,可能是脚注延续\n // 注意:这个逻辑已经在 updateContext() 中通过 inFootnote 标志处理\n // 这里不需要重复判断,统一使用 updateContext() 的结果\n if (!isEmptyLine(prevLine) && isFootnoteContinuation(prevLine)) {\n // 在脚注中的缩进行或空行,保持不稳定\n // 实际的脚注边界判断由 updateContext() 中的 inFootnote 标志控制\n return -1\n }\n\n // 前一行非空时,新脚注定义开始(排除连续脚注定义)\n if (!isEmptyLine(prevLine) && isFootnoteDefinitionStart(line) && !isFootnoteDefinitionStart(prevLine)) {\n return lineIndex - 1\n }\n\n return -1\n }\n}\n\n/**\n * 新块边界检查器\n */\nclass NewBlockBoundaryChecker implements StabilityChecker {\n check(lineIndex: number, context: BlockContext, lines: string[]): number {\n const line = lines[lineIndex]\n const prevLine = lines[lineIndex - 1]\n\n if (isEmptyLine(prevLine)) {\n return -1\n }\n\n // 检测 Setext 标题下划线\n if (isSetextHeadingUnderline(line, prevLine)) {\n return lineIndex - 1\n }\n\n // 新标题开始\n if (isHeading(line)) {\n return lineIndex - 1\n }\n\n // 新代码块开始\n if (detectFenceStart(line)) {\n return lineIndex - 1\n }\n\n // 新引用块开始(排除连续引用)\n if (isBlockquoteStart(line) && !isBlockquoteStart(prevLine)) {\n return lineIndex - 1\n }\n\n // 新列表开始(排除连续列表项)\n // ⚠️ 修改:只有在不在列表中时才触发这个逻辑\n if (!context.inList && isListItemStart(line) && !isListItemStart(prevLine)) {\n return lineIndex - 1\n }\n\n return -1\n }\n}\n\n/**\n * 空行边界检查器\n */\nclass EmptyLineBoundaryChecker implements StabilityChecker {\n check(lineIndex: number, context: BlockContext, lines: string[]): number {\n const line = lines[lineIndex]\n const prevLine = lines[lineIndex - 1]\n\n // 空行标志段落结束\n // ⚠️ 修改:如果在列表中,空行不作为稳定边界\n if (isEmptyLine(line) && !isEmptyLine(prevLine) && !context.inList) {\n return lineIndex\n }\n\n return -1\n }\n}\n\n/**\n * 边界检测器\n */\nexport class BoundaryDetector {\n private readonly containerConfig: ContainerConfig | undefined\n private readonly checkers: StabilityChecker[]\n /** 缓存每一行结束时对应的 Context,避免重复计算 */\n private contextCache: Map<number, BlockContext> = new Map()\n\n constructor(config: BoundaryDetectorConfig = {}) {\n this.containerConfig = config.containers\n // 初始化稳定性检查器链\n this.checkers = [\n new ContainerBoundaryChecker(this.containerConfig),\n new ListBoundaryChecker(),\n new FootnoteBoundaryChecker(),\n new NewBlockBoundaryChecker(),\n new EmptyLineBoundaryChecker()\n ]\n }\n\n /**\n * 清空上下文缓存\n * 当 pendingStartLine 推进后调用,释放不再需要的缓存\n */\n clearContextCache(beforeLine: number): void {\n for (const key of this.contextCache.keys()) {\n if (key < beforeLine) {\n this.contextCache.delete(key)\n }\n }\n }\n\n /**\n * 查找稳定边界\n * 返回稳定边界行号和该行对应的上下文(用于后续更新,避免重复计算)\n *\n * @param lines 所有行\n * @param startLine 起始行\n * @param context 当前上下文\n * @returns 稳定边界结果\n */\n findStableBoundary(\n lines: string[],\n startLine: number,\n context: BlockContext\n ): StableBoundaryResult {\n let stableLine = -1\n let stableContext: BlockContext = context\n\n // 尝试从缓存获取 startLine - 1 的 context,如果匹配则直接用,否则用传入的 context\n let tempContext = startLine > 0 && this.contextCache.has(startLine - 1)\n ? { ...this.contextCache.get(startLine - 1)! }\n : { ...context }\n\n for (let i = startLine; i < lines.length; i++) {\n const line = lines[i]\n const wasInFencedCode = tempContext.inFencedCode\n const wasInContainer = tempContext.inContainer\n const wasContainerDepth = tempContext.containerDepth\n\n // ⚠️ 关键修复:在 updateContext 之前检查明确的块边界\n // 如果当前行是代码块 fence 开始、新标题开始或分割线,且前一行不在 fenced code 中\n // 则应该标记前一个 block 为完成(即使在最后一行)\n const prevLine = i > 0 ? lines[i - 1] : ''\n const isSetextUnderline = i > 0 && isSetextHeadingUnderline(line, prevLine)\n const hasExplicitBlockBoundary =\n detectFenceStart(line) || // 代码块 fence 开始\n isHeading(line) || // 新标题开始\n isThematicBreak(line) // 分割线\n\n // ⚠️ 排除 Setext 下划线,因为它应该被视为标题的一部分,而不是独立块边界\n if (!wasInFencedCode && !wasInContainer && hasExplicitBlockBoundary && !isSetextUnderline) {\n // 前一个 block 已完成,可以标记为稳定边界\n stableLine = i - 1\n stableContext = { ...tempContext }\n }\n\n tempContext = updateContext(line, tempContext, this.containerConfig)\n\n // 写入缓存:第 i 行结束后的 context\n this.contextCache.set(i, { ...tempContext })\n\n if (wasInFencedCode && !tempContext.inFencedCode) {\n if (i < lines.length - 1) {\n stableLine = i\n stableContext = { ...tempContext }\n }\n continue\n }\n\n if (tempContext.inFencedCode) {\n continue\n }\n\n if (wasInContainer && wasContainerDepth === 1 && !tempContext.inContainer) {\n if (i < lines.length - 1) {\n stableLine = i\n stableContext = { ...tempContext }\n }\n continue\n }\n\n // ⚠️ 关键:如果当前在容器内,跳过所有稳定性检查\n // 容器内的所有内容(包括空行、列表等)都应该被视为容器的一部分\n // 只有容器结束标记才能作为稳定边界\n if (tempContext.inContainer) {\n continue\n }\n\n // 使用检查器链检查稳定性\n const stablePoint = this.checkStability(i, tempContext, lines)\n if (stablePoint >= 0) {\n stableLine = stablePoint\n stableContext = { ...tempContext }\n }\n }\n\n return { line: stableLine, context: stableContext }\n }\n\n /**\n * 检查指定行是否是稳定边界\n * 使用责任链模式,依次调用各个检查器\n *\n * @param lineIndex 行索引\n * @param context 当前上下文\n * @param lines 所有行\n * @returns 稳定边界行号,如果不是稳定边界返回 -1\n */\n private checkStability(\n lineIndex: number,\n context: BlockContext,\n lines: string[]\n ): number {\n // 第一行永远不稳定\n if (lineIndex === 0) {\n return -1\n }\n\n const line = lines[lineIndex]\n const prevLine = lines[lineIndex - 1]\n\n // ⚠️ 脚注特殊处理:在脚注中,空行是段落分隔,不是稳定边界\n // 只有脚注定义开始才算脚注的稳定边界\n if (context.inFootnote) {\n // ⚠️ 关键修复:在脚注中,不应该检测到代码块作为稳定边界\n // 因为脚注内容的缩进(4个空格)可能被误判为代码块 fence\n // 检查前一行是否是脚注定义的开始(脚注单行内容的情况)\n if (isFootnoteDefinitionStart(prevLine) && !isEmptyLine(line)) {\n // ⚠️ 关键:如果当前行是脚注延续(缩进),则不应该作为稳定边界\n // 因为这是脚注内容的一部分,而不是新块\n if (isFootnoteContinuation(line)) {\n return -1\n }\n return lineIndex - 1\n }\n // ⚠️ 另一个关键修复:如果前一行在脚注中(缩进或延续),\n // 且当前行也是缩进或延续,则不应该作为稳定边界\n // 这样可以避免脚注的多行内容被错误分割\n if (isEmptyLine(prevLine) && (isEmptyLine(line) || isFootnoteContinuation(line))) {\n return -1\n }\n // 其他情况(包括空行)都不作为脚注的稳定边界\n return -1\n }\n\n // 前一行是独立块(标题、分割线),该块已完成\n if (isHeading(prevLine) || isThematicBreak(prevLine)) {\n return lineIndex - 1\n }\n\n // 前一行是 Setext 标题下划线,该标题已完成\n if (isSetextHeadingUnderline(prevLine, lines[lineIndex - 2])) {\n return lineIndex - 1\n }\n\n // 最后一行不稳定(可能还有更多内容)\n const isLastLine = lineIndex >= lines.length - 1\n if (isLastLine) {\n return -1\n }\n\n // 依次调用检查器链,返回第一个匹配的稳定边界\n for (const checker of this.checkers) {\n const stablePoint = checker.check(lineIndex, context, lines)\n if (stablePoint >= 0) {\n return stablePoint\n }\n }\n\n return -1\n }\n}\n\n","/**\n * 工具函数\n */\n\nimport type { Definition, FootnoteDefinition, RootContent } from \"mdast\"\n\n/**\n * 生成唯一 ID\n */\nlet idCounter = 0\nexport function generateId(prefix = 'block'): string {\n return `${prefix}-${++idCounter}`\n}\n\n/**\n * 重置 ID 计数器(用于测试)\n */\nexport function resetIdCounter(): void {\n idCounter = 0\n}\n\n/**\n * 计算行的偏移量\n */\nexport function calculateLineOffset(lines: string[], lineIndex: number): number {\n let offset = 0\n for (let i = 0; i < lineIndex && i < lines.length; i++) {\n offset += lines[i].length + 1 // +1 for newline\n }\n return offset\n}\n\n/**\n * 将文本按行分割\n */\nexport function splitLines(text: string): string[] {\n return text.split('\\n')\n}\n\n/**\n * 合并行为文本\n */\nexport function joinLines(lines: string[], start: number, end: number): string {\n return lines.slice(start, end + 1).join('\\n')\n}\n\nexport function isDefinitionNode(node: RootContent): node is Definition {\n return node.type === 'definition'\n}\n\nexport function isFootnoteDefinitionNode(node: RootContent): node is FootnoteDefinition {\n return node.type === 'footnoteDefinition'\n}\n\n/**\n * 从 AST 节点中收集脚注引用标识符\n *\n * @param node 起始节点\n * @returns 脚注引用标识符列表(按出现顺序,去重)\n */\nexport function collectFootnoteReferences(node: RootContent): string[] {\n const references: string[] = []\n const seen = new Set<string>()\n\n traverseAst(node, (n) => {\n if (n.type === 'footnoteReference' && 'identifier' in n) {\n const identifier = n.identifier as string\n if (!seen.has(identifier)) {\n seen.add(identifier)\n references.push(identifier)\n }\n }\n })\n\n return references\n}\n\n/**\n * AST 节点遍历器\n * 深度优先遍历 AST 节点\n *\n * @param node 起始节点\n * @param visitor 访问者函数,返回 true 可以提前终止遍历\n */\nexport function traverseAst(\n node: RootContent,\n visitor: (node: RootContent) => boolean | void\n): void {\n // 访问当前节点\n const stopEarly = visitor(node)\n if (stopEarly === true) {\n return\n }\n\n // 递归遍历子节点\n if ('children' in node && Array.isArray(node.children)) {\n for (const child of node.children) {\n traverseAst(child as RootContent, visitor)\n }\n }\n}\n\n/**\n * 从 AST 节点中收集指定类型的节点\n *\n * @param node 起始节点\n * @param predicate 匹配谓词\n * @returns 匹配的节点列表\n */\nexport function collectAstNodes<T extends RootContent>(\n node: RootContent,\n predicate: (node: RootContent) => node is T\n): T[] {\n const results: T[] = []\n\n traverseAst(node, (node) => {\n if (predicate(node)) {\n results.push(node)\n }\n })\n\n return results\n}","/**\n * Definition 管理器\n *\n * 职责:\n * - 从 AST 节点中提取 definitions\n * - 管理 Definition 映射表\n * - 提供访问 Definition 的方法\n */\n\nimport type { ParsedBlock, DefinitionMap } from '../../types'\nimport { collectAstNodes, isDefinitionNode } from '../../utils'\n\n/**\n * Definition 管理器\n */\nexport class DefinitionManager {\n private definitions: DefinitionMap = {}\n\n /**\n * 从已完成的 blocks 中提取 definitions\n *\n * @param blocks 已完成的块\n */\n extractFromBlocks(blocks: ParsedBlock[]): void {\n for (const block of blocks) {\n const newDefinitions = this.findDefinitions(block)\n this.definitions = {\n ...this.definitions,\n ...newDefinitions\n }\n }\n }\n\n /**\n * 从 block 中提取 definitions\n *\n * @param block 解析块\n * @returns Definition 映射表\n */\n private findDefinitions(block: ParsedBlock): DefinitionMap {\n // 使用通用遍历工具收集 definition 节点\n const definitions = collectAstNodes(block.node, isDefinitionNode)\n\n return definitions.reduce<DefinitionMap>((acc, node) => {\n acc[node.identifier] = node\n return acc\n }, {})\n }\n\n /**\n * 获取所有 definitions\n *\n * @returns Definition 映射表\n */\n getAll(): DefinitionMap {\n return this.definitions\n }\n\n /**\n * 清空所有 definitions\n */\n clear(): void {\n this.definitions = {}\n }\n}\n\n","/**\n * Footnote 管理器\n *\n * 职责:\n * - 从 AST 节点中提取 footnote definitions\n * - 收集脚注引用顺序\n * - 管理 Footnote Definition 映射表\n * - 提供访问 Footnote 的方法\n */\n\nimport type { RootContent, FootnoteDefinition } from 'mdast'\nimport type { FootnoteDefinitionMap, ParsedBlock } from '../../types'\nimport { collectAstNodes, isFootnoteDefinitionNode, traverseAst } from '../../utils'\n\n/**\n * Footnote 管理器\n */\nexport class FootnoteManager {\n private definitions: FootnoteDefinitionMap = {}\n /** 已完成部分的脚注引用顺序(缓存) */\n private completedReferenceOrder: string[] = []\n /** 所有脚注引用顺序(包括 pending 部分) */\n private referenceOrder: string[] = []\n\n /**\n * 从已完成的 blocks 中提取 footnote definitions\n *\n * @param blocks 已完成的块\n */\n extractDefinitionsFromBlocks(blocks: ParsedBlock[]): void {\n for (const block of blocks) {\n const newDefinitions = this.findFootnoteDefinitions(block)\n this.definitions = {\n ...this.definitions,\n ...newDefinitions\n }\n }\n }\n\n /**\n * 从 block 中提取 footnote definitions\n *\n * @param block 解析块\n * @returns Footnote Definition 映射表\n */\n private findFootnoteDefinitions(block: ParsedBlock): FootnoteDefinitionMap {\n // 使用通用遍历工具收集 footnote definition 节点\n const definitions = collectAstNodes(block.node, isFootnoteDefinitionNode)\n\n return definitions.reduce<FootnoteDefinitionMap>((acc, node) => {\n acc[node.identifier] = node\n return acc\n }, {})\n }\n\n /**\n * 从已完成的 blocks 中收集脚注引用(增量更新)\n * 只收集新完成的 blocks 中的引用,并缓存结果\n *\n * @param blocks 新完成的 blocks\n */\n collectReferencesFromCompletedBlocks(blocks: ParsedBlock[]): void {\n const newReferences = new Set<string>()\n blocks.forEach((block) => {\n traverseAst(block.node, (n) => {\n if (n.type === 'footnoteReference') {\n const identifier = n.identifier\n // 只在已完成部分没出现过的引用才添加\n if (!this.completedReferenceOrder.includes(identifier)) {\n newReferences.add(identifier)\n }\n }\n })\n })\n // 更新已完成部分的引用顺序\n this.completedReferenceOrder.push(...Array.from(newReferences))\n }\n\n /**\n * 收集 pending blocks 中的脚注引用\n * 返回完整的引用顺序(已完成 + pending)\n *\n * @param pendingBlocks pending blocks\n * @returns 完整的脚注引用顺序\n */\n collectReferencesFromPending(pendingBlocks: ParsedBlock[]): string[] {\n // 收集 pending 部分的新引用\n const pendingReferences = new Set<string>()\n pendingBlocks.forEach((block) => {\n traverseAst(block.node, (n) => {\n if (n.type === 'footnoteReference') {\n const identifier = n.identifier\n // 只记录在已完成部分没出现过的引用\n if (!this.completedReferenceOrder.includes(identifier)) {\n pendingReferences.add(identifier)\n }\n }\n })\n })\n // 合并已完成和 pending 的引用顺序\n this.referenceOrder = [...this.completedReferenceOrder, ...Array.from(pendingReferences)]\n return this.referenceOrder\n }\n\n /**\n * 收集 AST 中的脚注引用(按出现顺序)\n *\n * @deprecated 使用 collectReferencesFromCompletedBlocks 和 collectReferencesFromPending 代替\n * @param nodes AST 节点列表\n */\n collectReferences(nodes: RootContent[]): void {\n nodes.forEach((node) => {\n traverseAst(node, (n) => {\n // 检查是否是脚注引用\n if (n.type === 'footnoteReference') {\n const identifier = n.identifier\n // 去重:只记录第一次出现的位置\n if (!this.referenceOrder.includes(identifier)) {\n this.referenceOrder.push(identifier)\n }\n }\n })\n })\n }\n\n /**\n * 获取所有 footnote definitions\n *\n * @returns Footnote Definition 映射表\n */\n getDefinitions(): FootnoteDefinitionMap {\n return this.definitions\n }\n\n /**\n * 获取脚注引用顺序\n *\n * @returns 脚注引用顺序\n */\n getReferenceOrder(): string[] {\n return this.referenceOrder\n }\n\n /**\n * 清空所有 footnote definitions 和引用顺序\n */\n clear(): void {\n this.definitions = {}\n this.completedReferenceOrder = []\n this.referenceOrder = []\n }\n}\n\n","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 * 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 * @param generateBlockId - 接收 block 的 startOffset 参数,用于生成稳定的 id\n */\n nodesToBlocks(\n nodes: RootContent[],\n startOffset: number,\n rawText: string,\n status: BlockStatus,\n generateBlockId: (startOffset: number) => string\n ): ParsedBlock[]\n\n /**\n * 更新配置选项(动态更新,不需要重建实例)\n * @param options 部分配置选项\n */\n updateOptions(options: Partial<EngineParserOptions>): void\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 * 显式 Definition 扩展\n *\n * 作用:捕获 [id]: ... 整行,手动解析,并立即注册到 marked 的 links 表中。\n * 这能让 marked 原生逻辑正确识别后续的引用图片。\n *\n * 注意:start 函数必须严格匹配 definition 格式 [id]:,否则会干扰 ![alt][id] 的解析\n */\n\nimport type { TokenizerExtension } from 'marked'\nimport type { ExplicitDefinitionToken } from './types'\n\n/**\n * 创建显式定义扩展\n *\n * @returns marked 扩展对象\n */\nexport function createExplicitDefinitionExtension(): TokenizerExtension {\n return {\n name: 'explicitDefinition',\n level: 'block',\n // 🔑 关键修复:start 必须匹配完整的 definition 模式 [id]:,\n // 而不能只匹配 [,否则会把 ![alt][id] 中的 [alt] 误认为是 definition 开头\n // 同时排除脚注定义 [^id]:\n start(src: string): number | undefined {\n // 匹配 [id]: 但不匹配 [^id]:(脚注定义)\n const match = src.match(/^ {0,3}\\[(?!\\^)[^\\]]+\\]:/m)\n return match?.index\n },\n tokenizer(this: any, src: string): ExplicitDefinitionToken | undefined {\n // 匹配整行:[id]: ... 直到换行,但排除脚注定义 [^id]:\n const rule = /^ {0,3}\\[(?!\\^)[^\\]]+\\]:.*?(?:\\n+|$)/\n const match = rule.exec(src)\n\n if (match) {\n const raw = match[0]\n // 手动解析内部结构:提取 identifier, url, title\n // 使用 \\S+ 匹配 URL,防止被怪异空格截断\n const contentMatch = raw.match(\n /^ {0,3}\\[([^\\]]+)\\]:\\s*(\\S+)(?:\\s+[\"'(](.*?)[\"')])?/\n )\n\n if (contentMatch) {\n const identifier = contentMatch[1].toLowerCase()\n const url = contentMatch[2]\n const title = contentMatch[3]\n\n // ⚡️ 关键步骤:立即注册到 marked 上下文\n // 这样 marked 在解析后续的 ![Alt][id] 时就能找到定义,从而生成正确的 Image Token\n if (this.lexer?.tokens?.links) {\n this.lexer.tokens.links[identifier] = { href: url, title }\n }\n\n return {\n type: 'explicitDefinition',\n raw,\n identifier,\n url,\n title\n }\n }\n\n // 如果捕获了行但解析失败,依然返回 raw Token,防止它漏到 paragraph 里被 Reference 误伤\n return { type: 'explicitDefinition', raw, identifier: '', url: '' }\n }\n return undefined\n },\n renderer(): string {\n return ''\n }\n } as TokenizerExtension\n}\n\n","/**\n * 乐观引用解析扩展\n *\n * 作用:仅当 marked 原生无法解析(即 ID 不存在)时,强制生成引用节点。\n * 注意:需要排除脚注引用 [^id],让脚注处理逻辑来处理\n */\n\nimport type { TokenizerExtension } from 'marked'\nimport type { OptimisticRefToken } from './types'\n\n/**\n * 创建乐观引用扩展\n *\n * @returns marked 扩展对象\n */\nexport function createOptimisticReferenceExtension(): TokenizerExtension {\n return {\n name: 'optimisticReference',\n level: 'inline',\n start(src: string): number | undefined {\n return src.match(/!?\\[/)?.index\n },\n tokenizer(this: any, src: string): OptimisticRefToken | undefined {\n // 匹配 ![...][...] 或 [...][...]\n const rule =\n /^(!?)\\[((?:\\[[^\\]]*\\]|[^\\[\\]]|\\](?=[^\\[]*\\]))*)\\](?:\\s*\\[((?:\\[[^\\]]*\\]|[^\\[\\]]|\\](?=[^\\[]*\\]))*)\\])?/\n const match = rule.exec(src)\n\n if (match) {\n const fullMatch = match[0]\n\n // 1. 如果是标准链接 [text](url),跳过\n if (src.length > fullMatch.length && src[fullMatch.length] === '(') {\n return undefined\n }\n\n // 2. ⚡️ 防抢断:如果后面紧跟 ':',说明这是 Definition 的一部分,坚决不碰\n if (src.length > fullMatch.length && src[fullMatch.length] === ':') {\n return undefined\n }\n\n const isImage = match[1] === '!'\n const text = match[2]\n const refRaw = match[3]\n\n // 3. ⚡️ 排除脚注引用:如果文本以 ^ 开头,这是脚注引用 [^id],交给脚注处理逻辑\n if (text.startsWith('^')) {\n return undefined\n }\n\n let identifier = ''\n let referenceType: 'shortcut' | 'collapsed' | 'full' = 'shortcut'\n\n if (refRaw !== undefined) {\n if (refRaw === '') {\n referenceType = 'collapsed'\n identifier = text\n } else {\n referenceType = 'full'\n identifier = refRaw\n }\n } else {\n referenceType = 'shortcut'\n identifier = text\n // 排除 Checkbox\n if (text.match(/^[ xX]$/)) {\n return undefined\n }\n }\n\n return {\n type: 'optimisticReference',\n raw: fullMatch,\n isImage,\n text,\n identifier: identifier.toLowerCase(),\n label: identifier,\n referenceType\n }\n }\n return undefined\n },\n renderer(): string {\n return ''\n }\n } as TokenizerExtension\n}\n\n","/**\n * 数学公式扩展\n *\n * 提供块级和行内数学公式的支持\n *\n * 块级公式(display math):\n * - $$...$$ 格式(Markdown 标准,默认支持)\n * - \\[...\\] 格式(TeX 风格,需要配置开启)\n *\n * 行内公式(inline math):\n * - $...$ 格式(Markdown 标准,默认支持)\n * - \\(...\\) 格式(TeX 风格,需要配置开启)\n *\n * 这两种格式都是 MathJax/KaTeX 支持的标准分隔符\n */\n\nimport type { TokenizerExtension } from 'marked'\nimport type { BlockMathToken, InlineMathToken } from './types'\n\n/**\n * 数学公式扩展配置选项\n */\nexport interface MathExtensionOptions {\n /**\n * 启用 TeX 风格的公式分隔符 (default: `false`)\n *\n * 开启后同时支持:\n * - 行内公式:\\(...\\)\n * - 块级公式:\\[...\\]\n *\n * 这是 LaTeX/TeX 原生语法,MathJax 和 KaTeX 都支持。\n */\n tex?: boolean\n}\n\n/**\n * 解析后的配置(所有选项都有默认值)\n */\ninterface ResolvedMathExtensionOptions {\n tex: boolean\n}\n\n/**\n * 解析配置,填充默认值\n */\nfunction resolveOptions(options?: MathExtensionOptions): ResolvedMathExtensionOptions {\n return {\n tex: options?.tex ?? false,\n }\n}\n\n/**\n * 创建块级数学公式扩展\n *\n * 支持两种格式:\n * - $$...$$ 格式(Markdown 标准,默认支持)\n * - \\[...\\] 格式(TeX 风格,需要配置开启)\n *\n * @param options - 配置选项\n * @returns marked 扩展对象\n */\nexport function createBlockMathExtension(options?: MathExtensionOptions): TokenizerExtension {\n const resolved = resolveOptions(options)\n\n return {\n name: 'blockMath',\n level: 'block',\n start(src: string): number | undefined {\n // 匹配行首的 $$ (允许前面有空格)\n const dollarMatch = src.match(/^ {0,3}\\$\\$/m)\n\n // 如果开启了 TeX 风格,也匹配 \\[\n let bracketMatch: RegExpMatchArray | null = null\n if (resolved.tex) {\n bracketMatch = src.match(/^ {0,3}\\\\\\[/m)\n }\n\n // 返回最先出现的位置\n if (dollarMatch && bracketMatch) {\n return Math.min(dollarMatch.index!, bracketMatch.index!)\n }\n return dollarMatch?.index ?? bracketMatch?.index\n },\n tokenizer(src: string): BlockMathToken | undefined {\n // 匹配 $$...$$ 块级公式(支持多行,允许行首空格)\n const dollarRule = /^ {0,3}\\$\\$([\\s\\S]*?)\\$\\$ *(?:\\n+|$)/\n const dollarMatch = dollarRule.exec(src)\n if (dollarMatch) {\n return {\n type: 'blockMath',\n raw: dollarMatch[0],\n text: dollarMatch[1].trim(),\n }\n }\n\n // 如果开启了 TeX 风格,匹配 \\[...\\] 块级公式\n if (resolved.tex) {\n const bracketRule = /^ {0,3}\\\\\\[([\\s\\S]*?)\\\\\\] *(?:\\n+|$)/\n const bracketMatch = bracketRule.exec(src)\n if (bracketMatch) {\n return {\n type: 'blockMath',\n raw: bracketMatch[0],\n text: bracketMatch[1].trim(),\n }\n }\n }\n\n return undefined\n },\n renderer(): string {\n return ''\n },\n } as TokenizerExtension\n}\n\n/**\n * 创建行内数学公式扩展\n *\n * 支持两种格式:\n * - $...$ 格式(Markdown 标准,默认支持)\n * - \\(...\\) 格式(TeX 风格,需要配置开启)\n *\n * @param options - 配置选项\n * @returns marked 扩展对象\n */\nexport function createInlineMathExtension(options?: MathExtensionOptions): TokenizerExtension {\n const resolved = resolveOptions(options)\n\n return {\n name: 'inlineMath',\n level: 'inline',\n start(src: string): number | undefined {\n // 查找 $ 分隔符\n const dollarIndex = src.indexOf('$')\n\n // 排除 $$ 开头(那是块级公式)\n const validDollarIndex =\n dollarIndex !== -1 && src[dollarIndex + 1] !== '$' ? dollarIndex : -1\n\n // 如果开启了 TeX 风格,也查找 \\( 分隔符\n let parenIndex = -1\n if (resolved.tex) {\n parenIndex = src.indexOf('\\\\(')\n }\n\n // 返回最先出现的位置\n if (validDollarIndex !== -1 && parenIndex !== -1) {\n return Math.min(validDollarIndex, parenIndex)\n }\n if (validDollarIndex !== -1) return validDollarIndex\n if (parenIndex !== -1) return parenIndex\n return undefined\n },\n tokenizer(src: string): InlineMathToken | undefined {\n // 匹配 $...$ 行内公式(不匹配 $$)\n // 使用非贪婪匹配,支持转义的 \\$\n const dollarRule = /^\\$(?!\\$)((?:\\\\.|[^\\\\\\n$])+?)\\$(?!\\d)/\n const dollarMatch = dollarRule.exec(src)\n if (dollarMatch) {\n return {\n type: 'inlineMath',\n raw: dollarMatch[0],\n text: dollarMatch[1].trim(),\n }\n }\n\n // 如果开启了 TeX 风格,匹配 \\(...\\) 行内公式\n if (resolved.tex) {\n const parenRule = /^\\\\\\(([\\s\\S]*?)\\\\\\)/\n const parenMatch = parenRule.exec(src)\n if (parenMatch) {\n return {\n type: 'inlineMath',\n raw: parenMatch[0],\n text: parenMatch[1].trim(),\n }\n }\n }\n\n return undefined\n },\n renderer(): string {\n return ''\n },\n } as TokenizerExtension\n}\n","/**\n * 脚注定义扩展\n *\n * 解析 [^id]: content 格式的脚注定义\n * 支持多行脚注(后续行需要 4 空格缩进)\n */\n\nimport type { TokenizerExtension } from 'marked'\nimport type { FootnoteDefinitionBlockToken } from './types'\n\n/**\n * 创建脚注定义扩展\n *\n * @returns marked 扩展对象\n */\nexport function createFootnoteDefinitionExtension(): TokenizerExtension {\n return {\n name: 'footnoteDefinitionBlock',\n level: 'block',\n start(src: string): number | undefined {\n // 匹配 [^id]: 格式的开头\n const match = src.match(/^ {0,3}\\[\\^[^\\]]+\\]:/m)\n return match?.index\n },\n tokenizer(src: string): FootnoteDefinitionBlockToken | undefined {\n // 匹配脚注定义的第一行:[^id]: content\n // 脚注标识符可以包含字母、数字、下划线、连字符\n const firstLineRule = /^ {0,3}\\[\\^([a-zA-Z0-9_-]+)\\]:\\s*(.*)/\n const firstLineMatch = firstLineRule.exec(src)\n\n if (!firstLineMatch) return undefined\n\n const identifier = firstLineMatch[1]\n let content = firstLineMatch[2]\n let raw = firstLineMatch[0]\n\n // 计算第一行后剩余的内容\n const remaining = src.slice(raw.length)\n\n // 处理多行脚注:后续行需要至少 4 空格缩进,或者是空行后的缩进行\n // 使用 lines 数组来简化处理\n const lines = remaining.split('\\n')\n let lineIndex = 0\n\n // 跳过第一个空字符串(如果 remaining 以 \\n 开头)\n if (lines[0] === '' && remaining.startsWith('\\n')) {\n lineIndex = 1\n raw += '\\n'\n content += '\\n'\n }\n\n while (lineIndex < lines.length) {\n const line = lines[lineIndex]\n\n // 空行:继续检查下一行是否有缩进\n if (line.trim() === '') {\n // 预检查:空行后是否有缩进行?\n let hasIndentedLineAfter = false\n for (let j = lineIndex + 1; j < lines.length; j++) {\n const nextLine = lines[j]\n if (nextLine.trim() === '') continue // 跳过连续空行\n if (nextLine.match(/^( |\\t)/)) {\n hasIndentedLineAfter = true\n }\n break\n }\n\n if (hasIndentedLineAfter) {\n raw += line + (lineIndex < lines.length - 1 ? '\\n' : '')\n content += '\\n' + line\n lineIndex++\n continue\n } else {\n // 空行后没有缩进行,结束脚注\n break\n }\n }\n\n // 检查是否有 4 空格缩进(脚注延续行)\n if (line.match(/^( |\\t)/)) {\n raw += line + (lineIndex < lines.length - 1 ? '\\n' : '')\n content += '\\n' + line\n lineIndex++\n continue\n }\n\n // 遇到新的脚注定义,结束当前脚注\n if (line.match(/^ {0,3}\\[\\^[^\\]]+\\]:/)) {\n break\n }\n\n // 遇到非缩进非空行,结束脚注\n break\n }\n\n // 如果最后有尾随空行,移除它们(不影响 raw,只影响 content)\n const trimmedContent = content.replace(/\\n+$/, '')\n\n return {\n type: 'footnoteDefinitionBlock',\n raw,\n identifier,\n content: trimmedContent\n }\n },\n renderer(): string {\n return ''\n }\n } as TokenizerExtension\n}\n\n","/**\n * 内联 HTML 扩展\n *\n * 解析内联 HTML 标签(如 <span>text</span>)\n * 用于与 Micromark 保持一致的 HTML 处理行为\n */\n\nimport type { TokenizerExtension } from 'marked'\nimport type { InlineHtmlToken } from './types'\n\n/**\n * HTML 标签正则表达式\n *\n * 匹配:\n * - 开标签: <tag> 或 <tag attr=\"value\">\n * - 闭标签: </tag>\n * - 自闭合: <tag /> 或 <br>\n */\nconst SELF_CLOSING_TAGS = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\n 'link', 'meta', 'param', 'source', 'track', 'wbr'\n])\n\n/**\n * 创建内联 HTML 扩展\n *\n * @returns marked 扩展对象\n */\nexport function createInlineHtmlExtension(): TokenizerExtension {\n return {\n name: 'inlineHtml',\n level: 'inline',\n start(src: string): number | undefined {\n // 查找 < 字符,但排除转义和特殊情况\n const index = src.indexOf('<')\n if (index === -1) return undefined\n\n // 检查是否是有效的 HTML 标签开始\n const afterLt = src.slice(index + 1)\n // 必须是字母开头(开标签)或 / 后跟字母(闭标签)\n if (!/^[a-zA-Z\\/]/.test(afterLt)) return undefined\n\n return index\n },\n tokenizer(src: string): InlineHtmlToken | undefined {\n // 尝试匹配完整的 HTML 元素(开标签 + 内容 + 闭标签)\n const completeTagMatch = matchCompleteHtmlElement(src)\n if (completeTagMatch) {\n return {\n type: 'inlineHtml',\n raw: completeTagMatch,\n text: completeTagMatch\n }\n }\n\n // 尝试匹配自闭合标签\n const selfClosingMatch = matchSelfClosingTag(src)\n if (selfClosingMatch) {\n return {\n type: 'inlineHtml',\n raw: selfClosingMatch,\n text: selfClosingMatch\n }\n }\n\n return undefined\n },\n renderer(): string {\n return ''\n }\n } as TokenizerExtension\n}\n\n/**\n * 匹配完整的 HTML 元素(开标签 + 内容 + 闭标签)\n *\n * 支持嵌套,但限制深度以避免性能问题\n */\nfunction matchCompleteHtmlElement(src: string): string | null {\n // 匹配开标签\n const openTagMatch = /^<([a-zA-Z][a-zA-Z0-9]*)((?:\\s+[a-zA-Z_:][a-zA-Z0-9_.:-]*(?:\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s\"'=<>`]+))?)*)\\s*>/.exec(src)\n if (!openTagMatch) return null\n\n const tagName = openTagMatch[1].toLowerCase()\n const openTag = openTagMatch[0]\n\n // 如果是自闭合标签,不需要找闭标签\n if (SELF_CLOSING_TAGS.has(tagName)) {\n return openTag\n }\n\n // 查找对应的闭标签\n const afterOpenTag = src.slice(openTag.length)\n\n // 简单的嵌套计数\n let depth = 1\n let pos = 0\n const openPattern = new RegExp(`<${tagName}(?:\\\\s[^>]*)?>`, 'gi')\n const closePattern = new RegExp(`</${tagName}>`, 'gi')\n\n while (depth > 0 && pos < afterOpenTag.length) {\n // 重置 lastIndex\n openPattern.lastIndex = pos\n closePattern.lastIndex = pos\n\n const nextOpen = openPattern.exec(afterOpenTag)\n const nextClose = closePattern.exec(afterOpenTag)\n\n if (!nextClose) {\n // 没有找到闭标签,说明 HTML 不完整\n return null\n }\n\n if (nextOpen && nextOpen.index < nextClose.index) {\n // 先遇到开标签,深度 +1\n depth++\n pos = nextOpen.index + nextOpen[0].length\n } else {\n // 先遇到闭标签,深度 -1\n depth--\n pos = nextClose.index + nextClose[0].length\n }\n }\n\n if (depth === 0) {\n return src.slice(0, openTag.length + pos)\n }\n\n return null\n}\n\n/**\n * 匹配自闭合标签\n */\nfunction matchSelfClosingTag(src: string): string | null {\n // 匹配 <tag /> 格式\n const explicitSelfClosing = /^<([a-zA-Z][a-zA-Z0-9]*)((?:\\s+[a-zA-Z_:][a-zA-Z0-9_.:-]*(?:\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s\"'=<>`]+))?)*)\\s*\\/>/.exec(src)\n if (explicitSelfClosing) {\n return explicitSelfClosing[0]\n }\n\n // 匹配隐式自闭合标签(如 <br>、<img src=\"...\">)\n const implicitSelfClosing = /^<([a-zA-Z][a-zA-Z0-9]*)((?:\\s+[a-zA-Z_:][a-zA-Z0-9_.:-]*(?:\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s\"'=<>`]+))?)*)\\s*>/.exec(src)\n if (implicitSelfClosing && SELF_CLOSING_TAGS.has(implicitSelfClosing[1].toLowerCase())) {\n return implicitSelfClosing[0]\n }\n\n return null\n}\n\n","/**\n * Marked Token 到 MDAST 节点转换助手\n *\n * 将 marked 解析产生的 Token 转换为标准的 mdast 节点\n * 严格遵循 marked 类型定义和 mdast 规范\n *\n * 支持通过 TransformContext 扩展自定义 token 类型的转换\n */\n\nimport { Lexer, type Token, type Tokens } from 'marked'\nimport type {\n RootContent,\n PhrasingContent,\n Heading,\n Paragraph,\n Code,\n Blockquote,\n List,\n ListItem,\n Table,\n TableRow,\n TableCell,\n ThematicBreak,\n HTML,\n Text,\n Link,\n Image,\n Strong,\n Emphasis,\n InlineCode,\n Break,\n Delete,\n FootnoteReference,\n FootnoteDefinition,\n Definition,\n ImageReference,\n LinkReference\n} from 'mdast'\n// 从 mdast 插件导入扩展类型\nimport type { Math, InlineMath } from 'mdast-util-math'\nimport type { ContainerDirective } from 'mdast-util-directive'\nimport type {\n ContainerToken,\n FootnoteDefToken,\n OptimisticRefToken,\n ExplicitDefinitionToken,\n BlockMathToken,\n InlineMathToken,\n FootnoteDefinitionBlockToken,\n ExtendedToken,\n InlineHtmlToken\n} from '../../extensions/marked-extensions'\nimport { parseHtmlFragment, type HtmlElementNode } from '../../extensions/html-extension'\n\n// ============ 类型定义 ============\n\n/**\n * 扩展的 ListItem,包含 spread 属性\n */\ninterface ExtendedListItem extends ListItem {\n spread?: boolean\n}\n\n/**\n * 块级 Token 转换函数类型\n *\n * 用于自定义扩展的 token 转换\n */\nexport type BlockTokenTransformer = (\n token: ExtendedToken,\n ctx: TransformContext\n) => RootContent | null | undefined\n\n/**\n * 行内 Token 转换函数类型\n *\n * 用于自定义扩展的 token 转换\n */\nexport type InlineTokenTransformer = (\n token: ExtendedToken,\n ctx: TransformContext\n) => PhrasingContent | PhrasingContent[] | null | undefined\n\n// ============ 转换上下文 ============\n\n/**\n * 转换上下文,用于递归转换时传递信息\n *\n * 支持通过 customBlockTransformers 和 customInlineTransformers 扩展自定义类型\n */\nexport interface TransformContext {\n /**\n * 转换块级 tokens(递归)\n */\n transformTokens: (tokens: Tokens.Generic[] | undefined) => RootContent[]\n\n /**\n * 转换带位置信息的 tokens\n */\n transformTokensWithPosition: (tokens: Tokens.Generic[] | undefined) => RootContent[]\n\n /**\n * 转换行内 tokens\n */\n transformInline: (tokens: Token[] | undefined) => PhrasingContent[]\n\n /**\n * 解析脚注内容为 AST 节点\n */\n parseFootnoteContent: (content: string) => RootContent[]\n\n /**\n * 自定义块级 token 转换器映射\n *\n * key 为 token.type,value 为转换函数\n * 优先于内置转换器执行\n *\n * @example\n * ```ts\n * customBlockTransformers: {\n * myCustomBlock: (token, ctx) => ({\n * type: 'myCustomNode',\n * data: token.data\n * })\n * }\n * ```\n */\n customBlockTransformers?: Record<string, BlockTokenTransformer>\n\n /**\n * 自定义行内 token 转换器映射\n *\n * key 为 token.type,value 为转换函数\n * 优先于内置转换器执行\n */\n customInlineTransformers?: Record<string, InlineTokenTransformer>\n}\n\n// ============ 块级转换 ============\n\n/**\n * 转换块级数学公式\n *\n * 生成 mdast-util-math 兼容的 Math 节点\n */\nexport function transformBlockMath(token: BlockMathToken): Math {\n return {\n type: 'math',\n value: token.text,\n meta: null\n }\n}\n\n/**\n * 转换脚注定义块\n */\nexport function transformFootnoteDefinitionBlock(\n token: FootnoteDefinitionBlockToken,\n ctx: TransformContext\n): FootnoteDefinition {\n // 类型断言说明:parseFootnoteContent 返回 RootContent[]\n // 而 FootnoteDefinition['children'] 要求 (BlockContent | DefinitionContent)[]\n // 实际上脚注内容解析后确实是块级内容,类型安全\n const children = ctx.parseFootnoteContent(token.content) as FootnoteDefinition['children']\n return {\n type: 'footnoteDefinition',\n identifier: token.identifier,\n label: token.identifier,\n children\n }\n}\n\n/**\n * 转换显式定义\n */\nexport function transformExplicitDefinition(token: ExplicitDefinitionToken): Definition | null {\n if (!token.identifier || !token.url) return null\n return {\n type: 'definition',\n identifier: token.identifier,\n label: token.identifier,\n url: token.url,\n title: token.title ?? null\n }\n}\n\n/**\n * 转换 marked 原生的 def token\n */\nexport function transformDef(token: Tokens.Def): Definition | FootnoteDefinition {\n // 检查是否是脚注定义 [^id]: content\n if (token.tag.startsWith('^')) {\n const footnoteId = token.tag.slice(1)\n return {\n type: 'footnoteDefinition',\n identifier: footnoteId,\n label: footnoteId,\n children: [\n {\n type: 'paragraph',\n children: [{ type: 'text', value: token.href }]\n }\n ]\n }\n }\n return {\n type: 'definition',\n identifier: token.tag,\n label: token.tag,\n url: token.href,\n title: token.title ?? null\n }\n}\n\n/**\n * 转换容器指令\n *\n * 生成 mdast-util-directive 兼容的 ContainerDirective 节点\n */\nexport function transformContainer(\n token: ContainerToken,\n ctx: TransformContext\n): ContainerDirective {\n const attributes: Record<string, string> = {}\n const attrRegex = /([a-zA-Z0-9_-]+)=?(\"([^\"]*)\"|'([^']*)'|([^ ]*))?/g\n let match\n while ((match = attrRegex.exec(token.attrs)) !== null) {\n attributes[match[1]] = match[3] || match[4] || match[5] || ''\n }\n // 类型断言说明:transformTokensWithPosition 返回 RootContent[]\n // 而 ContainerDirective['children'] 要求 (BlockContent | DefinitionContent)[]\n // 实际上容器内容确实是块级内容,类型安全\n const children = ctx.transformTokensWithPosition(token.tokens) as ContainerDirective['children']\n return {\n type: 'containerDirective',\n name: token.name,\n attributes,\n children\n }\n}\n\n/**\n * 转换脚注定义(预处理阶段生成的)\n */\nexport function transformFootnoteDefToken(\n token: FootnoteDefToken,\n ctx: TransformContext\n): FootnoteDefinition {\n return {\n type: 'footnoteDefinition',\n identifier: token.identifier,\n label: token.identifier,\n children: [\n {\n type: 'paragraph',\n children: ctx.transformInline(token.tokens)\n }\n ]\n }\n}\n\n/**\n * 转换标题\n */\nexport function transformHeading(token: Tokens.Heading, ctx: TransformContext): Heading {\n return {\n type: 'heading',\n depth: token.depth as 1 | 2 | 3 | 4 | 5 | 6,\n children: ctx.transformInline(token.tokens)\n }\n}\n\n/**\n * 转换段落\n */\nexport function transformParagraph(token: Tokens.Paragraph, ctx: TransformContext): Paragraph {\n return {\n type: 'paragraph',\n children: ctx.transformInline(token.tokens)\n }\n}\n\n/**\n * 转换代码块\n */\nexport function transformCode(token: Tokens.Code): Code {\n return {\n type: 'code',\n lang: token.lang || null,\n meta: null, // 对齐 micromark 输出\n value: token.text\n }\n}\n\n/**\n * 转换引用块\n */\nexport function transformBlockquote(\n token: Tokens.Blockquote,\n ctx: TransformContext\n): Blockquote {\n // 类型断言说明:\n // 1. token.tokens 是 Token[],需转为 Tokens.Generic[](marked 内部类型差异)\n // 2. transformTokens 返回 RootContent[],而 Blockquote['children'] 要求 (BlockContent | DefinitionContent)[]\n // 实际上引用块内容确实是块级内容,类型安全\n const children = ctx.transformTokens(token.tokens as Tokens.Generic[]) as Blockquote['children']\n return {\n type: 'blockquote',\n children\n }\n}\n\n/**\n * 转换列表\n */\nexport function transformList(token: Tokens.List, ctx: TransformContext): List {\n // 类型断言说明:\n // 1. item.tokens 是 Token[],需转为 Tokens.Generic[](marked 内部类型差异)\n // 2. transformTokens 返回 RootContent[],而 ListItem['children'] 要求 (BlockContent | DefinitionContent)[]\n // 实际上列表项内容确实是块级内容,类型安全\n const children: ListItem[] = token.items.map((item) => ({\n type: 'listItem' as const,\n spread: item.loose,\n checked: item.checked ?? null, // 对齐 micromark 输出(GFM 任务列表)\n children: ctx.transformTokens(item.tokens as Tokens.Generic[]) as ListItem['children']\n }))\n return {\n type: 'list',\n ordered: token.ordered,\n start: token.ordered ? (token.start || 1) : null, // 对齐 micromark:有序列表有 start,无序列表为 null\n spread: token.loose,\n children\n }\n}\n\n/**\n * 转换表格\n */\nexport function transformTable(token: Tokens.Table, ctx: TransformContext): Table {\n const headerCells: TableCell[] = token.header.map((cell) => ({\n type: 'tableCell',\n children: ctx.transformInline(cell.tokens)\n }))\n\n const bodyRows: TableRow[] = token.rows.map((row) => ({\n type: 'tableRow',\n children: row.map((cell) => ({\n type: 'tableCell',\n children: ctx.transformInline(cell.tokens)\n }))\n }))\n\n return {\n type: 'table',\n align: token.align as ('left' | 'right' | 'center' | null)[] | undefined,\n children: [{ type: 'tableRow', children: headerCells }, ...bodyRows]\n }\n}\n\n/**\n * 转换分隔线\n */\nexport function transformHr(): ThematicBreak {\n return { type: 'thematicBreak' }\n}\n\n/**\n * 转换 HTML\n */\nexport function transformHtml(token: Tokens.HTML): HTML {\n return {\n type: 'html',\n value: token.text\n }\n}\n\n/**\n * 转换文本块(顶级)\n */\nexport function transformTextBlock(token: Tokens.Text, ctx: TransformContext): Paragraph {\n if (token.tokens) {\n return {\n type: 'paragraph',\n children: ctx.transformInline(token.tokens)\n }\n }\n return {\n type: 'paragraph',\n children: [{ type: 'text', value: token.text }]\n }\n}\n\n// ============ 行内转换 ============\n\n/**\n * 转换行内数学公式\n *\n * 生成 mdast-util-math 兼容的 InlineMath 节点\n */\nexport function transformInlineMath(token: InlineMathToken): InlineMath {\n return {\n type: 'inlineMath',\n value: token.text\n }\n}\n\n/**\n * 转换乐观引用\n */\nexport function transformOptimisticReference(\n token: OptimisticRefToken,\n ctx: TransformContext\n): ImageReference | LinkReference {\n if (token.isImage) {\n return {\n type: 'imageReference',\n identifier: token.identifier,\n label: token.label,\n referenceType: token.referenceType,\n alt: token.text\n }\n }\n const labelChildren = ctx.transformInline(new Lexer().inlineTokens(token.text))\n return {\n type: 'linkReference',\n identifier: token.identifier,\n label: token.label,\n referenceType: token.referenceType,\n children: labelChildren.length ? labelChildren : [{ type: 'text', value: token.text }]\n }\n}\n\n/**\n * 转换链接\n */\nexport function transformLink(token: Tokens.Link, ctx: TransformContext): FootnoteReference | Link {\n // 检查是否是脚注引用:text 以 ^ 开头(如 [^1])\n if (token.text.startsWith('^') && token.text.length > 1) {\n const footnoteId = token.text.slice(1)\n return {\n type: 'footnoteReference',\n identifier: footnoteId,\n label: footnoteId\n }\n }\n return {\n type: 'link',\n url: token.href,\n title: token.title || null, // 对齐 micromark 输出\n children: ctx.transformInline(token.tokens)\n }\n}\n\n/**\n * 转换图片\n */\nexport function transformImage(token: Tokens.Image): Image {\n return {\n type: 'image',\n url: token.href,\n title: token.title || null, // 对齐 micromark 输出\n alt: token.text\n }\n}\n\n/**\n * 转换文本(包含脚注引用提取)\n */\nexport function transformText(token: Tokens.Text | Tokens.Escape): (Text | FootnoteReference)[] {\n const results: (Text | FootnoteReference)[] = []\n const text = token.text\n const footnoteRegex = /\\[\\^([a-zA-Z0-9_-]+)\\]/g\n let lastIndex = 0\n let match\n\n while ((match = footnoteRegex.exec(text)) !== null) {\n if (match.index > lastIndex) {\n results.push({\n type: 'text',\n value: text.substring(lastIndex, match.index)\n })\n }\n results.push({\n type: 'footnoteReference',\n identifier: match[1],\n label: match[1]\n })\n lastIndex = match.index + match[0].length\n }\n\n if (lastIndex < text.length) {\n results.push({\n type: 'text',\n value: text.substring(lastIndex)\n })\n }\n\n return results\n}\n\n/**\n * 转换加粗\n */\nexport function transformStrong(token: Tokens.Strong, ctx: TransformContext): Strong {\n return {\n type: 'strong',\n children: ctx.transformInline(token.tokens)\n }\n}\n\n/**\n * 转换斜体\n */\nexport function transformEmphasis(token: Tokens.Em, ctx: TransformContext): Emphasis {\n return {\n type: 'emphasis',\n children: ctx.transformInline(token.tokens)\n }\n}\n\n/**\n * 转换行内代码\n */\nexport function transformCodespan(token: Tokens.Codespan): InlineCode {\n return {\n type: 'inlineCode',\n value: token.text\n }\n}\n\n/**\n * 转换换行\n */\nexport function transformBreak(): Break {\n return { type: 'break' }\n}\n\n/**\n * 转换删除线\n */\nexport function transformDelete(token: Tokens.Del, ctx: TransformContext): Delete {\n return {\n type: 'delete',\n children: ctx.transformInline(token.tokens)\n }\n}\n\n/**\n * 转换内联 HTML\n *\n * 将内联 HTML token 转换为 HtmlElementNode 节点\n * 如果解析失败,回退为普通文本节点\n */\nexport function transformInlineHtml(\n token: InlineHtmlToken\n): PhrasingContent | PhrasingContent[] {\n // 使用 html-extension 的解析器\n const parsed = parseHtmlFragment(token.text)\n\n if (parsed.length > 0) {\n // 成功解析为 HtmlElementNode\n return parsed as unknown as PhrasingContent[]\n }\n\n // 解析失败,回退为文本节点\n return { type: 'text', value: token.text }\n}\n\n// ============ 主转换函数 ============\n\n// ============ 类型守卫 ============\n\n/**\n * 检查 token 是否为指定类型\n * 通过 type 字段判断,避免 as unknown as 的类型断言\n */\nfunction isTokenType<T extends ExtendedToken>(\n token: ExtendedToken,\n type: T['type']\n): token is T {\n return token.type === type\n}\n\n/**\n * 内置块级转换器映射\n *\n * 注意:由于 TypeScript 的类型系统限制,在回调中需要使用类型断言\n * 这是因为 Record 的 value 类型是统一的 BlockTokenTransformer\n * 而每个具体的转换函数需要特定的 token 类型\n */\nconst builtinBlockTransformers: Record<string, BlockTokenTransformer> = {\n blockMath: (token) => {\n if (isTokenType<BlockMathToken>(token, 'blockMath')) return transformBlockMath(token)\n return null\n },\n footnoteDefinitionBlock: (token, ctx) => {\n if (isTokenType<FootnoteDefinitionBlockToken>(token, 'footnoteDefinitionBlock'))\n return transformFootnoteDefinitionBlock(token, ctx)\n return null\n },\n explicitDefinition: (token) => {\n if (isTokenType<ExplicitDefinitionToken>(token, 'explicitDefinition'))\n return transformExplicitDefinition(token)\n return null\n },\n def: (token) => {\n if (isTokenType<Tokens.Def>(token, 'def')) return transformDef(token)\n return null\n },\n container: (token, ctx) => {\n if (isTokenType<ContainerToken>(token, 'container')) return transformContainer(token, ctx)\n return null\n },\n footnoteDefinition: (token, ctx) => {\n if (isTokenType<FootnoteDefToken>(token, 'footnoteDefinition'))\n return transformFootnoteDefToken(token, ctx)\n return null\n },\n heading: (token, ctx) => {\n if (isTokenType<Tokens.Heading>(token, 'heading')) return transformHeading(token, ctx)\n return null\n },\n paragraph: (token, ctx) => {\n if (isTokenType<Tokens.Paragraph>(token, 'paragraph')) return transformParagraph(token, ctx)\n return null\n },\n code: (token) => {\n if (isTokenType<Tokens.Code>(token, 'code')) return transformCode(token)\n return null\n },\n blockquote: (token, ctx) => {\n if (isTokenType<Tokens.Blockquote>(token, 'blockquote')) return transformBlockquote(token, ctx)\n return null\n },\n list: (token, ctx) => {\n if (isTokenType<Tokens.List>(token, 'list')) return transformList(token, ctx)\n return null\n },\n table: (token, ctx) => {\n if (isTokenType<Tokens.Table>(token, 'table')) return transformTable(token, ctx)\n return null\n },\n hr: () => transformHr(),\n html: (token) => {\n if (isTokenType<Tokens.HTML>(token, 'html')) return transformHtml(token)\n return null\n },\n space: () => null,\n text: (token, ctx) => {\n if (isTokenType<Tokens.Text>(token, 'text')) return transformTextBlock(token, ctx)\n return null\n }\n}\n\n/**\n * 内置行内转换器映射\n */\nconst builtinInlineTransformers: Record<string, InlineTokenTransformer> = {\n inlineMath: (token) => {\n if (isTokenType<InlineMathToken>(token, 'inlineMath')) return transformInlineMath(token)\n return null\n },\n optimisticReference: (token, ctx) => {\n if (isTokenType<OptimisticRefToken>(token, 'optimisticReference'))\n return transformOptimisticReference(token, ctx)\n return null\n },\n link: (token, ctx) => {\n if (isTokenType<Tokens.Link>(token, 'link')) return transformLink(token, ctx)\n return null\n },\n image: (token) => {\n if (isTokenType<Tokens.Image>(token, 'image')) return transformImage(token)\n return null\n },\n text: (token) => {\n if (isTokenType<Tokens.Text>(token, 'text')) return transformText(token)\n return null\n },\n escape: (token) => {\n if (isTokenType<Tokens.Escape>(token, 'escape')) return transformText(token)\n return null\n },\n strong: (token, ctx) => {\n if (isTokenType<Tokens.Strong>(token, 'strong')) return transformStrong(token, ctx)\n return null\n },\n em: (token, ctx) => {\n if (isTokenType<Tokens.Em>(token, 'em')) return transformEmphasis(token, ctx)\n return null\n },\n codespan: (token) => {\n if (isTokenType<Tokens.Codespan>(token, 'codespan')) return transformCodespan(token)\n return null\n },\n br: () => transformBreak(),\n del: (token, ctx) => {\n if (isTokenType<Tokens.Del>(token, 'del')) return transformDelete(token, ctx)\n return null\n },\n inlineHtml: (token) => {\n if (isTokenType<InlineHtmlToken>(token, 'inlineHtml')) return transformInlineHtml(token)\n return null\n }\n}\n\n/**\n * 转换单个块级 Token 为 MDAST 节点\n *\n * 转换优先级:\n * 1. 自定义转换器(customBlockTransformers)\n * 2. 内置转换器\n * 3. 回退处理(带 text 属性的 token 转为段落)\n *\n * @param token 要转换的 token\n * @param ctx 转换上下文\n * @returns MDAST 节点或 null\n */\nexport function transformBlockToken(token: ExtendedToken, ctx: TransformContext): RootContent | null {\n const tokenType = token.type\n\n // 1. 优先使用自定义转换器\n if (ctx.customBlockTransformers?.[tokenType]) {\n const result = ctx.customBlockTransformers[tokenType](token, ctx)\n if (result !== undefined) return result\n }\n\n // 2. 使用内置转换器\n if (builtinBlockTransformers[tokenType]) {\n const result = builtinBlockTransformers[tokenType](token, ctx)\n if (result !== undefined) return result\n }\n\n // 3. 回退处理:带 text 属性的 token 转为段落\n if ('text' in token && typeof token.text === 'string') {\n const paragraph: Paragraph = {\n type: 'paragraph',\n children: [{ type: 'text', value: token.text }]\n }\n return paragraph\n }\n\n return null\n}\n\n/**\n * 转换单个行内 Token 为 MDAST 节点\n *\n * 转换优先级:\n * 1. 自定义转换器(customInlineTransformers)\n * 2. 内置转换器\n * 3. 回退处理(带 text 属性的 token 转为文本节点)\n *\n * @param token 要转换的 token\n * @param ctx 转换上下文\n * @returns MDAST 节点或 null\n */\nexport function transformInlineToken(\n token: ExtendedToken,\n ctx: TransformContext\n): PhrasingContent | PhrasingContent[] | null {\n const tokenType = token.type\n\n // 1. 优先使用自定义转换器\n if (ctx.customInlineTransformers?.[tokenType]) {\n const result = ctx.customInlineTransformers[tokenType](token, ctx)\n if (result !== undefined) return result\n }\n\n // 2. 使用内置转换器\n if (builtinInlineTransformers[tokenType]) {\n const result = builtinInlineTransformers[tokenType](token, ctx)\n if (result !== undefined) return result\n }\n\n // 3. 回退处理:带 text 属性的 token 转为文本节点\n if ('text' in token && typeof token.text === 'string') {\n const text: Text = { type: 'text', value: token.text }\n return text\n }\n\n return null\n}\n\n/**\n * 获取内置块级转换器(用于扩展或覆盖)\n */\nexport function getBuiltinBlockTransformers(): Readonly<Record<string, BlockTokenTransformer>> {\n return builtinBlockTransformers\n}\n\n/**\n * 获取内置行内转换器(用于扩展或覆盖)\n */\nexport function getBuiltinInlineTransformers(): Readonly<Record<string, InlineTokenTransformer>> {\n return builtinInlineTransformers\n}\n","/**\n * Marked AST 构建器(极速模式)\n *\n * 基于 marked 解析器\n * 特点:\n * - 速度更快\n * - 适合流式渲染场景\n *\n */\n\nimport { lexer, Lexer, type Tokens, type Token, type MarkedExtension } from 'marked'\nimport type {\n Root,\n RootContent,\n PhrasingContent\n} from 'mdast'\nimport type { ParsedBlock, BlockStatus, ContainerConfig } from '../../types'\nimport { transformHtmlNodes, type HtmlTreeExtensionOptions } from '../../extensions/html-extension'\nimport type { IAstBuilder, EngineParserOptions } from './types'\nimport { extractMarkedExtensions } from './types'\n\n// 导入扩展\nimport {\n createExplicitDefinitionExtension,\n createOptimisticReferenceExtension,\n createBlockMathExtension,\n createInlineMathExtension,\n createFootnoteDefinitionExtension,\n createInlineHtmlExtension,\n type ContainerToken,\n type FootnoteDefToken\n} from '../../extensions/marked-extensions'\n\n// 导入转换助手\nimport {\n transformBlockToken,\n transformInlineToken,\n type TransformContext\n} from './markedHelpers'\n\n// ============ 类型定义 ============\ntype LinkDefinitions = Record<string, { href: string; title?: string }>\n\n/**\n * Marked AST 构建器\n *\n * 使用 marked 解析 Markdown,速度更快\n * 适用于流式渲染和高性能场景\n */\nexport class MarkedAstBuilder implements IAstBuilder {\n readonly containerConfig: ContainerConfig | undefined\n readonly htmlTreeOptions: HtmlTreeExtensionOptions | undefined\n private globalLinks: LinkDefinitions = {}\n /** 用户传入的 marked 扩展 */\n private readonly userExtensions: MarkedExtension[] = []\n /** 转换上下文(用于递归转换) */\n private readonly transformContext: TransformContext\n\n constructor(private options: EngineParserOptions = {}) {\n this.containerConfig = typeof options.containers === 'object'\n ? options.containers\n : (options.containers === true ? {} : undefined)\n\n this.htmlTreeOptions = typeof options.htmlTree === 'object'\n ? options.htmlTree\n : (options.htmlTree === true ? {} : undefined)\n\n // 收集用户扩展\n if (options.plugins) {\n this.userExtensions.push(...extractMarkedExtensions(options.plugins))\n }\n if (options.markedExtensions) {\n this.userExtensions.push(...options.markedExtensions)\n }\n\n // 初始化转换上下文\n this.transformContext = {\n transformTokens: this.transformTokens.bind(this),\n transformTokensWithPosition: this.transformTokensWithPosition.bind(this),\n transformInline: this.transformInline.bind(this),\n parseFootnoteContent: this.parseFootnoteContent.bind(this)\n }\n }\n\n parse(text: string): Root {\n // 1. 文本清洗:这是解决 URL 截断的第一道防线\n const normalizedText = text.replace(/[\\u00A0\\u200b\\u202f]/g, ' ')\n\n // 2. 构造 Extensions\n const optimisticRefExt = createOptimisticReferenceExtension()\n const explicitDefExt = createExplicitDefinitionExtension()\n const footnoteDefExt = createFootnoteDefinitionExtension()\n\n // 收集用户扩展中的 block/inline tokenizers\n const userBlockExts: any[] = []\n const userBlockStartExts: any[] = []\n const userInlineExts: any[] = []\n const userInlineStartExts: any[] = []\n\n for (const ext of this.userExtensions) {\n if ((ext as any).level === 'block') {\n if ((ext as any).tokenizer) userBlockExts.push((ext as any).tokenizer)\n if ((ext as any).start) userBlockStartExts.push((ext as any).start)\n } else if ((ext as any).level === 'inline') {\n if ((ext as any).tokenizer) userInlineExts.push((ext as any).tokenizer)\n if ((ext as any).start) userInlineStartExts.push((ext as any).start)\n }\n }\n\n // 脚注定义扩展需要在 explicitDefinitionExtension 之前,确保 [^id]: 优先被脚注扩展处理\n const blockExts: any[] = [\n footnoteDefExt.tokenizer,\n explicitDefExt.tokenizer,\n ...userBlockExts\n ]\n const blockStartExts: any[] = [\n footnoteDefExt.start,\n explicitDefExt.start,\n ...userBlockStartExts\n ]\n const inlineExts: any[] = [optimisticRefExt.tokenizer, ...userInlineExts]\n const inlineStartExts: any[] = [optimisticRefExt.start, ...userInlineStartExts]\n\n // Math 扩展(仅当 options.math 启用时)\n if (this.options.math) {\n // 解析 math 配置\n const mathOptions = typeof this.options.math === 'object'\n ? this.options.math\n : {}\n\n const blockMathExt = createBlockMathExtension(mathOptions)\n const inlineMathExt = createInlineMathExtension(mathOptions)\n blockExts.unshift(blockMathExt.tokenizer)\n blockStartExts.unshift(blockMathExt.start)\n inlineExts.unshift(inlineMathExt.tokenizer)\n inlineStartExts.unshift(inlineMathExt.start)\n }\n\n // 内联 HTML 扩展(仅当 options.htmlTree 启用时)\n // 这使得内联 HTML 能够被识别为完整的 token,与 Micromark 行为一致\n if (this.htmlTreeOptions) {\n const inlineHtmlExt = createInlineHtmlExtension()\n inlineExts.unshift(inlineHtmlExt.tokenizer)\n inlineStartExts.unshift(inlineHtmlExt.start)\n }\n\n const lexerOptions: any = {\n gfm: true,\n breaks: false, // 关闭软换行转 break,与 Micromark 保持一致\n ...this.options,\n extensions: {\n inline: inlineExts,\n startInline: inlineStartExts,\n block: blockExts,\n startBlock: blockStartExts\n }\n }\n\n const lexerInstance = new Lexer(lexerOptions)\n\n // 3. 注入历史 Links\n if (lexerInstance.tokens && (lexerInstance.tokens as any).links) {\n Object.assign((lexerInstance.tokens as any).links, this.globalLinks)\n }\n\n // 4. 执行解析\n let tokens = lexerInstance.lex(normalizedText) as Token[]\n\n // 5. 保存 Links\n if (lexerInstance.tokens && (lexerInstance.tokens as any).links) {\n Object.assign(this.globalLinks, (lexerInstance.tokens as any).links)\n }\n\n // 6. 预处理\n tokens = this.preprocessTokens(tokens)\n\n // 7. 转换 AST\n let children = this.transformTokensWithPosition(tokens)\n\n // 8. HTML 后处理\n if (this.htmlTreeOptions) {\n children = this.processHtmlNodes(children)\n }\n\n return {\n type: 'root',\n children\n }\n }\n\n /**\n * 预处理 tokens\n *\n * 处理容器指令和遗留的脚注定义(从 paragraph 中提取)\n */\n private preprocessTokens(tokens: Token[]): Token[] {\n const result: Token[] = []\n let i = 0\n\n while (i < tokens.length) {\n const token = tokens[i]\n\n if (token.type === 'paragraph') {\n const text = (token as Tokens.Paragraph).text\n\n // 处理遗留的脚注定义(从 paragraph 中提取)\n const footnoteMatch = text.match(/^\\[\\^([a-zA-Z0-9_-]+)\\]:\\s+([\\s\\S]*)$/)\n if (footnoteMatch) {\n const defToken: FootnoteDefToken = {\n type: 'footnoteDefinition',\n identifier: footnoteMatch[1],\n text: footnoteMatch[2],\n tokens: new Lexer().inlineTokens(footnoteMatch[2]),\n raw: token.raw\n }\n result.push(defToken as unknown as Token)\n i++\n continue\n }\n\n // 处理容器指令\n const containerStartMatch = text.match(/^:::(\\s*)([a-zA-Z0-9_-]+)(.*?)(\\n|$)/)\n if (containerStartMatch) {\n const name = containerStartMatch[2]\n const attrs = containerStartMatch[3].trim()\n let rawAccumulator = ''\n let j = i\n let depth = 0\n let foundEnd = false\n let contentRaw = ''\n\n while (j < tokens.length) {\n const currentToken = tokens[j]\n rawAccumulator += currentToken.raw\n const lines = rawAccumulator.split('\\n')\n depth = 0\n let startLineIndex = -1\n let endLineIndex = -1\n\n for (let k = 0; k < lines.length; k++) {\n const line = lines[k]\n if (line.match(/^:::(\\s*)([a-zA-Z0-9_-]+)/)) {\n if (depth === 0 && startLineIndex === -1) startLineIndex = k\n depth++\n } else if (line.trim() === ':::') {\n depth--\n if (depth === 0) {\n endLineIndex = k\n foundEnd = true\n break\n }\n }\n }\n\n if (foundEnd) {\n const contentLines = lines.slice(startLineIndex + 1, endLineIndex)\n contentRaw = contentLines.join('\\n')\n const remainingLines = lines.slice(endLineIndex + 1)\n const remainingText = remainingLines.join('\\n')\n\n const containerToken: ContainerToken = {\n type: 'container',\n name,\n attrs,\n tokens: this.preprocessTokens(lexer(contentRaw)),\n raw: rawAccumulator\n }\n result.push(containerToken as unknown as Token)\n\n if (remainingText.trim()) {\n const remainingTokens = this.preprocessTokens(lexer(remainingText))\n result.push(...remainingTokens)\n }\n\n i = j + 1\n break\n }\n j++\n }\n\n if (foundEnd) continue\n }\n }\n\n result.push(token)\n i++\n }\n\n return result\n }\n\n /**\n * 转换 tokens 为 MDAST 节点(带位置信息)\n */\n private transformTokensWithPosition(tokens: Tokens.Generic[] | undefined): RootContent[] {\n if (!tokens) return []\n\n const results: RootContent[] = []\n let currentOffset = 0\n\n for (const token of tokens) {\n const rawLength = token.raw?.length ?? 0\n const node = transformBlockToken(token as Token, this.transformContext)\n\n if (node) {\n node.position = {\n start: { line: 0, column: 0, offset: currentOffset },\n end: { line: 0, column: 0, offset: currentOffset + rawLength }\n }\n results.push(node)\n }\n\n currentOffset += rawLength\n }\n\n return results\n }\n\n /**\n * 转换 tokens 为 MDAST 节点(不带位置信息)\n */\n private transformTokens(tokens: Tokens.Generic[] | undefined): RootContent[] {\n if (!tokens) return []\n return tokens\n .map((t) => transformBlockToken(t as Token, this.transformContext))\n .filter(Boolean) as RootContent[]\n }\n\n /**\n * 转换行内 tokens\n */\n private transformInline(tokens: Token[] | undefined): PhrasingContent[] {\n if (!tokens) return []\n\n const results: PhrasingContent[] = []\n\n for (const token of tokens) {\n const result = transformInlineToken(token, this.transformContext)\n if (result) {\n if (Array.isArray(result)) {\n results.push(...result)\n } else {\n results.push(result)\n }\n }\n }\n\n return results\n }\n\n /**\n * 解析脚注内容为 AST 节点\n */\n private parseFootnoteContent(content: string): RootContent[] {\n if (!content.trim()) {\n return []\n }\n\n // 移除脚注延续行的前导缩进(4 空格或 1 tab)\n const normalizedContent = content\n .split('\\n')\n .map((line, index) => {\n // 第一行不需要移除缩进\n if (index === 0) return line\n // 后续行移除 4 空格或 1 tab 的缩进\n if (line.startsWith(' ')) return line.slice(4)\n if (line.startsWith('\\t')) return line.slice(1)\n return line\n })\n .join('\\n')\n\n // 使用简单的 Lexer 解析内容\n const contentLexer = new Lexer({ gfm: true, breaks: true })\n const tokens = contentLexer.lex(normalizedContent)\n\n return this.transformTokens(tokens)\n }\n\n /**\n * 处理 HTML 节点\n *\n * 使用 html-extension 的 transformHtmlNodes 来处理:\n * - 合并被空行分割的 HTML 节点\n * - 将 HTML 解析为 HtmlElementNode 树结构\n */\n private processHtmlNodes(nodes: RootContent[]): RootContent[] {\n // 构造一个临时的 Root 节点,使用 transformHtmlNodes 处理\n const tempRoot: Root = {\n type: 'root',\n children: nodes as Root['children']\n }\n\n const transformed = transformHtmlNodes(tempRoot, this.htmlTreeOptions)\n return transformed.children as RootContent[]\n }\n\n /**\n * 将 AST 节点转换为 ParsedBlock\n */\n nodesToBlocks(\n nodes: RootContent[],\n startOffset: number,\n rawText: string,\n status: BlockStatus,\n generateBlockId: (startOffset: number) => string\n ): ParsedBlock[] {\n const blocks: ParsedBlock[] = []\n\n for (const node of nodes) {\n const relativeStart = node.position?.start?.offset ?? 0\n const relativeEnd = node.position?.end?.offset ?? rawText.length\n const nodeText = rawText.substring(relativeStart, relativeEnd)\n const absoluteStart = startOffset + relativeStart\n const absoluteEnd = startOffset + relativeEnd\n\n blocks.push({\n id: generateBlockId(absoluteStart),\n status,\n node,\n startOffset: absoluteStart,\n endOffset: absoluteEnd,\n rawText: nodeText\n })\n }\n\n return blocks\n }\n\n /**\n * 更新配置选项\n * @param options 部分配置选项\n */\n updateOptions(options: Partial<EngineParserOptions>): void {\n // 合并选项\n Object.assign(this.options, options)\n\n // 更新容器配置\n if ('containers' in options) {\n ;(this as any).containerConfig = typeof options.containers === 'object'\n ? options.containers\n : (options.containers === true ? {} : undefined)\n }\n\n // 更新 HTML Tree 配置\n if ('htmlTree' in options) {\n ;(this as any).htmlTreeOptions = typeof options.htmlTree === 'object'\n ? options.htmlTree\n : (options.htmlTree === true ? {} : undefined)\n }\n\n // 更新用户扩展(如果有)\n if (options.plugins || options.markedExtensions) {\n this.userExtensions.length = 0\n if (options.plugins) {\n this.userExtensions.push(...extractMarkedExtensions(options.plugins))\n }\n if (options.markedExtensions) {\n this.userExtensions.push(...options.markedExtensions)\n }\n }\n }\n}\n\n/**\n * AstBuilder 别名(向后兼容)\n */\nexport const AstBuilder = MarkedAstBuilder\n","/**\n * 增量 Markdown 解析器\n *\n * 设计思路:\n * 1. 维护一个文本缓冲区,接收流式输入\n * 2. 识别\"稳定边界\"(如空行、标题等),将已完成的块标记为 completed\n * 3. 对于正在接收的块,每次重新解析,但只解析该块的内容\n * 4. 复杂嵌套节点(如列表、引用)作为整体处理,直到确认完成\n *\n * 引擎选择:\n * - 默认使用 marked(极速模式),只打包 marked 依赖\n * - 如需使用 micromark,通过 astBuilder 选项注入 MicromarkAstBuilder\n *\n * Tree-shaking 说明:\n * - 默认只打包 marked 引擎\n * - micromark 引擎需要从 '@incremark/core/engines/micromark' 单独导入\n */\n\nimport type {\n Root,\n ParsedBlock,\n IncrementalUpdate,\n BlockContext,\n ParserState,\n DefinitionMap,\n FootnoteDefinitionMap\n} from '../types'\n\nimport {\n createInitialContext,\n} from '../detector'\nimport { BoundaryDetector } from './boundary'\nimport { DefinitionManager } from './manager'\nimport { FootnoteManager } from './manager'\nimport type { IAstBuilder, EngineParserOptions } from './ast/types'\n// 只默认导入 MarkedAstBuilder,实现 tree-shaking\nimport { MarkedAstBuilder } from './ast/MarkedAstBuildter'\n\n/**\n * AST 构建器类型(用于注入)\n */\nexport type AstBuilderClass = new (options: EngineParserOptions) => IAstBuilder\n\n/**\n * 扩展的解析器选项(支持注入自定义 AstBuilder)\n */\nexport interface IncremarkParserOptions extends EngineParserOptions {\n /**\n * 自定义 AST 构建器类\n *\n * 用于注入不同的引擎实现,实现 tree-shaking\n *\n * @example\n * ```ts\n * // 使用 micromark 引擎\n * import { MicromarkAstBuilder } from '@incremark/core/engines/micromark'\n * const parser = createIncremarkParser({\n * astBuilder: MicromarkAstBuilder\n * })\n * ```\n */\n astBuilder?: AstBuilderClass\n}\n\n// ============ 解析器类 ============\n\nexport class IncremarkParser {\n private lines: string[] = []\n /** 行偏移量前缀和:lineOffsets[i] = 第i行起始位置的偏移量 */\n private lineOffsets: number[] = [0]\n private completedBlocks: ParsedBlock[] = []\n private pendingStartLine = 0\n private context: BlockContext\n private options: IncremarkParserOptions\n /** 边界检测器 */\n private readonly boundaryDetector: BoundaryDetector\n /** AST 构建器 */\n private astBuilder: IAstBuilder\n /** Definition 管理器 */\n private readonly definitionManager: DefinitionManager\n /** Footnote 管理器 */\n private readonly footnoteManager: FootnoteManager\n /** 上次 append 返回的 pending blocks,用于 getAst 复用 */\n private lastPendingBlocks: ParsedBlock[] = []\n\n constructor(options: IncremarkParserOptions = {}) {\n this.options = {\n gfm: true,\n ...options\n }\n this.context = createInitialContext()\n\n // 初始化 AST 构建器\n // 默认使用 MarkedAstBuilder(极速模式),支持注入自定义构建器\n const BuilderClass = options.astBuilder || MarkedAstBuilder\n this.astBuilder = new BuilderClass(this.options)\n\n // 初始化边界检测器\n this.boundaryDetector = new BoundaryDetector({ containers: this.astBuilder.containerConfig })\n // 初始化 Definition 和 Footnote 管理器\n this.definitionManager = new DefinitionManager()\n this.footnoteManager = new FootnoteManager()\n }\n\n /**\n * 生成 block 的 id(直接使用 offset)\n * @param startOffset - block 的起始偏移量\n */\n private generateBlockId(startOffset: number): string {\n return String(startOffset)\n }\n\n /**\n * 生成 pending block 的稳定 id(基于 startOffset)\n * pending blocks 在每次 append 时都会重新生成,使用 startOffset 确保 id 稳定\n * @param startOffset - block 的起始偏移量,用作稳定的 id\n */\n private generatePendingBlockId(startOffset: number): string {\n return String(startOffset)\n }\n\n /**\n * 更新已完成的 blocks 中的 definitions 和 footnote definitions\n */\n private updateDefinitionsFromCompletedBlocks(blocks: ParsedBlock[]): void {\n this.definitionManager.extractFromBlocks(blocks)\n this.footnoteManager.extractDefinitionsFromBlocks(blocks)\n }\n\n /**\n * 增量更新 lines 和 lineOffsets\n * 优化策略:只 split 新增的 chunk,不拼接旧字符串,避免长行性能劣化\n */\n private updateLines(chunk: string): void {\n const prevLineCount = this.lines.length\n\n // 1. 初始化情况\n if (prevLineCount === 0) {\n this.lines = chunk.split('\\n')\n this.lineOffsets = [0]\n // 计算后续行的 offset\n for (let i = 0; i < this.lines.length - 1; i++) {\n this.lineOffsets.push(this.lineOffsets[i] + this.lines[i].length + 1)\n }\n return\n }\n\n // 2. 增量更新情况\n // 关键优化:只对 chunk 进行 split,不触碰 oldText\n const chunkLines = chunk.split('\\n')\n const lastLineIndex = prevLineCount - 1\n\n // 步骤 A: 将 chunk 的第一部分追加到当前最后一行\n // 注意:这一步只会改变最后一行的内容长度,不会改变它的【起始偏移量】\n this.lines[lastLineIndex] += chunkLines[0]\n\n // 步骤 B: 如果 chunk 包含换行,处理新增的行\n for (let i = 1; i < chunkLines.length; i++) {\n // 这里的上一行(prevLine)可能是刚刚被追加过的 lastLine,也可能是 chunk 中间的新行\n // 我们需要根据\"上一行\"的 offset 和 length 来计算\"当前新行\"的 offset\n const prevLineIndex = this.lines.length - 1 // 总是取当前数组最后一行作为基准\n const prevLineStart = this.lineOffsets[prevLineIndex]\n const prevLineLength = this.lines[prevLineIndex].length\n\n // 计算新行的 offset = 上一行起始 + 上一行长度 + 1个换行符\n const newOneOffset = prevLineStart + prevLineLength + 1\n\n this.lineOffsets.push(newOneOffset)\n this.lines.push(chunkLines[i])\n }\n }\n\n /**\n * O(1) 获取行偏移量\n */\n private getLineOffset(lineIndex: number): number {\n return this.lineOffsets[lineIndex] ?? 0\n }\n\n /**\n * 查找稳定边界\n * 返回稳定边界行号和该行对应的上下文(用于后续更新,避免重复计算)\n */\n private findStableBoundary(): { line: number; contextAtLine: BlockContext } {\n const result = this.boundaryDetector.findStableBoundary(\n this.lines,\n this.pendingStartLine,\n this.context\n )\n return { line: result.line, contextAtLine: result.context }\n }\n\n /**\n * 追加新的 chunk 并返回增量更新\n */\n append(chunk: string): IncrementalUpdate {\n this.updateLines(chunk)\n\n const { line: stableBoundary, contextAtLine } = this.findStableBoundary()\n\n const update: IncrementalUpdate = {\n completed: [],\n updated: [],\n pending: [],\n ast: { type: 'root', children: [] },\n definitions: {},\n footnoteDefinitions: {},\n footnoteReferenceOrder: []\n }\n\n if (stableBoundary >= this.pendingStartLine && stableBoundary >= 0) {\n const stableText = this.lines.slice(this.pendingStartLine, stableBoundary + 1).join('\\n')\n const stableOffset = this.getLineOffset(this.pendingStartLine)\n\n const ast = this.astBuilder.parse(stableText)\n // 使用绝对偏移量,确保 Block 的位置信息正确\n const newBlocks = this.astBuilder.nodesToBlocks(ast.children, stableOffset, stableText, 'completed', (offset) => this.generateBlockId(offset))\n\n // 检查是否有重叠的旧 blocks 需要移除\n // 这主要处理容器增量解析的情况:容器内部的内容先被添加为独立 blocks,\n // 然后整个容器被添加时,需要移除之前添加的内部 blocks\n const blocksToRemove: ParsedBlock[] = []\n\n for (const newBlock of newBlocks) {\n for (const existingBlock of this.completedBlocks) {\n // 检查是否有重叠:新 block 的起始位置在旧 block 的范围内\n const isOverlapping = newBlock.startOffset >= existingBlock.startOffset && newBlock.startOffset < existingBlock.endOffset\n // 或者旧 block 的起始位置在新 block 的范围内\n const isOverlappingReverse = existingBlock.startOffset >= newBlock.startOffset && existingBlock.startOffset < newBlock.endOffset\n\n if (isOverlapping || isOverlappingReverse) {\n // 如果 ID 不同,说明是容器增量解析的情况,需要移除旧的\n if (newBlock.id !== existingBlock.id) {\n blocksToRemove.push(existingBlock)\n }\n }\n }\n }\n\n // 移除重叠的 blocks\n if (blocksToRemove.length > 0) {\n const idsToRemove = new Set(blocksToRemove.map(b => b.id))\n this.completedBlocks = this.completedBlocks.filter(b => !idsToRemove.has(b.id))\n }\n\n this.completedBlocks.push(...newBlocks)\n update.completed = newBlocks\n\n // 标记被移除的 blocks(用于通知上层)\n if (blocksToRemove.length > 0) {\n // 将被移除的 blocks 添加到 update.updated 中,标记它们已被替换\n update.updated = blocksToRemove\n }\n\n // 更新 definitions 从新完成的 blocks\n this.updateDefinitionsFromCompletedBlocks(newBlocks)\n\n // 增量收集脚注引用(只扫描新完成的 blocks)\n this.footnoteManager.collectReferencesFromCompletedBlocks(newBlocks)\n\n // 清理不再需要的上下文缓存\n this.boundaryDetector.clearContextCache(this.pendingStartLine)\n\n // 直接使用 findStableBoundary 计算好的上下文,避免重复遍历\n this.context = contextAtLine\n this.pendingStartLine = stableBoundary + 1\n }\n\n if (this.pendingStartLine < this.lines.length) {\n const pendingText = this.lines.slice(this.pendingStartLine).join('\\n')\n\n if (pendingText.trim()) {\n const pendingOffset = this.getLineOffset(this.pendingStartLine)\n const ast = this.astBuilder.parse(pendingText)\n // pending blocks 使用基于 offset 的稳定 id,避免每次 append 时 id 变化\n // 这对于 Vue/React 等框架的 key 稳定性很重要\n update.pending = this.astBuilder.nodesToBlocks(\n ast.children,\n pendingOffset,\n pendingText,\n 'pending',\n (offset) => this.generatePendingBlockId(offset)\n )\n }\n }\n\n // 缓存 pending blocks 供 getAst 使用\n this.lastPendingBlocks = update.pending\n\n update.ast = {\n type: 'root',\n children: [...this.completedBlocks.map((b) => b.node), ...update.pending.map((b) => b.node)]\n }\n\n // 使用优化的脚注引用收集(只扫描 pending 部分)\n update.footnoteReferenceOrder = this.footnoteManager.collectReferencesFromPending(update.pending)\n\n // 填充 definitions 和 footnote 相关数据\n update.definitions = this.getDefinitionMap()\n update.footnoteDefinitions = this.getFootnoteDefinitionMap()\n\n // 触发状态变化回调\n this.emitChange(update.pending)\n\n return update\n }\n\n /**\n * 触发状态变化回调\n */\n private emitChange(pendingBlocks: ParsedBlock[] = []): void {\n if (this.options.onChange) {\n const state: ParserState = {\n completedBlocks: this.completedBlocks,\n pendingBlocks,\n markdown: this.lines.join('\\n'),\n ast: {\n type: 'root',\n children: [\n ...this.completedBlocks.map((b) => b.node),\n ...pendingBlocks.map((b) => b.node)\n ]\n },\n definitions: { ...this.getDefinitionMap() },\n footnoteDefinitions: { ...this.getFootnoteDefinitionMap() }\n }\n this.options.onChange(state)\n }\n }\n\n /**\n * 标记解析完成,处理剩余内容\n * 也可用于强制中断时(如用户点击停止),将 pending 内容标记为 completed\n */\n finalize(): IncrementalUpdate {\n const update: IncrementalUpdate = {\n completed: [],\n updated: [],\n pending: [],\n ast: { type: 'root', children: [] },\n definitions: this.getDefinitionMap(),\n footnoteDefinitions: this.getFootnoteDefinitionMap(),\n footnoteReferenceOrder: this.getFootnoteReferenceOrder()\n }\n\n if (this.pendingStartLine < this.lines.length) {\n const remainingText = this.lines.slice(this.pendingStartLine).join('\\n')\n\n if (remainingText.trim()) {\n const remainingOffset = this.getLineOffset(this.pendingStartLine)\n const ast = this.astBuilder.parse(remainingText)\n // 使用绝对偏移量,确保 Block 的位置信息正确\n const finalBlocks = this.astBuilder.nodesToBlocks(\n ast.children,\n remainingOffset,\n remainingText,\n 'completed',\n (offset) => this.generateBlockId(offset)\n )\n\n this.completedBlocks.push(...finalBlocks)\n update.completed = finalBlocks\n\n // 更新 definitions 从最终完成的 blocks\n this.updateDefinitionsFromCompletedBlocks(finalBlocks)\n\n // 增量收集脚注引用(只扫描新完成的 blocks)\n this.footnoteManager.collectReferencesFromCompletedBlocks(finalBlocks)\n\n // 清理不再需要的上下文缓存\n this.boundaryDetector.clearContextCache(this.pendingStartLine)\n }\n }\n\n // 清空 pending 缓存\n this.lastPendingBlocks = []\n this.pendingStartLine = this.lines.length\n\n update.ast = {\n type: 'root',\n children: this.completedBlocks.map((b) => b.node)\n }\n\n // 填充 definitions 和 footnote 相关数据\n update.definitions = this.getDefinitionMap()\n update.footnoteDefinitions = this.getFootnoteDefinitionMap()\n update.footnoteReferenceOrder = this.getFootnoteReferenceOrder()\n\n // 触发状态变化回调\n this.emitChange([])\n\n return update\n }\n\n /**\n * 强制中断解析,将所有待处理内容标记为完成\n * @deprecated 请使用 finalize() 代替,功能完全相同\n */\n abort(): IncrementalUpdate {\n return this.finalize()\n }\n\n /**\n * 获取当前完整的 AST\n * 复用上次 append 的 pending 结果,避免重复解析\n */\n getAst(): Root {\n const children = [\n ...this.completedBlocks.map((b) => b.node),\n ...this.lastPendingBlocks.map((b) => b.node)\n ]\n\n // 使用优化的脚注引用收集\n this.footnoteManager.collectReferencesFromPending(this.lastPendingBlocks)\n\n return {\n type: 'root',\n children\n }\n }\n\n /**\n * 获取所有已完成的块\n */\n getCompletedBlocks(): ParsedBlock[] {\n return [...this.completedBlocks]\n }\n\n /**\n * 获取当前缓冲区内容\n */\n getBuffer(): string {\n return this.lines.join('\\n')\n }\n\n /**\n * 获取 Definition 映射表(用于引用式图片和链接)\n */\n getDefinitionMap(): DefinitionMap {\n return this.definitionManager.getAll()\n }\n\n /**\n * 获取 Footnote Definition 映射表\n */\n getFootnoteDefinitionMap(): FootnoteDefinitionMap {\n return this.footnoteManager.getDefinitions()\n }\n\n /**\n * 获取脚注引用的出现顺序\n */\n getFootnoteReferenceOrder(): string[] {\n return this.footnoteManager.getReferenceOrder()\n }\n\n /**\n * 设置状态变化回调(用于 DevTools 等)\n */\n setOnChange(callback: ((state: import('../types').ParserState) => void) | undefined): void {\n const originalOnChange = this.options.onChange;\n this.options.onChange = (state: ParserState) => {\n originalOnChange?.(state);\n callback?.(state);\n }\n }\n\n /**\n * 重置解析器状态\n */\n reset(): void {\n this.lines = []\n this.lineOffsets = [0]\n this.completedBlocks = []\n this.pendingStartLine = 0\n this.context = createInitialContext()\n this.lastPendingBlocks = []\n // 清空 definition 和 footnote 映射\n this.definitionManager.clear()\n this.footnoteManager.clear()\n\n // 触发状态变化回调\n this.emitChange([])\n }\n\n /**\n * 一次性渲染完整 Markdown(reset + append + finalize)\n * @param content 完整的 Markdown 内容\n * @returns 解析结果\n */\n render(content: string): IncrementalUpdate {\n this.reset()\n this.append(content)\n return this.finalize()\n }\n\n /**\n * 更新解析器配置(动态更新,不需要重建 parser 实例)\n *\n * 注意:更新配置后会自动调用 reset() 重置状态\n *\n * @param options 部分配置选项\n *\n * @example\n * ```ts\n * // 动态启用 TeX 数学公式语法\n * parser.updateOptions({ math: { tex: true } })\n *\n * // 禁用 GFM\n * parser.updateOptions({ gfm: false })\n *\n * // 切换引擎\n * import { MicromarkAstBuilder } from '@incremark/core/engines/micromark'\n * parser.updateOptions({ astBuilder: MicromarkAstBuilder })\n * ```\n */\n updateOptions(options: Partial<IncremarkParserOptions>): void {\n // 重置状态\n this.reset()\n\n // 合并选项\n Object.assign(this.options, options)\n\n if (options.astBuilder) {\n const BuilderClass = options.astBuilder\n if (!(this.astBuilder instanceof BuilderClass)) {\n this.astBuilder = new BuilderClass(this.options)\n } else {\n this.astBuilder.updateOptions(options)\n }\n } else {\n this.astBuilder.updateOptions(options)\n }\n }\n}\n\n/**\n * 创建 Incremark 解析器实例\n *\n * @param options 解析器配置\n * @param options.astBuilder 自定义 AST 构建器类(用于切换引擎)\n * @param options.plugins 统一插件列表\n *\n * @example\n * ```ts\n * // 使用默认的 marked 引擎(极速模式)\n * const parser = createIncremarkParser({ gfm: true, math: true })\n *\n * // 使用 micromark 引擎(需要单独导入,支持 tree-shaking)\n * import { MicromarkAstBuilder } from '@incremark/core/engines/micromark'\n * const parser = createIncremarkParser({\n * astBuilder: MicromarkAstBuilder,\n * gfm: true\n * })\n * ```\n */\nexport function createIncremarkParser(options?: IncremarkParserOptions): IncremarkParser {\n return new IncremarkParser(options)\n}\n","import type { RootContent, Text } from 'mdast'\nimport type { AstNode } from '../types'\n\n/**\n * 文本块片段(用于渐入动画)\n */\nexport interface TextChunk {\n /** 文本内容 */\n text: string\n /** 创建时间戳 */\n createdAt: number\n}\n\n/**\n * 扩展的文本节点(支持 chunks)\n */\nexport interface TextNodeWithChunks extends Text {\n /** 稳定部分的长度(不需要动画) */\n stableLength?: number\n /** 临时的文本片段,用于渐入动画 */\n chunks?: TextChunk[]\n}\n\n/**\n * 计算 AST 节点的总字符数\n */\nexport function countChars(node: RootContent): number {\n return countCharsInNode(node as AstNode)\n}\n\n/**\n * 计算单个 AST 节点的字符数(内部辅助函数)\n */\nfunction countCharsInNode(n: AstNode): number {\n if (n.value && typeof n.value === 'string') {\n return n.value.length\n }\n if (n.children && Array.isArray(n.children)) {\n let count = 0\n for (const child of n.children) {\n count += countCharsInNode(child)\n }\n return count\n }\n // 其他节点(如 thematicBreak, image)算作 1 个字符\n return 1\n}\n\n/**\n * 累积的 chunks 信息\n */\nexport interface AccumulatedChunks {\n /** 已经稳定显示的字符数(不需要动画) */\n stableChars: number\n /** 累积的 chunk 列表 */\n chunks: TextChunk[]\n}\n\n/** chunk 范围信息 */\ninterface ChunkRange {\n start: number\n end: number\n chunk: TextChunk\n}\n\n/**\n * 截断 AST 节点,只保留前 maxChars 个字符\n * 支持 chunks(用于渐入动画)\n * \n * 性能说明:\n * - 此函数每次调用都会从头遍历 AST 节点\n * - 但由于 BlockTransformer 是按 block 处理的,每次只遍历单个 block 的 AST\n * - 单个 block(如一个段落、一个代码块)通常只有几百个字符,性能开销很小\n * - 对于整个文档的渲染,已完成的 blocks 不会重新遍历\n * \n * @param node 原始节点(单个 block 的 AST)\n * @param maxChars 最大字符数\n * @param accumulatedChunks 累积的 chunks 信息(用于渐入动画)\n * @returns 截断后的节点,如果 maxChars <= 0 返回 null\n */\nexport function sliceAst(\n node: RootContent, \n maxChars: number,\n accumulatedChunks?: AccumulatedChunks\n): RootContent | null {\n if (maxChars <= 0) return null\n\n let remaining = maxChars\n let charIndex = 0\n \n // 计算 chunks 在文本中的范围\n const chunkRanges: ChunkRange[] = []\n if (accumulatedChunks && accumulatedChunks.chunks.length > 0) {\n let chunkStart = accumulatedChunks.stableChars\n for (const chunk of accumulatedChunks.chunks) {\n chunkRanges.push({\n start: chunkStart,\n end: chunkStart + chunk.text.length,\n chunk\n })\n chunkStart += chunk.text.length\n }\n }\n\n function process(n: AstNode): AstNode | null {\n if (remaining <= 0) return null\n\n // 文本类节点:截断 value,可能添加 chunks\n if (n.value && typeof n.value === 'string') {\n const nodeStart = charIndex\n const nodeEnd = charIndex + n.value.length\n \n const take = Math.min(n.value.length, remaining)\n remaining -= take\n charIndex = nodeEnd\n\n const slicedValue = n.value.slice(0, take)\n \n const result: AstNode & { stableLength?: number; chunks?: TextChunk[] } = { \n ...n, \n value: slicedValue \n }\n \n // 检查是否有 chunks 落在这个节点范围内\n if (chunkRanges.length > 0 && accumulatedChunks) {\n const nodeChunks: TextChunk[] = []\n let firstChunkLocalStart = take // 第一个 chunk 在节点中的起始位置\n \n for (const range of chunkRanges) {\n // 计算 chunk 与当前节点的交集\n const overlapStart = Math.max(range.start, nodeStart)\n const overlapEnd = Math.min(range.end, nodeStart + take)\n \n if (overlapStart < overlapEnd) {\n // 有交集,提取对应的文本(相对于 slicedValue)\n const localStart = overlapStart - nodeStart\n const localEnd = overlapEnd - nodeStart\n const chunkText = slicedValue.slice(localStart, localEnd)\n \n if (chunkText.length > 0) {\n // 记录第一个 chunk 的起始位置\n if (nodeChunks.length === 0) {\n firstChunkLocalStart = localStart\n }\n nodeChunks.push({\n text: chunkText,\n createdAt: range.chunk.createdAt\n })\n }\n }\n }\n \n if (nodeChunks.length > 0) {\n result.stableLength = firstChunkLocalStart\n result.chunks = nodeChunks\n }\n }\n \n return result\n }\n\n // 容器节点:递归处理 children\n if (n.children && Array.isArray(n.children)) {\n const newChildren: AstNode[] = []\n \n for (const child of n.children) {\n if (remaining <= 0) break\n \n const processed = process(child)\n \n if (processed) {\n newChildren.push(processed)\n }\n }\n \n if (newChildren.length === 0) {\n return null\n }\n return { ...n, children: newChildren }\n }\n\n // 其他节点(如 thematicBreak, image)\n remaining -= 1\n charIndex += 1\n return { ...n }\n }\n\n return process(node as AstNode) as RootContent | null\n}\n\n/**\n * 追加到 AST:将源节点截断到指定字符数,并与基础节点合并\n *\n * 实现说明:\n * - 完整截断 sourceNode 到 endChars,然后通过 smartMergeAst 复用已有节点引用\n * - 虽然每次都重新遍历,但由于只处理单个 block,性能开销很小\n * - smartMergeAst 确保前面已稳定的子节点引用被复用,减少 React/Vue 的重渲染\n *\n * @param baseNode 已截断的基础节点(稳定的部分)\n * @param sourceNode 原始完整节点(单个 block)\n * @param endChars 结束字符位置(新的进度)\n * @param accumulatedChunks 累积的 chunks 信息(用于渐入动画)\n * @returns 合并后的完整节点\n */\nexport function appendToAst(\n baseNode: RootContent,\n sourceNode: RootContent,\n endChars: number,\n accumulatedChunks?: AccumulatedChunks\n): RootContent {\n // 完整截断到 endChars,保留完整的结构信息\n const fullSlice = sliceAst(sourceNode, endChars, accumulatedChunks)\n\n // 如果截断失败,返回 baseNode\n if (!fullSlice) {\n return baseNode\n }\n\n // 智能合并:复用 baseNode 中已有的稳定节点引用\n return smartMergeAst(baseNode, fullSlice)\n}\n\n/**\n * 合并 AST 节点:复用已稳定的子节点引用\n *\n * 目的:\n * - 虽然 sliceAst 已经创建了新的节点对象,但通过复用 baseNode 中的子节点引用\n * - 可以让 React/Vue/Svelte 的 diff 算法识别出未变化的部分,减少 DOM 更新\n *\n * 策略:\n * - 容器节点:复用前面已完成的子节点引用,只替换最后一个(正在增长的)子节点\n * - 文本节点:直接使用 fullSlice(因为文本内容在变化)\n * - 这是一个\"事后优化\",不减少遍历开销,但减少框架层面的重渲染\n */\nfunction smartMergeAst(baseNode: RootContent, fullSlice: RootContent): RootContent {\n // 类型不同,直接返回 fullSlice\n if (baseNode.type !== fullSlice.type) {\n return fullSlice\n }\n\n const base = baseNode as AstNode\n const full = fullSlice as AstNode\n\n // 文本节点:直接使用 fullSlice(chunks 信息在 fullSlice 中)\n if (full.value !== undefined) {\n return fullSlice\n }\n\n // 容器节点:智能合并 children\n if (base.children && Array.isArray(base.children) && full.children && Array.isArray(full.children)) {\n // 如果 fullSlice 的 children 更少(不应该发生),直接返回 fullSlice\n if (full.children.length < base.children.length) {\n return fullSlice\n }\n\n // 如果 children 数量相同,只有最后一个 child 可能变化\n if (full.children.length === base.children.length) {\n if (base.children.length === 0) {\n return fullSlice\n }\n // 复用前面的稳定节点,只递归处理最后一个\n const lastIndex = base.children.length - 1\n const mergedLast = smartMergeAst(\n base.children[lastIndex] as RootContent,\n full.children[lastIndex] as RootContent\n )\n return {\n ...full,\n children: [\n ...base.children.slice(0, lastIndex),\n mergedLast as AstNode\n ]\n } as RootContent\n }\n\n // fullSlice 的 children 更多,说明有新的 child 被添加\n // 复用 base 的前 (base.children.length - 1) 个节点\n // 递归处理 base 的最后一个和 full 对应位置的节点\n // 然后追加 full 的新节点\n const baseLastIndex = base.children.length - 1\n const mergedLast = smartMergeAst(\n base.children[baseLastIndex] as RootContent,\n full.children[baseLastIndex] as RootContent\n )\n return {\n ...full,\n children: [\n ...base.children.slice(0, baseLastIndex),\n mergedLast as AstNode,\n ...full.children.slice(base.children.length)\n ]\n } as RootContent\n }\n\n // 其他情况,直接返回 fullSlice\n return fullSlice\n}\n\n/**\n * 深拷贝 AST 节点\n * 使用递归浅拷贝实现,比 JSON.parse/stringify 更高效\n * 且保持对象结构完整性\n */\nexport function cloneNode<T extends RootContent>(node: T): T {\n // 优先使用 structuredClone(Node 17+ / 现代浏览器)\n if (typeof structuredClone === 'function') {\n return structuredClone(node)\n }\n \n // 回退到递归拷贝\n return deepClone(node) as T\n}\n\n/**\n * 递归深拷贝对象\n */\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') {\n return obj\n }\n\n if (Array.isArray(obj)) {\n return obj.map(item => deepClone(item)) as T\n }\n\n const cloned = {} as T\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n cloned[key] = deepClone(obj[key])\n }\n }\n return cloned\n}\n","import type { RootContent } from 'mdast'\nimport type { AstNode } from '../types'\nimport type {\n SourceBlock,\n DisplayBlock,\n TransformerOptions,\n TransformerState,\n TransformerPlugin,\n AnimationEffect\n} from './types'\nimport { countChars as defaultCountChars, sliceAst as defaultSliceAst, appendToAst, type TextChunk, type AccumulatedChunks } from './utils'\n\n/**\n * Block Transformer\n *\n * 用于控制 blocks 的逐步显示(打字机效果)\n * 作为解析器和渲染器之间的中间层\n *\n * 特性:\n * - 使用 requestAnimationFrame 实现流畅动画\n * - 支持随机步长,模拟真实打字效果\n * - 支持 typing 动画效果\n * - 页面不可见时自动暂停,节省资源\n * - 插件系统支持自定义节点处理\n *\n * @example\n * ```typescript\n * const transformer = new BlockTransformer({\n * charsPerTick: [1, 3], // 随机 1-3 个字符\n * tickInterval: 30,\n * effect: 'typing',\n * onChange: (displayBlocks) => {\n * // 更新 UI\n * }\n * })\n *\n * // 推入新 blocks\n * transformer.push(blocks)\n *\n * // 获取当前显示状态\n * const displayBlocks = transformer.getDisplayBlocks()\n * ```\n */\nexport class BlockTransformer<T = unknown> {\n private state: TransformerState<T>\n private options: {\n charsPerTick: number | [number, number]\n tickInterval: number\n effect: AnimationEffect\n plugins: TransformerPlugin[]\n onChange: (displayBlocks: DisplayBlock<T>[]) => void\n onAllComplete: (() => void) | null\n pauseOnHidden: boolean\n }\n private rafId: number | null = null\n private lastTickTime = 0\n private isRunning = false\n private isPaused = false\n private chunks: TextChunk[] = [] // 累积的 chunks(用于 fade-in 动画)\n private visibilityHandler: (() => void) | null = null\n \n // ============ 性能优化:缓存机制 ============\n /** 缓存的已截断 displayNode(稳定的部分,避免重复遍历) */\n private cachedDisplayNode: RootContent | null = null\n /** 缓存的字符数(避免重复计算) */\n private cachedTotalChars: number | null = null\n /** 当前缓存的进度(对应 cachedDisplayNode) */\n private cachedProgress: number = 0\n\n constructor(options: TransformerOptions = {}) {\n this.options = {\n charsPerTick: options.charsPerTick ?? 1,\n tickInterval: options.tickInterval ?? 20,\n effect: options.effect ?? 'none',\n plugins: options.plugins ?? [],\n onChange: options.onChange ?? (() => {}),\n onAllComplete: options.onAllComplete ?? null,\n pauseOnHidden: options.pauseOnHidden ?? true\n }\n\n this.state = {\n completedBlocks: [],\n currentBlock: null,\n currentProgress: 0,\n pendingBlocks: []\n }\n\n // 设置页面可见性监听\n if (this.options.pauseOnHidden && typeof document !== 'undefined') {\n this.setupVisibilityHandler()\n }\n }\n\n /**\n * 推入新的 blocks\n *\n * 逻辑:\n * 1. 移除不在传入列表中的旧 blocks(处理容器增量解析等场景)\n * 2. 如果 block ID 不存在,添加到 pending\n * 3. 如果 block ID 已存在且内容变化,更新对应位置的 block\n */\n push(blocks: SourceBlock<T>[]): void {\n const inputIds = new Set(blocks.map(b => b.id))\n const existingIds = this.getAllBlockIds()\n\n // ============ 第一步:移除不在传入列表中的旧 blocks ============\n // 这主要处理容器增量解析的情况:容器内部的内容先被添加为独立 blocks,\n // 然后整个容器被添加时,内部 blocks 不再单独返回,需要移除它们\n let hasRemovals = false\n\n // 检查 completedBlocks\n const completedBefore = this.state.completedBlocks.length\n this.state.completedBlocks = this.state.completedBlocks.filter(b => inputIds.has(b.id))\n if (this.state.completedBlocks.length < completedBefore) {\n hasRemovals = true\n }\n\n // 检查 currentBlock\n if (this.state.currentBlock && !inputIds.has(this.state.currentBlock.id)) {\n this.state.currentBlock = null\n this.state.currentProgress = 0\n this.chunks = []\n this.clearCache()\n hasRemovals = true\n }\n\n // 检查 pendingBlocks\n const pendingBefore = this.state.pendingBlocks.length\n this.state.pendingBlocks = this.state.pendingBlocks.filter(b => inputIds.has(b.id))\n if (this.state.pendingBlocks.length < pendingBefore) {\n hasRemovals = true\n }\n\n // 如果有移除,需要重新启动处理(如果 currentBlock 被移除了)\n if (hasRemovals && !this.state.currentBlock && this.state.pendingBlocks.length > 0) {\n this.startIfNeeded()\n }\n\n // ============ 第二步:找出新增的 blocks ============\n const newBlocks = blocks.filter((b) => !existingIds.has(b.id))\n\n if (newBlocks.length > 0) {\n this.state.pendingBlocks.push(...newBlocks)\n this.startIfNeeded()\n }\n\n // ============ 第三步:检查已存在 blocks 的内容更新 ============\n for (const block of blocks) {\n // 跳过新增的 blocks(已经处理过了)\n if (!existingIds.has(block.id)) continue\n\n // 检查 currentBlock\n if (this.state.currentBlock?.id === block.id) {\n // 检查 currentBlock 是否已经完成\n const total = this.getTotalChars()\n const isComplete = this.state.currentProgress >= total\n\n if (isComplete) {\n // currentBlock 已经完成,直接移到 completedBlocks\n this.state.completedBlocks.push(block)\n this.state.currentBlock = null\n this.state.currentProgress = 0\n this.chunks = []\n this.clearCache()\n this.processNext()\n } else if (this.state.currentBlock.node !== block.node) {\n // currentBlock 还在处理中,内容变化,使用 handleContentChange 处理\n this.handleContentChange(this.state.currentBlock.node, block.node, true)\n // 更新引用\n this.state.currentBlock = block\n }\n continue\n }\n\n // 检查 completedBlocks\n const completedIndex = this.state.completedBlocks.findIndex(b => b.id === block.id)\n if (completedIndex !== -1) {\n if (this.state.completedBlocks[completedIndex].node !== block.node) {\n // 内容变化,直接替换\n this.state.completedBlocks[completedIndex] = block\n this.emit()\n }\n continue\n }\n\n // 检查 pendingBlocks\n const pendingIndex = this.state.pendingBlocks.findIndex(b => b.id === block.id)\n if (pendingIndex !== -1) {\n if (this.state.pendingBlocks[pendingIndex].node !== block.node) {\n // 内容变化,直接替换\n this.state.pendingBlocks[pendingIndex] = block\n }\n continue\n }\n }\n\n // 如果有移除,触发更新\n if (hasRemovals) {\n this.emit()\n }\n }\n\n /**\n * 更新指定 block(用于 pending block 内容增加时)\n */\n update(block: SourceBlock<T>): void {\n if (this.state.currentBlock?.id === block.id) {\n // 使用统一的方法处理内容变化\n this.handleContentChange(this.state.currentBlock.node, block.node, false)\n this.state.currentBlock = block\n return\n }\n\n // 检查是否是已完成的 block\n const completedIndex = this.state.completedBlocks.findIndex(b => b.id === block.id)\n if (completedIndex !== -1) {\n // 更新已完成的 block\n this.state.completedBlocks[completedIndex] = block\n this.emit()\n return\n }\n\n // 检查是否是 pending blocks\n const pendingIndex = this.state.pendingBlocks.findIndex(b => b.id === block.id)\n if (pendingIndex !== -1) {\n // 更新 pending block\n this.state.pendingBlocks[pendingIndex] = block\n return\n }\n }\n\n /**\n * 跳过所有动画,直接显示全部内容\n */\n skip(): void {\n this.stop()\n\n const allBlocks = [\n ...this.state.completedBlocks,\n ...(this.state.currentBlock ? [this.state.currentBlock] : []),\n ...this.state.pendingBlocks\n ]\n\n this.state = {\n completedBlocks: allBlocks,\n currentBlock: null,\n currentProgress: 0,\n pendingBlocks: []\n }\n this.chunks = []\n this.clearCache()\n\n this.emit()\n // 跳过动画也视为完成\n this.options.onAllComplete?.()\n }\n\n /**\n * 重置状态\n */\n reset(): void {\n this.stop()\n this.state = {\n completedBlocks: [],\n currentBlock: null,\n currentProgress: 0,\n pendingBlocks: []\n }\n this.chunks = []\n this.clearCache()\n this.emit()\n }\n\n /**\n * 暂停动画\n */\n pause(): void {\n this.isPaused = true\n this.cancelRaf()\n }\n\n /**\n * 恢复动画\n */\n resume(): void {\n if (this.isPaused) {\n this.isPaused = false\n this.startIfNeeded()\n }\n }\n\n /**\n * 获取用于渲染的 display blocks\n * 优化:使用缓存的 displayNode,避免重复遍历已稳定的节点\n *\n * 注意:DisplayBlock 的 status 表示的是**打字机动画状态**,而不是解析器的状态:\n * - 'completed': 打字机动画已完成,内容已完全显示\n * - 'pending': 打字机动画还在进行中,内容还在逐字显示\n */\n getDisplayBlocks(): DisplayBlock<T>[] {\n const result: DisplayBlock<T>[] = []\n\n // 已完成动画的 blocks(打字机动画已完成)\n for (const block of this.state.completedBlocks) {\n result.push({\n ...block,\n // 打字机动画已完成,状态为 completed\n status: 'completed',\n displayNode: block.node,\n progress: 1,\n isDisplayComplete: true\n })\n }\n\n // 当前正在显示的 block(打字机动画进行中)\n if (this.state.currentBlock) {\n // 使用缓存的字符数\n const total = this.getTotalChars()\n\n // 如果进度变化了或缓存无效,更新缓存的 displayNode\n if (this.state.currentProgress !== this.cachedProgress || !this.cachedDisplayNode) {\n this.updateCachedDisplayNode()\n }\n\n result.push({\n ...this.state.currentBlock,\n // 打字机动画进行中,状态为 pending\n status: 'pending',\n displayNode: this.cachedDisplayNode || { type: 'paragraph', children: [] },\n progress: total > 0 ? this.state.currentProgress / total : 1,\n isDisplayComplete: false\n })\n }\n\n return result\n }\n\n /**\n * 是否正在处理中\n */\n isProcessing(): boolean {\n return this.isRunning || this.state.currentBlock !== null || this.state.pendingBlocks.length > 0\n }\n\n /**\n * 是否已暂停\n */\n isPausedState(): boolean {\n return this.isPaused\n }\n\n /**\n * 获取内部状态(用于调试)\n */\n getState(): Readonly<TransformerState<T>> {\n return { ...this.state }\n }\n\n /**\n * 动态更新配置\n */\n setOptions(options: Partial<Pick<TransformerOptions, 'charsPerTick' | 'tickInterval' | 'effect' | 'pauseOnHidden'>>): void {\n if (options.charsPerTick !== undefined) {\n this.options.charsPerTick = options.charsPerTick\n }\n if (options.tickInterval !== undefined) {\n this.options.tickInterval = options.tickInterval\n }\n if (options.effect !== undefined) {\n this.options.effect = options.effect\n }\n if (options.pauseOnHidden !== undefined) {\n this.options.pauseOnHidden = options.pauseOnHidden\n if (options.pauseOnHidden && typeof document !== 'undefined') {\n this.setupVisibilityHandler()\n } else {\n this.removeVisibilityHandler()\n }\n }\n }\n\n /**\n * 获取当前配置\n */\n getOptions(): { \n charsPerTick: number | [number, number]\n tickInterval: number\n effect: AnimationEffect\n } {\n return {\n charsPerTick: this.options.charsPerTick,\n tickInterval: this.options.tickInterval,\n effect: this.options.effect\n }\n }\n\n /**\n * 获取当前动画效果\n */\n getEffect(): AnimationEffect {\n return this.options.effect\n }\n\n /**\n * 销毁,清理资源\n */\n destroy(): void {\n this.stop()\n this.removeVisibilityHandler()\n }\n\n // ============ 私有方法 ============\n\n /**\n * 处理 block 内容更新时的字符数变化和进度调整\n * 统一 push 和 update 方法中的重复逻辑\n */\n private handleContentChange(\n oldNode: RootContent,\n newNode: RootContent,\n isUpdateFromPush?: boolean\n ): void {\n const oldTotal = this.cachedTotalChars ?? this.countChars(oldNode)\n const newTotal = this.countChars(newNode)\n\n // 如果字符数减少了(AST 结构变化,如 **xxx 变成 **xxx**)\n // 重新计算进度,保持相对位置,并清除 chunks\n if (newTotal < oldTotal || newTotal < this.state.currentProgress) {\n this.state.currentProgress = Math.min(this.state.currentProgress, newTotal)\n // AST 结构变化,chunks 可能错位,需要清除\n this.chunks = []\n }\n\n // 内容变化,清除缓存\n this.clearCache()\n\n // 如果是 push 方法调用的更新,可能需要重新开始动画\n if (isUpdateFromPush) {\n // 如果之前暂停了(因为到达末尾),重新开始\n if (!this.rafId && !this.isPaused) {\n if (this.state.currentProgress < newTotal) {\n this.startIfNeeded()\n }\n }\n } else {\n // 如果是 update 方法调用的更新,内容增加了且之前暂停了,继续\n if (newTotal > oldTotal && !this.rafId && !this.isPaused && this.state.currentProgress >= oldTotal) {\n this.startIfNeeded()\n }\n }\n }\n\n private getAllBlockIds(): Set<string> {\n return new Set([\n ...this.state.completedBlocks.map((b) => b.id),\n this.state.currentBlock?.id,\n ...this.state.pendingBlocks.map((b) => b.id)\n ].filter((id): id is string => id !== undefined))\n }\n\n private setupVisibilityHandler(): void {\n if (this.visibilityHandler) return\n\n this.visibilityHandler = () => {\n if (document.hidden) {\n this.pause()\n } else {\n this.resume()\n }\n }\n\n document.addEventListener('visibilitychange', this.visibilityHandler)\n }\n\n private removeVisibilityHandler(): void {\n if (this.visibilityHandler) {\n document.removeEventListener('visibilitychange', this.visibilityHandler)\n this.visibilityHandler = null\n }\n }\n\n private startIfNeeded(): void {\n if (this.rafId || this.isPaused) return\n\n if (!this.state.currentBlock && this.state.pendingBlocks.length > 0) {\n this.state.currentBlock = this.state.pendingBlocks.shift()!\n this.state.currentProgress = 0\n this.clearCache() // 新 block,清除缓存\n }\n\n if (this.state.currentBlock) {\n this.isRunning = true\n this.lastTickTime = 0\n this.scheduleNextFrame()\n }\n }\n\n private scheduleNextFrame(): void {\n this.rafId = requestAnimationFrame((time) => this.animationFrame(time))\n }\n\n private animationFrame(time: number): void {\n this.rafId = null\n\n // 计算是否应该执行 tick\n if (this.lastTickTime === 0) {\n this.lastTickTime = time\n }\n\n const elapsed = time - this.lastTickTime\n\n if (elapsed >= this.options.tickInterval) {\n this.lastTickTime = time\n this.tick()\n }\n\n // 如果还在运行,继续调度\n if (this.isRunning && !this.isPaused) {\n this.scheduleNextFrame()\n }\n }\n\n private tick(): void {\n const block = this.state.currentBlock\n if (!block) {\n this.processNext()\n return\n }\n\n // 使用缓存的字符数,避免重复计算\n const total = this.getTotalChars()\n const step = this.getStep()\n const prevProgress = this.state.currentProgress\n \n this.state.currentProgress = Math.min(prevProgress + step, total)\n\n // 如果是 fade-in 效果,添加新的 chunk\n if (this.options.effect === 'fade-in' && this.state.currentProgress > prevProgress) {\n // 从 block.node 中提取新增的字符\n const newText = this.extractText(block.node, prevProgress, this.state.currentProgress)\n if (newText.length > 0) {\n this.chunks.push({\n text: newText,\n createdAt: Date.now()\n })\n }\n }\n\n this.emit()\n\n if (this.state.currentProgress >= total) {\n // 当前 block 完成,清空 chunks 和缓存\n this.notifyComplete(block.node)\n this.state.completedBlocks.push(block)\n this.state.currentBlock = null\n this.state.currentProgress = 0\n this.chunks = []\n this.clearCache()\n this.processNext()\n }\n }\n\n /**\n * 从 AST 节点中提取指定范围的文本\n *\n * 优化说明:\n * - 提前终止:当 charIndex >= end 时立即返回,避免不必要的遍历\n * - 局部更新:charIndex 只在需要时更新,减少计算\n * - 早期返回:发现足够的文本后可以提前退出(当前未实现,可作为未来优化)\n *\n * @param node 要提取文本的 AST 节点\n * @param start 起始字符索引(包含)\n * @param end 结束字符索引(不包含)\n * @returns 提取的文本\n */\n private extractText(node: RootContent, start: number, end: number): string {\n // 快速路径:空范围或无效范围\n if (start >= end) {\n return ''\n }\n\n let result = ''\n let charIndex = 0\n\n function traverse(n: AstNode): boolean {\n // 提前终止:已达到目标范围\n if (charIndex >= end) return false\n\n if (n.value && typeof n.value === 'string') {\n const nodeStart = charIndex\n const nodeEnd = charIndex + n.value.length\n const overlapStart = Math.max(start, nodeStart)\n const overlapEnd = Math.min(end, nodeEnd)\n\n // 只有当节点与目标范围有交集时才处理\n if (overlapStart < overlapEnd) {\n result += n.value.slice(overlapStart - nodeStart, overlapEnd - nodeStart)\n }\n\n // 更新索引(仅在处理文本节点后)\n charIndex = nodeEnd\n return charIndex < end\n }\n\n if (n.children && Array.isArray(n.children)) {\n for (const child of n.children) {\n if (!traverse(child)) return false\n }\n }\n\n return true\n }\n\n traverse(node as AstNode)\n return result\n }\n\n private getStep(): number {\n const { charsPerTick } = this.options\n if (typeof charsPerTick === 'number') {\n return charsPerTick\n }\n // 随机步长\n const [min, max] = charsPerTick\n return Math.floor(Math.random() * (max - min + 1)) + min\n }\n\n private processNext(): void {\n if (this.state.pendingBlocks.length > 0) {\n this.state.currentBlock = this.state.pendingBlocks.shift()!\n this.state.currentProgress = 0\n this.chunks = []\n this.clearCache() // 新 block,清除缓存\n this.emit()\n // 继续运行(rAF 已经在调度中)\n } else {\n this.isRunning = false\n this.cancelRaf()\n this.emit()\n // 所有动画完成,触发回调\n this.options.onAllComplete?.()\n }\n }\n\n private cancelRaf(): void {\n if (this.rafId) {\n cancelAnimationFrame(this.rafId)\n this.rafId = null\n }\n }\n\n private stop(): void {\n this.cancelRaf()\n this.isRunning = false\n this.isPaused = false\n }\n\n private emit(): void {\n this.options.onChange(this.getDisplayBlocks())\n }\n\n // ============ 插件调用 ============\n\n private countChars(node: RootContent): number {\n // 先找匹配的插件\n for (const plugin of this.options.plugins) {\n if (plugin.match?.(node) && plugin.countChars) {\n const result = plugin.countChars(node)\n if (result !== undefined) return result\n }\n }\n // 默认计算\n return defaultCountChars(node)\n }\n\n private sliceNode(node: RootContent, chars: number, accumulatedChunks?: AccumulatedChunks): RootContent | null {\n // 先找匹配的插件\n for (const plugin of this.options.plugins) {\n if (plugin.match?.(node) && plugin.sliceNode) {\n const total = this.countChars(node)\n const result = plugin.sliceNode(node, chars, total)\n if (result !== null) return result\n }\n }\n // 默认截断,传入累积的 chunks\n return defaultSliceAst(node, chars, accumulatedChunks)\n }\n\n private notifyComplete(node: RootContent): void {\n for (const plugin of this.options.plugins) {\n if (plugin.match?.(node) && plugin.onComplete) {\n plugin.onComplete(node)\n }\n }\n }\n\n // ============ 缓存管理方法 ============\n\n /**\n * 更新缓存的 displayNode\n * 使用真正的增量追加模式:只处理新增部分,不重复遍历已稳定的节点\n */\n private updateCachedDisplayNode(): void {\n const block = this.state.currentBlock\n if (!block) {\n this.cachedDisplayNode = null\n this.cachedProgress = 0\n return\n }\n\n const currentProgress = this.state.currentProgress\n\n // 如果进度减少了(内容更新导致),需要重新截断\n if (currentProgress < this.cachedProgress) {\n this.cachedDisplayNode = this.sliceNode(\n block.node,\n currentProgress,\n this.getAccumulatedChunks()\n )\n this.cachedProgress = currentProgress\n return\n }\n\n // 如果进度增加了,使用追加模式\n if (currentProgress > this.cachedProgress && this.cachedDisplayNode) {\n // 截断并合并:复用已稳定的节点引用,减少框架重渲染\n this.cachedDisplayNode = appendToAst(\n this.cachedDisplayNode,\n block.node,\n currentProgress,\n this.getAccumulatedChunks()\n )\n this.cachedProgress = currentProgress\n } else if (!this.cachedDisplayNode) {\n // 首次截断\n this.cachedDisplayNode = this.sliceNode(\n block.node,\n currentProgress,\n this.getAccumulatedChunks()\n )\n this.cachedProgress = currentProgress\n }\n }\n\n /**\n * 获取总字符数(带缓存)\n *\n * 缓存策略:\n * - 首次调用时计算并缓存\n * - 内容更新时通过 clearCache() 清除缓存,下次重新计算\n * - 切换到新 block 时也会清除缓存\n */\n private getTotalChars(): number {\n // 没有当前 block 时返回 0\n if (!this.state.currentBlock) {\n this.cachedTotalChars = null\n return 0\n }\n\n // 缓存为空时计算\n if (this.cachedTotalChars === null) {\n this.cachedTotalChars = this.countChars(this.state.currentBlock.node)\n }\n\n return this.cachedTotalChars\n }\n\n /**\n * 清除缓存(当 block 切换或内容更新时)\n */\n private clearCache(): void {\n this.cachedDisplayNode = null\n this.cachedTotalChars = null\n this.cachedProgress = 0\n }\n\n /**\n * 获取累积的 chunks(用于 fade-in 效果)\n * stableChars 表示在 chunks 之前的稳定字符数\n */\n private getAccumulatedChunks(): AccumulatedChunks | undefined {\n if (this.options.effect === 'fade-in' && this.chunks.length > 0) {\n // 计算 chunks 之前的稳定字符数\n // 当前进度 = stableChars + 所有 chunks 的长度\n const chunksLength = this.chunks.reduce((sum, c) => sum + c.text.length, 0)\n const stableChars = this.state.currentProgress - chunksLength\n return { stableChars: Math.max(0, stableChars), chunks: this.chunks }\n }\n return undefined\n }\n}\n\n/**\n * 创建 BlockTransformer 实例的工厂函数\n */\nexport function createBlockTransformer<T = unknown>(\n options?: TransformerOptions\n): BlockTransformer<T> {\n return new BlockTransformer<T>(options)\n}\n\n\n\n","import type { RootContent, Code } from 'mdast'\nimport type { TransformerPlugin } from './types'\n\n/**\n * 代码块插件:整体出现,不逐字符显示\n * \n * 注意:默认不启用,代码块默认参与打字机效果\n * 如需整体显示代码块,可手动添加此插件\n */\nexport const codeBlockPlugin: TransformerPlugin = {\n name: 'code-block',\n match: (node: RootContent) => node.type === 'code',\n countChars: () => 1, // 算作 1 个字符,整体出现\n sliceNode: (node, displayedChars, totalChars) => {\n // 要么全部显示,要么不显示\n return displayedChars >= totalChars ? node : null\n }\n}\n\n/**\n * Mermaid 图表插件:整体出现\n * \n * 注意:默认不启用,mermaid 默认参与打字机效果\n * 如需整体显示 mermaid,可手动添加此插件\n */\nexport const mermaidPlugin: TransformerPlugin = {\n name: 'mermaid',\n match: (node: RootContent) => {\n if (node.type !== 'code') return false\n const codeNode = node as Code\n return codeNode.lang === 'mermaid'\n },\n countChars: () => 1,\n sliceNode: (node, displayedChars) => (displayedChars > 0 ? node : null)\n}\n\n/**\n * 图片插件:立即显示(不参与打字机效果)\n * 图片没有文本内容,应立即显示\n */\nexport const imagePlugin: TransformerPlugin = {\n name: 'image',\n match: (node: RootContent) => node.type === 'image',\n countChars: () => 0 // 0 字符,立即显示\n}\n\n/**\n * 数学公式插件:整体出现\n * \n * 注意:默认不启用,数学公式默认参与打字机效果\n * 如需整体显示公式,可手动添加此插件\n */\nexport const mathPlugin: TransformerPlugin = {\n name: 'math',\n match: (node: RootContent) => {\n const type = node.type as string\n return type === 'math' || type === 'inlineMath'\n },\n countChars: () => 1,\n sliceNode: (node, displayedChars) => (displayedChars > 0 ? node : null)\n}\n\n/**\n * 分割线插件:立即显示\n * 分隔线没有文本内容,应立即显示\n */\nexport const thematicBreakPlugin: TransformerPlugin = {\n name: 'thematic-break',\n match: (node: RootContent) => node.type === 'thematicBreak',\n countChars: () => 0\n}\n\n/**\n * 默认插件集合\n * \n * 只包含确实需要特殊处理的节点:\n * - 图片:无文本内容,立即显示\n * - 分隔线:无文本内容,立即显示\n * \n * 代码块、mermaid、数学公式默认参与打字机效果\n * 如需整体显示,可手动添加对应插件\n */\nexport const defaultPlugins: TransformerPlugin[] = [\n imagePlugin,\n thematicBreakPlugin\n]\n\n/**\n * 完整插件集合(所有特殊节点整体显示)\n * 包含代码块、mermaid、数学公式等的整体显示\n */\nexport const allPlugins: TransformerPlugin[] = [\n mermaidPlugin, // mermaid 优先于普通 code block\n codeBlockPlugin,\n imagePlugin,\n mathPlugin,\n thematicBreakPlugin\n]\n\n/**\n * 创建自定义插件的辅助函数\n */\nexport function createPlugin(\n name: string,\n matcher: (node: RootContent) => boolean,\n options: Partial<Omit<TransformerPlugin, 'name' | 'match'>> = {}\n): TransformerPlugin {\n return {\n name,\n match: matcher,\n ...options\n }\n}\n"]}
|