跳转到内容

Markdown 渲染 MarkdownRender

从 Markstream 迁移时,将包名替换为 @sdata/web-vue,模板使用 SdMarkdownRender(全量插件)或命名导入 MarkdownRender。保留 content、nodes、流式配置、事件和实例方法。

样式通过现有 SD 全量样式或 @sdata/web-vue/es/markdown-render/style/index.js 接入。请删除原来单独导入的 Markstream CSS,基础样式已纳入组件库的 CSS 层。

覆盖六级标题、富内联、转义与换行、链接、引用、嵌套列表、任务项、表格、图片、分隔线、脚注、提示块、命名容器和原始 HTML;补充 nodes 方式的定义列表、emoji、引用编号与复选框节点,以及代码、数学和三种图表节点。数学和图表需要对应可选 peer/loader;未配置时展示上游降级状态。自定义业务节点的完整覆盖方式见下方「覆盖节点与嵌入 SD 组件」。

以《临江仙·滚滚长江东逝水》为内容,分六次追加诗词、引用、列表、表格、代码与脚注。加粗标记和代码围栏跨批次闭合,仅最后一批将 final 设为 true;重置后可重新观察完整过程。

300 段长文档(标题、段落、列表,每 25 节插入一个代码块),在固定高度滚动容器内开启 nodeVirtual 与 virtualScroll。切换「SD 封装 / 上游原生」对比:两种引擎的文档节点总数和实际挂载节点一致,嵌套渲染器恒为 0。

这条对比是组件库刻意维护的边界。上游对列表项里的段落有两条路径——映射表里没有 paragraph 键时走轻量行内渲染,只要出现该键(无论映射到哪个组件)就退化为给每个列表项创建一个嵌套渲染器,带来约 2/3 的额外 DOM、撑破 maxLiveNodes / liveNodeBuffer 预算,并让嵌套的 data-node-index 与父级索引空间冲突。因此段落保留上游原生 p.paragraph-node,只由组件库用正文 token 对齐观感;标题、引用、链接、图片、复选框、行内代码、分隔线、提示块和原始 HTML 仍使用 SD 组件——这些键不触发该分支。回归用例见 __test__/perf.cy.ts。

用 SD 组件覆盖 TypeScript 与 JSON 代码节点,显示语言标签、代码正文和可展开的节点信息,周围的诗词和引用仍使用默认渲染。调用方显式映射优先于默认适配;卸载时注销自己创建的作用域。

对同一份诗词 HTML 切换 safe、trusted 和 escape,比较标题、段落、链接、引用与按钮的处理。按钮仅在显式 trusted、且上游清理后仍保留该标签时适配;escape 显示字面内容。

展示诗词数据的 TypeScript 与 JSON 代码、Mermaid 阅读流程,以及行内和块级数学公式。使用轻量代码节点,保留复制事件;图表和数学沿用可选依赖的加载方式,未配置时显示原有降级内容。

组件库不依赖任何图表或公式引擎。markstream-vue 把它们全部声明为 optional peer,未安装时对应代码块降级为展示源码,Markdown 渲染的其余部分不受影响。需要哪种能力就在业务项目里安装哪种:

能力 包 装上后是否需要配置
Mermaid mermaid 否,装上即用(默认已启用)
数学公式 katex 否,装上即用(默认已启用)
D2 @terrastruct/d2 否,装上即用(默认已启用)
信息图 @antv/infographic 是,默认关闭且无自动加载,必须提供 loader

前三者由上游在检测到包后动态 import()。信息图既默认关闭、也没有自动加载兜底,需要显式提供 loader(同样从 @sdata/web-vue 导入):

终端窗口
pnpm add mermaid katex @terrastruct/d2 @antv/infographic
import { setInfographicLoader } from '@sdata/web-vue';
setInfographicLoader(() => import('@antv/infographic'));

两点需要注意:

  • 前三者是隐式启用的。 一旦业务项目装了 mermaid,Markdown 就会开始渲染图表并把它打进产物,没有额外开关。不需要时用 disableMermaid()(同理 disableKatex() / disableD2())显式关闭,或用自己的 loader 覆盖默认行为。
  • 没有任何 CDN 或自动下载行为。 组件库不注入脚本、不发起外部请求;完全离线可用。

本页示例之所以能真实出图,是因为文档站作为消费方安装了上述四个包——组件库本身依旧零可选依赖。

在独立背景中对照诗词、富内联、引用、表格、任务项和提示块的明暗颜色。最近的 ThemeProvider 控制默认明暗;显式 is-dark 优先。容器中的 SD 按钮维持自己的尺寸与交互。

直接传入代码和公式节点,再用公开解析器生成完整诗词结构;节点统计和 HTML 标签解析结果显示在示例中。组件、工具与节点类型均由 SD 包提供;公式未配置可选 loader 时保持上游降级行为。

组件属性与 markstream-vue@2.0.13 的 NodeRendererProps 完全对应,导出为 MarkdownRenderProps。下表列出常用入口,其余代码、图表、性能与虚拟化选项保持上游类型和语义。

属性 类型 说明 默认值
content string Markdown 文本,nodes 未传时解析 —
nodes BaseNode[] 已解析节点,优先于 content —
final boolean 内容是否传输完成 false
parse-options ParseOptions 组合使用上游解析配置及 hooks —
custom-markdown-it (md: MarkdownIt) => MarkdownIt 扩展 MarkdownIt 实例 —
debug-performance boolean 性能调试开关 false
custom-html-tags readonly string[] 调用方自定义 HTML 标签 —
mode docs / chat / minimal 展示与性能预设 docs
dom-mode full / minimal 节点 DOM 模式 full
html-policy safe / trusted / escape HTML 信任策略 safe
viewport-priority boolean 优先调度视口节点 上游自动选择
viewport-priority-options MarkstreamViewportPriorityOptions 视口调度配置 —
code-block-stream boolean 代码流式更新 true
code-block-dark-theme / code-block-light-theme CodeBlockTheme 代码增强主题 —
render-code-blocks-as-pre boolean 轻量代码展示 false
code-block-min-width / code-block-max-width string / number 代码块宽度约束 —
code-block-options CodeBlockOptions 代码渲染器配置 —
code-block-props NodeRendererProps[codeBlockProps] 代码节点展示与工具栏属性 —
mermaid-props / d2-props / infographic-props 对应节点的 Partial Props 图表展示及工具栏配置 —
show-tooltips boolean 节点提示 按 mode
themes CodeBlockThemes 代码主题组合 —
is-dark boolean 显式主题优先于最近 SD 主题容器 SD 主题
custom-id string 调用方已注册的节点映射作用域 —
index-key string / number 节点会话键前缀 —
typewriter boolean / simple / precise 打字机显示方式 false
smooth-streaming boolean / auto 平滑流式更新 auto
smooth-streaming-options SmoothMarkdownStreamOptions 平滑流控制配置 —
parse-coalesce-ms number 解析合并间隔 上游默认
fade boolean 节点淡入 按 mode
batch-rendering boolean 分批渲染 true
initial-render-batch-size number 首批渲染节点数 按 mode
render-batch-size number 后续批次节点数 按 mode
render-batch-delay number 批次间隔毫秒 按 mode
render-batch-budget-ms number 批次工作预算 按 mode
render-batch-idle-timeout-ms number 空闲回调等待上限 按 mode
defer-nodes-until-visible boolean 视口外节点延迟激活 true
max-live-nodes number 活动节点数限制 按 mode
live-node-buffer number 活动范围缓冲 按 mode
node-virtual boolean / auto 节点虚拟化 auto
virtual-scroll MarkstreamVirtualScrollOptions 独立虚拟滚动会话配置 —
render-as-fragment boolean 不创建上游根容器 false

普通模式与 render-as-fragment 模式均保留鼠标事件,每次操作只转发一次。

事件 参数
copy、copy-code code: string
click event: MouseEvent, referenceId?: string
mouseover、mouseout event: MouseEvent
handleArtifactClick CodeBlockPreviewPayload
virtual-state-change MarkstreamVirtualState
height-change、render-settled、render-final MarkstreamVirtualMetrics
anchor-change MarkstreamVirtualAnchor

锁定版本的根渲染器没有公开插槽,因此 SdMarkdownRender 不接受具名插槽。代码块的 header-left、header-center、header-right 属于 CodeBlockNode 等节点组件自身,只能通过 setCustomComponents 整体替换对应节点组件来接管,替换后需自行实现复制、折叠、预览和字号等动作。图片节点适配保留了上游的 placeholder 与 error 插槽。

getVirtualMetrics、captureVirtualState、restoreVirtualState、forceMeasure、settle、scrollToNode 保留上游参数及返回类型。

上游其余组件、运行时配置和类型可直接从 SD 根入口引入,例如 MathBlockNode、CodeBlockNode、setCustomComponents、CodeBlockNodeProps。SD 的 Tooltip 保持原义,上游 Tooltip 的根入口名称为 MarkstreamTooltip。

需要完整保留上游名称或默认导出时使用 @sdata/web-vue/markstream;上游 utils、tailwind 和 worker 子路径对应 @sdata/web-vue/markstream/<原子路径>。这些直接导出的组件保持原行为,SD 默认节点适配仅作用于 MarkdownRender。

标题使用 TypographyTitle,引用块使用 TypographyParagraph 的引用模式。段落保留上游原生节点、用 SD 正文 token 对齐观感,原因见上方「长文档与虚拟化」。Strong/Emphasis 保留 strong/em 语义,表格保留原生 table 的对齐、富内容与流式状态。代码、公式、图表和脚注继续使用上游引擎。

代码块工具栏无法通过 MarkdownRender 定制。 锁定版本的根渲染器不提供任何插槽,上游也不把 header-left / header-center / header-right 传给节点组件——插槽只存在于 CodeBlockNode 自身。因此复制、折叠、展开、预览和字号控制保持上游原控件(用 SD token 统一外观)。需要自定义头部时,请整体替换 code_block 节点组件(见「覆盖节点与嵌入 SD 组件」),并自行保留上述动作;SdMarkdownRender 不会转发节点级插槽。

原始 HTML 的未完成节点、自定义业务标签和 escape 内容继续交给上游 HTML 节点。适配不执行 HTML 内联事件,不自动增加信任标签,不切换到 trusted,也不覆盖调用方解析 hooks。

图片节点的 source/fallback、load/error/click、pending 请求身份与异步结算规则由 web-core/markdown/image 管理。Vue 提供原始生命周期对象、nextTick、节点高度和响应式缓存;上游 renderer、插槽和事件协议保持原样。

web-core/markdown/html 负责策略优先级、HTML 适配条件、空白 token 保留、token 建树和宿主标签判断;VNode 到 SD 组件的映射继续留在 Vue。web-core/markdown/html-entities 共享原来的惰性实体工具和双次还原行为,旧深入口继续转发同一函数。

Core 显式依赖 stream-markdown-parser@1.2.19,与当前 markstream-vue@2.0.18 使用的解析器版本一致。升级上游时须同时复核解析器版本与函数/可变标签 Set 的共享身份,保持 sanitizer 行为和 HTML 策略一致。

Vue adapter 同时将 markstream-vue 固定为 2.0.18;两项版本成对复核和升级,避免消费项目自动解析到另一组 parser 行为。