Newer
Older
#!/usr/bin/env python3
'''
Application for "fixing" SVGs edited with Inkscape
These problems are addressed:
* Inkscape notoriously copies class styles into the object definitions.
https://bugs.launchpad.net/inkscape/+bug/167937
* Inkscape uses labels on layers. Layers are basically named groups.
Inkscape does not sync the group id with the layer label.
Usage Example:
python3 inkscape_svg_fixup.py vector_source.svg
'''
import lxml.etree as etree
import sys
def fix(tree):
# know namespaces
ns = {
'svg' : 'http://www.w3.org/2000/svg',
'inkscape' : 'http://www.inkscape.org/namespaces/inkscape'
}
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# find document global style definition
# mangle it and interpret as python dictionary
style_element = tree.find('./svg:style',namespaces=ns)
style_definitions = style_element.text
pythonic_style_definitions = '{'+style_definitions.\
replace('\t.','"').replace('{','":"').replace('}','",').\
replace('/*','#')+'}'
styles = eval(pythonic_style_definitions)
# go through all SVG elements
for elem in tree.iter():
if (elem.tag == etree.QName(ns['svg'], 'g')):
# compare inkscape label with group element ID
l = elem.get(etree.QName(ns['inkscape'], 'label'))
if l:
i = elem.get('id')
if (i != l):
print("Overwriting ID %s with Label %s..."%(i, l))
elem.set('id', l)
# remove all offending style attributes
s = elem.get('style')
c = elem.get('class')
if (c and s):
s = s.lower()
c = c.split(' ')[0] # regard main style only
cs = ''
if c in styles:
cs = styles[c].strip('; ').lower()
if (c not in styles):
print("Object id %s references unknown style class %s."%(i,c))
else:
if (cs != s.strip('; ')):
print("Style %s removed from object id %s differed from class %s style %s."%(s,i,c,cs))
del elem.attrib["style"]
if __name__ == "__main__":
input_file = sys.argv[1]
tree = etree.parse(input_file)
fix(tree)
# store SVG into file (input file is overwritten)
svg = etree.tostring(tree, pretty_print=True)
with open(input_file, 'wb') as f:
f.write('<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n'.encode("utf-8"))
f.write(svg)