mermaid-js / mermaid

Generation of diagrams like flowcharts or sequence diagrams from text in a similar manner as markdown
https://mermaid.js.org
MIT License
72.83k stars 6.66k forks source link

SVG export does not work properly when the exported SVG is used outside Firefox #2102

Open jmg-duarte opened 3 years ago

jmg-duarte commented 3 years ago

Describe the bug SVG export does not work properly when the exported SVG is used outside Firefox.

To Reproduce

  1. Pick up the Code Sample
  2. Download as SVG

Expected behavior The SVG export to be just like the one on Firefox.

Screenshots The SVG renders just fine on Firefox: image

But not on Inkscape: image

Code Sample

Desktop

Additional context This bug was previously reported in https://github.com/mermaid-js/mermaid-live-editor/issues/169

amal329 commented 3 years ago

I tried to reproduce the bug and yea, it does not render as expected. But it works fine on some other online editors that I tried. Can we assume that this is an issue with Inkscape?

jmg-duarte commented 3 years ago

It can be a 50/50, maybe the exported SVG can use some "APIs" not supported by Inkscape which could be expressed in other ways?

ghtyrant commented 3 years ago

I can reproduce this as well and this blocks me from using SVG diagrams in LaTeX (because I use Inkscape to transform it to PDF). For reference, here's an example diagram:

sequenceDiagram
  autonumber

  Node->>+Server: Hello
  Server->>Server: Hello?
  Server-->>Node: Hello!
  deactivate Server

Here's the rendered result in Firefox: image

Here's what it looks like in Inkscape (dark background comes from Inkscape): image

Inkscape logs the following things:

** (org.inkscape.Inkscape:647855): WARNING **: 16:02:05.688: Ignoring unrecognized CSS property: max-width
parsing error: 1:2498:could not recognize next production
parsing error: 1:2528:while parsing rulset: current char must be a '}'
parsing error: 1:2527:while parsing declaration: next property is malformed

** (org.inkscape.Inkscape:647855): WARNING **: 16:02:05.802: Ignoring unrecognized CSS property: max-width

Image viewers (I tried eog and geeqie) fail to properly scale the SVG, resulting in 1x1 pixel size. Removing the viewBox attribute of the svg tag fixes that issue and then I can see the SVG being rendered properly, arrows and all: image

So I think this is an issue with Inkscape - I don't know about the viewBox thing though.

icecog commented 3 years ago

I just ran into this issue when trying to use Pandoc from html with the mermaid generated SVG to docx (word). Pandoc uses rsvg-convert under the hood which produces the following errors:

rsvg-convert.exe:20208): librsvg-WARNING **: CSS parsing error
(rsvg-convert.exe:20208): librsvg-WARNING **: CSS parsing error
(rsvg-convert.exe:20208): librsvg-WARNING **: CSS parsing error
(rsvg-convert.exe:20208): librsvg-WARNING **: CSS parsing error
(rsvg-convert.exe:20208): librsvg-WARNING **: CSS parsing error
(rsvg-convert.exe:20208): librsvg-WARNING **: CSS unrecoverable error
parsing error: 1:8974:could not recognize next production
parsing error: 1:8981:while parsing rulset: current char must be a '}'
parsing error: 1:8980:while parsing declaration: next property is malformed

I'm using the latest Pandoc version (pandoc-2.16.1-windows-x86_64.msi) and am generating the html from Obsidian.md (version v0.12.19), not that it should matter.

graph TD;
    A[Lots of text];
    B[Lots text];
    C{Lots text};
    A -->|one| B;
    B -->|two| C;
    C -->|three| A;

generates this SVG:

<svg id="mb6c37ce8dc45a6f0" width="203.4453125" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="403.54608154296875" viewBox="0 0 203.4453125 403.54608154296875"><style>#mb6c37ce8dc45a6f0 #mb6c37ce8dc45a6f0{color:var(--text-normal);}{font-family:var(--mermaid-font);font-size:16px;fill:var(--text-normal);}#mb6c37ce8dc45a6f0 .error-icon{fill:var(--background-primary);}#mb6c37ce8dc45a6f0 .error-text{fill:var(--text-error);stroke:var(--text-error);}#mb6c37ce8dc45a6f0 .edge-thickness-normal{stroke-width:2px;}#mb6c37ce8dc45a6f0 .edge-thickness-thick{stroke-width:3.5px;}#mb6c37ce8dc45a6f0 .edge-pattern-solid{stroke-dasharray:0;}#mb6c37ce8dc45a6f0 .edge-pattern-dashed{stroke-dasharray:3;}#mb6c37ce8dc45a6f0 .edge-pattern-dotted{stroke-dasharray:2;}#mb6c37ce8dc45a6f0 .marker{fill:var(--text-normal);stroke:var(--text-normal);}#mb6c37ce8dc45a6f0 .marker.cross{stroke:var(--text-normal);}#mb6c37ce8dc45a6f0 svg{font-family:var(--mermaid-font);font-size:16px;}#mb6c37ce8dc45a6f0 .label{font-family:var(--mermaid-font);color:var(--text-normal);}#mb6c37ce8dc45a6f0 .cluster-label text{fill:var(--text-normal);}#mb6c37ce8dc45a6f0 .cluster-label span{color:var(--text-normal);}#mb6c37ce8dc45a6f0 .label text,#mb6c37ce8dc45a6f0 span{fill:var(--text-normal);color:var(--text-normal);}#mb6c37ce8dc45a6f0 .node rect,#mb6c37ce8dc45a6f0 .node circle,#mb6c37ce8dc45a6f0 .node ellipse,#mb6c37ce8dc45a6f0 .node polygon,#mb6c37ce8dc45a6f0 .node path{fill:var(--background-primary);stroke:var(--text-muted);stroke-width:1px;}#mb6c37ce8dc45a6f0 .node .label{text-align:center;}#mb6c37ce8dc45a6f0 .node.clickable{cursor:pointer;}#mb6c37ce8dc45a6f0 .arrowheadPath{fill:undefined;}#mb6c37ce8dc45a6f0 .edgePath .path{stroke:var(--text-normal);stroke-width:2.0px;}#mb6c37ce8dc45a6f0 .flowchart-link{stroke:var(--text-normal);fill:none;}#mb6c37ce8dc45a6f0 .edgeLabel{background-color:var(--background-secondary);text-align:center;}#mb6c37ce8dc45a6f0 .edgeLabel rect{opacity:0.5;background-color:var(--background-secondary);fill:var(--background-secondary);}#mb6c37ce8dc45a6f0 .cluster rect{fill:var(--background-secondary-alt);stroke:var(--background-modifier-border);stroke-width:1px;}#mb6c37ce8dc45a6f0 .cluster text{fill:var(--text-normal);}#mb6c37ce8dc45a6f0 .cluster span{color:var(--text-normal);}#mb6c37ce8dc45a6f0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:var(--mermaid-font);font-size:12px;background:var(--background-secondary-alt);border:1px solid undefined;border-radius:2px;pointer-events:none;z-index:100;}#mb6c37ce8dc45a6f0 foreignObject{overflow:visible;}#mb6c37ce8dc45a6f0 #arrowhead,#mb6c37ce8dc45a6f0 #sequencenumber,#mb6c37ce8dc45a6f0 .cluster text,#mb6c37ce8dc45a6f0 .label text,#mb6c37ce8dc45a6f0 text,#mb6c37ce8dc45a6f0 text.actor{fill:var(--text-normal);}#mb6c37ce8dc45a6f0 line{stroke:var(--text-normal);}#mb6c37ce8dc45a6f0 g>g>circle,#mb6c37ce8dc45a6f0 g>g>path{stroke:var(--background-accent);}.label rect{display:none;}.cluster rect{stroke-width:1px;}.node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--background-secondary-alt);stroke:var(--background-modifier-border);stroke-width:1px;}.node .label{text-align:center;}.node.clickable{cursor:pointer;}.arrowheadPath{fill:var(--text-muted);}.edgePath .path{stroke:var(--text-muted);stroke-width:1.5px;}.edgeLabel{background-color:var(--background-primary);text-align:center;}.cluster rect{fill:var(--background-primary-alt);stroke:var(--background-modifier-border);}div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-size:12px;background:var(--background-secondary);border:1px solid var(--interactive-accent);border-radius:2px;pointer-events:none;z-index:100;}.actor{stroke:var(--background-modifier-border);fill:var(--background-secondary-alt);font-family:inherit!important;}text.actor{stroke:none;}.actor-line{stroke:var(--text-muted);}.messageLine0,.messageLine1{stroke-width:1.5;stroke-dasharray:'2 2';stroke:var(--text-normal);}.sequenceNumber{fill:#fff;}#crosshead path{fill:var(--text-normal)!important;stroke:var(--text-normal)!important;}.messageText{fill:var(--text-normal);stroke:none;font-family:inherit!important;}.labelBox{stroke:var(--background-modifier-border);fill:var(--background-secondary-alt);}.labelText,.loopText{fill:var(--text-normal);stroke:none;}.loopLine{stroke-width:2;stroke-dasharray:'2 2';stroke:var(--background-modifier-border);}.note{stroke:#645c10;fill:#f3edb3;}.noteText{fill:#000;stroke:none;font-size:14px;}.activation0,.activation1,.activation2{fill:var(--background-secondary) stroke:var(--text-muted);}.section{stroke:none;opacity:.2;}.section0,.section2{fill:var(--text-accent);}.section1,.section3{fill:#fff;opacity:.2;}.sectionTitle0,.sectionTitle1,.sectionTitle2,.sectionTitle3{fill:var(--text-normal);}.sectionTitle{text-anchor:start;font-size:11px;text-height:14px;}.grid .tick{stroke:var(--background-primary-alt);opacity:.8;shape-rendering:crispEdges;}.grid path{stroke-width:0;}.today{fill:none;stroke:#d42;stroke-width:2px;}.task{stroke-width:2;}.taskText{text-anchor:middle;}.taskText:not([font-size]){font-size:11px;}.taskTextOutsideRight{fill:var(--text-normal);text-anchor:start;font-size:11px;}.taskTextOutsideLeft{fill:var(--text-normal);text-anchor:end;font-size:11px;}.task.clickable,g.clickable{cursor:pointer;}.taskText.clickable,.taskTextOutsideLeft.clickable,.taskTextOutsideRight.clickable{cursor:pointer;fill:#003163!important;font-weight:700;}.taskText0,.taskText1,.taskText2,.taskText3{fill:#fff;}.task0,.task1,.task2,.task3{fill:var(--interactive-accent);stroke:var(--interactive-accent);}.taskTextOutside0,.taskTextOutside1,.taskTextOutside2,.taskTextOutside3{fill:var(--text-normal);}.active0,.active1,.active2,.active3,g.classGroup rect,g.stateGroup rect{fill:var(--background-primary-alt);stroke:var(--background-modifier-border);}g.classGroup rect,g.stateGroup rect{stroke:var(--background-modifier-border);}.activeText0,.activeText1,.activeText2,.activeText3{fill:var(--text-normal)!important;}.done0,.done1,.done2,.done3{stroke:var(--text-muted);fill:#bbb;stroke-width:2;}.doneText0,.doneText1,.doneText2,.doneText3{fill:var(--text-normal)!important;}.crit0,.crit1,.crit2,.crit3{stroke:#b1361b;fill:#d42;stroke-width:2;}.activeCrit0,.activeCrit1,.activeCrit2,.activeCrit3,.classLabel .box{stroke:#b1361b;fill:var(--background-secondary-alt);stroke-width:2;}.classLabel .box{stroke:none;stroke-width:0;opacity:.5;}.doneCrit0,.doneCrit1,.doneCrit2,.doneCrit3{stroke:#b1361b;fill:#bbb;stroke-width:2;cursor:pointer;shape-rendering:crispEdges;}.milestone{transform:rotate(45deg) scale(.8,.8);}.milestoneText{font-style:italic;}.activeCritText0,.activeCritText1,.activeCritText2,.activeCritText3,.doneCritText0,.doneCritText1,.doneCritText2,.doneCritText3{fill:var(--text-normal)!important;}.titleText{text-anchor:middle;font-size:18px;fill:var(--text-normal);}g.classGroup text{fill:var(--text-normal);stroke:none;font-size:11px;}g.classGroup text .title{font-weight:bolder;}#aggregationEnd,#aggregationStart,#compositionEnd,#compositionStart,.relation,g.classGroup line,g.stateGroup line{stroke:var(--background-modifier-border);stroke-width:1;}.classLabel .label{font-size:11px;}.relation{fill:none;}.dashed-line{stroke-dasharray:3;}#compositionEnd,#compositionStart{fill:var(--background-modifier-border);}#aggregationEnd,#aggregationStart{fill:var(--background-secondary-alt);}#dependencyEnd,#dependencyStart,#extensionEnd,#extensionStart{fill:var(--background-modifier-border);stroke:var(--background-modifier-border);stroke-width:1;}.branch-label,.commit-id,.commit-msg{fill:#d3d3d3;color:#d3d3d3;}.pieTitleText{text-anchor:middle;font-size:25px;fill:var(--text-normal);}.state-note text,g.stateGroup text{stroke:none;font-size:10px;}g.stateGroup .state-title{font-weight:bolder;fill:var(--text-normal);}.transition{stroke:var(--background-modifier-border);stroke-width:1;fill:none;}.stateGroup .composit{fill:#fff;border-bottom:1px;}.stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}.state-note{stroke:#645c10;fill:#f3edb3;}.state-note text{fill:#000;}.stateLabel .box{stroke:none;stroke-width:0;fill:var(--background-secondary-alt);opacity:.5;}.stateLabel text{fill:var(--text-normal);font-size:10px;font-weight:700;}.node circle.state-start{fill:var(--text-normal);stroke:var(--text-normal);}.node circle.state-end{stroke:var(--background-primary);stroke-width:2;}#statediagram-barbEnd,g.stateGroup text{fill:var(--background-modifier-border);}.statediagram-cluster rect{stroke-width:1px;}.statediagram-cluster rect,.statediagram-state .divider{stroke:var(--background-modifier-border);}.statediagram-cluster rect,.statediagram-cluster.statediagram-cluster .inner{fill:var(--background-secondary-alt);}.statediagram-cluster.statediagram-cluster-alt .inner{fill:var(--background-secondary);}.cluster-label text,.node circle.state-end{fill:var(--text-normal);}.statediagram-state rect.divider{stroke-dasharray:10,10;fill:var(--background-secondary);}.note-edge{stroke-dasharray:5;}.statediagram-note rect{fill:#f3edb3;stroke:#645c10;stroke-width:1px;}.error-icon{fill:var(--background-modifier-error);}.error-text{fill:var(--text-error);stroke:var(--text-error);}:root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style><g><g class="output"><g class="clusters"></g><g class="edgePaths"><g class="edgePath LS-A LE-B" id="L-A-B" style="opacity: 1;"><path class="path" d="M86.30909090909091,50.5L79.9053622159091,58.416666666666664C73.50163352272727,66.33333333333333,60.69417613636364,82.16666666666667,54.29044744318182,98.20833333333333C47.88671875,114.25,47.88671875,130.5,47.88671875,138.625L47.88671875,146.75" marker-end="url(app://obsidian.md/index.html#arrowhead1156)" style="fill:none"></path><defs><marker id="arrowhead1156" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath LS-B LE-C" id="L-B-C" style="opacity: 1;"><path class="path" d="M47.88671875,189.25L47.88671875,197.375C47.88671875,205.5,47.88671875,221.75,54.01360181920134,241.10000469731884C60.14048488840268,260.4500093946377,72.39425102680535,282.90001878927535,78.52113409600669,294.1250234865942L84.64801716520803,305.350028183913" marker-end="url(app://obsidian.md/index.html#arrowhead1157)" style="fill:none"></path><defs><marker id="arrowhead1157" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath LS-C LE-A" id="L-C-A" style="opacity: 1;"><path class="path" d="M123.34807551157618,305.35003016245514L129.30829209298017,294.1250251353793C135.26850867438412,282.9000201083034,147.18894183719206,260.45001005415173,153.14915841859604,237.55833836040918C159.109375,214.66666666666666,159.109375,191.33333333333334,159.109375,168C159.109375,144.66666666666666,159.109375,121.33333333333333,152.70564630681818,101.75C146.30191761363636,82.16666666666667,133.49446022727273,66.33333333333333,127.09073153409092,58.416666666666664L120.68700284090909,50.5" marker-end="url(app://obsidian.md/index.html#arrowhead1158)" style="fill:none"></path><defs><marker id="arrowhead1158" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" transform="translate(47.88671875,98)" style="opacity: 1;"><g transform="translate(-24.4296875,-22.5)" class="label"><rect rx="0" ry="0" width="48.859375" height="45"></rect><foreignObject width="48.859375" height="45"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span id="L-L-A-B" class="edgeLabel L-LS-A' L-LE-B">one</span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(47.88671875,238)" style="opacity: 1;"><g transform="translate(-25.1640625,-22.5)" class="label"><rect rx="0" ry="0" width="50.328125" height="45"></rect><foreignObject width="50.328125" height="45"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span id="L-L-B-C" class="edgeLabel L-LS-B' L-LE-C">two</span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(159.109375,168)" style="opacity: 1;"><g transform="translate(-36.3359375,-22.5)" class="label"><rect rx="0" ry="0" width="72.671875" height="45"></rect><foreignObject width="72.671875" height="45"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;"><span id="L-L-C-A" class="edgeLabel L-LS-C' L-LE-A">three</span></div></foreignObject></g></g></g><g class="nodes"><g class="node default" id="flowchart-A-884" transform="translate(103.498046875,29.25)" style="opacity: 1;"><rect rx="0" ry="0" x="-48.9453125" y="-21.25" width="97.890625" height="42.5" class="label-container"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-38.9453125,-11.25)"><foreignObject width="77.890625" height="22.5"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;">Lots of text</div></foreignObject></g></g></g><g class="node default" id="flowchart-B-885" transform="translate(47.88671875,168)" style="opacity: 1;"><rect rx="0" ry="0" x="-39.88671875" y="-21.25" width="79.7734375" height="42.5" class="label-container"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-29.88671875,-11.25)"><foreignObject width="59.7734375" height="22.5"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;">Lots text</div></foreignObject></g></g></g><g class="node default" id="flowchart-C-886" transform="translate(103.498046875,340.5230484008789)" style="opacity: 1;"><polygon points="55.023046875,0 110.04609375,-55.023046875 55.023046875,-110.04609375 0,-55.023046875" transform="translate(-55.023046875,55.023046875)" class="label-container"></polygon><g class="label" transform="translate(0,0)"><g transform="translate(-29.88671875,-11.25)"><foreignObject width="59.7734375" height="22.5"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;">Lots text</div></foreignObject></g></g></g></g></g></g></svg>

