MyST-Parser icon indicating copy to clipboard operation
MyST-Parser copied to clipboard

support mermaid

Open LuisBL opened this issue 4 years ago • 15 comments

Describe the solution you'd like

support mermaid

Describe alternatives you've considered

The conf.py I used to make work mermaid with recommonmark:

$ tail conf.py
extensions = [ 'recommonmark', 'sphinxcontrib.mermaid']
from recommonmark.transform import AutoStructify
def setup(app):
    app.add_transform(AutoStructify)
$

This mermaid is rendered

```mermaid::

  graph LR
    a --> b
\```

Note that the above need to have a new line after mermaid:: and graph need to start with a space.

LuisBL avatar May 03 '21 07:05 LuisBL

Thanks for opening your first issue here! Engagement like this is essential for open source projects! :hugs:
If you haven't done so already, check out EBP's Code of Conduct. Also, please try to follow the issue template as it helps other community members to contribute more effectively.
If your issue is a feature request, others may react to it, to raise its prominence (see Feature Voting).
Welcome to the EBP community! :tada:

welcome[bot] avatar May 03 '21 07:05 welcome[bot]

Hey @LuisBL, from https://github.com/mgaitan/sphinxcontrib-mermaid, mermaid is a directive (not a code-block) so you have use it with braces


```{mermaid}
graph LR
a --> b
```

I'm a little unclear how this would have worked in recommonmark, since that does not support directives. Are you sure you didn't use it before inside an eval-rst?

chrisjsewell avatar May 03 '21 08:05 chrisjsewell

Hey @LuisBL, from https://github.com/mgaitan/sphinxcontrib-mermaid, mermaid is a directive (not a code-block) so you have use it with braces


```{mermaid}
graph LR
a --> b

I'm a little unclear how this would have worked in recommonmark, since that does not support directives. Are you sure you didn't use it before inside an `eval-rst`?

Sorry my issue was not clear/compleat, updated.

LuisBL avatar May 03 '21 19:05 LuisBL

Sorry my issue was not clear/compleat, updated.

Cheers, but what happens now if you add?

```{mermaid}
graph LR
  a --> b
```

(with extensions = [ 'myst_parser', 'sphinxcontrib.mermaid'])

chrisjsewell avatar May 03 '21 19:05 chrisjsewell

with

```{mermaid}
graph LR
  a --> b
```

It render perfectly well and there is no need to add a def setup(app): to conf.py

so I can close this and open an issue to improve the documentation with the above exemple.

LuisBL avatar May 03 '21 19:05 LuisBL

so I can close this and open an issue to improve the documentation with the above exemple.

brilliant 😄

chrisjsewell avatar May 03 '21 19:05 chrisjsewell

Note: The

```mermaid::

  graph LR
    a --> b
```

syntax has the advantage that is render with the gitlab.com markdown renderer, that is not the case with the MyST-Parser syntax

```{mermaid}
graph LR
  a --> b
```

LuisBL avatar May 03 '21 19:05 LuisBL

FYI, If you want to show nested code blocks you can just use more surrounding `

````
```{mermaid}
graph LR
  a --> b
```
````

chrisjsewell avatar May 03 '21 19:05 chrisjsewell

syntax has the advantage that is render with the gitlab.com markdown renderer

You can always use:

```{eval-rst}
.. mermaid::

   graph LR
     a --> b
```

that would show up as:

.. mermaid::

   graph LR
     a --> b

chrisjsewell avatar May 03 '21 19:05 chrisjsewell

great I will add it to the documentation too.

BTW: your https://aiida.readthedocs.io/projects/aiida-core/en/latest/intro/tutorial.html documentation is awesome I guess it's your own sphinx theme ?

LuisBL avatar May 03 '21 20:05 LuisBL

oh thanks! No its just https://pydata-sphinx-theme.readthedocs.io

chrisjsewell avatar May 03 '21 20:05 chrisjsewell

On my gitlab the below:

```{eval-rst}
.. mermaid::

   graph LR
     a --> b
```

```mermaid::

  graph LR
     a --> b
```

produce this: Sélection_683

so no real rendenring on gitlab using {mermaid} ;( neither on github

So we can conclude (I think) that

```mermaid::

  graph LR
     a --> b
