Support more diagrams in AsciiDoc and Markdown using Kroki
Release notes
GitLab can now render more than a dozen diagrams using Kroki!
Once enabled in the GitLab admin area, you will be able to create a wide variety of diagrams in AsciiDoc and Markdown documents.
For instance, you can now render Vega-Lite diagrams:
Textual description
```vegalite
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"description": "Horizontally concatenated charts that show different types of discretizing scales.",
"data": {
"values": [
{"a": "A", "b": 28},
{"a": "B", "b": 55},
{"a": "C", "b": 43},
{"a": "D", "b": 91},
{"a": "E", "b": 81},
{"a": "F", "b": 53},
{"a": "G", "b": 19},
{"a": "H", "b": 87},
{"a": "I", "b": 52}
]
},
"hconcat": [
{
"mark": "circle",
"encoding": {
"y": {
"field": "b",
"type": "nominal",
"sort": null,
"axis": {
"ticks": false,
"domain": false,
"title": null
}
},
"size": {
"field": "b",
"type": "quantitative",
"scale": {
"type": "quantize"
}
},
"color": {
"field": "b",
"type": "quantitative",
"scale": {
"type": "quantize",
"zero": true
},
"legend": {
"title": "Quantize"
}
}
}
},
{
"mark": "circle",
"encoding": {
"y": {
"field": "b",
"type": "nominal",
"sort": null,
"axis": {
"ticks": false,
"domain": false,
"title": null
}
},
"size": {
"field": "b",
"type": "quantitative",
"scale": {
"type": "quantile",
"range": [80, 160, 240, 320, 400]
}
},
"color": {
"field": "b",
"type": "quantitative",
"scale": {
"type": "quantile",
"scheme": "magma"
},
"legend": {
"format": "d",
"title": "Quantile"
}
}
}
},
{
"mark": "circle",
"encoding": {
"y": {
"field": "b",
"type": "nominal",
"sort": null,
"axis": {
"ticks": false,
"domain": false,
"title": null
}
},
"size": {
"field": "b",
"type": "quantitative",
"scale": {
"type": "threshold",
"domain": [30, 70],
"range": [80, 200, 320]
}
},
"color": {
"field": "b",
"type": "quantitative",
"scale": {
"type": "threshold",
"domain": [30, 70],
"scheme": "viridis"
},
"legend": {
"title": "Threshold"
}
}
}
}
],
"resolve": {
"scale": {
"color": "independent",
"size": "independent"
}
}
}
```
Problem to solve
As a technical writer, I want to be able to use a wide variety of diagrams, so I can improve my documentation. Currently, GitLab supports two diagrams libraries:
- PlantUML (server-side using an external server/container)
- Mermaid (client-side JavaScript library)
While PlantUML and Mermaid are great diagram libraries, there are quite a few other very useful open source diagram libraries:
- BlockDiag (BlockDiag, SeqDiag, ActDiag, NwDiag, PacketDiag, RackDiag)
- BPMN
- Bytefield
- Ditaa
- Erd
- GraphViz
- Nomnoml
- SvgBob
- UMLet
- Vega/Vega-Lite
- WaveDrom
- WireViz
- ...
It's worth noting that the above diagrams libraries are written in a variety of languages: Haskell, Python, JavaScript, Go, PHP, Java... some also have C bindings. No need to say that managing all the dependencies can quickly become tedious! It also means that the server needs to execute local binaries which can be a serious security threat vector. So we want to use a wide variety of diagrams but we don't want to install/manage all the dependencies.
Kroki is designed to solve this issue by providing a unified API (compatible with the PlantUML API) to render diagrams from textual descriptions. It supports a wide variety of diagram libraries and is available as a Docker image.
There's also a public instance (powered by Exoscale) available at https://kroki.io
Intended users
Technical writers but really anyone that writes good documentation!
User experience goal
While writing documentation in plain text using Markdown or AsciiDoc, it becomes increasingly popular to use a textual definition for diagrams. Using a textual definition means that I can edit a diagram using any text editor. Another benefit is that I can use all the nice features that Git provides on my diagrams: merge, diff, log...
In this context, I expect GitLab to render the diagrams that I wrote in plain text in my documentation.
Proposal
Delegate the processing/rendering of diagrams to Kroki similar to what we are already doing for PlantUML. When a textual definition is found in a Markdown or AsciiDoc document, extract the content and send it to the Kroki server:
```plantuml
Bob->Alice : hello
Alice -> Bob : hi
```
In the example above, we will extract the following content and send it to Kroki:
Bob->Alice : hello
Alice -> Bob : hi
Kroki will generate the following image:
https://kroki.io/plantuml/png/U9npoa_IjNFCoKnELR1Io4ZDoSddWl1qxHISyfD0WfbS0Dbe2kO0
When using GET
requests, the diagram is encoded in the URL using a deflate + base64 algorithm.
Please note that it's also possible to use a POST
request.
In "Admin Area > General", a new settings section will allow to:
- configure the Kroki server URL
- enable/disable this feature
Further details
Here's a few example using the public instance of Kroki:
digraph finite_state_machine {
rankdir=LR;
size="8,5"
node [shape = doublecircle]; LR_0 LR_3 LR_4 LR_8;
node [shape = circle];
LR_0 -> LR_2 [ label = "SS(B)" ];
LR_0 -> LR_1 [ label = "SS(S)" ];
LR_1 -> LR_3 [ label = "S($end)" ];
LR_2 -> LR_6 [ label = "SS(b)" ];
LR_2 -> LR_5 [ label = "SS(a)" ];
LR_2 -> LR_4 [ label = "S(A)" ];
LR_5 -> LR_7 [ label = "S(b)" ];
LR_5 -> LR_5 [ label = "S(a)" ];
LR_6 -> LR_6 [ label = "S(b)" ];
LR_6 -> LR_5 [ label = "S(a)" ];
LR_7 -> LR_8 [ label = "S(b)" ];
LR_7 -> LR_5 [ label = "S(a)" ];
LR_8 -> LR_6 [ label = "S(b)" ];
LR_8 -> LR_5 [ label = "S(a)" ];
}
A C4 diagram (based on PlantUML):
@startuml
!include C4_Context.puml
title System Context diagram for Internet Banking System
Person(customer, "Banking Customer", "A customer of the bank, with personal bank accounts.")
System(banking_system, "Internet Banking System", "Allows customers to check their accounts.")
System_Ext(mail_system, "E-mail system", "The internal Microsoft Exchange e-mail system.")
System_Ext(mainframe, "Mainframe Banking System", "Stores all of the core banking information.")
Rel(customer, banking_system, "Uses")
Rel_Back(customer, mail_system, "Sends e-mails to")
Rel_Neighbor(banking_system, mail_system, "Sends e-mails", "SMTP")
Rel(banking_system, mainframe, "Uses")
@enduml
It's also possible to generate Mermaid diagram server-side:
graph LR
A[Square Rect] -- Link text --> B((Circle))
A --> C(Round Rect)
B --> D{Rhombus}
C --> D
Permissions and Security
The rendering part does not require any permission but only an administrator will be able to configure the Kroki integration from the "Admin area".
Documentation
We will probably need to update the following pages to describe how to configure the Kroki integration:
Availability & Testing
If the Kroki server is unavailable, for whatever reason, we should not block the rendering of the Markdown or AsciiDoc page. So in theory, it should not affect the availability of GitLab.
Since Kroki is available as Docker containers, I guess we should be able to write end-to-end tests to make sure that everything is working as expected. We should also write unit tests.
What does success look like, and how can we measure that?
All the diagrams supported by Kroki are rendered on GitLab in both Markdown and AsciiDoc (when the Kroki integration is enabled).
What is the type of buyer?
Cannot tell but apparently two customers are interested in this feature.
In #31818 (closed), @kmcknight said:
This customer is interested in this enhancement.
and @john_long said:
Premium customer requesting this in internal ticket
Is this a cross-stage feature?
It might be, I'm not sure...
Links / references
Related issues: #31818 (closed)