which generates this in HTLM (with some additional CSS intoduced by the Obsidian-Pandoc plugin - which doesn't work too well with mermaid, so it probably can't be reproduced without my local changes to the main.js): image mermaid diagram example.zip

and this in Word (.docx) image

Is this something we could try to address?

Reproduction of above errors: Install Pandoc, Install rsvg-convert (via chocolatey for instance choco install rsvg-convert) and run pandoc --from html -i "mermaid diagram example.html" --to docx -o "mermaid diagram example.docx" `

My local input and output from above execution (+ ouput to odt): mermaid diagram example.zip

DigitalFlow commented 2 years ago

Any update on this? Fighting with this as well. Embedding mermaid diagrams inside PDFs as SVGs would be great, as png suffers with its resolution really fast.

sebhahn commented 2 years ago

still exists, any updates?

aloisklink commented 2 years ago

The issues with inkscape and rsvg-convert seem to be caused by https://gitlab.com/inkscape/inbox/-/issues/1180, as mermaid's CSS uses CSS variables that are not yet supported in inkscape.

It might be fixed by on the mermaid side by not using that CSS feature; I'm not sure if that's something a user can override in the mermaid config, or it's something that needs to be changed in the mermaid source code.

Embedding mermaid diagrams inside PDFs as SVGs

If you're okay with embedding mermaid diagrams inside PDFs as PDFs (e.g. with LaTeX), you can try using mermaid-cli's PDF output mode.

Of course, PDFs aren't as good as SVGs, but they should render identically pretty much anywhere.

ghalbuquerque commented 1 year ago

Hi. In my web application, everything was working fine with Mermaid 8.14, but when I upgraded to Mermaid 9, I experienced exactly the same issue, but not necessarily during export. Paths were gone, just the arrow head in black, rectangle all filled in black. See attached both SVG files. I tried to import them in Box SVG and could replicate the error.

I'm not sure if this is helpful, but I noticed STYLE tag inside SVG was not working. In my case, it was just a stupid mistake regarding my container identification in HTML template.

Hope I have helped somehow.

svg-mmd-8 svg-mmd-9

toddeTV commented 1 year ago

Currently, mermaid uses CSS variables ( https://gitlab.com/inkscape/inbox/-/issues/1180 ) and that is not yet fully supported in inkscape and rsvg-convert (part of package librsvg2-bin).

You can:

  1. Use rsvg-convert command (sudo apt-get install librsvg2-bin) to convert SVG to SVG with rsvg-convert -f svg -o './output.svg' './input.svg' and use the new "reconverted" svg file. But be aware that with this the texts get lost bc the output.svg will have baked paths that represent font, not the font itself.

  2. Use mermaid to generate a PDF and not a SVG, e.g. with mmdc -i 'input.md' -o 'output.pdf' -f. Then use the PDF in LaTeX as a figure like so:

    \begin{figure}[h]
    \begin{center}
        \includegraphics[width=\textwidth,page=1]{output.pdf}%
        \caption{Some caption}%
        \label{fig:MyPdfFigure}
    \end{center}
    \end{figure}
ghost commented 1 year ago

Relates to #2485 , which contains more information about why issuing and waiting on rsvg and Inkscape bugs to be resolved isn't a great solution. The summary is that there are at least nine SVG renderers (EchoSVG is a Batik fork) that cannot currently render MermaidJS diagrams.

Instead of relying on all the developers of all of those projects to implement CSS variables, wouldn't it be less development effort overall to remove CSS variables from MermaidJS? Or perhaps provide a switch that replaces the variables inline? Or find another way to make the output meet the SVG 1.1 specification?

Does MermaidJS create diagrams having more complexity than what Graphviz can produce? Graphviz doesn't use CSS variables, so any SVG diagram it produces can be rendered in any SVG rasterizing software.

ghost commented 1 year ago

See also these duplicates and related issues, which contain additional details:

challengemkr20 commented 1 year ago

Adobe FrameMaker 2020 also cannot render mermaid SVG diagrams correctly.

ghost commented 1 year ago

Adobe FrameMaker 2020 also cannot render mermaid SVG diagrams correctly.

See: https://github.com/mermaid-js/mermaid/issues/2485

laillatoyumi commented 1 year ago

FYI this also doesn't work in Adobe Illustrator nor Figma. So basically the svg is useless?

danielwagn3r commented 10 months ago

Just to mention, it's not possible to use exported SVG files in Microsoft Office products.

codesalatdev commented 7 months ago

Just to mention, it's not possible to use exported SVG files in Microsoft Office products.

Nor in LibreOffice.

thomas-ferchau commented 6 months ago

I try to use Mermaid diagrams in Asciidoc documents and generate the SVG images with Kroki (asciidoctor-kroki).

Generating HTML files works, and the SVGs look fine in Chrome, for example.

But generating PDF files (asciidoctor-pdf) with Mermaid diagrams in SVG format prints warnings like these:

Example output:

asciidoctor: WARNING: problem encountered in image: /tmp/image-20240606-1-1gmseq.svg; Must have attributes width, height on tag rect; skipping tag

If it helps, I could prepare a reproducible example (in a GitHub repository?) that does not require any installation except Docker Engine.

As a workaround I tried to use PNG format with useWidth for larger diagrams. config.gantt.useWidth works, but useWidth is ignored by any other diagram I tried: sequence, class, flowchart, gitGraph, mindmap.

Is there any other config option to generate higher resolution PNG files as a workaround?

The PDF file with the broken SVG is generated, but the images are broken. Some examples: mermaid-class-diagram-svg-by-kroki-in-asciidoc-pdf mermaid-mindmap-svg-by-kroki-in-asciidoc-pdf mermaid-flowchart-svg-by-kroki-in-asciidoc-pdf

hoehrmann commented 5 months ago

In my case the mmdc output contains:

            <foreignObject style="width: 47.1719px; height: 51px;" height="51" width="47.171875">
              <div xmlns="http://www.w3.org/1999/xhtml" style="display: table-cell; white-space: nowrap; max-width: 200px;">
                <span class="nodeLabel markdown-node-label">
                  <p>start A</p>
                </span>
              </div>
            </foreignObject>

It is a bit unreasonable to expect SVG implementations to implement a HTML+CSS layout engine.

Turns out the Ubuntu version of my own CutyCapt can handle this fairly well, cutycapt --url=file:///home/bjoern/.../in.svg --out=o.svg handles the CSS variables and the foreignObjects.

johamada commented 5 months ago

I guess you can embed mermaid diagrams to Word/PowerPoint with some restrictions when you give it some variables

%%{init: {'themeVariables': {
'cScale0': '#3CB5A1',
'cScale1': '#42BBA5',
'cScale7': '#66DFBD'
} } }%%
timeline
    2024 : Test
    2025 : test 2
    2026 : Test 3

makes in PowerPoint this SVG:

image

Should also work for other diagrams if you define the variables?

Just to mention, it's not possible to use exported SVG files in Microsoft Office products.

DeadLockStarve commented 5 months ago

There seems to be a workaround for Inkscape: https://gitlab.com/inkscape/inbox/-/issues/3268, specifically https://gitlab.com/-/project/10403243/uploads/9c1444bd2eaa3562c48d06b63969af5a/mermaid_input.zip

Changing the file's extension to .htmlsvg and installing the zip's content in ~/.config/inkscape/extensions partially solves the issue. However, the python code (as follows) doesn't seem to deal correctly with text positions, as shown by the last line, it just lazily places text at coordinates x0 y0

class MermaidInput(SvgInputMixin, inkex.InputExtension):
    def effect(self):
        # Clean up the styles
        sts = inkex.StyleSheet()
        for style in self.svg.xpath('//svg:style'):
            for rule in style.stylesheet():
                for attr in list(rule):
                    if attr.startswith('--'):
                        del(rule[attr])
                sts.append(rule)
            style.delete()

        # Add in a fresh stylesheet
        st = self.svg.stylesheet
        st.extend(sts)
        st._callback()

        # Baddly import the html elements
        for elem in self.svg.xpath('//svg:foreignObject'):
            text = ''.join([e.text for e in elem.descendants() if e.text])
            parent = elem.getparent()
            elem.delete()
            parent.add(TextElement()).add(Tspan(x='0', y='0')).text = text

What could be doable for extracting correctly text formatting infos and creating a proper SVG importing for inkscape as a temporary solution?

aloisklink commented 5 months ago

What could be doable for extracting correctly text formatting infos and creating a proper SVG importing for inkscape as a temporary solution?

I have heard some people say that converting a mermaid diagram to a PDF using https://github.com/mermaid-js/mermaid-cli, then converting that PDF to an SVG using a program like pdf2svg often works (but it does create some other oddities, and I'd imagine the SVGs would be much more complicated and difficult to edit in Inkscape).

E.g. something like:

npx @mermaid-js/mermaid-cli --input my-example-mermaid-input.mermaid --output my-pdf-file.pdf --pdfFit --backgroundColor transparent
svg2png my-pdf-file.pdf my-svg-file.svg
Rascarquapac commented 3 months ago

The workaround proposed by Rgoubet in #4290 issue (closed because of duplicate with this thread) works for using the SVG file generated from Mermaid in Inkscape or Illustrator

  1. Modify default config of Mermaid to avoid "htmlLabels" generation { "flowchart": { "htmlLabels": "false" } }
  2. Generate and Download the SVG file on Mermaid Live Editor for example
  3. Patch the SVG file by replacing root{--mermaid-font-family by root{mermaid-font-family
  4. Read / Edit the resulting file in Inkscape / Illustrator
  5. The resulting file can be read by firefox/chrome
rrrodzilla commented 3 days ago

The workaround proposed by Rgoubet in #4290 issue (closed because of duplicate with this thread) works for using the SVG file generated from Mermaid in Inkscape or Illustrator

  1. Modify default config of Mermaid to avoid "htmlLabels" generation { "flowchart": { "htmlLabels": "false" } }
  2. Generate and Download the SVG file on Mermaid Live Editor for example
  3. Patch the SVG file by replacing root{--mermaid-font-family by root{mermaid-font-family
  4. Read / Edit the resulting file in Inkscape / Illustrator
  5. The resulting file can be read by firefox/chrome

In the latest version, that didn't work for me. But putting it at the root instead of at the diagram worked:

{ "htmlLabels": "false" }