How to enable MediaWiki to generate perfect mindmaps: Difference between revisions

From 清冽之泉
Jump to navigation Jump to search
Tags: Mobile edit Mobile web edit
Line 90: Line 90:
</pre>
</pre>


== 最终效果 ==
成功用以下内容:
成功用以下内容:
<pre>
<pre>

Revision as of 18:05, 22 September 2025

在 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自定义一下 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,而是用路径引用时,权限有问题。

  1. 路径必须是 plantuml 能找到的路径,所以在 LocalSettings.php 里用-Dplantuml.include.path="/path/to/wiki/extensions/Diagrams/styles"加入路径变量,能解决路径问题
  2. 权限可以是:文件夹 750,文件 640。若文件夹限缩至 640 则 light.puml 可能无法被访问。总之要确保 www-data 用户有 r 权限。
  3. 另外,某些默认文本编辑器,复制粘贴较长行时,会产生不恰当断行,我就在 extensions 被不恰当断行上栽过半小时,一定要明确复制的参数正确地写入了

#tag

{{#tag:tagname
|content
|attribute1=value1
|attribute2=value2
}}

在解决了 uml 中文乱码、 样式复用的问题后,就想用模板解决重复输入的问题。但发现,uml 一见到 {{{1}}} 模板参数就报错,原因在于 <uml> 标签无法先展开参数、再渲染生图。核心就是怎么样让 {{{1}}} 参数先展开,再交给 <uml> 处理,而 #tag 解释器刚好解决了这个问题。#tag 的本质是parser function,能确保参数先被 MediaWiki 展开,再交给扩展处理

最终模板如下:

<!-- Template:Swdt -->
<includeonly>{{#tag:uml
|@startmindmap
!include light.puml

{{{1}}}
@endmindmap
|format=svg}}</includeonly>
<noinclude>
“思维导图”模板用法:
{{Swdt|
* ChatGPT
** 冷静
*** 耐心
*** 强大
** 博学
}}
</noinclude>

最终效果

成功用以下内容:

{{Swdt|
* ChatGPT
** 冷静
*** 耐心
*** 强大
** 博学
}}

生成以下思维导图: