import katex from 'katex'; import hljs from 'highlight.js'; export interface MediaInfo { type: 'img' | 'video'; src: string; alt?: string; } export interface RenderResult { html: string; media: MediaInfo[]; } function escapeHtml(text: string): string { return text .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"'); } /** * 将 Markdown 文本转为带占位符的 HTML 字符串。 * * 设计契约(曾被线上 bug 击穿、用单测固化,见 markdown.test.ts): * - 段落内【单个 \n 转为空格】而非
,避免 AI 回复被强制大量换行; * - 【3+ 连续空行压缩为 2 个】(/\n{3,}/ -> \n\n),避免多余空白把内容撑成多行; * - 【表格在加粗/链接转换之后提取】,单元格内的 **xxx** / [文本](url) 才能被渲染; * 且单元格内连续
被压缩为单个(normalizeCell)。 * * 媒体(/