Skip to content

Instantly share code, notes, and snippets.

@thebabush
Created November 25, 2020 16:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thebabush/ef19891880b1d13c2c300386c91cab7f to your computer and use it in GitHub Desktop.
Save thebabush/ef19891880b1d13c2c300386c91cab7f to your computer and use it in GitHub Desktop.
If you created a diagram using draw.io and now only web browsers can display it somewhat correctly, use this script + manual inkscape editing to fix them.
#!/usr/bin/env python3
"""
draw.io uses foreignObject tags to put fancy text on SVGs.
The structure it creates is like this:
```
<switch>
<foreignObject>...</foreignObject>
<text>...</text>
</switch>
```
This is _"nice"_ becase it means that if a visualization tool doesn't support foreignObjects properly,
the output changes completely.
At some point I had the text completely modified in inkscape but my browser was still showing the
old version.
Even their PDF export doesn't support this correctly, let alone inkscape and similar OS tools.
So, unlucky you, if you need consistent SVG display across applications/mediums,
you better use this script to remove the switches and the foreign objects.
You will probably lose text formatting but your SVG will finally show up identical in
firefox, chrome, inkscape, etc...
Bottom line: don't use draw.io even if its layouting features are nice. It's not worth a half a day of fixes later.
"""
import sys
import xml.etree.ElementTree as ET
def main(src, tgt):
tree = ET.parse(src)
root = tree.getroot()
parent_map = {c: p for p in tree.iter() for c in p}
for switch in root.iter('{http://www.w3.org/2000/svg}switch'):
children = list(switch)
if len(children) != 2:
continue
bad = None
good = None
for child in children:
if child.tag == '{http://www.w3.org/2000/svg}foreignObject':
bad = child
else:
good = child
if bad is None:
continue
parent_map[switch].append(good)
parent_map[switch].remove(switch)
tree.write(tgt)
if __name__ == '__main__':
main(*sys.argv[1:])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment