Pele wrapper library
A work in progress
Pele is a recently released Mermaid rendering library in JavaScript from the CEO of Obsidian, kepano. It was designed for use in Obsidian itself, which I am currently writing this blog post in, and where I do render a Mermaid chart from time to time. I even had half a mind to include Mermaid charts on my list of site enhancements, since they map pretty cleanly onto Gemtext preformatted blocks tagged with 'mermaid', same as is done in Obsidian.
kepano: "Pele"Mermaid.jsCurrently koine runs in Erlang, but that's just because it's the default; I could (I think) switch it to JavaScript with zero effort. (Just tested it, and: yes. Even the flake build is a one-line config change, yay.) I'd like to keep it cross-target to the degree that I can, but if I do it right I should be able to include support for Pele sandboxed so that it's only used when enabled, and if not enabled everything still works on the Erlang target.
But first I need to be able to use Pele from Gleam!
π π π
I've attempted two Gleam wrapper libraries of sorts in the past, both at work during downtime I had for various reasons so I can unfortunately show you neither of them.
The first was an attempt at wrapping the Obsidian plugin API so I could write Obsidian plugins in Gleam; this was wildly ill-fated and I gave up almost immediately, because the Obsidian plugin API is 1. extremely imperative and 2. enormous. I still might go back to it one day, because the challenge of wrapping the extremely imperative API in a functional Gleam API with managed effects or something is interesting to me, but it would probably be a tiny subset of the API/added to as needed. Also, I don't write that many Obsidian plugins. (Yet! Growth mindset!)
The second was of necessity. I recently worked through *WebAssembly from the Ground Up*, a neat little book that walks you through constructing a compiler for a small language targeting WASM. As soon as we started writing functions that returned raw bytes I knew I wanted to do the book in Gleam so I could use BitArrays.
WebAssembly from the Ground UpThe book is based on Ohm, an all-in-one parser/interpreter/compiler library meant for didactic use. (One of the WASM from the Ground Up authors is a co-creator of Ohm.) It's a neat library and great for hiding the messy details of parsing in a book like WASM from the Ground Up, but unfortunately for me and my Gleamish aspirations its API is extremely dynamic. You do things like pass in an object with keys matching the names of your stringly-defined grammar's productions. Gleam does not want you to behave this way.
Patrick Dubroy: "Ohm"But for better or for worse I didn't realize what I was getting myself in to when I made the choice to work in Gleam, and the early chapters only use a few Ohm features, so I was nicely frogboiled by the slow addition of more and more Ohm features until eventually I had an essentially complete Ohm wrapper library embedded in my WASM book implementation.
It was fun to write, even if it made the entire project take probably at least twice as long as otherwise would have, and designing the types and API made me understand the whole domain much more deeply than I otherwise would have. Recommended!
(The WASM book itself is also recommended, it was a very effective introduction and WASM is super cool technology. Maybe do it in JavaScript if you're not getting paid to learn and save yourself the however-many-hours.)
π π π
With these previous projects under and/or vaguely near my belt, I'm not too worried about the idea of doing the same kind of thing for Pele. Its API is very nice and simple and lends itself much better to use in Gleam than either of my previous targets. If all you want to do is convert Mermaid.js to SVG, you need one function. This is in fact all I want to do, but it wouldn't be much of a wrapper library if we only provided a single function!
While the API is relatively small, it's still taken long enough to get it in good shape that I don't have anything finished to show you tonight. As a teaser, here's what my Gleam dev file looks like:
Pretty much what you'd expect, but I think giving the options (the render function especially has many many options) as a list of custom type instances was a neat idea. The type looks like this:
The biggest decision I haven't yet gotten around to making is how to model the 'HTMLElement' type, which Pele uses in two functions ('mount', 'enableZoom'). I may shell out to something like Plinth that wraps the browser APIs, or I may make my own opaque type that consumers can unsafely cast to.
CrowdHailer et. al: "Plinth"A-ny-way, hopefully I'll have time to wrap this up soon so I can add optional Mermaid support to koine. And then come up with something to draw diagrams about, I guess.
The kanji of the day is ε³
- Its Kodansha Kanji Learner's Course keyword is DRAWING.
- Its readings are γ, γ―γ, γΊ, and γ.
Conning says something about X marking the spot on the drawing of a map, but I can't help but see the guy from γ with a slash across his face. This helps me remember what it means somehow, couldn't tell you how. Its premiere vocab word is ε³ζΈι€¨/DRAWING-WRITING-PUBLIC BUILDING, i.e., library. *Toshokan* is classic JAPNS 1 stuff, so getting to this one made me feel warm fuzzies.
Discuss this post on Bluesky