概要
最近githubが対応したことで熱を帯びてきているMermaidですが、従来使ってきたPlantUMLを使っているという方もまだまだ多いのではないでしょうか。
そこで、PlantUMLからMermaidへの変換サービスを実装しました。
PlantUML -> Mermaid変換器
現在のところER図とシーケンス図のみに対応していますが、今後別の図にも対応予定です。
基本的な構造
変換時にやっていることは、以下のように
1. PlantUMLを構文解析して、JSのObjectに変換
2. JSのObjectをMermaidに変換
という流れです
サービスに落とし込む前は、PlantUMLからMermaidへの変換を一括でやってしまってたのですが、分割することでそれぞれの関数がそれぞれの役割に集中でき、コードがだいぶシンプルになりました。
PlantUMLの構文解析部分は、以下のように正規表現でそれぞれの行を解釈し、objectに落とし込んでいきます。
// analyze PlantUML text
for (let line of lines) {
if(line.match('(participant|actor|boudary|control|entity|database|collections|queue) .+( as .+|)')){
//block
} else if(line.match('(activate|deactivate) .*')){
//activate or deactivate
} else if(line.match('.+ ((<|).*-.*(>|)) .+ :.+')) {
// relation
}
}
プログラムを見て分かる通り、正規表現に当てはまらないものは、Mermaidに変換不可として取り除かれるようになっています。こうしてできた、「言語の意味に関係ない情報を取り除き、意味に関係ある情報のみを取り出した構文木」のことを 抽象構文木(AST) というそうです(定義間違っていたらごめなさい🙇♂️ )
やっていて困ったこと
MermaidのReactコンポーネントがNext.jsで使用できなかった
当初はreact-mermaid2を使って、図をリアルタイムレンダリングする予定でしたが、適用すると以下のようなエラーが...
Error: Must use import to load ES Module: /Users/hogehoge/index.js
require() of ES modules is not supported.
require() of /Users/hogehoge/index.js from /Users/hogehoge/node_modules/mermaid/dist/mermaid.core.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/hogehoge/package.json.
調べたところ、ファイルの拡張子を.mjs
にするか, package.jsonに対して、type: "module"
を追記する必要があるということ
が、自分の場合にはそれで解決できなかったので、以下のように、変換が終わったタイミングで図を再renderingさせています。 (ここは後々解決したい...)
const svg = mermaid.mermaidAPI.render('hoge', mermaidText)
document.getElementById("svgCode").insertAdjacentHTML('afterbegin', svg)
今後
まだまだPlantUMLの構文解析の性能が低いので、さらに変換精度をあげられるようにプログラムを改変していきます 🔥