Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: upgrade to latest version of mermaid to add new diagrams #1252

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

loopingz
Copy link
Contributor

@loopingz loopingz commented Jul 1, 2021

I just updated the mermaid version to 8.11.0 to allow new type of diagrams like erDiagram

We might want to create a github actions to automate such updates

@hraftery
Copy link

hraftery commented Nov 16, 2022

I just did similar for 9.2.2 to support flowchart LR. Using the same method as in the original commit works. I found the updated mermaid.min.js after running npm install mermaid and looking in node_modules/mermaid/dist/.

However, arrows do not appear and there are other stylistic oddities. See before and after results for demo.md below:

Screenshot 2022-11-16 at 1 04 15 pm

Screenshot 2022-11-16 at 1 17 10 pm

In investigating, I found two clues:

  1. The mermaid.forest.css file is no longer used. Looks like styles are now embedded in the .min.js file. Indeed, setting the theme parameter in the .init.js file takes effect, so styles are working. I set it to "forest" to take the "after" screenshot above. Update: I see now this has already been noted but not merged in Remove "forest.css" in Mermaid #1156.
  2. Obsidian seems to be having similar issues, which they've traced to a bug in mermaid where div ids are not unique. There is work in progress to fix this, but it is not merged yet.

But I'm not sure if I fully understand the issue.

@hraftery
Copy link

hraftery commented Nov 16, 2022

Yeah I think that unique id issue is a red herring. After a bit more investigation I found that the PDF export is also missing the arrowheads, but that the HTML export shows them... except in Safari!

There's various reports of this over time. Some indicate arrowMarkerAbsolute: true fixes it but it made no difference for me. That appears to be the same unique id red herring. Then there's an awfully mysterious "I fixed a specific instance - it was a bug" comment that still leaves the cause unknown.

Armed with this vague data, I studied the DOM in both Safari and Opera. It's identical in both, but for some reason Safari does not see or use the marker definitions that define the arrowheads. After comparing with the Mermaid Live Editor (which does work) and playing with a bunch of things, I found this change restored the arrowheads in Safari:

Original:

<svg>
  <g>
    <marker ... id="flowchart-pointEnd"><path ...></path></marker>
    <marker ... id="flowchart-pointStart"><path ...></path></marker>
    ...
    <g class="root">
      <g class="clusters"></g>
      <g class="edgePaths">
        <path marker-end="url(#flowchart-pointEnd)" ...></path>
        <path marker-end="url(#flowchart-pointEnd)" ...></path>
        ...

Working:

<svg>
  <g>
    <defs>
      <marker ... id="flowchart-pointEnd"><path ...></path></marker>
      <marker ... id="flowchart-pointStart"><path ...></path></marker>
      ...
    </defs>
    <g class="root">
      <g class="clusters"></g>
      <g class="edgePaths">
        <path marker-end="url(#flowchart-pointEnd)" ...></path>
        <path marker-end="url(#flowchart-pointEnd)" ...></path>
        ...

In other words, simply wrapping the marker definitions in defs tags was enough to get them to appear.

So I guess it's probably up to mermaid to fix this, since that's what generates the svg tag. And I suppose there's no simple workaround in the meantime, because MacDown uses a WebKit or something Safari related to render the preview?

But if anyone has a better suggestion I'd love to hear it.

@hraftery
Copy link

hraftery commented Nov 16, 2022

Eh, FWIW, the existence of the defs tags was another red herring - just the act of forcing Safari to re-parse the HTML is enough, which fiddling with the DOM with the developer tools was sufficient to do. I fixed the defs tag by modifying the source to add all markers to a single defs tag, but the issue persisted. On the other hand, if I export the rendered HTML and reload it in Safari, it works regardless of the existence of the defs tag! So it's something to do with the dynamic generation of the SVG, and things are getting messy now. There's been a long history of overzealous security restrictions in Safari and Chrome that have prevented url() references within SVGs from working, but I still can't find the trigger here.

@hraftery
Copy link

hraftery commented Nov 22, 2022

OMG, I nearly gave up on this so many times. Every potential cause ended up being another red herring. It seems markers have a fragile relationship with svg in browsers.

So I finally gave up and went to create a MRE to leave for posterity, and in crafting exactly the right MRE... accidentally stumbled on the cause!

It turns out that the arrows appear in all cases, except in recent mermaid versions when the syntax highlighting script is present. Somehow this clashing with the mermaid script, and despite the resulting DOM looking fine, the arrows only appear in Chrome/Opera, but not in MacDown/Safari.

Here's a JSFiddle demonstrating this, with the syntax highlighting script (copied out of a HTML export from MacDown). It pulls mermaid 9.2.2 from CDN, but otherwise attempts to recreate what MacDown does manually. If you run the fiddle on Safari, and uncomment the script tag from the HTML section, the arrows disappear!

So I suspect if syntax highlighting could be disabled blocks where mermaid is in effect, we'd be golden. But I haven't investigated yet.

<SNIP beautified script because I realise now it's Prism>

@hraftery
Copy link

That does it. The syntax highlighting script is of course, Prism, and it turns out this co-existence issue with mermaid is known. By following that issue, I came across the Filter highlightAll plugin. Sure enough, if I replace the contents of the <script> tag with the latest minified Prism core, and add the "Filter highlightAll" plugin code, then adding data-reject-selector=".language-mermaid" to the <script> tag brings back the arrows!

I'm not sure how to apply this fix to MacDown itself...

@hraftery
Copy link

Ah yes, there it is. Alas the built-in template for the script tag doesn't allow insertion of an attribute without a re-build, not to mention the fact that the list of Prism plugins is fixed. But... it does just pull in the Prism code from file, so could I embed the fix in the file itself?

Yes!!

I replaced the contents of MacDown.app/Contents/Resources/Prism/components/prism-core.min.js with the concatenation of:

  • PrismJs 1.29.0 core, minified
  • The Filter HighlightAll plugin, minified.
  • The literal function call: Prism.plugins.filterHighlightAll.reject.addSelector('.language-mermaid');

Refreshed the document in MacDown, and voila, arrows everywhere!

Screenshot 2022-11-22 at 8 05 14 pm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants