Skip to content

Instantly share code, notes, and snippets.

@Moulick
Forked from plamentotev/diagrams.adoc
Created June 24, 2024 10:31
Show Gist options
  • Save Moulick/1f2f212f6998cbbd293a7a06489ec0e0 to your computer and use it in GitHub Desktop.
Save Moulick/1f2f212f6998cbbd293a7a06489ec0e0 to your computer and use it in GitHub Desktop.

Hello, Diagrams!

GitHub recently added support for including Mermaid diagrams in Markdown files. The good news is that it works for AsciiDoc files as well. Here is an example:

sequenceDiagram
    participant Alice
    participant Bob
    Alice->>Bob: Hello Bob, how are you?
    Bob-->>Alice: Great!
Loading

The catch? The way it works for AsciiDoc is similar to how it works for Markdown. Here is the source code for the above diagram:

[source,mermaid]
....
sequenceDiagram
    participant Alice
    participant Bob
    Alice->>Bob: Hello Bob, how are you?
    Bob-->>Alice: Great!
....

When a source code block marked with mermaid is encountered, GitHub generates an iframe that takes the raw Mermaid code and turns it into diagram using Mermaid.js. This approach is common workaround for the lack of custom blocks in Makrdown. The correct way to add diagram in AsciiDoc is to use custom diagram block, in this case [mermaid]:

[mermaid]
....
sequenceDiagram
    participant Alice
    participant Bob
    Alice->>Bob: Hello Bob, how are you?
    Bob-->>Alice: Great!
....

Using code block to display Mermaid.js diagrams works only in GitHub and would be displayed as source code by AsciiDoc tools such as Asciidoctor. Using mermaid block works with Asciidoctor, given Asciidoctor Diagram extension is enabled, but not in GitHub. This means that the same file would be displayed differently in GitHub and in HTML file generated by Asciidoctor. This is not an issue if the file is intended to be rendered only in GitHub, e.g. Wiki pages. But what if we want to generate HTML documentation from the AsciiDoc files and in the same time to get the diagrams rendered in GitHub?

Conditional processing

Thanks to @umutsahin for suggesting this approach. Conditional preprocessor directives allow content to be included only if given attribute is set. For example:

ifdef::env-github[]
[source,mermaid]
endif::[]

would add [source,mermaid] if the env-github is set, which is the case when the document is rendered on GitHub. The above could be shortened to ifdef::env-github[[source,mermaid]]. The following code would properly display diagram when the document is rendered both on GitHub and using Asciidoctor.

[mermaid]
ifdef::env-github[[source,mermaid]]
....
sequenceDiagram
    participant Alice
    participant Bob
    Alice->>Bob: Hello Bob, how are you?
    Bob-->>Alice: Great!
....

Custom preprocessor

Another solution is to use custom preprocessor. Here is an example using Asciidoctor Gradle plugin:

asciidoctorj {
    modules {
       diagram.use()
       diagram.version '2.2.1'
    }

    docExtensions {
        preprocessor {
            document, reader ->
            List<String> lines = reader.readLines();
            List<String> newLines = new ArrayList<String>();
            for (String line: lines) {
                if("[source,mermaid]".equals(line)) {
                    line = "[mermaid]"
                }
                newLines.add(line)
            }
            reader.restoreLines(newLines)
        }
    }
}

It would replace [source,mermaid] with [mermaid]. This way the same AsciiDoc file would look the same both in GitHub and in the generated HTML file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment