How to enable MediaWiki to generate perfect mindmaps
在 MediaWiki 里原生生成思维导图,一直是我的梦想。没想到,它实现了。
外部
不论采用外部哪个思维导图,生成的图,都得多一个上传的过程,烦不胜烦,所以只有从 MediaWiki 内部解决。
Diagrams
MediaWiki 的 Diagrams 拓展,提供了四种能力:<graphviz>, <mscgen>, <uml>, and <mermaid>。
<graphviz> 可谓理科思维导图。默认样式几乎没有。要定义节点,给节点连线,非常繁琐,只适合少图精调,不适合批量多图。
<mscgen> 我尚未用过。
<uml> 是我的最终方案。
<mermaid> 可谓文科思维导图。默认样式漂亮。要定义节点,给节点连线,非常繁琐,只适合少图精调,不适合批量多图。
Diagrams 里的 mermaid,目前版本为 9.1.x,太老旧了,没有 mindmap 直接写节点的能力。于是我尝试单独的 Mermaid 拓展。
但最终发现,单独的 Mermaid 拓展,虽然 mermaid 版本较新,但也没支持 mindmap 直接写节点的能力。
<uml>
中文乱码
用 Diagrams 的 <uml> 能力生图,发现中文是乱码。网上有人叫在 <uml> 内部设置中文字体,测了一会儿字体,改了一会儿字体名,均无效。
用下面的命令可以查看 <uml> 支持的字体。
@startuml
listfonts
@enduml
后来发现原因在于,Diagrams 调用 plantuml 时,没有继承到正确的 charset 设置,ChatGPT 多次提醒我改变 plantuml 的环境参数,我不知如何下手,我以为要动 Diagrams 的源码。
ChatGPT 又建议我做一个 plantuml-wrapper,把 plantuml 的二进制文件包裹一层环境参数,看着也挺麻烦,既要新建 plantuml-wrapper,又要改权限,还要同时去 LocalSettings.php 更改设置,我认为流程过于繁琐,不利于未来维护,于是放弃用 wrapper。
经过坚持不懈地翻找,我终于找到 plantuml 官方,里面有提到 utf-8 相关设置,而且我把 Diagrams 拓展的文档界面 发给 ChatGPT,叫它找找线索。细心的 ChatGPT 明确说,在 Diagrams 拓展的文档界面,明确可以自定义 plantuml 的本地环境参数。这并不是对 Diagrams 源码的入侵,而是官方提供的接口,我终于细心看了一下文档,才发现在文档底部明确写着可以自定义本地环境参数。终于,在 LocalSettings.php 里用-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8
自定义一下 utf-8 就解决了中文乱码的问题。
$wgDiagramsLocalCommands = [
'plantuml' => '/usr/bin/java -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 -Dplantuml.include.path="/path/to/wiki/extensions/Diagrams/styles" -jar /usr/share/plantuml/plantuml.jar',
];
样式复用
解决了中文乱码问题,好不容易调试出了一个文科思维导图,界面非常优美,又遇到了每次生图都需要带同样的样式参数的问题,于是查找到 plantuml 具有 !include 的能力,于是引入,但发现总是在 !include 行报错。
plantuml 官网明晃晃写着支持 !include,但是却不生效。ChatGPT 教了一个巨有用的调试技巧,用 www-data 用户查看文本内容,看是否存在权限问题:
sudo -u www-data cat styles/light.puml
如果能查看内容,证明权限无误。如果不能查看内容,证明权限有误。
测试 ChatGPT 建议的,用 !includeurl https://xxxx/light.puml 引入,直接杜绝了权限问题,发现立即可以实现想要的效果了,于是可以推测出不是 Diagrams 不支持 !include,而是用路径引用时,权限有问题。
- 路径必须是 plantuml 能找到的路径,所以在 LocalSettings.php 里用
-Dplantuml.include.path="/path/to/wiki/extensions/Diagrams/styles"
加入路径变量,能解决路径问题 - 权限必须是 750 文件夹内的 640 文件,若文件夹限缩至 640 则 light.puml 无法被访问
- 另外,某些默认文本编辑器,复制粘贴较长行时,会产生不恰当断行,我就在 extensions 被不恰当断行上栽过半小时,一定要明确复制的参数正确地写入了
#tag
{{#tag:tagname |content |attribute1=value1 |attribute2=value2 }}
在解决了 uml 中文乱码、 样式复用的问题后,就想用模板解决重复输入的问题。但发现,uml 一见到 {{{1}}} 模板参数就报错,原因在于 <uml> 标签无法先展开参数、再渲染生图。核心就是怎么样让 {{{1}}} 参数先展开,再交给 <uml> 处理,而 #tag 解释器刚好解决了这个问题。
最终模板如下:
<!-- Template:Swdt --> <includeonly>{{#tag:uml |@startmindmap !include light.puml {{{1}}} @endmindmap |format=svg}}</includeonly> <noinclude> “思维导图”模板用法: {{Swdt| * ChatGPT ** 冷静 *** 耐心 *** 强大 ** 博学 }} </noinclude>
成功用以下内容:
{{Swdt| * ChatGPT ** 冷静 *** 耐心 *** 强大 ** 博学 }}
生成以下思维导图: