Way for Elixir code cell in Livebook to emit a Mermaid graph which gets rendered?

Hello! I have some code:

:sentence
|> RuleBasedGrammar.generate_tree(RuleBasedGrammar.bigger_grammar())

that returns something like:

[
  :sentence,
  [:noun_phrase, [:pronoun, "it"]],
  [:verb_phrase, [:verb, "took"], [:noun_phrase, [:name, "Lee"]], []]
]

I would now like to take this output and render it, via a function call, as a graph. Is there a way to have a function emit Mermaid markdown and then get that rendered somehow?

For example, I would have a function RuleBasedGrammar.render_as_mermad/1 that would internally take the above output, convert it to the Mermaid markdown:

graph TD

:sentence --- :noun_phrase
:noun_phrase --- :pronoun
:pronoun --- it["#quot;it#quot;"]

:sentence --- :verb_phrase
:verb_phrase --- :verb
:verb --- took["#quot;took#quot;"]
:verb_phrase --- :name
:name --- lee["#quot;Lee#quot;"]

and then the Mermaid would render to the diagram in the output cell.

Here’s a mockup:

I’m sure there is a way to do this using Kino, but I’m just not sure how at the moment. So I thought I would ask here to check:

  1. Is there already an existing solution for this?
  2. If not, does anyone have some pointers on how to get Kino to do this?

Thank you!

1 Like

Kino.Markdown.new() is likely what you want. It emits new markdown as a control but is not like a markdown cell. I assume you care about the output and not editing the markdown, correct? If that’s the case, Kino.Markdown is perfect. If you want to edit output around it you could always just use a separate markdown cell. It’d be clunky to mix them.

The only caveat is I don’t know if Mermaid works that way exactly. I remember there being some gotchas but memory is hazy.

The added bonus of using Kino is that’s how apps display output.

5 Likes

Good call! You caused me to realize that I haven’t recently inspected Kino’s modules, and there’s a lot of stuff there. I should have done so before, but upon looking up Kino.Markdown, I happened to notice Kino.Mermaid. Kino.Mermaid.new/1 does exactly what I needed with zero changes:

So now I just need to translate my graph to the Mermaid markdown, which should be straightforward enough.

I’m unfortunately not using Elixir for work at the moment, and so I get to my Livebook projects in spurts. So this is a good time to go through all the updates that have been added in Kino (unless these have been there a while, and I missed them the past few times. Haha.)

Thanks for your help!

3 Likes

I had tried with Kino.Markdown.new/1, but I just realized that I didn’t surround the Mermaid markdown with triple backticks and the mermaid designation. Upon doing so, it works as well:

So either Kino.Markdown.new/1 or Kino.Mermaid.new/1 work fine, with the latter requiring only the content.

1 Like

Nice. TIL there was a Kino.Mermaid but it makes sense given how much it’s used. I’m glad it all worked as expected