PlantUML in Sphinx (using MyST Markdown) and GitLab
tl;dr: PlantUML in Sphinx cannot be written in a way that is compatible with both MyST Markdown and the GitLab UI preview. You need to either use reStructuredText instead of Markdown or stick with Markdown and forget about GitLab UI preview support).
Context §
I have some documentation written in Markdown, and use Sphinx to convert it into HTML. By default, Sphinx uses reStructuredText, but I have used MyST to get Markdown support.
With this existing setup, my goal was to do the following:
- In Markdown, add diagrams within code fences using PlantUML, which are then rendered into the HTML when Sphinx executes.
- Additionally, be able to view the diagrams in GitHub preview.
Long story short, as far as I can tell, this isn’t currently possible. The crux of the issue is:
- In Markdown files (
*.md
), the only code fence that GitLab will render as PlantUML isplantuml
. - In MyST, the PlantUML is rendered using the
{uml}
directive1 (which is effectively a code fence).
Example of issue §
Works in GitLab Markdown (but not MyST) §
The following will render in GitLab Markdown:
But under Sphinx with MyST Markdown will print WARNING: Pygments lexer name 'plantuml' is not known
at build time.
Works in MyST Markdown (but not GitLab) §
The following will render in Sphinx with MyST Markdown:
But will show as plain-text in the GitLab UI.
Setup §
First, here are the steps for adding PlantUML support to Sphinx, using MyST Markdown.
Assumptions §
- Sphinx is already set up using MyST for Markdown support.
- Platform is Windows 10.
Install Java §
Chances are you already have Java installed. But if not, PlantUML needs Java for it to run.
Install PlantUML §
Download the PlantUML compiled jar file, and save it to a safe location. I placed it at C:\plantuml\plantuml-1.2023.12.jar
.
Install sphinxcontrib-plantuml
§
The following Python packages is required to add PlantUML support to Sphinx:
Update your conf.py
§
To correctly configure sphinxcontrib-plantuml
, make the following changes:
- Add
sphinxcontrib.plantuml
to the list ofextensions
inconf.py
:
- Append the following line to your
conf.py
. Update the path to match where you put the PlantUML jar file23.
Example §
Now you can include PlantUML diagrams in your MyST Markdown as follows:
Which should get rendered as:
However, the challenge is to get this working in both MyST Markdown and the GitLab UI preview. Following are three possible solutions, none of which are ideal:
- Put the diagram in a separate
*.rst
file, but use*.md
for the main document. - Just use
*.rst
for documents with diagrams (but use*.md
for other documents). - Just use
*.md
for all documents (and forget about GitLab UI preview support) (my preferred option).
Solutions §
Include diagram as reStructuredText §
MyST provides the eval-rst
directive, which allows using the reStructuredText to include
another reStructuredText file:
This means we can write the document in Markdown, and the diagrams will render in GitLab UI if you are viewing the file directly (e.g. in this case, if you had diagram.rst
open in the GitLab UI).
This workaround is not ideal, because the reader must open each diagram individually in order for it to render within the GitLab UI. By this point it is probably better to just use reStructuredText.
Pros:
- Technically, the PlantUML does get rendered in Sphinx and in the GitLab UI preview.
Cons:
- Have to put diagrams in separate files, which are reStructuredText.
- In the GitLab UI, have to open the individual files to see them rendered.
Just use reStructuredText §
With Sphinx and MyST, you can use reStructuredText and Markdown side-by-side.
This will render in both Sphinx and the GitLab UI.
Pros:
- The PlantUML does get rendered in Sphinx and the GitLab UI preview, all in one document.
Cons:
- We forgoe using Markdown.
Forget about GitLab UI support (and just use GitLab Pages) §
Alternatively, just stick with Markdown, and forget about trying to also support rendering in the GitLab UI. Assuming you are building the documentation in CI and pushing it to GitLab Pages, you can just include a link in the project’s README.md
to the GitLab Pages URL.
Pros:
- We avoid using reStructuredText, and just use Markdown.
Cons:
- We forgoe GitLab UI preview support.
Ideal Solution §
In my opinion, the ideal solution would be for GitLab to add support for rendering PlantUML written in Markdown files within the {uml}
directive (in adddition to the already supported plantuml
directive). As a precedence, GitLab already added support for rendering PlantUML in reStructuredText files within the uml::
directive, specifically for compatibility with sphinxcontrib-plantuml
:
Although you can use the
uml::
directive for compatibility withsphinxcontrib-plantuml
, GitLab supports only thecaption
option.
If GitLabs upported the {uml}
directive then it would be possible to use MyST Markdown without forgoing GitLab UI preview support.
Dead ends §
Embed diagram as reStructredText §
Following on from the earlier workaround, you might be tempted to use uml::
inside a an {eval-rst}
block, since as previous mentioned GitLab UI supports rendering the uml::
directive in reStructuredText, e.g.:
Unfortunately the uml::
block does not render in GitLab, presumably because it is embedded within the {eval-rst}
block.
Executable Books issue §
This two year old issue on the Executable Books GitHub page describes a very similar issue, but has no answer.
The
{uml}
directive is becausesphinxcontrib-plantuml
uses the.. uml::
directive, which in MyST parlance becomes a code fence with curly braces around the directive name. ↩︎This issue was useful in figuring out how to get the
plantuml = ...
line to work correctly under Windows. ↩︎If the
plantuml = ...
line is omitted, or if the command fails for any reason, at Sphinx build time you will getWARNING: plantuml command 'plantuml' cannot be run
. This can be a little opaque to debug. ↩︎