Fixes to globals used for tracking statistics (#118)

- Collect globals in `scourString()` and make sure they're all properly initialized to zero. Before statistics were wrong when scouring multiple files/strings because initialization was only done once when loading the module.
- harmonize names
- adjust according to PEP 8 while at it (including leading underscore to mark as non-public)
- include one missing variable in statistics output (number of comments removed)
This commit is contained in:
Eduard Braun 2016-09-18 16:23:00 +02:00 committed by GitHub
parent 4410f91dad
commit 2487f4433b

View file

@ -534,8 +534,8 @@ def findElementsWithId(node, elems=None):
findElementsWithId(child, elems) findElementsWithId(child, elems)
return elems return elems
referencingProps = ['fill', 'stroke', 'filter', 'clip-path', 'mask', 'marker-start',
'marker-end', 'marker-mid'] referencingProps = ['fill', 'stroke', 'filter', 'clip-path', 'mask', 'marker-start', 'marker-end', 'marker-mid']
def findReferencedElements(node, ids=None): def findReferencedElements(node, ids=None):
@ -625,20 +625,6 @@ def findReferencingProperty(node, prop, val, ids):
else: else:
ids[id] = [1, [node]] ids[id] = [1, [node]]
numIDsRemoved = 0
numElemsRemoved = 0
numAttrsRemoved = 0
numRastersEmbedded = 0
numPathSegmentsReduced = 0
numCurvesStraightened = 0
numBytesSavedInPathData = 0
numBytesSavedInColors = 0
numBytesSavedInIDs = 0
numBytesSavedInLengths = 0
numBytesSavedInTransforms = 0
numPointsRemovedFromPolygon = 0
numCommentBytes = 0
def removeUnusedDefs(doc, defElem, elemsToRemove=None): def removeUnusedDefs(doc, defElem, elemsToRemove=None):
if elemsToRemove is None: if elemsToRemove is None:
@ -668,7 +654,7 @@ def removeUnreferencedElements(doc, keepDefs):
Returns the number of unreferenced elements removed from the document. Returns the number of unreferenced elements removed from the document.
""" """
global numElemsRemoved global _num_elements_removed
num = 0 num = 0
# Remove certain unreferenced elements outside of defs # Remove certain unreferenced elements outside of defs
@ -684,7 +670,7 @@ def removeUnreferencedElements(doc, keepDefs):
and goner.parentNode.tagName != 'defs'): and goner.parentNode.tagName != 'defs'):
goner.parentNode.removeChild(goner) goner.parentNode.removeChild(goner)
num += 1 num += 1
numElemsRemoved += 1 _num_elements_removed += 1
if not keepDefs: if not keepDefs:
# Remove most unreferenced elements inside defs # Remove most unreferenced elements inside defs
@ -693,7 +679,7 @@ def removeUnreferencedElements(doc, keepDefs):
elemsToRemove = removeUnusedDefs(doc, aDef) elemsToRemove = removeUnusedDefs(doc, aDef)
for elem in elemsToRemove: for elem in elemsToRemove:
elem.parentNode.removeChild(elem) elem.parentNode.removeChild(elem)
numElemsRemoved += 1 _num_elements_removed += 1
num += 1 num += 1
return num return num
@ -868,20 +854,20 @@ def removeUnreferencedIDs(referencedIDs, identifiedElements):
Returns the number of ID attributes removed Returns the number of ID attributes removed
""" """
global numIDsRemoved global _num_ids_removed
keepTags = ['font'] keepTags = ['font']
num = 0 num = 0
for id in list(identifiedElements.keys()): for id in list(identifiedElements.keys()):
node = identifiedElements[id] node = identifiedElements[id]
if id not in referencedIDs and node.nodeName not in keepTags: if id not in referencedIDs and node.nodeName not in keepTags:
node.removeAttribute('id') node.removeAttribute('id')
numIDsRemoved += 1 _num_ids_removed += 1
num += 1 num += 1
return num return num
def removeNamespacedAttributes(node, namespaces): def removeNamespacedAttributes(node, namespaces):
global numAttrsRemoved global _num_attributes_removed
num = 0 num = 0
if node.nodeType == 1: if node.nodeType == 1:
# remove all namespace'd attributes from this element # remove all namespace'd attributes from this element
@ -893,7 +879,7 @@ def removeNamespacedAttributes(node, namespaces):
attrsToRemove.append(attr.nodeName) attrsToRemove.append(attr.nodeName)
for attrName in attrsToRemove: for attrName in attrsToRemove:
num += 1 num += 1
numAttrsRemoved += 1 _num_attributes_removed += 1
node.removeAttribute(attrName) node.removeAttribute(attrName)
# now recurse for children # now recurse for children
@ -903,7 +889,7 @@ def removeNamespacedAttributes(node, namespaces):
def removeNamespacedElements(node, namespaces): def removeNamespacedElements(node, namespaces):
global numElemsRemoved global _num_elements_removed
num = 0 num = 0
if node.nodeType == 1: if node.nodeType == 1:
# remove all namespace'd child nodes from this element # remove all namespace'd child nodes from this element
@ -914,7 +900,7 @@ def removeNamespacedElements(node, namespaces):
childrenToRemove.append(child) childrenToRemove.append(child)
for child in childrenToRemove: for child in childrenToRemove:
num += 1 num += 1
numElemsRemoved += 1 _num_elements_removed += 1
node.removeChild(child) node.removeChild(child)
# now recurse for children # now recurse for children
@ -937,7 +923,7 @@ def removeDescriptiveElements(doc, options):
if not elementTypes: if not elementTypes:
return return
global numElemsRemoved global _num_elements_removed
num = 0 num = 0
elementsToRemove = [] elementsToRemove = []
for elementType in elementTypes: for elementType in elementTypes:
@ -946,7 +932,7 @@ def removeDescriptiveElements(doc, options):
for element in elementsToRemove: for element in elementsToRemove:
element.parentNode.removeChild(element) element.parentNode.removeChild(element)
num += 1 num += 1
numElemsRemoved += 1 _num_elements_removed += 1
return num return num
@ -957,7 +943,7 @@ def removeNestedGroups(node):
which do not have any attributes or a title/desc child and which do not have any attributes or a title/desc child and
promoting their children up one level promoting their children up one level
""" """
global numElemsRemoved global _num_elements_removed
num = 0 num = 0
groupsToRemove = [] groupsToRemove = []
@ -978,7 +964,7 @@ def removeNestedGroups(node):
while g.childNodes.length > 0: while g.childNodes.length > 0:
g.parentNode.insertBefore(g.firstChild, g) g.parentNode.insertBefore(g.firstChild, g)
g.parentNode.removeChild(g) g.parentNode.removeChild(g)
numElemsRemoved += 1 _num_elements_removed += 1
num += 1 num += 1
# now recurse for children # now recurse for children
@ -1084,7 +1070,7 @@ def createGroupsForCommonAttributes(elem):
This function acts recursively on the given element. This function acts recursively on the given element.
""" """
num = 0 num = 0
global numElemsRemoved global _num_elements_removed
# TODO perhaps all of the Presentation attributes in http://www.w3.org/TR/SVG/struct.html#GElement # TODO perhaps all of the Presentation attributes in http://www.w3.org/TR/SVG/struct.html#GElement
# could be added here # could be added here
@ -1183,7 +1169,7 @@ def createGroupsForCommonAttributes(elem):
group.parentNode = elem group.parentNode = elem
num += 1 num += 1
curChild = runStart - 1 curChild = runStart - 1
numElemsRemoved -= 1 _num_elements_removed -= 1
else: else:
curChild -= 1 curChild -= 1
else: else:
@ -1253,7 +1239,7 @@ def removeUnusedAttributesOnParent(elem):
def removeDuplicateGradientStops(doc): def removeDuplicateGradientStops(doc):
global numElemsRemoved global _num_elements_removed
num = 0 num = 0
for gradType in ['linearGradient', 'radialGradient']: for gradType in ['linearGradient', 'radialGradient']:
@ -1287,14 +1273,14 @@ def removeDuplicateGradientStops(doc):
for stop in stopsToRemove: for stop in stopsToRemove:
stop.parentNode.removeChild(stop) stop.parentNode.removeChild(stop)
num += 1 num += 1
numElemsRemoved += 1 _num_elements_removed += 1
# linear gradients # linear gradients
return num return num
def collapseSinglyReferencedGradients(doc): def collapseSinglyReferencedGradients(doc):
global numElemsRemoved global _num_elements_removed
num = 0 num = 0
identifiedElements = findElementsWithId(doc.documentElement) identifiedElements = findElementsWithId(doc.documentElement)
@ -1346,13 +1332,13 @@ def collapseSinglyReferencedGradients(doc):
# now delete elem # now delete elem
elem.parentNode.removeChild(elem) elem.parentNode.removeChild(elem)
numElemsRemoved += 1 _num_elements_removed += 1
num += 1 num += 1
return num return num
def removeDuplicateGradients(doc): def removeDuplicateGradients(doc):
global numElemsRemoved global _num_elements_removed
num = 0 num = 0
gradientsToRemove = {} gradientsToRemove = {}
@ -1446,7 +1432,7 @@ def removeDuplicateGradients(doc):
# now that all referencing elements have been re-mapped to the master # now that all referencing elements have been re-mapped to the master
# it is safe to remove this gradient from the document # it is safe to remove this gradient from the document
dupGrad.parentNode.removeChild(dupGrad) dupGrad.parentNode.removeChild(dupGrad)
numElemsRemoved += 1 _num_elements_removed += 1
num += 1 num += 1
return num return num
@ -2051,9 +2037,8 @@ def cleanPath(element, options):
""" """
Cleans the path string (d attribute) of the element Cleans the path string (d attribute) of the element
""" """
global numBytesSavedInPathData global _num_bytes_saved_in_path_data
global numPathSegmentsReduced global _num_path_segments_removed
global numCurvesStraightened
# this gets the parser object from svg_regex.py # this gets the parser object from svg_regex.py
oldPathStr = element.getAttribute('d') oldPathStr = element.getAttribute('d')
@ -2183,40 +2168,40 @@ def cleanPath(element, options):
# 'm0,0 x,y' can be replaces with 'lx,y', # 'm0,0 x,y' can be replaces with 'lx,y',
# except the first m which is a required absolute moveto # except the first m which is a required absolute moveto
path[pathIndex] = ('l', data[2:]) path[pathIndex] = ('l', data[2:])
numPathSegmentsReduced += 1 _num_path_segments_removed += 1
else: # else skip move coordinate else: # else skip move coordinate
i = 2 i = 2
while i < len(data): while i < len(data):
if data[i] == data[i + 1] == 0: if data[i] == data[i + 1] == 0:
del data[i:i + 2] del data[i:i + 2]
numPathSegmentsReduced += 1 _num_path_segments_removed += 1
else: else:
i += 2 i += 2
elif cmd == 'c': elif cmd == 'c':
while i < len(data): while i < len(data):
if data[i] == data[i + 1] == data[i + 2] == data[i + 3] == data[i + 4] == data[i + 5] == 0: if data[i] == data[i + 1] == data[i + 2] == data[i + 3] == data[i + 4] == data[i + 5] == 0:
del data[i:i + 6] del data[i:i + 6]
numPathSegmentsReduced += 1 _num_path_segments_removed += 1
else: else:
i += 6 i += 6
elif cmd == 'a': elif cmd == 'a':
while i < len(data): while i < len(data):
if data[i + 5] == data[i + 6] == 0: if data[i + 5] == data[i + 6] == 0:
del data[i:i + 7] del data[i:i + 7]
numPathSegmentsReduced += 1 _num_path_segments_removed += 1
else: else:
i += 7 i += 7
elif cmd == 'q': elif cmd == 'q':
while i < len(data): while i < len(data):
if data[i] == data[i + 1] == data[i + 2] == data[i + 3] == 0: if data[i] == data[i + 1] == data[i + 2] == data[i + 3] == 0:
del data[i:i + 4] del data[i:i + 4]
numPathSegmentsReduced += 1 _num_path_segments_removed += 1
else: else:
i += 4 i += 4
elif cmd in ['h', 'v']: elif cmd in ['h', 'v']:
oldLen = len(data) oldLen = len(data)
path[pathIndex] = (cmd, [coord for coord in data if coord != 0]) path[pathIndex] = (cmd, [coord for coord in data if coord != 0])
numPathSegmentsReduced += len(path[pathIndex][1]) - oldLen _num_path_segments_removed += len(path[pathIndex][1]) - oldLen
# fixup: Delete subcommands having no coordinates. # fixup: Delete subcommands having no coordinates.
path = [elem for elem in path if len(elem[1]) > 0 or elem[0] == 'z'] path = [elem for elem in path if len(elem[1]) > 0 or elem[0] == 'z']
@ -2254,7 +2239,6 @@ def cleanPath(element, options):
newData = [] newData = []
# now create a straight line segment # now create a straight line segment
newPath.append(('l', [dx, dy])) newPath.append(('l', [dx, dy]))
numCurvesStraightened += 1
else: else:
newData.extend(data[i:i + 6]) newData.extend(data[i:i + 6])
@ -2306,14 +2290,14 @@ def cleanPath(element, options):
lineTuples = [] lineTuples = []
# append the v and then the remaining line coords # append the v and then the remaining line coords
newPath.append(('v', [data[i + 1]])) newPath.append(('v', [data[i + 1]]))
numPathSegmentsReduced += 1 _num_path_segments_removed += 1
elif data[i + 1] == 0: elif data[i + 1] == 0:
if lineTuples: if lineTuples:
# flush the line command, then append the h and then the remaining line coords # flush the line command, then append the h and then the remaining line coords
newPath.append(('l', lineTuples)) newPath.append(('l', lineTuples))
lineTuples = [] lineTuples = []
newPath.append(('h', [data[i]])) newPath.append(('h', [data[i]]))
numPathSegmentsReduced += 1 _num_path_segments_removed += 1
else: else:
lineTuples.extend(data[i:i + 2]) lineTuples.extend(data[i:i + 2])
i += 2 i += 2
@ -2333,7 +2317,7 @@ def cleanPath(element, options):
cmd = 'l' # dealing with linetos now cmd = 'l' # dealing with linetos now
# append the v and then the remaining line coords # append the v and then the remaining line coords
newPath.append(('v', [data[i + 1]])) newPath.append(('v', [data[i + 1]]))
numPathSegmentsReduced += 1 _num_path_segments_removed += 1
elif data[i + 1] == 0: elif data[i + 1] == 0:
if lineTuples: if lineTuples:
# flush the m/l command, then append the h and then the remaining line coords # flush the m/l command, then append the h and then the remaining line coords
@ -2341,7 +2325,7 @@ def cleanPath(element, options):
lineTuples = [] lineTuples = []
cmd = 'l' # dealing with linetos now cmd = 'l' # dealing with linetos now
newPath.append(('h', [data[i]])) newPath.append(('h', [data[i]]))
numPathSegmentsReduced += 1 _num_path_segments_removed += 1
else: else:
lineTuples.extend(data[i:i + 2]) lineTuples.extend(data[i:i + 2])
i += 2 i += 2
@ -2370,7 +2354,7 @@ def cleanPath(element, options):
curveTuples = [] curveTuples = []
# append the s command # append the s command
newPath.append(('s', [data[i + 2], data[i + 3], data[i + 4], data[i + 5]])) newPath.append(('s', [data[i + 2], data[i + 3], data[i + 4], data[i + 5]]))
numPathSegmentsReduced += 1 _num_path_segments_removed += 1
else: else:
j = 0 j = 0
while j <= 5: while j <= 5:
@ -2395,7 +2379,7 @@ def cleanPath(element, options):
curveTuples = [] curveTuples = []
# append the t command # append the t command
newPath.append(('t', [data[i + 2], data[i + 3]])) newPath.append(('t', [data[i + 2], data[i + 3]]))
numPathSegmentsReduced += 1 _num_path_segments_removed += 1
else: else:
j = 0 j = 0
while j <= 3: while j <= 3:
@ -2424,7 +2408,7 @@ def cleanPath(element, options):
if isSameSign(data[coordIndex - 1], data[coordIndex]): if isSameSign(data[coordIndex - 1], data[coordIndex]):
data[coordIndex - 1] += data[coordIndex] data[coordIndex - 1] += data[coordIndex]
del data[coordIndex] del data[coordIndex]
numPathSegmentsReduced += 1 _num_path_segments_removed += 1
else: else:
coordIndex += 1 coordIndex += 1
@ -2459,7 +2443,7 @@ def cleanPath(element, options):
# if for whatever reason we actually made the path longer don't use it # if for whatever reason we actually made the path longer don't use it
# TODO: maybe we could compare path lengths after each optimization step and use the shortest # TODO: maybe we could compare path lengths after each optimization step and use the shortest
if len(newPathStr) <= len(oldPathStr): if len(newPathStr) <= len(oldPathStr):
numBytesSavedInPathData += (len(oldPathStr) - len(newPathStr)) _num_bytes_saved_in_path_data += (len(oldPathStr) - len(newPathStr))
element.setAttribute('d', newPathStr) element.setAttribute('d', newPathStr)
@ -2527,7 +2511,7 @@ def cleanPolygon(elem, options):
""" """
Remove unnecessary closing point of polygon points attribute Remove unnecessary closing point of polygon points attribute
""" """
global numPointsRemovedFromPolygon global _num_points_removed_from_polygon
pts = parseListOfPoints(elem.getAttribute('points')) pts = parseListOfPoints(elem.getAttribute('points'))
N = len(pts) / 2 N = len(pts) / 2
@ -2536,7 +2520,7 @@ def cleanPolygon(elem, options):
(endx, endy) = pts[-2:] (endx, endy) = pts[-2:]
if startx == endx and starty == endy: if startx == endx and starty == endy:
del pts[-2:] del pts[-2:]
numPointsRemovedFromPolygon += 1 _num_points_removed_from_polygon += 1
elem.setAttribute('points', scourCoordinates(pts, options, True)) elem.setAttribute('points', scourCoordinates(pts, options, True))
@ -2944,10 +2928,10 @@ def removeComments(element):
""" """
Removes comments from the element and its children. Removes comments from the element and its children.
""" """
global numCommentBytes global _num_bytes_saved_in_comments
if isinstance(element, xml.dom.minidom.Comment): if isinstance(element, xml.dom.minidom.Comment):
numCommentBytes += len(element.data) _num_bytes_saved_in_comments += len(element.data)
element.parentNode.removeChild(element) element.parentNode.removeChild(element)
else: else:
for subelement in element.childNodes[:]: for subelement in element.childNodes[:]:
@ -2961,7 +2945,7 @@ def embedRasters(element, options):
Converts raster references to inline images. Converts raster references to inline images.
NOTE: there are size limits to base64-encoding handling in browsers NOTE: there are size limits to base64-encoding handling in browsers
""" """
global numRastersEmbedded global _num_rasters_embedded
href = element.getAttributeNS(NS['XLINK'], 'href') href = element.getAttributeNS(NS['XLINK'], 'href')
@ -3009,7 +2993,7 @@ def embedRasters(element, options):
ext = 'jpeg' ext = 'jpeg'
element.setAttributeNS(NS['XLINK'], 'href', 'data:image/' + ext + ';base64,' + b64eRaster) element.setAttributeNS(NS['XLINK'], 'href', 'data:image/' + ext + ';base64,' + b64eRaster)
numRastersEmbedded += 1 _num_rasters_embedded += 1
del b64eRaster del b64eRaster
@ -3253,14 +3237,37 @@ def scourString(in_string, options=None):
global scouringContext global scouringContext
scouringContext = Context(prec=options.digits) scouringContext = Context(prec=options.digits)
global numAttrsRemoved # globals for tracking statistics
global numStylePropsFixed # TODO: get rid of these globals...
global numElemsRemoved global _num_elements_removed
global numBytesSavedInColors global _num_attributes_removed
global numCommentsRemoved global _num_ids_removed
global numBytesSavedInIDs global _num_comments_removed
global numBytesSavedInLengths global _num_style_properties_fixed
global numBytesSavedInTransforms global _num_rasters_embedded
global _num_path_segments_removed
global _num_points_removed_from_polygon
global _num_bytes_saved_in_path_data
global _num_bytes_saved_in_colors
global _num_bytes_saved_in_comments
global _num_bytes_saved_in_ids
global _num_bytes_saved_in_lengths
global _num_bytes_saved_in_transforms
_num_elements_removed = 0
_num_attributes_removed = 0
_num_ids_removed = 0
_num_comments_removed = 0
_num_style_properties_fixed = 0
_num_rasters_embedded = 0
_num_path_segments_removed = 0
_num_points_removed_from_polygon = 0
_num_bytes_saved_in_path_data = 0
_num_bytes_saved_in_colors = 0
_num_bytes_saved_in_comments = 0
_num_bytes_saved_in_ids = 0
_num_bytes_saved_in_lengths = 0
_num_bytes_saved_in_transforms = 0
doc = xml.dom.minidom.parseString(in_string) doc = xml.dom.minidom.parseString(in_string)
# determine number of flowRoot elements in input document # determine number of flowRoot elements in input document
@ -3295,7 +3302,7 @@ def scourString(in_string, options=None):
for attr in xmlnsDeclsToRemove: for attr in xmlnsDeclsToRemove:
doc.documentElement.removeAttribute(attr) doc.documentElement.removeAttribute(attr)
numAttrsRemoved += 1 _num_attributes_removed += 1
# ensure namespace for SVG is declared # ensure namespace for SVG is declared
# TODO: what if the default namespace is something else (i.e. some valid namespace)? # TODO: what if the default namespace is something else (i.e. some valid namespace)?
@ -3330,24 +3337,24 @@ def scourString(in_string, options=None):
for attrName in xmlnsDeclsToRemove: for attrName in xmlnsDeclsToRemove:
doc.documentElement.removeAttribute(attrName) doc.documentElement.removeAttribute(attrName)
numAttrsRemoved += 1 _num_attributes_removed += 1
for prefix in redundantPrefixes: for prefix in redundantPrefixes:
remapNamespacePrefix(doc.documentElement, prefix, '') remapNamespacePrefix(doc.documentElement, prefix, '')
if options.strip_comments: if options.strip_comments:
numCommentsRemoved = removeComments(doc) _num_comments_removed = removeComments(doc)
if options.strip_xml_space_attribute and doc.documentElement.hasAttribute('xml:space'): if options.strip_xml_space_attribute and doc.documentElement.hasAttribute('xml:space'):
doc.documentElement.removeAttribute('xml:space') doc.documentElement.removeAttribute('xml:space')
numAttrsRemoved += 1 _num_attributes_removed += 1
# repair style (remove unnecessary style properties and change them into XML attributes) # repair style (remove unnecessary style properties and change them into XML attributes)
numStylePropsFixed = repairStyle(doc.documentElement, options) _num_style_properties_fixed = repairStyle(doc.documentElement, options)
# convert colors to #RRGGBB format # convert colors to #RRGGBB format
if options.simple_colors: if options.simple_colors:
numBytesSavedInColors = convertColors(doc.documentElement) _num_bytes_saved_in_colors = convertColors(doc.documentElement)
# remove unreferenced gradients/patterns outside of defs # remove unreferenced gradients/patterns outside of defs
# and most unreferenced elements inside of defs # and most unreferenced elements inside of defs
@ -3369,7 +3376,7 @@ def scourString(in_string, options=None):
removeElem = True removeElem = True
if removeElem: if removeElem:
elem.parentNode.removeChild(elem) elem.parentNode.removeChild(elem)
numElemsRemoved += 1 _num_elements_removed += 1
if options.strip_ids: if options.strip_ids:
bContinueLooping = True bContinueLooping = True
@ -3401,10 +3408,10 @@ def scourString(in_string, options=None):
# doesn't accept fill=, stroke= etc.! # doesn't accept fill=, stroke= etc.!
referencedIds = findReferencedElements(doc.documentElement) referencedIds = findReferencedElements(doc.documentElement)
for child in doc.documentElement.childNodes: for child in doc.documentElement.childNodes:
numAttrsRemoved += moveCommonAttributesToParentGroup(child, referencedIds) _num_attributes_removed += moveCommonAttributesToParentGroup(child, referencedIds)
# remove unused attributes from parent # remove unused attributes from parent
numAttrsRemoved += removeUnusedAttributesOnParent(doc.documentElement) _num_attributes_removed += removeUnusedAttributesOnParent(doc.documentElement)
# Collapse groups LAST, because we've created groups. If done before # Collapse groups LAST, because we've created groups. If done before
# moveAttributesToParentGroup, empty <g>'s may remain. # moveAttributesToParentGroup, empty <g>'s may remain.
@ -3429,7 +3436,7 @@ def scourString(in_string, options=None):
# shorten ID names as much as possible # shorten ID names as much as possible
if options.shorten_ids: if options.shorten_ids:
numBytesSavedInIDs += shortenIDs(doc, options.shorten_ids_prefix, unprotected_ids(doc, options)) _num_bytes_saved_in_ids += shortenIDs(doc, options.shorten_ids_prefix, unprotected_ids(doc, options))
# scour lengths (including coordinates) # scour lengths (including coordinates)
for type in ['svg', 'image', 'rect', 'circle', 'ellipse', 'line', for type in ['svg', 'image', 'rect', 'circle', 'ellipse', 'line',
@ -3441,13 +3448,13 @@ def scourString(in_string, options=None):
elem.setAttribute(attr, scourLength(elem.getAttribute(attr))) elem.setAttribute(attr, scourLength(elem.getAttribute(attr)))
# more length scouring in this function # more length scouring in this function
numBytesSavedInLengths = reducePrecision(doc.documentElement) _num_bytes_saved_in_lengths = reducePrecision(doc.documentElement)
# remove default values of attributes # remove default values of attributes
numAttrsRemoved += removeDefaultAttributeValues(doc.documentElement, options) _num_attributes_removed += removeDefaultAttributeValues(doc.documentElement, options)
# reduce the length of transformation attributes # reduce the length of transformation attributes
numBytesSavedInTransforms = optimizeTransforms(doc.documentElement, options) _num_bytes_saved_in_transforms = optimizeTransforms(doc.documentElement, options)
# convert rasters references to base64-encoded strings # convert rasters references to base64-encoded strings
if options.embed_rasters: if options.embed_rasters:
@ -3734,19 +3741,22 @@ def getInOut(options):
def getReport(): def getReport():
return ' Number of elements removed: ' + str(numElemsRemoved) + os.linesep + \ return (
' Number of attributes removed: ' + str(numAttrsRemoved) + os.linesep + \ ' Number of elements removed: ' + str(_num_elements_removed) + os.linesep +
' Number of unreferenced id attributes removed: ' + str(numIDsRemoved) + os.linesep + \ ' Number of attributes removed: ' + str(_num_attributes_removed) + os.linesep +
' Number of style properties fixed: ' + str(numStylePropsFixed) + os.linesep + \ ' Number of unreferenced IDs removed: ' + str(_num_ids_removed) + os.linesep +
' Number of raster images embedded inline: ' + str(numRastersEmbedded) + os.linesep + \ ' Number of comments removed: ' + str(_num_comments_removed) + os.linesep +
' Number of path segments reduced/removed: ' + str(numPathSegmentsReduced) + os.linesep + \ ' Number of style properties fixed: ' + str(_num_style_properties_fixed) + os.linesep +
' Number of bytes saved in path data: ' + str(numBytesSavedInPathData) + os.linesep + \ ' Number of raster images embedded: ' + str(_num_rasters_embedded) + os.linesep +
' Number of bytes saved in colors: ' + str(numBytesSavedInColors) + os.linesep + \ ' Number of path segments reduced/removed: ' + str(_num_path_segments_removed) + os.linesep +
' Number of points removed from polygons: ' + str(numPointsRemovedFromPolygon) + os.linesep + \ ' Number of points removed from polygons: ' + str(_num_points_removed_from_polygon) + os.linesep +
' Number of bytes saved in comments: ' + str(numCommentBytes) + os.linesep + \ ' Number of bytes saved in path data: ' + str(_num_bytes_saved_in_path_data) + os.linesep +
' Number of bytes saved in id attributes: ' + str(numBytesSavedInIDs) + os.linesep + \ ' Number of bytes saved in colors: ' + str(_num_bytes_saved_in_colors) + os.linesep +
' Number of bytes saved in lengths: ' + str(numBytesSavedInLengths) + os.linesep + \ ' Number of bytes saved in comments: ' + str(_num_bytes_saved_in_comments) + os.linesep +
' Number of bytes saved in transformations: ' + str(numBytesSavedInTransforms) ' Number of bytes saved in IDs: ' + str(_num_bytes_saved_in_ids) + os.linesep +
' Number of bytes saved in lengths: ' + str(_num_bytes_saved_in_lengths) + os.linesep +
' Number of bytes saved in transformations: ' + str(_num_bytes_saved_in_transforms)
)
def start(options, input, output): def start(options, input, output):