Peleを使ってみる話

Peleってなんでしょうか?
Peleとは Obsidian の開発チームが作ったUMLのレンダリング・ライブラリー(mermaid.js互換)です
mermaid.jsよりも超速らしいです
「Zero dependencies, 6× smaller, and up to 500× faster than Mermaid.js. Pele supports every diagram type built into Mermaid 12.1.0.」

また、Obsidianの次期バージョン 1.15?から導入されるらしいです

今回はこのpeleを使ってみたかったので使ってみました

peleを使うだけでしたらプレイグラウンドにてどう言った画像になるかはここで確認できます
https://pele.run/playground

Obsidianで使われるものを確認するだけでしたらプレイグラウンドにて十分です。
しかし…実際にアプリで使ってみました
簡単な比較ページを作成して動作と描写を確認してみました。

https://dp5rf6.csb.app/

入力すると同じ画像ではないですが、peleの方がスマートです。
また、表示速度は早いです。

入力例を考えるのは大変なのでmermaidの入力サンプルはmermaidのライブエディットのサンプルを参考していたいただきました。
「ZenUML」は動作しないようです。
https://mermaid.ai/live/edit

成果物

肝心の使い方ですが、APIの通りにすると簡単に使えました
https://pele.run/api

APIのサンプルではrenderを呼ぶだけなのでそのままでは使い勝手が悪いのでREACTのコンポーネントにして表示せました。
動作チェックなのでdangerouslySetInnerHTMLを使っています。
SVGだけが入ると思いますが、普通に使う場合には要注意です

'use client';

import { useEffect, useState } from "react";
import { PeleError, render } from 'pele';

interface Props {
    src: string;
    className: string;
}

export function PeleMarkdown({ src, className }: Props) {
    const [svg, setSvg] = useState("");

    useEffect(() => {
        if (src) {
            try{
                const {svg} = render(src);
                setSvg(svg);
            } catch (e) {
                if (e instanceof PeleError) {
                    setSvg(`<pre>${e.message}</pre>`);
                } else {
                    setSvg(`<pre>${e}</pre>`);
                }
            }
        }
    }, [src]);
    return <div className={className} dangerouslySetInnerHTML={{ __html: svg }} />;
}

https://github.com/wataru775/learn_pele_uml/blob/main/app/comopnents/PeleMarkdown.tsx

参考までにMermaid.jsでのサンプルは以下です
mermaidは以下です

'use client'

import mermaid from "mermaid";
import { useRef, useEffect } from "react";

type Props = {
    src: string;
    className: string;
}

export function MermaidMermaid({src, className}: Props) {
    const ref = useRef<HTMLDivElement>(null);

    useEffect(() => {
        if (src) {
            mermaid.init({});
        }
    }, [ref.current, src])

    if(!src) {
        return <div className={className} key={src} />
    }

    return (
        <div className={className} ref={ref} key={src} suppressHydrationWarning>
            {src}
        </div>
    );
}

https://github.com/wataru775/learn_pele_uml/blob/main/app/comopnents/MermaidMermaid.tsx

コンポーネントの呼び出し方法は以下のようにしています

	<MermaidMermaid src={content} className="mermaid" />
	<PeleMarkdown src={content} className="pele" />
https://github.com/wataru775/learn_pele_uml/blob/main/app/uml/page.tsx

ま、単純ですね

終いに

今回はObsidianに新しいMermaidレンダラーが実装されるぞ!
と言うことで使ってみました
Mermaidは複雑になってきますので、速度が上がるのは嬉しいですね

参考

pele
https://pele.run/

mermaid
https://mermaid.ai/

GitHub:
https://github.com/wataru775/learn_pele_uml