【免费下载链接】plantuml
Generate diagrams from textual description
项目地址:
https://gitcode.com/gh_mirrors/pl/plantuml
点击查看 免费下载
本篇技术指南围绕 PlantUML 仓库中的 docs/LOGSEQ_INTEGRATION.md 展开,讲解如何把由 TeaVM 编译出的纯 JavaScript PlantUML 引擎(plantuml.js + viz-global.js)以第二渲染后端的形式接入 Logseq 的 PlantUML 社区插件,彻底摆脱对 plantuml.com 或自建服务器的依赖。读完本文,你将掌握该 JS 引擎的完整 API 面、异步渲染的约束与串行化要求、插件接入的最小改动路径,以及背后基于 TeaVM 协程 + Worker 线程的实现原理。
背景现状:Logseq 里的 PlantUML 至今依赖服务器
Logseq 自身的应用核心是开源的,但它原生不渲染任何图表类型——既不支持 Mermaid,也不支持 PlantUML,一切图表能力都依赖插件市场。当前 Logseq 生态里维护中的 PlantUML 插件是 cofcool/logseq-plantuml-plugin(MIT 协议,仍在发布小版本更新)。它的使用方式很直接:输入 /Draw plantuml diagram 斜杠命令,在生成的代码块里书写 PlantUML 源码,点击 "Render" 渲染。默认情况下,插件把源码发送到 https://www.plantuml.com/plantuml/png,也提供设置项指向自建服务器。本地渲染从未实现——插件自己的 README 把 "Supports plantuml.jar" 列为待办事项。
在此之前,Logseq 社区还有一个更主流、功能更全的替代品:npgrosser/logseq-diagrams-as-code,它通过 Kroki API(可自托管)渲染 PlantUML、Mermaid、Graphviz、D2 以及大约十五种其他图表语言,曾是 Logseq 图表方案的首选。该仓库已于 2026 年 2 月 13 日被作者归档,且未指定继任者。留下的只有上述那个更小、单一用途的插件——仍然依赖服务器,仍然没有本地选项。
为什么这个方案特别契合 Logseq
有趣的地方不在于"缺少本地选项"本身,而在于 Logseq 的插件架构已经证明了本地方案可行——只是发生在另一种图表语言身上。
cofcool/logseq-plantuml-plugin 是 benjypng/logseq-mermaid-plugin 的一个 fork。而那个 Mermaid 插件是完全在客户端渲染的:它自行打包 mermaid.js,在浏览器里绘制图表,再通过 canvas 转成 PNG——没有服务器、没有网络请求,使用的是两个插件共有的 {{renderer :plugin-id, …}} 宏渲染器 + 斜杠命令机制。当 cofcool fork 它来支持 PlantUML 时,之所以被迫改走公共服务器,唯一原因就是当时没有可打包的纯 JavaScript PlantUML 引擎——不像 benjypng 可以打包 mermaid.js。本文档提议所要填补的正是这个缺口:这不是架构问题,而是"这个(引擎)此前不存在"的问题。
此外,在此之前从未有人在 cofcool/logseq-plantuml-plugin 上提出过纯 JS 后端,因此不存在"我们不想在这里引入更多自定义 JS"的历史包袱——这与 Outline 的 PR 讨论形成对比,详见 docs/OUTLINE_INTEGRATION.md。相反:Logseq 市场提交指南并未提及对打包第三方 JS 或 WASM 的任何限制,而 benjypng 的插件本身就是"已发布、现在就可安装"的活例子。
现有的真实需求
图表渲染在 Logseq 社区是一个悬置多年、始终未决的诉求:
- Mermaid 渲染支持讨论帖自 Logseq 早期就存在,横跨两页论坛,核心团队始终没有给出承诺;有贡献者(@junyu)曾提出鉴于当时插件系统尚年轻,"一个测试插件"可以探索原生支持;@Carey_Black 则提出(未获答复)是否能把图表渲染器"紧密打包"进 Logseq 本体,而不是依赖独立的服务器进程。
- "不想让服务器掺和进来"正是打包 JS 引擎所能消除的痛点。
- 在此之上叠加的事实是:最流行的全能图表插件(logseq-diagrams-as-code)刚被归档,剩下的 PlantUML 插件把"无服务器"列为未实现的 todo 而非已发布的功能。
立即体验:在线 playground
一个可工作的引擎构建已经在线运行,无需任何配置:
https://plantuml.github.io/plantuml/js-plantuml/index.html
在左侧输入或粘贴任意 PlantUML 源码(@startuml … @enduml),右侧即时渲染出 SVG——完全在浏览器内完成,使用的正是下文描述的 plantuml.js + viz-global.js 组合。仓库内对应这份 playground 的源码位于 src/main/resources/teavm/:index.html 是带分栏编辑器的完整 playground,main.js 是它的渲染逻辑——可以看到它直接 import { render } from "./plantuml.js",并把编辑器内容按行拆分后调用 render(lines, "out", {dark: dark})。
PlantUML JS API:两个导出函数
整个 JS 引擎的公开接口只有两个导出函数:
| import { render, renderToString } from './plantuml.js' | 从 ES2015 模块导入 API。 |
| render(lines, targetId) | 把图表渲染进给定 id 的 DOM 元素。lines 是 Array<string>。 |
| render(lines, targetId, { dark: true }) | 同上,但生成暗色模式 SVG。 |
| renderToString(lines, onSuccess, onError) | 渲染并以字符串形式通过 onSuccess(svg) 回调交付 SVG;错误交给 onError(message)。 |
加载方式:plantuml.js 是 ES2015 模块(通过 <script type="module"> 加载),viz-global.js 是经典脚本(通过普通 <script> 标签加载),且必须在任何渲染发生前存在于页面中。引擎在首次 render / renderToString 调用时惰性启动内部 worker——无需显式初始化步骤。
关键约束:异步渲染
render() 立即返回,但把 SVG 写入目标 DOM 元素是异步完成的;而且在同一个 JS 上下文里渲染多个图表必须串行化——等一个 SVG 落地后再开始下一个。对 Logseq 而言,一个页面上有大量 PlantUML 块正是需要面对的场景。好消息是 docs/GITHUB_INTEGRATION.md 描述了一种"每个图表一个隐藏 iframe"的模式,可以为每个图表提供独立的引擎实例,从而并行渲染且不阻塞编辑器——该文档中 github-integration-web-worker-poc.html 就是这一模式的落地原型,而 github-integration-poc.html 则是串行队列版本。
源码视角:JS 引擎如何在浏览器里跑起来
虽然 plantuml.js 是由构建过程生成的(生成物不在源码树中),它的 Java 源头完全开源,位于 PlantUMLBrowser.java:
- JS 驱动架构:JavaScript 负责 UI 事件、输入防抖、按行拆分、DOM 元素选择与应用流程;Java(经 TeaVM 编译)只负责 PlantUML 解析和 SVG 渲染。这让 Java 侧保持最小,Web 开发者可按任意方式集成。
- 为什么需要 worker 线程:TeaVM 把 Java 编译成 JavaScript,但 JS 是单线程事件驱动的。为支持 Java 的同步阻塞 API(如 Thread.sleep()、Object.wait()),TeaVM 采用基于协程的方式把阻塞调用转换为异步 Promise。PlantUML 用 Viz.js(GraphViz 的 JS 移植版)渲染类图、组件图等需要图布局的图表,而 Viz.js 的 API 是异步的(Viz.instance().then(viz => viz.renderString(dot, options)))。如果直接从原生 JS 上下文(如事件回调)调用渲染函数,一旦走到 Viz.js 的异步调用,TeaVM 会抛出 Error: Suspension point reached from non-threading context。
- 解决方案:首次调用 render / renderToString 时惰性启动一个后台线程(见 ensureWorkerStarted()),导出函数只负责把请求入队并唤醒线程(典型的生产者-消费者模式,LOCK + wait/notify),真正的渲染在 worker 线程的协程上下文中完成。若渲染期间到达多个请求,只保留最新一个——这是有意的设计:用户打字时只需渲染最新版本。
- 渲染选项:render 与 renderToString 都接受可选 options 对象,如 { dark: true } 启用暗色模式,{ maxSvgSize: 9999 } 把最大 SVG 宽高(像素)从默认值 8192 调高,{ maxSvgSize: 0 } 完全禁用尺寸检查(SVG 没有栅格内存成本,此限制只是安全护栏)。渲染结果还会把 PlantUML 源码作为 plantuml-src 处理指令嵌入 SVG,使其之后可被重新导入/编辑,与经典 Java 后端和 editor.plantuml.com 产出的 SVG 行为一致。
- Viz.js 与 Smetana 回退:GraphVizjsTeaVMEngine.java 通过 TeaVM 的 @Async 注解把 Viz.js 的异步调用包装成对 Java 同步可见的 renderDotToSvg(dotSource);当检测到 viz-global.js 未加载时(vizMissingFallback()),会输出一次性控制台提示并回退到内置的 Smetana 布局引擎。
如何接入 Logseq 插件:最小改动路径
Logseq 插件是 JavaScript/TypeScript,通过 @logseq/libs 加载,经 Logseq marketplace 分发。cofcool/logseq-plantuml-plugin 已经注册了斜杠命令和一个宏渲染器(onMacroRendererSlotted)——它给代码块一个渲染落点和一个触发渲染的 "Render" 动作,与 benjypng Mermaid 插件全本地渲染所用的形状完全相同。把 plantuml.js 和 viz-global.js 作为打包资源加入,并把它们接入既有的渲染步骤,是增量改动而非重写——作为当前服务器调用的第二后端,就像现在 render server 只是一个设置字符串一样:
import { renderToString } from "./plantuml.js";
// 在插件既有的宏渲染器回调里,作为当前 fetch-from-plantuml.com 调用的替代:
function renderWithJsEngine(source, targetElement, dark) {
const lines = source.split(/\\r\\n|\\r|\\n/);
renderToString(
lines,
svg => { targetElement.innerHTML = svg; },
error => { targetElement.textContent = `PlantUML error: ${error}`; }
);
}
关于市场审查:Logseq 的市场提交指南没有像 Obsidian 的审查流程那样明文限制打包第三方 JS 或 WASM(对比详见 docs/OBSIDIAN_INTEGRATION.md)。目前唯一值得注意的审查提示是:启用 effect 能力标志会触发"更严格"的审查,但文档没有说明它具体管辖什么——在假设"这不是问题"之前值得直接向 Logseq 团队核实,不过没有任何迹象表明打包渲染引擎属于该标志针对的情形。
对插件而言的关键优势
- 移除插件唯一的外部依赖。不再依赖 plantuml.com(或自建服务器)保持可达——"Supports plantuml.jar"这个 todo 无需 JVM 即可解决。
- 隐私。图表源码永不离开设备,与 benjypng 本地 Mermaid 渲染的动机一致。
- 填补真实且当前的空白。最流行的替代方案(logseq-diagrams-as-code)已于 2026 年 2 月归档且无接替者;这个插件是仅存的方案,却仍然无法离线渲染。
- 对 Logseq 插件生态不是新范式。benjypng 的 Mermaid 插件已经证明:在 Logseq 的宏渲染器架构内,完全本地、打包 JS 的图表渲染是可行的——这只是 PlantUML 追上一个既有的先例,只不过 Logseq 核心不像 Obsidian 原生支持 Mermaid 那样可达。
- 增量而非破坏性。在现有服务器调用旁增加第二后端选项;偏好自建 PlantUML 服务器的用户保留原有选择。
- 极小的体量。两个导出函数;渲染步骤接线只有寥寥几行,与现有基于 fetch() 的渲染器形状相似。
相关文件索引
本文档位于 docs/ 下,与 docs/GITHUB_INTEGRATION.md、docs/NOTION_INTEGRATION.md、docs/OUTLINE_INTEGRATION.md、docs/OBSIDIAN_INTEGRATION.md 同列。文档所述的引擎文件位于 src/main/resources/teavm/:
| plantuml.js | TeaVM 编译的 PlantUML 引擎(由构建生成)。 |
| viz-global.js | Graphviz(Viz.js)布局引擎。 |
| index.html | 带分栏编辑器的完整 playground——与上文演示 URL 在线的是同一份。 |
Java 侧实现与验证材料:
| PlantUMLBrowser.java | 浏览器渲染引擎的 Java 源头:render / renderToString 导出、worker 线程、暗色模式与 maxSvgSize 选项。 |
| GraphVizjsTeaVMEngine.java | Viz.js 异步桥接与 Smetana 回退。 |
| main.js | Playground 渲染逻辑:按行拆分源码、render(lines, "out", {dark})、URL hash 分享。 |
| GITHUB_INTEGRATION.md | 面向 GitHub 的原始提案(含 iframe 并行渲染架构与消息协议)。 |
| NOTION_INTEGRATION.md | 面向 Notion 的同款提案。 |
| NOTION_EMBED_HOWTO.md | 可立即使用的零代码 Notion 变通方案。 |
| OUTLINE_INTEGRATION.md | 面向 Outline 的同款提案。 |
| OBSIDIAN_INTEGRATION.md | 面向 obsidian-plantuml 社区插件的同款提案。 |
落地路径小结
对整个方案做一次收束:现状是 Logseq 的 PlantUML 体验完全依赖外部服务器;缺口是唯一的纯 JS PlantUML 引擎此前不存在,而这个缺口如今已由本仓库 TeaVM 编译的 plantuml.js 补齐,并有在线 playground 可立即验证;接入方式是把两个 JS 文件作为打包资源接入 cofcold/logseq-plantuml-plugin 既有的宏渲染器,改动量极小且完全增量;前提约束是要遵守引擎的异步渲染语义(同一 JS 上下文内串行渲染,或采用 GITHUB_INTEGRATION.md 中每图一个隐藏 iframe 的并行模式)。对于关心隐私、离线可用性,或不想维护 JVM / 服务器进程的 Logseq 用户来说,这是一个零服务器、零 JVM、且已被同类 Mermaid 插件验证过的可行路径。
赞
【免费下载链接】plantuml
Generate diagrams from textual description
项目地址:
https://gitcode.com/gh_mirrors/pl/plantuml
点击查看 免费下载
相关推荐
Python数据导入工具Pandas:高效读取Excel文件的完整指南
深入解析 Opik 的 LlamaIndex 集成:用 LlamaIndexCallbackHandler 为 RAG 与 LLM 应用建立端到端追踪
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网硕互联帮助中心![可白嫖源码---课程设计--课程设计--毕业设计-- springboot停车场车位停车管理系统[编号:project62330] (案件分析)-网硕互联帮助中心](https://www.wsisp.com/helps/wp-content/uploads/2026/09/20260922063407-6ab2215f182f3-220x150.png)




评论前必须登录!
注册