FSL.Diagram.Mermaid (fsl v0.2.0)

Copy Markdown View Source

Renders an FSL.Journal run as a Mermaid sequence diagram.

The same journal and the same lane rule as FSL.Diagram.PlantUML — read that module for what is drawn and why — in the dialect that needs no toolchain: GitHub, GitLab and most Markdown viewers render a ```mermaid block in place, so a diagram pasted into an issue is a diagram, not an attachment somebody has to run a jar over. It is also what the TypeScript sibling ships (Machine.toMermaid()), so the two dialects converge on one output format that a reader can compare side by side.

defmodule MyApp.FSLHost do
  @behaviour FSL.Host
  @impl true
  def diagram_renderer, do: FSL.Diagram.Mermaid
end

What Mermaid cannot do, and what is done instead

Mermaid's sequence grammar has no per-arrow colour, where PlantUML has -[#DarkOrange]>. So media is distinguished by lane and arrow style rather than by colour: a media message is dotted (-->>) and lands on the media participant, a protocol message is solid (->>) and lands on the peer. That is a weaker signal than a colour and it is the honest trade — inventing a rect rgb(...) block around every media line would colour the background of a region, which is not the same statement.

A terminal outcome is a note over the local lane, carrying the outcome word (succeeded: … / failed: …), where PlantUML tints it green or pink. Same information, one less channel.

Escaping

Message text runs to the end of the line in Mermaid, so a : inside a label is safe and a newline is not. # starts an entity code (#quot;), and ; ends a statement. All three are neutralised, and a label is never allowed to be empty — an empty one makes Mermaid drop the arrow silently, which is worse than a placeholder.

Summary

Functions

<scenario>_<pid>.mmd, with the pid sanitized to digits and dots.

Render the full Mermaid document as a String.

Functions

filename(meta)

@spec filename(map()) :: String.t()

<scenario>_<pid>.mmd, with the pid sanitized to digits and dots.

.mmd and not .md: the file holds a diagram and not a document, and every Mermaid tool recognises the extension.

render(events, meta)

@spec render([map()], map()) :: String.t()

Render the full Mermaid document as a String.