Mermaid-Chart / vscode-mermaid-preview

Previews Mermaid diagrams
MIT License
142 stars 15 forks source link

Add support for mermaid diagrams embedded in sphinx docs #52

Closed leorochael closed 6 years ago

leorochael commented 6 years ago

sphinxcontrib-mermaid is a plugin for Sphinx docs which uses ReStructuredText (ReST) syntax.

The mermaid identified code block syntax for ReST (equivalent of the fenced and identified code blocks in Markdown) is:

.. mermaid::

   sequenceDiagram
      participant Alice
      participant Bob
      Alice->John: Hello John, how are you?
      loop Healthcheck
          John->John: Fight against hypochondria
      end
      Note right of John: Rational thoughts <br/>prevail...
      John-->Alice: Great!
      John->Bob: How about you?
      Bob-->John: Jolly good!

That is: an indented block of text preceded by an unidented .. mermaid:: code block tag.

It would be nice if this format could be detected for preview, as an aide for writing Sphinx docs with mermaid graphs in VS.Code

vstirbu commented 6 years ago

This feature is pretty much related to #48

The start tag for sphinx is .. mermaid::. What is the end tag?

leorochael commented 6 years ago

The start tag for sphinx is .. mermaid::. What is the end tag?

There is not an "end tag" per se. .. mermaid:: is a ReStructuredText directive:

http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#directives

The block of text controlled by the directive starts with the first indented line after the (non-indented) line containing the directive, and ends when the first non-indented line is found. It includes all blank (non-indented) lines in between.

vstirbu commented 6 years ago

can you check with some common variations if the diagram is captured correctly https://regex101.com/r/iAmzA9/5?

I'll need the examples for the test fixtures. thanks!

leorochael commented 6 years ago

It's a good start, but the regex doesn't stop on the first non-indented text if there are further non-indented texts.

It also fails if there are two diagrams one after another.

A ReStructuredText sample with some graphs would be:


A diagram:

.. mermaid::
  sequenceDiagram
      participant Alice
      participant Bob
      Alice->John: Hello John, how are you?
      loop Healthcheck
          John->John: Fight against hypochondria
      end
      Note right of John: Rational thoughts <br/>prevail...
      John-->Alice: Great!
      John->Bob: How about you?

      Bob-->John: Jolly good!

A random paragraph.

A diagram with parameters (the parameters can't be considered as part of the mermaid markup):

.. mermaid::
    :alt: The image alternate text for HTML output
    :align: center
    :caption: Caption Text underneath the generated image

    sequenceDiagram
      participant Alice
      participant Bob
      Alice->John: Hello John, how are you?
      loop Healthcheck
          John->John: Fight against hypochondria
      end
      Note right of John: Rational thoughts <br/>prevail...
      John-->Alice: Great!
      John->Bob: How about you?

      Bob-->John: Jolly good!

A diagram on an external file. You might decide not to match it, as the file itself can be previewed easily:

.. mermaid:: graphs/mygraph.mmd

Another diagram on an external file. Now with parameters:

.. mermaid:: graphs/mygraph.mmd
    :alt: The image alternate text for HTML output
    :align: center
    :caption: Caption Text underneath the generated image

Two diagrams one after the other. Should be matched separately. The file ends with no paragraph after the last diagram:

.. mermaid::
  sequenceDiagram
      participant Alice
      participant Bob
      Alice->John: Hello John, how are you?
      loop Healthcheck
          John->John: Fight against hypochondria
      end
      Note right of John: Rational thoughts <br/>prevail...
      John-->Alice: Great!
      John->Bob: How about you?

      Bob-->John: Jolly good!

.. mermaid::
    :alt: The image alternate text for HTML output
    :align: center
    :caption: Caption Text underneath the generated image

    sequenceDiagram
      participant Alice
      participant Bob
      Alice->John: Hello John, how are you?
      loop Healthcheck
          John->John: Fight against hypochondria
      end
      Note right of John: Rational thoughts <br/>prevail...
      John-->Alice: Great!
      John->Bob: How about you?

      Bob-->John: Jolly good!
leorochael commented 6 years ago

I've created another regex, with capturing groups for the various parts of the directive structure:

https://regex101.com/r/tpvjm1/1

The 1st matching group would be the filename of the external graph, if present. You can ignore it if you don't want to do previews of external files.

The 2nd matching group, if present, contains rendering options for the final html output, which could be ignored in a preview.

The 3rd matching group, if present and not only whitespace, is the text of the diagram itself.

It's illegal for the directive to have both the 1st and the (non-whitespace-only) 3rd group.

vstirbu commented 6 years ago

Ok, thanks for detailed explanation. Now is clearer how it works.

Sphinx documents (and the ReST directive) have more options than the alternatives supported by the plugin to embed mermaid diagram. For this reason, I think that only the third capturing group in your regex is important. Can you update the regex to have only one capturing group for the mermaid diagram itself?

We'll stick with this option for the moment (as previewing external files can be achieved by previewing the file itself).

leorochael commented 6 years ago

Here is a new revision of the regex:

https://regex101.com/r/tpvjm1/3

It only leaves one capturing group for the diagram text, fixes an issue where the parameters would take the place of the diagram capturing group if there was no diagram, and makes sure the diagram is complete even if the file ends on the last line of the diagram without a line-break.

vstirbu commented 6 years ago

The regex is not handling this case properly as the content of the nature group is undefined:

.. mermaid:: graphs/mygraph.mmd
    :alt: The image alternate text for HTML output
    :align: center
    :caption: Caption Text underneath the generated image

https://regex101.com/r/tpvjm1/5

leorochael commented 6 years ago

This example is one where we don't want to capture anything. It's for a graph definition in an external file, which we don't plan to preview, with HTML rendering options, which we don't plan to support.

So the capture group 1 returning undefined should be exactly what we want, right?

vstirbu commented 6 years ago

I would have expected to be no match (e.g. running {regex}.exec() to return null).

leorochael commented 6 years ago

What we could do then is make regex not match for the directive variant for external files version at all.

See if you like this version better:

https://regex101.com/r/tpvjm1/6

vstirbu commented 6 years ago

expect a release over the weekend...

leorochael commented 6 years ago

Thanks!

vstirbu commented 6 years ago

You've done the heavy lifting here... :)