=== modified file 'scour.py' --- scour.py 2011-02-11 00:48:53 +0000 +++ scour.py 2011-02-11 16:01:08 +0000 @@ -596,8 +596,9 @@ """ global numElemsRemoved num = 0 + + # Remove certain unreferenced elements outside of defs removeTags = ['linearGradient', 'radialGradient', 'pattern'] - identifiedElements = findElementsWithId(doc.documentElement) referencedIDs = findReferencedElements(doc.documentElement) @@ -609,8 +610,7 @@ num += 1 numElemsRemoved += 1 - # TODO: should also go through defs and vacuum it - num = 0 + # Remove most unreferenced elements inside defs defs = doc.documentElement.getElementsByTagName('defs') for aDef in defs: elemsToRemove = removeUnusedDefs(doc, aDef) @@ -2784,15 +2784,21 @@ if options.remove_metadata: removeMetadataElements(doc) + # remove unreferenced gradients/patterns outside of defs + # and most unreferenced elements inside of defs + while removeUnreferencedElements(doc) > 0: + pass + # remove empty defs, metadata, g - # NOTE: these elements will be removed even if they have (invalid) text nodes - elemsToRemove = [] + # NOTE: these elements will be removed if they just have whitespace-only text nodes for tag in ['defs', 'metadata', 'g'] : for elem in doc.documentElement.getElementsByTagName(tag) : removeElem = not elem.hasChildNodes() if removeElem == False : for child in elem.childNodes : - if child.nodeType in [1, 3, 4, 8] : + if child.nodeType in [1, 4, 8]: + break + elif child.nodeType == 3 and not child.nodeValue.isspace(): break else: removeElem = True @@ -2800,10 +2806,6 @@ elem.parentNode.removeChild(elem) numElemsRemoved += 1 - # remove unreferenced gradients/patterns outside of defs - while removeUnreferencedElements(doc) > 0: - pass - if options.strip_ids: bContinueLooping = True while bContinueLooping: === modified file 'testscour.py' --- testscour.py 2011-02-11 00:48:53 +0000 +++ testscour.py 2011-02-11 16:04:10 +0000 @@ -1205,6 +1205,12 @@ self.assertEquals(doc.getElementsByTagName('path')[10].getAttribute('fill-rule'), '', 'Default attribute not removed, although its parent used default'); +class RemoveDefsWithUnreferencedElements(unittest.TestCase): + def runTest(self): + doc = scour.scourXmlFile('unittests/useless-defs.svg') + self.assertEquals(doc.getElementsByTagName('defs').length, 0, + 'Unremoved defs, although it contains only unreferenced elements'); + # TODO: write tests for --enable-viewboxing # TODO; write a test for embedding rasters # TODO: write a test for --disable-embed-rasters === added file 'unittests/useless-defs.svg' --- unittests/useless-defs.svg 1970-01-01 00:00:00 +0000 +++ unittests/useless-defs.svg 2011-02-11 13:33:24 +0000 @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + +