Mermaid - Generation of diagrams and flowcharts from text in a similar manner as markdown

IMO ! does not help with readability or programming. In theory, it could help to avoid collisions between language name & extension name, but i don’t know real world examples of that.



looks more natural than


The last looks like pushing users think like programmers :slight_smile:

If you wish block name to be !mermaid, you can do it right now, without spec change.

You are right. inline markup has no such simple principle to extend, as blocks. But AFAIK, at current moment only math equations are a real pain.

I’d propose:

  • Create a list of demanded inline extensions (except math). If those are rare, inline bbcode would be not too horrible.
  • Land ASAP math block/inline syntax (as separate well known problem)




vs B:


Looks like the consensus is just to stick with A (without the !). Will ensure that GitHub aligns with that as we introduce mermaidjs support.

I was thinking that the !language approach helps differentiate between block rendering/execution vs straight syntax highlighting and would also have the advantage of not adjusting any existing examples of folks inlining mermaid code examples, but folks today don’t do !mermaid for those examples, they do javascript. Similarly even things like inline SVG would be xml in syntax highlighting terms.

Let’s kick off a separate thread for math?


I agree it is kind odd to be forced to do:

graph TD;

graph TD;

That said, I get @vitaly’s argument here that we would be hurting readability for an edge case here.

Teaching people about something like mermaid-hl etc. when they need to apply highlighting to mermaid syntax is probably easier than teaching people about a new ! mark that would be required.

What about attributes? I am not sure we are aligned as an industry, but I think maybe GitHub should support something like this: (there is a forest theme here:

```mermaid theme=forest

We have theoretical support for that scheme at Discourse now, just need to implement the component.

1 Like

Under CommonMark this would display the source code of a Mermaid diagram if no extensions are applied. I do not think it should render the output of that code as this behaviour would be inconsistent from the behaviour of other code blocks with syntax highlighting. If the behaviour is inconsistent between different types of code blocks it doesn’t follow the principle of least surprise.

CommonMark renders to an HTML <code> element. The HTML Standard’s definition is “The code element represents a fragment of computer code.”

If we need to render the output of source code with a CommonMark document, perhaps it would be better to go with a dedicated syntax?


I have no personal preference about attrs format, and dont’ know reasons why something should be prefered/avoided.

I this case, following this logic, we will need new syntax for EVERY new block renderer. That’s overkill.

May be, i could agree, using fenced syntax to wrap things with nested md markup like quotes may be unusual, but i see no problem with code-like blocks, as mermaid.

Fallback of mermaid to code text block when no extension installed looks natural, IMO.

Also, spec (markdown) is for humans, not humans for spec. We should not push users follow blind with abstract rules, if result does not looks “natural”.

Let’s be realistic - doing nothing will cause waste of several years more. I’d be happy if process of math markup stabilization can move forward.


One more possibility - tag name can be more descriptive:


I’m not sure how nice and good is that. Just sharing idea.

1 Like

Yes it’s too far late to dictate a rule that says a fenced code block without some new signifier must only render as source. And adding modifiers to the first info string token such as !mermaid will break too many things as well.

The simplest most backward compatible solution would be to establish a standard around an optional second token of the info string that, if used, makes explicit whether the code block should be rendered as source code or “executed”. It could work like this:

  1. an = second token is an explicit declaration that the content should be rendered literally, as source code.

    ``` mermaid =
    show the mermaid diagram source code here, 
    perhaps with syntax highlighting
  2. a ( or () second token is an explicit declaration that the content should be “executed” (interpreted, rendered or otherwise processed) if possible.

    ``` mermaid ()
    render the diagram described here
    ``` markdown ()
    render the markdown source here
  3. If neither of the above tokens occurs in the second position, you get todays behavior, thus backward compatibility.

    ``` mermaid theme:dark
    whatever happens today for the above info string

    :triangular_flag_on_post: The above form also serves as the “user friendly” form, meaning that, for the given content type named by the first token, the most natural thing should happen. For Mermaid, what most users expect is that a diagram is rendered.

  4. The remainder of the info string is passed thru to the syntax highlighter or extension determined by the first token, i.e. with the = or ( and ) removed. Calls to existing libraries will continue to work without changes.

    ``` mermaid ( width:300px height:300px )
    invoke the diagram renderer with the
    following args:
       width:300px height:300px
    ``` javascript = numberedLines:true
    configure the syntax highlighter with:

backward compatibility

The only case where backward compatibility might be lost is when all of the following are true:

  • the renderer doesn’t know about the above tokens and does not remove them from the info string before passing it to the extension or syntax highlighter
  • that extension looks beyond the first token
  • and has brittle expectations for the second token (it isn’t designed to skip unknown tokens in the info string) and fails hard

I think this will be rather rare and mostly limited to power users, who will figure it out and update their software or demand that it gets updated.

The other proposals mod the first token. They won’t degrade gracefully.

1 Like

Let me summarize “problem”.

  1. It’s not specific to mermaid, it’s about extending fenced-like markup for blocks, to land new renderers.
  2. Currently, spec says fenced blocks are for code only. But IMO this approach has bigger potential than initially expected.
    • I would not use alternate guards (::: and so on). IMO “```” could be preferable (subject to discuss).
  3. There are two main directions, where to extend fenced blocks:
    a) Self-sufficient isolated content with alternate renderers (diagrams, math and so on)
    b) Blocks with nested markdown content (quotes, asides, notes…)
  4. It’s not mandatory, but would be nice to have recommendation about fenced params format.
  5. IMO, the most influencing parties for CM promotion are Discourse & Gihtub.
    • From my past experience, guys from Discource use markdown-it, and are very responsive. No problems at this side.
    • Communication with Github is not clear. They publish own spec (CM + addons), but i don’t know contact, who can say explicit their plans and intents about future [syntax] extensions. It would be nice if we could move forward in sync.
  6. IMO, extending fenced blocks for isolated content (see [3. a]) is not difficult and does not require too much time to collect & balance opinions. But for “solid” result, feedback from Github is mandatory (see [5]). I’d like to know exactly their opinion, if possible, before start. Of cause, we could do everything with Discource only, but that’s not good for CM spec in long term. I understand importance of unified spec, and would like to avoid any possibilities of future splits.

Could you clarify what breakage do you mean?

IMO, the only possible breakage is collision with language name for highlight, but i don’t know any examples from real world. In worst case, this can be solved by human-friendly tag name & recommendation how to create those.

For example:

  • draw-mermaid
  • `draw-<anything_you_wish>

That similar to !, but more clear for human & still easy to type.

Alternative is to just use mermade and add mermade-code for crazy case, if anyone really wish to show source with highlight.

1 Like

I mean there is already much extant content that expects the following to result in rendered mermaid diagrams:

diagram code

All I’m saying is that it’s too late to dictate that the above should always be rendered as source code.

How do you like my updated syntax for execution (mermaid ())?


I clarified the sentence you quoted.

1 Like

Ah, no problem then. IMO, fenced blocks have bigger potential, than initially expected and declared in spec. It should not be a principal problem to clarify.

But as i said, we should unblock syntax extension process from main spec. To be able add new things in parallel, but still with reasonable guarantees of compatibility. And that requires more active participation of Github. At least, with “official” confirmation of acceptance.

Probably, @martinwoodward could give some light about what we could expect.


In the case of Mermaid, there are two primary ways of viewing the block: as source or as the rendered output.

In practice if there are differences with how the block is rendered in different implementations, that rendering is not going to be portable. This could change the meaning of the document between implementations.

In the case of a Mermaid diagram, for implementations that only render the output, it will become impossible for others to extend/change the diagram without access to the source Markdown file (or rewriting the diagram). This may not have been the intent of the original author, for example if they intended to demonstrate how to write the source Mermaid syntax to the reader.

So that’s why I think we need to a seperate, explicit syntax to differentiate between the two conceptually seperate approaches to displaying Mermaid. That could be extending the fenced code block with a flag or a new syntax.

1 Like

IMO, when we speak about usage, every use case is not just presentation, but pair of [presentation, usage frequency]. That help to understand the real needs, because rare case should not “poison” major cases.

Let’s consider variants:

  • !mermaid + mermaid
  • draw:mermaid + mermaid
  • mermaid + mermaid_src

All have 2 labels (one for diagram, one for source).

  • first is difficult to understand.
  • second - readable, but may be verbose
  • last reflects usage frequency

I’m still not sure, what is better, 2 or 3, but i don’t like 1.

1 Like

You forgot my proposal :wink:

Proposals: Syntax and Semantics

explicit “show code” semantics explicit “execute code” semantics non-explicit, do what is usually expected / most natural
A mermaid !mermaid
B mermaid draw:mermaid
C mermaid_src mermaid
D mermaid = mermaid () or
mermaid ()
  • A: not bad, but breaks existing things, and “rare case should not “poison” major cases”

  • B: readable, but uses English, and same problems as A

  • C: reflects usage frequency, but then some users will naturally start using markdown_src and even javascript_src, so those should be supported. Also, for those things like javascript and markdown that by default are “show code”, how do you say “execute code”? Will we then add markdown_draw? If we do, we’ve ended up doing D, but not as nicely.

  • D: semantics of non-explicit form reflects usage frequency. Author can always choose to be explicit. Is consistent and logical (semantic explicitness in both cases is syntactically explicit). Does not use English. Tokens make sense. Uses second token rather than modding the first, so more backward compatible, degrades gracefully in vast majority of cases.

1 Like


  • D is more close to programming language.
  • explicit is preferable in most of cases.

Also, if someone has a lot of documents with “old” notation of anything, those can be mass-updated with some convertor tool.


Why not reuse existing syntax:

    ![alt text](
    "optional title")

which could be understood as embedding an image from an inline URL.

It goes against Markdown’s philosophy.

It’s unnecessarily complex, wrapping a complex structure in an even more complex structure, one that even Gruber regrets.


I’m a bit late to the party here: I had thought this just had to do with mermaid, which I don’t really care about, but it actually has implications far beyond that, so I do have something to say.

I think it’s always very useful to try to keep in mind prior art and not reinvent the wheel in 17 different ways. Pandoc and a number of other implementations have long supported attributes in braces: e.g.,

``` {.mermaid theme=forest}

