How to define diagrams and integrate Kroki outputs into a Typst document?

We just started experimenting with Typst to understand if it can replace our asciidoc-based solution for some technical documentation.

It looks very promising with fast updates and pipeline-able document generation. The addition of a WYSIWYG editor is compelling and not something our current setup can offer, so I wanted to understand whether our current documentation and use cases can be covered adequately with Typst.

One of our biggest use cases is dynamically embedding various diagram types (mermaid, wavedrom, graphviz, others) by the use of an internally-hosted kroki server. Asciidoctor can handle this well; the diagram code itself lives in the .adoc file and with proper editor settings, can show real-time previews of the entire document as arbitrary diagrams or other document contents are updated.

I spent some time trying to understand how such an integration might function for Typst documentation and the solution is not as clear as I expected it to be. I did not find any mention of “kroki” on the forums or in documentation. While we could generate an image output from Kroki and have it imported, the code itself would not live in the Typst document (that I can tell), and is very static. I think it would require a mutli-step build process of running a script to re-generate all Kroki diagrams, then previewing with Typst to pull in all new images.

Because I am not familiar with the Typst ecosystem, I expect there is a better way to do what we need. What is the “right” way to solve this?

Welcome! Seeing as this is a typst forum and I have no idea what kroki is beyond what I just now learned scrolling through their website, I might ask some stupid questions.

First, do I understand that you can use kroki to generate (for example) svg images from some “code”? If you can use it to export images, typst of course supports including images in your document, see the documentation for image.

Do you mean that you have the code inside your asciidoc plaintext file, then asciidoctor uses kroki to generate an image of the diagram on the fly, and then includes this image inside your document? Typst cannot run external commands due to security concerns, so this isn’t possible. You’d need some sort of preprocessor to compile compile the images first, and then include those in your document. I saw that there are some rust crates for kroki, so you might be able to write a custom WASM plugin to do this.

Perhaps someone more knowlegable in plugin development could chime in?

If by diagram code you mean something like svg data, then sure:

#let circle-svg = bytes(
```
<svg height="100" width="100" xmlns="http://www.w3.org/2000/svg">
  <circle r="45" cx="50" cy="50" fill="red" />
</svg>
```.text,
)

#image(circle-svg)

And if you only need some sort of way to include diagrams in your outputs (not necessarily using kroki), there are some nice visualisation libraries available on typst universe. Fletcher comes to mind: fletcher – Typst Universe

Thank you for the quick response. No such thing as a stupid question, I may have jumped a bit fast into Kroki so hopefully I can clear a few things up.

Yes, this is the desired use case (not just embedding static images). For example, here is a valid sanitized snippet of one of our plantext asciidoc files:

A visual depiction of the packet structure is shown in <<protocol_frame>>.

[[protocol_frame]]
.Protocol Frame Definition
[wavedrom]
----
{
  reg: [
    { "name": "SIZE", "bits": 16},
    { "name": "TYPE", "bits": 8},
    { "name": "...", "bits": 8, "type": 0},
    { "name": "CRC", "bits": 32,},
  ],
  config: {
    bits: 64,
    lanes: 8,
    hflip:true,
    vflip:false,
    compact:true,
    margin: {left: 180},
    label: {
      left: [
        'SIZE 0',
        'SIZE 1',
        'TYPE 2',
        'PAYLOAD ...',
        'CRC N+6',
        'CRC N+7',
        'CRC N+8',
    	'CRC N+9',
      ]
    },
  }
}
----

The messaging format follows a transactional pattern where every message as an immediate corresponding response.
For commands, the expected response is an Ack message, whereas the expected response to a query is a corresponding message.

[edit: here’s a rendered example of that output: wavedrom]

The above can be edited within the file itself and is rendered real time in an adjacent preview window. As a user types or modifies a part of that block in their IDE, that text gets sent via an HTTP API request to Kroki, which then returns an SVG representing that content. That image is subsequently placed into the full document content preview. I call this “real time”, but it is more like 1-2 seconds delay per edit.

This is what I was thinking might need to happen, but didn’t have the right search terms. I think fletcher is the closest to the functionality I am expecting (nice tool, by the way, thank you for pointing that out). I want to be able to do something similar with any of the diagrams that Kroki supports, effectively passing the diagram off to an external handler to return the rendered image for the preview. Seeing that it needs to be internal and I cannot reference an external HTTP API however gives me pause. I am hearing that the only way to do this to is embed Kroki functionality into a rust crate to be called locally via a plugin?