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:
Cynthia Gauthier 2010-06-15 20:58:57 -04:00
parent 00804fb833
commit f4cca44faf
9 changed files with 1153 additions and 518 deletions

View file

@ -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()