Add SVG output suitable for inlining in HTML
Offer a new output format svg:tag
or inline_svg
or svg_inline
or svg_html
, or maybe even xhtml
. Naming bikeshed comments welcome, I think it's important that this has a good name.
This should output a <svg>...</svg>
tree suitable for inline inclusion in an HTML5 document, i.e.:
$ echo 'digraph {}' | dot -Tinline_svg
<svg width="8pt" height="8pt"
viewBox="0.00 0.00 8.00 8.00">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 4)">
<polygon fill="white" stroke="none" points="-4,4 -4,-4 4,-4 4,4 -4,4"/>
</g>
</svg>
Extra points if it's suitable for inclusion in an XHTML document too, though I don't think XHTML is very popular these days. I'm not sure if the xmlns
attributes are required for inclusion in XHTML? If so, this should be a separate output format.
This would particularly be helpful for the Graphviz docs, and in other technical docs. I'd love to 'scratch my own itch' here.
Background
Sometimes, I like to embed Graphviz generations into websites.
There aren't many great options for this.
-
<img>
tags don't let you click on HREFs, can't select text -
<iframe>
s are heavyweight, are harder to use javascript cross-page, and don't set their height automatically, and links open in the iframe. We use these a lot in technical docs, but it requires settingtarget=_parent
on everyhref
in the graph. -
<object>
tags are kinda obsolete. - there are some other funny ways, but they're all silly: https://vecta.io/blog/best-way-to-embed-svg
Inlining an <svg>
tag directly into the HTML is very nice, and makes hrefs open in the same frame, lets javascript access the nodes, sets correct height. It's a great option!
But it's hard to use in Graphviz's output today. If you try to output SVG, you get output unsuitable for inline SVG, with <?xml>
, <!DOCTYPE>
tags and xmlns
attributes that you have to remove to inline:
$ echo 'digraph {}' | dot -Tsvg
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 5.0.1 (20220820.1526)
-->
<!-- Pages: 1 -->
<svg width="8pt" height="8pt"
viewBox="0.00 0.00 8.00 8.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 4)">
<polygon fill="white" stroke="none" points="-4,4 -4,-4 4,-4 4,4 -4,4"/>
</g>
</svg>
Demand for this feature
This ends up with fairly silly workarounds, like:
- this jekyll-graphviz plugin that parses the XML to remove the
<?xml>
,<!DOCTYPE>
tags andxmlns
attributes: https://github.com/kui/jekyll-graphviz/blob/master/lib/jekyll/graphviz/renderer.rb#L46-L56 - another jekyll diagram plugin, that regexes out the
<?xml>
: https://github.com/zhustec/jekyll-diagrams/blob/master/lib/jekyll-diagrams/graphviz/renderer.rb#L21 - @magjac's own Graphviz Visual Editor parses the SVG, to grab the document element from inside it (probably the cleanest option I've seen out there, full credit to Magnus): https://github.com/magjac/d3-graphviz/blob/4cc0267fdc721c579c0457ca745d5a15fc93fb85/src/dot.js#L323
- This blogpost mentions stripping off the
<?xml>
tag and<!doctype>
with some brittle array indexing: https://hokstad.com/inline-graphviz#:~:text=strip%20off%20the%20XML%20declaration%20and%20DOCTYPE - This old email mentions stripping the
<!DOCTYPE>
and<?xml>
: https://lists.w3.org/Archives/Public/public-html/2008Mar/0156.html
I think such a feature would remove the need for these workarounds.
How would we do it?
Hopefully, reuse most of the SVG code, just don't output the header!