```

render both on sphinx and on gitlab/github with the following conf.py:

$ tail conf.py
extensions = [ 'recommonmark', 'sphinxcontrib.mermaid']
from recommonmark.transform import AutoStructify
def setup(app):
    app.add_transform(AutoStructify)
$

LuisBL avatar May 03 '21 20:05 LuisBL

Oh so you are talking about this Gitlab only feature: https://docs.gitlab.com/ee/user/markdown.html#mermaid? This won't work on Github (unless perhaps you have a browser extension https://github.com/BackMarket/github-mermaid-extension), and kind of works more by luck, than by design on Gitlab (it seems to be ok ignoring the :: at the end)

chrisjsewell avatar May 03 '21 21:05 chrisjsewell

Oh so you are talking about this Gitlab only feature: https://docs.gitlab.com/ee/user/markdown.html#mermaid? This won't work on Github (unless perhaps you have a browser extension https://github.com/BackMarket/github-mermaid-extension), and kind of works more by luck, than by design on Gitlab (it seems to be ok ignoring the :: at the end)

It works now on GitHub as well: https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/

Here an example:

```mermaid
graph TD;
  A-->B;
  A-->C;
  B-->D;
  C-->D;
 ```

It produces:

  graph TD;
      A-->B;
      A-->C;
      B-->D;
      C-->D;

ajcerejeira avatar Mar 14 '22 11:03 ajcerejeira

Just to add a bit of context which may be helpful. Mermaid itself already has directives that are relevant for rendering a figure. Those are already passed through to e.g. mmdc and sphinxcontrib-mermaid, for example. sphinxcontrib-mermaid supports a few extra parameters for it's directive.

I'd like to request that mermaid-tagged fenced code blocks, specifically, and possibly others down the road, be treated as directives instead of languages.

You could do so here, by detecting "special" languages that should be interpreted as directives instead of languages to highlight.

https://github.com/executablebooks/MyST-Parser/blob/310580730652f3b84da3868f2a886ef9fc743959/myst_parser/mdit_to_docutils/base.py#L596-L603

A hacky version I did was able to deal with this:

 info = token.info.strip() if token.info else token.info 
 language = info.split()[0] if info else "" 
 if language in ["mermaid", ...]:
     # update language to mimic directive
     language = "{%s}" % language
     # rewrite token.token.info for render_directive
     token.token.info = language + (" %s" + ' '.join(info.split()[1:]) if info.split()[1:] else "")
  
 if (not self.md_config.commonmark_only) and (not self.md_config.gfm_only): 
     if language == "{eval-rst}": 
         return self.render_restructuredtext(token) 
     if language.startswith("{") and language.endswith("}"): 
         return self.render_directive(token) 

brianv0 avatar Sep 07 '22 17:09 brianv0

+1 to what @brianv0 mentions and the example! Having this capability would be amazing. Is there anything preventing this from being added as a change?

d33bs avatar Feb 20 '23 21:02 d33bs

I think its a slippery slop, starting to special case treating lexer names as directives in core; what, for example, if you actually want to just syntax highlight the raw mermaid text!?

but... with https://myst-parser.readthedocs.io/en/latest/syntax/optional.html#attributes, I think there is now a middle ground.

Just in general, for any code fence, you could allow for something like:


{directive=name}
```lexer
content
```

This allows for "native" rendering of the lexer name in places like Github, but then gives MyST-Parser the additional information, to know to treat this as a directive.

The other option two options that can be used instead or with this are:

  1. A global option with a user set list of lexer names to treat as directives
  2. the sphinx-mermaid extension could simply walk through all code_block nodes (in a sphinx transform) and find all the ones with the mermaid lexer name, do the same conversion it does in the directive

chrisjsewell avatar Feb 20 '23 22:02 chrisjsewell

FYI, I would strongly suggest you guys also help https://github.com/mgaitan/sphinxcontrib-mermaid/issues/109 get fixed. For now I think I will take this extension out of the MyST parser documentation, because its killing all the page loads 😒

image

chrisjsewell avatar Feb 21 '23 12:02 chrisjsewell

While I don't personally agree this is a slippery slope, as it's easy to defer to the de-facto standard of supporting what the other guys support (code fences and text representations of diagrams - mermaid but also plantuml, dot, and similar), it's obviously your decision to pick and choose what to support and that's respectable (though ironically an argument why there's no slippery slope)

This is probably a very nice middle ground, so thanks! One of my gripes with the github implementation for mermaidjs is that you can't readily control how it's displayed in any meaningful way - as an example, you'd want to add a viewport of the diagram cannot be represented in 1000 pixels width or something, and this at least offers a generic escape hatch.

It would still be nice if there was a default that could work out of the box, for people who mostly want to just write markdown that's mostly compatible with GFM/etc... but need the escape hatch of directives once in a while.

brianv0 avatar Mar 02 '23 21:03 brianv0