首页
/ 在 Slidev 中使用 PlantUML 绘制 UML 图:语法、渲染原理与自定义服务器配置

在 Slidev 中使用 PlantUML 绘制 UML 图:语法、渲染原理与自定义服务器配置

2026-09-08 11:29:10作者:伍希望

本篇技术指南围绕 Slidev 内置的 PlantUML 支持展开,讲解如何直接在幻灯片中以 plantuml 代码块编写文本描述并自动渲染为 UML 图,涵盖基础语法、代码块参数、plantUmlServer 配置项,以及从 Markdown 解析到浏览器渲染的完整实现链路。读完本文,你将能够写出可复现的 PlantUML 幻灯片,并根据内网、离线等场景自定义渲染服务器,深入理解底层每个环节的作用。

一句话认识这个能力

Slidev 把 PlantUML 作为「开箱即用」的代码块能力内置:不需要安装任何插件,只要在一个以 plantuml 作为语言标识的围栏代码块(fenced code block)中书写 @startuml ... @enduml 描述,幻灯片解析器就会在构建阶段将其转换为 <PlantUml> 组件,最终由浏览器向 PlantUML 服务端请求渲染好的 SVG 图片并展示在页面上。对应功能文档见 docs/features/plantuml.md

PlantUML 代码块的基础用法

slides.md 的任意一张幻灯片中写入如下围栏代码块,即可生成一张时序图:

```plantuml
@startuml
Alice -> Bob : Hello!
@enduml
```

图内文本(即 @startuml@enduml 之间的全部内容)是标准的 PlantUML 描述语言。例如把 Alice 与 Bob 之间的消息改为中文或补充多条消息、添加激活条(activate / deactivate)、分组(group)等,都会被 PlantUML 服务端原样解释:

```plantuml
@startuml
Alice -> Bob : 请求数据
activate Bob
Bob --> Alice : 返回结果
deactivate Bob
@enduml
```

该用法与 Mermaid 一致——docs/features/mermaid.md 中同样是靠围栏语言标识触发渲染。二者的取舍通常看团队习惯与图种偏好:PlantUML 的语法更为「文本化、结构贴近代码」,适合从代码注释与设计文档中直接迁移图描述。

支持的主要图表类型

plantuml 代码块没有限定图种,凡是 PlantUML 语言本身支持的图,理论上都能渲染,常见的包括:

  • 时序图(Sequence diagrams):Alice -> Bob : Hello! 即属此类;
  • 类图(Class diagrams):用 class、继承与关联关系描述领域模型;
  • 活动图(Activity diagrams):用 startifrepeat 描述业务流程分支;
  • 组件图(Component diagrams):描述软件模块之间的依赖与接口;
  • 状态图(State diagrams):用 [*]state 描述对象状态机;
  • 对象图(Object diagrams):描述某一时刻的对象实例关系;
  • 用例图(Use case diagrams):用 actorusecase 表达系统需求场景。