And no, pandoc didn’t invent this syntax; it was already prior art more than a decade ago (e.g. from PHP Markdown Extra). A bare word is allowed when it’s just a class and there are no other attributes:

``` mermaid

The braces make it extremely clear that this material is not part of the text, but more like metadata. They also help reduce the ambiguities between fenced code and hard-wrapped inline code. After all, inline code is allowed to start with three backticks, and might contain text like mermaid theme=forest.


Prior art is very important for initial investigation. But that’s not the only criteria to check. The second criteria is convenience. And, important factor is usage frequiency. Also, PHP Markdown extra is not defacto standard. So, it can be refered as prior art, but not as “trusted authority”.

The most frequent use cases - blocks. IMO {.mermaid theme=forest} is overcomplicated there (braces, dot). IMO this looks like reinventing html.

For blocks, backtics ``` signal about metadata very well. “unneeded” braces enforce this too mush an looks like programming or something alien

I think, this is important wish at start. Ideally, we like to have this in the end. But inlines are used much more rare than blocks. And making blocks “ugly” in favor of rare feature may be not optimal.

I use standard approach, when problem has no good universal solution at start - split to parts, try to resolve each & join back. Then iterate again and again, until satisfied.

IMO your arguments do not take into account “usage frequency” & “use case coverage”. Every rule has eхclusions, but if we consider exclusions without appropriate weight, that’s a direct way to destroy any logic (or get overcomplicated result).

1 Like