forked from HBehrens/fixup_shaper_svg
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fixup_shaper_svg.py
73 lines (56 loc) · 2.45 KB
/
fixup_shaper_svg.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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
63
64
65
66
67
68
69
70
71
72
73
#!/usr/bin/env python3
import argparse
import re
import sys
import xml.etree.ElementTree
# Author: [email protected], 2020-01-08
#
# Works around two bugs in the SVG export of FreeCAD 0.18 as
# Shaper Origin rejects the file with
# > Unable to place design. Check that your file is formatted properly.
#
# Bug 1) incorrect formats length attributes which
# separate a number and unit literal with a space, e.g. "0.35 px".
#
# According to https://www.w3.org/TR/SVG/coords.html#Units,
# https://www.w3.org/TR/css-values/#absolute-lengths
# https://developer.mozilla.org/en-US/docs/Web/CSS/length#syntax
# this is incorrect as
# > there is no space between the unit literal and the number.
#
# Bug 2) invalid CSS style "fill-rule". This is not a CSS style property
# but an SVG attribute.
# https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill-rule
# For the time being, the property is simply removed.
# https://developer.mozilla.org/en-US/docs/Web/CSS/number
# https://developer.mozilla.org/en-US/docs/Web/CSS/length#syntax
RE_LENGTH_WITH_UNIT = re.compile(r'^\s*([+-]?)(\d*\.)?(\d+)([Ee][+-]?\d+)?\s*(cm|mm|Q|in|pc|pt|px)\s*$')
def length_value_without_spaces(value):
m = RE_LENGTH_WITH_UNIT.match(value)
if not m:
return value
return value.replace(" ", "")
def style_attribute_without_fill_rule(value):
props = value.split(";")
props_without_fill_rule = [p for p in props if not p.strip().startswith("fill-rule") and p.strip()]
return ";".join(props_without_fill_rule) + (";" if len(props_without_fill_rule) > 0 else "")
def fixup_element(element):
for k, v in element.attrib.items():
if k == "style":
new_value = style_attribute_without_fill_rule(v)
else:
new_value = length_value_without_spaces(v)
if new_value != v:
element.attrib[k] = new_value
def fixup_svg(infile, outfile):
xml.etree.ElementTree.register_namespace("", "http://www.w3.org/2000/svg")
svg = xml.etree.ElementTree.parse(infile)
for elem in svg.iter():
fixup_element(elem)
svg.write(outfile, encoding='unicode', xml_declaration=True)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), default=sys.stdin)
parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'), default=sys.stdout)
args = parser.parse_args()
fixup_svg(infile=args.infile, outfile=args.outfile)