在真实使用中,若同一页出现 ```plantuml 以外的图种(如 mermaidtsmd 等),各个渲染器会按注册顺序逐个尝试处理,并不会互相干扰(详见下文「渲染原理」的代码块流水线)。

自定义 PlantUML 服务器(plantUmlServer)

默认行为

默认情况下,Slidev 会把图描述发送给公共服务器 https://www.plantuml.com/plantuml 进行渲染。这个默认值来自 packages/parser/src/config.tsgetDefaultConfig()

plantUmlServer: 'https://www.plantuml.com/plantuml',

类型定义同步声明于 packages/types/src/frontmatter.ts,注释明确标注其默认值为 https://www.plantuml.com/plantuml,含义为「渲染图表所用的 PlantUML 服务器 URL」。

在 headmatter 中覆盖

如果幻灯片运行环境无法访问公网,或企业出于安全考虑不允许把图源文本发送到第三方服务器,可以在 slides.md 顶部的 headmatter 中覆盖它:

---
plantUmlServer: https://your-server.com/plantuml
---

这里的 plantUmlServer 是顶层配置键(不是嵌套在 config: 下的子项),文档示例同时出现在 docs/custom/index.md,并附注释 Learn more: https://sli.dev/features/plantuml.html,指向本功能对应文档页。VS Code 扩展还为其提供了 schema 补全与校验支持,见 packages/vscode/schema/headmatter.json

一个典型的自定义地址形态如 http://localhost:8080/plantuml(本地 docker 镜像 plantuml/plantuml-server 默认路径为 /plantuml)。需要注意:该 URL 只需指向「PlantUML Server 根路径」,Slidev 会在其后自动拼接 /svg/<编码串>(见下节),因此请勿把 /svg 或编码路径一并写进配置。

代码块级参数:缩放等渲染选项

和 Mermaid、Monaco 等代码块一样,plantuml 围栏代码块支持在语言标识后跟一个花括号对象来注入渲染参数。以缩放为例:

```plantuml {scale:0.5}
@startuml
Alice -> Bob : Hello!
@enduml
```

{scale:0.5} 会把图片缩放为原始尺寸的一半。解析规则在 packages/slidev/node/syntax/codeblock/plant-uml.ts 的正则中定义:

const RE_PLANT_UML = /^plantuml\s*(\{[^\n]*\})?/

即在 plantuml 语言标识后允许可选地跟一个单行对象字面量。该对象会被整体透传给渲染组件:

const optionsProp = options ? `v-bind="${options}"` : ''

因而除 scale 外,任何组件支持的 prop(如自定义 alt)都可以这样传入,例如 plantuml {alt:"系统时序图"}。这一行为有端到端测试佐证:packages/slidev/node/syntax/integration.test.tsplantuml {scale:0.5} 被转换为:

<PlantUml v-bind="{scale:0.5}" code="SoWkIImgAStDuNBCoKnELT2rKt3AJx9Iy4ZDoSddSaZDIodDpG40" />

渲染原理:从 Markdown 代码块到 <img>

理解这个功能的底层链路,有助于排查「图不显示」「请求了错误地址」等问题。整体分三步:

  1. Markdown 围栏被拦截:解析期,Slidev 覆写 MarkdownIt 的 fence 渲染规则,并按顺序执行一组代码块转换器,见 packages/slidev/node/syntax/codeblock/index.tsplantUmlTransformermermaidTransformermagicMoveTransformermonacoTransformer 等并列注册,任一转换器返回非空结果即结束处理。

  2. 转换为组件:在 packages/slidev/node/syntax/codeblock/plant-uml.ts 中,转换器读取已解析的 plantUmlServer 配置,并用 plantuml-encoder(一种 deflate + base64 编码,也是 PlantUML 官方服务器识别的 URL 编码)压缩图源文本:

    const encoded = encodePlantUml(code.trim())
    const serverProp = plantUmlServer === undefined ? '' : ` server=${JSON.stringify(plantUmlServer)}`
    return `<PlantUml ${optionsProp} code="${encoded}"${serverProp} />`
    

    也就是说,plantUmlServer 未显式配置时,最终 <PlantUml> 组件会退回到运行期的默认服务器地址;若在 headmatter 中显式配置,则会被序列化进组件属性。

  3. 浏览器端请求 SVG:运行时渲染组件 packages/client/builtin/PlantUml.vue 仅是一个轻量封装——按 props 组合出图片地址并输出 <img>

    const uri = computed(() => `${props.server}/svg/${props.code}`)
    
    <img :src="uri" :style="{ scale }" :alt="alt">
    

    即最终图片 URL 形如 https://www.plantuml.com/plantuml/svg/<编码串>alt 默认值为 'PlantUML diagram',可通过代码块参数覆盖。注释中也明确提示:这是一个「自动转换」得到的组件,无需手动直接使用 <PlantUml>

由此引出的三条实践结论

  • 渲染发生在浏览器端:幻灯片页面加载时才会按需向 plantUmlServer 发起图片请求,因此离线浏览、导出 PDF 与在线演示一样需要保证到该服务器网络可达;
  • 编码并非「明文传参」:图源经压缩编码后才出现在 URL 中,但 PlantUML 服务器本质上仍能解码还原出全部描述内容——涉及保密架构图时,请务必使用自建服务器而不是默认的公网实例;
  • 构建阶段只做转写:真正的图形渲染完全委托给 PlantUML 服务端,本地机器无需安装任何 Java/Graphviz 等 PlantUML 依赖。

常见问题与排查要点

  • 图片区域空白 / 裂图:先检查当前环境能否访问 plantUmlServer(默认 https://www.plantuml.com/plantuml)。网络受限时,在 headmatter 中改指内网服务器即可,无需改动任何代码块内容。
  • 请求落到了错误的地址:确认 headmatter 中的键拼写为 plantUmlServer(首字母大写 U、S 均大写),且是顶层键。
  • 缩进中的代码块不生效plantuml 围栏可以出现在列表等嵌套结构中(integration.test.ts 中即有嵌套在有序列表中的用例),只要保持 Markdown 围栏语法正确即可被识别。
  • 缩放不生效:确认花括号紧跟语言标识且无多余换行,例如 plantuml {scale:0.5},因为正则要求选项位于同一行内。

小结

PlantUML 是 Slidev 中与 Mermaid 并列的内置文本化图表方案,入口极简:写好 plantuml 代码块即渲染。它的深度可控性体现在两端——作者侧可通过 headmatter 的 plantUmlServer 切换到私有服务器、通过代码块参数控制缩放等表现;实现侧则是一条清晰的分层链路:fence 转换器负责把文本压缩编码成组件参数(codeblock/plant-uml.ts),轻量组件负责把地址拼装为远程 SVG 图片(client/builtin/PlantUml.vue)。需要图源保密或离线演示时,配置一个私有 plantUmlServer 即可继续沿用同一套书写语法,这也是本能力在生产环境中落地最常用的一步。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391