Merge branch lp:~louis-simard/scour/rework. Summary of changes:
scour.py, scour.inkscape.py, scour.inx: * Add options --quiet, --enable-comment-stripping, --shorten-ids, --remove-metadata, --renderer-workaround. scour.py: * Optimisations in time (so Scour runs faster) and space (so Scour allocates less memory, less often). * Change #E+# to #e#, #E-# to #e-#, 0.# to .# and -0.# into -.# in path/polygon/polyline data + lengths, if renderer workarounds are disabled. Use spaces instead of commas in path/polygon/polyline data. Use lower-case #rrggbb and #rgb instead of upper-case. All of this makes gzip work better, since the rest of SVG documents mostly has lower-case letters in tag names and spaces to separate XML attributes etc. * Fix a bug whereby an SVG document would become filled with black if all elements had the same fill color. * Fix a bug whereby a path's second command would not start at the right coordinates if the first command was a relative moveto 'm' with at least 1 implied lineto. * Fix a bug whereby a path's absolute lineto 'L' commands would not become the right relative lineto 'l' commands. * Allow the implicit linetos after a path's moveto 'M'/'m' to be converted into relative horizontal linetos 'h' and vertical 'v' too. scour.inx: * Fix help typos. Make options more descriptive in the plugin option window. Add something about enable-group-collapsing requiring enable-id-stripping. testscour.py: * Rework tests that relied on #E+#, #E-#, 0.# and -0.# so that they accept the changes to scour.py. Add unit tests for strip-xml-prolog, enable-comment-stripping and remove-metadata.
This commit is contained in:
parent
00804fb833
commit
f4cca44faf
9 changed files with 1153 additions and 518 deletions
42
svg_regex.py
42
svg_regex.py
|
|
@ -43,6 +43,7 @@ Out[5]: [('M', [(100.0, -200.0)])]
|
|||
"""
|
||||
|
||||
import re
|
||||
from decimal import *
|
||||
|
||||
|
||||
# Sentinel.
|
||||
|
|
@ -52,8 +53,8 @@ class _EOF(object):
|
|||
EOF = _EOF()
|
||||
|
||||
lexicon = [
|
||||
('float', r'[-\+]?(?:(?:[0-9]*\.[0-9]+)|(?:[0-9]+\.?))(?:[Ee][-\+]?[0-9]+)?'),
|
||||
('int', r'[-\+]?[0-9]+'),
|
||||
('float', r'[-+]?(?:(?:[0-9]*\.[0-9]+)|(?:[0-9]+\.?))(?:[Ee][-+]?[0-9]+)?'),
|
||||
('int', r'[-+]?[0-9]+'),
|
||||
('command', r'[AaCcHhLlMmQqSsTtVvZz]'),
|
||||
]
|
||||
|
||||
|
|
@ -161,7 +162,7 @@ class SVGPathParser(object):
|
|||
def rule_closepath(self, next, token):
|
||||
command = token[1]
|
||||
token = next()
|
||||
return (command, None), token
|
||||
return (command, []), token
|
||||
|
||||
def rule_moveto_or_lineto(self, next, token):
|
||||
command = token[1]
|
||||
|
|
@ -169,7 +170,7 @@ class SVGPathParser(object):
|
|||
coordinates = []
|
||||
while token[0] in self.number_tokens:
|
||||
pair, token = self.rule_coordinate_pair(next, token)
|
||||
coordinates.append(pair)
|
||||
coordinates.extend(pair)
|
||||
return (command, coordinates), token
|
||||
|
||||
def rule_orthogonal_lineto(self, next, token):
|
||||
|
|
@ -189,7 +190,9 @@ class SVGPathParser(object):
|
|||
pair1, token = self.rule_coordinate_pair(next, token)
|
||||
pair2, token = self.rule_coordinate_pair(next, token)
|
||||
pair3, token = self.rule_coordinate_pair(next, token)
|
||||
coordinates.append((pair1, pair2, pair3))
|
||||
coordinates.extend(pair1)
|
||||
coordinates.extend(pair2)
|
||||
coordinates.extend(pair3)
|
||||
return (command, coordinates), token
|
||||
|
||||
def rule_curveto2(self, next, token):
|
||||
|
|
@ -199,7 +202,8 @@ class SVGPathParser(object):
|
|||
while token[0] in self.number_tokens:
|
||||
pair1, token = self.rule_coordinate_pair(next, token)
|
||||
pair2, token = self.rule_coordinate_pair(next, token)
|
||||
coordinates.append((pair1, pair2))
|
||||
coordinates.extend(pair1)
|
||||
coordinates.extend(pair2)
|
||||
return (command, coordinates), token
|
||||
|
||||
def rule_curveto1(self, next, token):
|
||||
|
|
@ -208,7 +212,7 @@ class SVGPathParser(object):
|
|||
coordinates = []
|
||||
while token[0] in self.number_tokens:
|
||||
pair1, token = self.rule_coordinate_pair(next, token)
|
||||
coordinates.append(pair1)
|
||||
coordinates.extend(pair1)
|
||||
return (command, coordinates), token
|
||||
|
||||
def rule_elliptical_arc(self, next, token):
|
||||
|
|
@ -216,51 +220,51 @@ class SVGPathParser(object):
|
|||
token = next()
|
||||
arguments = []
|
||||
while token[0] in self.number_tokens:
|
||||
rx = float(token[1])
|
||||
rx = Decimal(token[1]) * 1
|
||||
if rx < 0.0:
|
||||
raise SyntaxError("expecting a nonnegative number; got %r" % (token,))
|
||||
|
||||
token = next()
|
||||
if token[0] not in self.number_tokens:
|
||||
raise SyntaxError("expecting a number; got %r" % (token,))
|
||||
ry = float(token[1])
|
||||
ry = Decimal(token[1]) * 1
|
||||
if ry < 0.0:
|
||||
raise SyntaxError("expecting a nonnegative number; got %r" % (token,))
|
||||
|
||||
token = next()
|
||||
if token[0] not in self.number_tokens:
|
||||
raise SyntaxError("expecting a number; got %r" % (token,))
|
||||
axis_rotation = float(token[1])
|
||||
axis_rotation = Decimal(token[1]) * 1
|
||||
|
||||
token = next()
|
||||
if token[1] not in ('0', '1'):
|
||||
raise SyntaxError("expecting a boolean flag; got %r" % (token,))
|
||||
large_arc_flag = bool(int(token[1]))
|
||||
large_arc_flag = Decimal(token[1]) * 1
|
||||
|
||||
token = next()
|
||||
if token[1] not in ('0', '1'):
|
||||
raise SyntaxError("expecting a boolean flag; got %r" % (token,))
|
||||
sweep_flag = bool(int(token[1]))
|
||||
sweep_flag = Decimal(token[1]) * 1
|
||||
|
||||
token = next()
|
||||
if token[0] not in self.number_tokens:
|
||||
raise SyntaxError("expecting a number; got %r" % (token,))
|
||||
x = float(token[1])
|
||||
x = Decimal(token[1]) * 1
|
||||
|
||||
token = next()
|
||||
if token[0] not in self.number_tokens:
|
||||
raise SyntaxError("expecting a number; got %r" % (token,))
|
||||
y = float(token[1])
|
||||
y = Decimal(token[1]) * 1
|
||||
|
||||
token = next()
|
||||
arguments.append(((rx,ry), axis_rotation, large_arc_flag, sweep_flag, (x,y)))
|
||||
arguments.extend([rx, ry, axis_rotation, large_arc_flag, sweep_flag, x, y])
|
||||
|
||||
return (command, arguments), token
|
||||
|
||||
def rule_coordinate(self, next, token):
|
||||
if token[0] not in self.number_tokens:
|
||||
raise SyntaxError("expecting a number; got %r" % (token,))
|
||||
x = float(token[1])
|
||||
x = getcontext().create_decimal(token[1])
|
||||
token = next()
|
||||
return x, token
|
||||
|
||||
|
|
@ -269,13 +273,13 @@ class SVGPathParser(object):
|
|||
# Inline these since this rule is so common.
|
||||
if token[0] not in self.number_tokens:
|
||||
raise SyntaxError("expecting a number; got %r" % (token,))
|
||||
x = float(token[1])
|
||||
x = getcontext().create_decimal(token[1])
|
||||
token = next()
|
||||
if token[0] not in self.number_tokens:
|
||||
raise SyntaxError("expecting a number; got %r" % (token,))
|
||||
y = float(token[1])
|
||||
y = getcontext().create_decimal(token[1])
|
||||
token = next()
|
||||
return (x,y), token
|
||||
return [x, y], token
|
||||
|
||||
|
||||
svg_parser = SVGPathParser()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue