Files
planet/docs/plans/frontend-markdown-renderer-plan.md
2026-04-28 16:10:17 +08:00

4.3 KiB
Raw Blame History

Markdown 渲染器完善计划

背景

Planet 控制台当前有三类主要 Markdown 使用场景:

  • 文档中心:技术文档、计划文档、运行手册。
  • AI Playground模型回复、分析结果、代码片段。
  • BGP 简报:由系统生成并保存的态势报告。

这些场景都复用 frontend/src/components/MarkdownRenderer/MarkdownRenderer.tsx。因此 Markdown 能力应该集中在共享渲染器内完成,页面只负责传入内容、链接转换和布局约束,不能让每篇文档或每个页面手写复制按钮、表格样式、列表样式等交互细节。

目标

建设一个稳定、可复用、适合技术文档和 AI 输出的 Markdown 渲染器,优先覆盖常用语法、代码块操作和清晰的阅读样式,并为后续语法高亮、锚点导航、内容安全策略留出接口。

成功标准

  • 代码块支持 fenced language、语言标签、复制按钮、复制成功状态和横向滚动。
  • 常用块语法稳定渲染:标题 1-6、段落、引用、分割线、表格、无序列表、有序列表、任务列表。
  • 常用行内语法稳定渲染:链接、自动链接、图片、行内代码、粗体、斜体、删除线。
  • 文档中心、AI Playground、BGP 简报继续复用同一个组件,不出现页面级重复实现。
  • 样式在普通业务面板和文档中心都有合理表现,文档中心可以通过 .docs-markdown 覆盖主题变量。
  • 前端 TypeScript build 通过,git diff --check 无空白错误。

当前实施范围

第一阶段:共享渲染器补齐

  • MarkdownRenderer 内解析 fenced code block 的语言信息。
  • 引入 MarkdownCodeBlock 子组件,负责语言标签、复制按钮和复制状态。
  • 保留现有 Scrollbar 横向滚动能力,避免长代码撑破页面。
  • 扩展标题渲染到 h1-h6并保留 getHeadingId 对文档目录的支持。
  • 扩展列表解析,支持 -*+1.1) 和 GitHub 风格任务列表。
  • 扩展行内解析,支持图片、自动链接、删除线。

第二阶段:样式统一

  • 全局 Markdown 样式覆盖业务场景,保持紧凑、清晰、可扫描。
  • 文档中心用 .docs-markdown 适配主题变量,避免硬编码颜色破坏明暗主题。
  • 代码块 toolbar 和 copy button 不依赖具体页面。
  • 图片默认响应式展示,避免超出内容区域。

第三阶段:验证

  • 使用前端 build 验证 TypeScript 和 Vite 构建。
  • 使用 git diff --check 验证补丁格式。
  • 手动检查至少一个文档页中代码块复制按钮、语言标签和表格滚动是否出现。

后续增强项

语法高亮

当前不新增高亮依赖,避免一次性引入过重运行时代码。后续可以在以下方案中二选一:

  • shiki:适合文档中心,视觉质量高,但包体和初始化成本更高。
  • highlight.js:接入简单,覆盖语言广,但样式控制需要额外约束。

建议当文档代码块数量稳定增加后再引入,并做按需加载或懒加载。

更完整 CommonMark 支持

当前渲染器覆盖 Planet 常见内容,不追求完整 CommonMark 兼容。后续如果需要完整规范,建议切换到成熟生态:

  • react-markdown
  • remark-gfm
  • rehype-sanitize
  • rehype-slug

切换前需要评估:链接转换、目录 ID、现有样式、AI 输出安全策略和包体影响。

安全策略

目前渲染器不解析原始 HTML这是正确默认值。后续如需支持 HTML必须先明确

  • 是否允许用户输入 Markdown。
  • 是否需要 HTML 白名单。
  • 是否需要 rehype-sanitize
  • 图片和链接是否需要域名策略。

文档页能力

可继续补齐:

  • 标题锚点悬浮复制。
  • Mermaid 图表。
  • 代码块折叠。
  • 文档内搜索结果定位到代码块。
  • 复制按钮埋点,用于判断文档片段是否真正被使用。

维护约束

  • Markdown 语法能力优先放在共享渲染器,不在具体文档页面散落实现。
  • 文档内容只表达内容,不承载 UI 行为。
  • 新增 Markdown 能力必须同时考虑文档中心、AI Playground、BGP 简报三个调用方。
  • 不解析原始 HTML除非同步引入明确的 sanitize 策略。
  • 与主题相关的样式优先走页面容器变量覆盖,不在组件内写死文档中心颜色。