More fixes for globals used for statistics

- 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:05:11 +02:00
parent 47bc477cd1
commit 4ae7e93d7e

View file

@ -654,7 +654,7 @@ def removeUnreferencedElements(doc, keepDefs):
Returns the number of unreferenced elements removed from the document.
"""
global numElemsRemoved
global _num_elements_removed
num = 0
# Remove certain unreferenced elements outside of defs
@ -670,7 +670,7 @@ def removeUnreferencedElements(doc, keepDefs):
and goner.parentNode.tagName != 'defs'):
goner.parentNode.removeChild(goner)
num += 1
numElemsRemoved += 1
_num_elements_removed += 1
if not keepDefs:
# Remove most unreferenced elements inside defs
@ -679,7 +679,7 @@ def removeUnreferencedElements(doc, keepDefs):
elemsToRemove = removeUnusedDefs(doc, aDef)
for elem in elemsToRemove:
elem.parentNode.removeChild(elem)
numElemsRemoved += 1
_num_elements_removed += 1
num += 1
return num
@ -854,20 +854,20 @@ def removeUnreferencedIDs(referencedIDs, identifiedElements):
Returns the number of ID attributes removed
"""
global numIDsRemoved
global _num_ids_removed
keepTags = ['font']
num = 0
for id in list(identifiedElements.keys()):
node = identifiedElements[id]
if id not in referencedIDs and node.nodeName not in keepTags:
node.removeAttribute('id')
numIDsRemoved += 1
_num_ids_removed += 1
num += 1
return num
def removeNamespacedAttributes(node, namespaces):
global numAttrsRemoved
global _num_attributes_removed
num = 0
if node.nodeType == 1:
# remove all namespace'd attributes from this element
@ -879,7 +879,7 @@ def removeNamespacedAttributes(node, namespaces):
attrsToRemove.append(attr.nodeName)
for attrName in attrsToRemove:
num += 1
numAttrsRemoved += 1
_num_attributes_removed += 1
node.removeAttribute(attrName)
# now recurse for children
@ -889,7 +889,7 @@ def removeNamespacedAttributes(node, namespaces):
def removeNamespacedElements(node, namespaces):
global numElemsRemoved
global _num_elements_removed
num = 0
if node.nodeType == 1:
# remove all namespace'd child nodes from this element
@ -900,7 +900,7 @@ def removeNamespacedElements(node, namespaces):
childrenToRemove.append(child)
for child in childrenToRemove:
num += 1
numElemsRemoved += 1
_num_elements_removed += 1
node.removeChild(child)
# now recurse for children
@ -923,7 +923,7 @@ def removeDescriptiveElements(doc, options):
if not elementTypes:
return
global numElemsRemoved
global _num_elements_removed
num = 0
elementsToRemove = []
for elementType in elementTypes:
@ -932,7 +932,7 @@ def removeDescriptiveElements(doc, options):
for element in elementsToRemove:
element.parentNode.removeChild(element)
num += 1
numElemsRemoved += 1
_num_elements_removed += 1
return num
@ -943,7 +943,7 @@ def removeNestedGroups(node):
which do not have any attributes or a title/desc child and
promoting their children up one level
"""
global numElemsRemoved
global _num_elements_removed
num = 0
groupsToRemove = []
@ -964,7 +964,7 @@ def removeNestedGroups(node):
while g.childNodes.length > 0:
g.parentNode.insertBefore(g.firstChild, g)
g.parentNode.removeChild(g)
numElemsRemoved += 1
_num_elements_removed += 1
num += 1
# now recurse for children
@ -1070,7 +1070,7 @@ def createGroupsForCommonAttributes(elem):
This function acts recursively on the given element.
"""
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
# could be added here
@ -1169,7 +1169,7 @@ def createGroupsForCommonAttributes(elem):
group.parentNode = elem
num += 1
curChild = runStart - 1
numElemsRemoved -= 1
_num_elements_removed -= 1
else:
curChild -= 1
else:
@ -1239,7 +1239,7 @@ def removeUnusedAttributesOnParent(elem):
def removeDuplicateGradientStops(doc):
global numElemsRemoved
global _num_elements_removed
num = 0
for gradType in ['linearGradient', 'radialGradient']:
@ -1273,14 +1273,14 @@ def removeDuplicateGradientStops(doc):
for stop in stopsToRemove:
stop.parentNode.removeChild(stop)
num += 1
numElemsRemoved += 1
_num_elements_removed += 1
# linear gradients
return num
def collapseSinglyReferencedGradients(doc):
global numElemsRemoved
global _num_elements_removed
num = 0
identifiedElements = findElementsWithId(doc.documentElement)
@ -1332,13 +1332,13 @@ def collapseSinglyReferencedGradients(doc):
# now delete elem
elem.parentNode.removeChild(elem)
numElemsRemoved += 1
_num_elements_removed += 1
num += 1
return num
def removeDuplicateGradients(doc):
global numElemsRemoved
global _num_elements_removed
num = 0
gradientsToRemove = {}
@ -1432,7 +1432,7 @@ def removeDuplicateGradients(doc):
# now that all referencing elements have been re-mapped to the master
# it is safe to remove this gradient from the document
dupGrad.parentNode.removeChild(dupGrad)
numElemsRemoved += 1
_num_elements_removed += 1
num += 1
return num
@ -2037,8 +2037,8 @@ def cleanPath(element, options):
"""
Cleans the path string (d attribute) of the element
"""
global numBytesSavedInPathData
global numPathSegmentsReduced
global _num_bytes_saved_in_path_data
global _num_path_segments_removed
# this gets the parser object from svg_regex.py
oldPathStr = element.getAttribute('d')
@ -2168,40 +2168,40 @@ def cleanPath(element, options):
# 'm0,0 x,y' can be replaces with 'lx,y',
# except the first m which is a required absolute moveto
path[pathIndex] = ('l', data[2:])
numPathSegmentsReduced += 1
_num_path_segments_removed += 1
else: # else skip move coordinate
i = 2
while i < len(data):
if data[i] == data[i + 1] == 0:
del data[i:i + 2]
numPathSegmentsReduced += 1
_num_path_segments_removed += 1
else:
i += 2
elif cmd == 'c':
while i < len(data):
if data[i] == data[i + 1] == data[i + 2] == data[i + 3] == data[i + 4] == data[i + 5] == 0:
del data[i:i + 6]
numPathSegmentsReduced += 1
_num_path_segments_removed += 1
else:
i += 6
elif cmd == 'a':
while i < len(data):
if data[i + 5] == data[i + 6] == 0:
del data[i:i + 7]
numPathSegmentsReduced += 1
_num_path_segments_removed += 1
else:
i += 7
elif cmd == 'q':
while i < len(data):
if data[i] == data[i + 1] == data[i + 2] == data[i + 3] == 0:
del data[i:i + 4]
numPathSegmentsReduced += 1
_num_path_segments_removed += 1
else:
i += 4
elif cmd in ['h', 'v']:
oldLen = len(data)
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.
path = [elem for elem in path if len(elem[1]) > 0 or elem[0] == 'z']
@ -2290,14 +2290,14 @@ def cleanPath(element, options):
lineTuples = []
# append the v and then the remaining line coords
newPath.append(('v', [data[i + 1]]))
numPathSegmentsReduced += 1
_num_path_segments_removed += 1
elif data[i + 1] == 0:
if lineTuples:
# flush the line command, then append the h and then the remaining line coords
newPath.append(('l', lineTuples))
lineTuples = []
newPath.append(('h', [data[i]]))
numPathSegmentsReduced += 1
_num_path_segments_removed += 1
else:
lineTuples.extend(data[i:i + 2])
i += 2
@ -2317,7 +2317,7 @@ def cleanPath(element, options):
cmd = 'l' # dealing with linetos now
# append the v and then the remaining line coords
newPath.append(('v', [data[i + 1]]))
numPathSegmentsReduced += 1
_num_path_segments_removed += 1
elif data[i + 1] == 0:
if lineTuples:
# flush the m/l command, then append the h and then the remaining line coords
@ -2325,7 +2325,7 @@ def cleanPath(element, options):
lineTuples = []
cmd = 'l' # dealing with linetos now
newPath.append(('h', [data[i]]))
numPathSegmentsReduced += 1
_num_path_segments_removed += 1
else:
lineTuples.extend(data[i:i + 2])
i += 2
@ -2354,7 +2354,7 @@ def cleanPath(element, options):
curveTuples = []
# append the s command
newPath.append(('s', [data[i + 2], data[i + 3], data[i + 4], data[i + 5]]))
numPathSegmentsReduced += 1
_num_path_segments_removed += 1
else:
j = 0
while j <= 5:
@ -2379,7 +2379,7 @@ def cleanPath(element, options):
curveTuples = []
# append the t command
newPath.append(('t', [data[i + 2], data[i + 3]]))
numPathSegmentsReduced += 1
_num_path_segments_removed += 1
else:
j = 0
while j <= 3:
@ -2408,7 +2408,7 @@ def cleanPath(element, options):
if isSameSign(data[coordIndex - 1], data[coordIndex]):
data[coordIndex - 1] += data[coordIndex]
del data[coordIndex]
numPathSegmentsReduced += 1
_num_path_segments_removed += 1
else:
coordIndex += 1
@ -2443,7 +2443,7 @@ def cleanPath(element, options):
# 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
if len(newPathStr) <= len(oldPathStr):
numBytesSavedInPathData += (len(oldPathStr) - len(newPathStr))
_num_bytes_saved_in_path_data += (len(oldPathStr) - len(newPathStr))
element.setAttribute('d', newPathStr)
@ -2511,7 +2511,7 @@ def cleanPolygon(elem, options):
"""
Remove unnecessary closing point of polygon points attribute
"""
global numPointsRemovedFromPolygon
global _num_points_removed_from_polygon
pts = parseListOfPoints(elem.getAttribute('points'))
N = len(pts) / 2
@ -2520,7 +2520,7 @@ def cleanPolygon(elem, options):
(endx, endy) = pts[-2:]
if startx == endx and starty == endy:
del pts[-2:]
numPointsRemovedFromPolygon += 1
_num_points_removed_from_polygon += 1
elem.setAttribute('points', scourCoordinates(pts, options, True))
@ -2928,10 +2928,10 @@ def removeComments(element):
"""
Removes comments from the element and its children.
"""
global numCommentBytes
global _num_bytes_saved_in_comments
if isinstance(element, xml.dom.minidom.Comment):
numCommentBytes += len(element.data)
_num_bytes_saved_in_comments += len(element.data)
element.parentNode.removeChild(element)
else:
for subelement in element.childNodes[:]:
@ -2945,7 +2945,7 @@ def embedRasters(element, options):
Converts raster references to inline images.
NOTE: there are size limits to base64-encoding handling in browsers
"""
global numRastersEmbedded
global _num_rasters_embedded
href = element.getAttributeNS(NS['XLINK'], 'href')
@ -2993,7 +2993,7 @@ def embedRasters(element, options):
ext = 'jpeg'
element.setAttributeNS(NS['XLINK'], 'href', 'data:image/' + ext + ';base64,' + b64eRaster)
numRastersEmbedded += 1
_num_rasters_embedded += 1
del b64eRaster
@ -3239,34 +3239,34 @@ def scourString(in_string, options=None):
# globals for tracking statistics
# TODO: get rid of these globals...
global numElemsRemoved
global numAttrsRemoved
global numIDsRemoved
global numCommentsRemoved
global numStylePropsFixed
global numRastersEmbedded
global numPathSegmentsReduced
global numBytesSavedInPathData
global numBytesSavedInColors
global numPointsRemovedFromPolygon
global numCommentBytes
global numBytesSavedInIDs
global numBytesSavedInLengths
global numBytesSavedInTransforms
numElemsRemoved = 0
numAttrsRemoved = 0
numIDsRemoved = 0
numCommentsRemoved = 0
numStylePropsFixed = 0
numRastersEmbedded = 0
numPathSegmentsReduced = 0
numBytesSavedInPathData = 0
numBytesSavedInColors = 0
numPointsRemovedFromPolygon = 0
numCommentBytes = 0
numBytesSavedInIDs = 0
numBytesSavedInLengths = 0
numBytesSavedInTransforms = 0
global _num_elements_removed
global _num_attributes_removed
global _num_ids_removed
global _num_comments_removed
global _num_style_properties_fixed
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)
@ -3302,7 +3302,7 @@ def scourString(in_string, options=None):
for attr in xmlnsDeclsToRemove:
doc.documentElement.removeAttribute(attr)
numAttrsRemoved += 1
_num_attributes_removed += 1
# ensure namespace for SVG is declared
# TODO: what if the default namespace is something else (i.e. some valid namespace)?
@ -3337,24 +3337,24 @@ def scourString(in_string, options=None):
for attrName in xmlnsDeclsToRemove:
doc.documentElement.removeAttribute(attrName)
numAttrsRemoved += 1
_num_attributes_removed += 1
for prefix in redundantPrefixes:
remapNamespacePrefix(doc.documentElement, prefix, '')
if options.strip_comments:
numCommentsRemoved = removeComments(doc)
_num_comments_removed = removeComments(doc)
if options.strip_xml_space_attribute and doc.documentElement.hasAttribute('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)
numStylePropsFixed = repairStyle(doc.documentElement, options)
_num_style_properties_fixed = repairStyle(doc.documentElement, options)
# convert colors to #RRGGBB format
if options.simple_colors:
numBytesSavedInColors = convertColors(doc.documentElement)
_num_bytes_saved_in_colors = convertColors(doc.documentElement)
# remove unreferenced gradients/patterns outside of defs
# and most unreferenced elements inside of defs
@ -3376,7 +3376,7 @@ def scourString(in_string, options=None):
removeElem = True
if removeElem:
elem.parentNode.removeChild(elem)
numElemsRemoved += 1
_num_elements_removed += 1
if options.strip_ids:
bContinueLooping = True
@ -3408,10 +3408,10 @@ def scourString(in_string, options=None):
# doesn't accept fill=, stroke= etc.!
referencedIds = findReferencedElements(doc.documentElement)
for child in doc.documentElement.childNodes:
numAttrsRemoved += moveCommonAttributesToParentGroup(child, referencedIds)
_num_attributes_removed += moveCommonAttributesToParentGroup(child, referencedIds)
# 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
# moveAttributesToParentGroup, empty <g>'s may remain.
@ -3436,7 +3436,7 @@ def scourString(in_string, options=None):
# shorten ID names as much as possible
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)
for type in ['svg', 'image', 'rect', 'circle', 'ellipse', 'line',
@ -3448,13 +3448,13 @@ def scourString(in_string, options=None):
elem.setAttribute(attr, scourLength(elem.getAttribute(attr)))
# more length scouring in this function
numBytesSavedInLengths = reducePrecision(doc.documentElement)
_num_bytes_saved_in_lengths = reducePrecision(doc.documentElement)
# remove default values of attributes
numAttrsRemoved += removeDefaultAttributeValues(doc.documentElement, options)
_num_attributes_removed += removeDefaultAttributeValues(doc.documentElement, options)
# 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
if options.embed_rasters:
@ -3741,19 +3741,22 @@ def getInOut(options):
def getReport():
return ' Number of elements removed: ' + str(numElemsRemoved) + os.linesep + \
' Number of attributes removed: ' + str(numAttrsRemoved) + os.linesep + \
' Number of unreferenced id attributes removed: ' + str(numIDsRemoved) + os.linesep + \
' Number of style properties fixed: ' + str(numStylePropsFixed) + os.linesep + \
' Number of raster images embedded inline: ' + str(numRastersEmbedded) + os.linesep + \
' Number of path segments reduced/removed: ' + str(numPathSegmentsReduced) + os.linesep + \
' Number of bytes saved in path data: ' + str(numBytesSavedInPathData) + os.linesep + \
' Number of bytes saved in colors: ' + str(numBytesSavedInColors) + os.linesep + \
' Number of points removed from polygons: ' + str(numPointsRemovedFromPolygon) + os.linesep + \
' Number of bytes saved in comments: ' + str(numCommentBytes) + os.linesep + \
' Number of bytes saved in id attributes: ' + str(numBytesSavedInIDs) + os.linesep + \
' Number of bytes saved in lengths: ' + str(numBytesSavedInLengths) + os.linesep + \
' Number of bytes saved in transformations: ' + str(numBytesSavedInTransforms)
return (
' Number of elements removed: ' + str(_num_elements_removed) + os.linesep +
' Number of attributes removed: ' + str(_num_attributes_removed) + os.linesep +
' Number of unreferenced IDs removed: ' + str(_num_ids_removed) + os.linesep +
' Number of comments removed: ' + str(_num_comments_removed) + os.linesep +
' Number of style properties fixed: ' + str(_num_style_properties_fixed) + os.linesep +
' Number of raster images embedded: ' + str(_num_rasters_embedded) + os.linesep +
' Number of path segments reduced/removed: ' + str(_num_path_segments_removed) + os.linesep +
' Number of points removed from polygons: ' + str(_num_points_removed_from_polygon) + os.linesep +
' Number of bytes saved in path data: ' + str(_num_bytes_saved_in_path_data) + os.linesep +
' Number of bytes saved in colors: ' + str(_num_bytes_saved_in_colors) + os.linesep +
' Number of bytes saved in comments: ' + str(_num_bytes_saved_in_comments) + os.linesep +
' 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):