diff --git a/scour/scour.py b/scour/scour.py
index afee25d..754e5dd 100644
--- a/scour/scour.py
+++ b/scour/scour.py
@@ -1381,22 +1381,27 @@ def removeDuplicateGradients(doc):
for dupGrad in gradientsToRemove[masterGrad]:
# if the duplicate gradient no longer has a parent that means it was
# already re-mapped to another master gradient
- if not dupGrad.parentNode: continue
+ if not dupGrad.parentNode:
+ continue
+
+ # for each element that referenced the gradient we are going to replace dup_id with master_id
dup_id = dupGrad.getAttribute('id')
- # for each element that referenced the gradient we are going to remove
+ funcIRI = re.compile('url\([\'"]?#' + dup_id + '[\'"]?\)') # matches url(#a), url('#a') and url("#a")
for elem in referencedIDs[dup_id][1]:
# find out which attribute referenced the duplicate gradient
for attr in ['fill', 'stroke']:
v = elem.getAttribute(attr)
- if v == 'url(#'+dup_id+')' or v == 'url("#'+dup_id+'")' or v == "url('#"+dup_id+"')":
- elem.setAttribute(attr, 'url(#'+master_id+')')
+ (v_new, n) = funcIRI.subn('url(#'+master_id+')', v)
+ if n > 0:
+ elem.setAttribute(attr, v_new)
if elem.getAttributeNS(NS['XLINK'], 'href') == '#'+dup_id:
elem.setAttributeNS(NS['XLINK'], 'href', '#'+master_id)
styles = _getStyle(elem)
for style in styles:
v = styles[style]
- if v == 'url(#'+dup_id+')' or v == 'url("#'+dup_id+'")' or v == "url('#"+dup_id+"')":
- styles[style] = 'url(#'+master_id+')'
+ (v_new, n) = funcIRI.subn('url(#'+master_id+')', v)
+ if n > 0:
+ styles[style] = v_new
_setStyle(elem, styles)
# now that all referencing elements have been re-mapped to the master
diff --git a/testscour.py b/testscour.py
index f409225..294cb7f 100755
--- a/testscour.py
+++ b/testscour.py
@@ -864,9 +864,9 @@ class RereferenceForLinearGradient(unittest.TestCase):
svgdoc = scour.scourXmlFile('unittests/remove-duplicate-gradients.svg')
rects = svgdoc.getElementsByTagNameNS(SVGNS, 'rect')
self.assertEqual(rects[0].getAttribute('fill'), rects[1].getAttribute('stroke'),
- 'Rect not changed after removing duplicate linear gradient')
+ 'Reference not updated after removing duplicate linear gradient')
self.assertEqual(rects[0].getAttribute('fill'), rects[4].getAttribute('fill'),
- 'Rect not changed after removing duplicate linear gradient')
+ 'Reference not updated after removing duplicate linear gradient')
class RemoveDuplicateRadialGradients(unittest.TestCase):
def runTest(self):
@@ -880,7 +880,15 @@ class RereferenceForRadialGradient(unittest.TestCase):
svgdoc = scour.scourXmlFile('unittests/remove-duplicate-gradients.svg')
rects = svgdoc.getElementsByTagNameNS(SVGNS, 'rect')
self.assertEqual(rects[2].getAttribute('stroke'), rects[3].getAttribute('fill'),
- 'Rect not changed after removing duplicate radial gradient')
+ 'Reference not updated after removing duplicate radial gradient')
+
+class RereferenceForGradientWithFallback(unittest.TestCase):
+ def runTest(self):
+ svgdoc = scour.scourXmlFile('unittests/remove-duplicate-gradients.svg')
+ rects = svgdoc.getElementsByTagNameNS(SVGNS, 'rect')
+ self.assertEqual(rects[0].getAttribute('fill') + ' #fff', rects[5].getAttribute('fill'),
+ 'Reference (with fallback) not updated after removing duplicate linear gradient')
+
class CollapseSamePathPoints(unittest.TestCase):
def runTest(self):
@@ -1536,13 +1544,14 @@ class DuplicateGradientsUpdateStyle(unittest.TestCase):
def runTest(self):
doc = scour.scourXmlFile('unittests/duplicate-gradients-update-style.svg',
scour.parse_args(['--disable-style-to-xml']))
- gradientTag = doc.getElementsByTagName('linearGradient')[0]
- rectTag0 = doc.getElementsByTagName('rect')[0]
- rectTag1 = doc.getElementsByTagName('rect')[1]
- self.assertEqual('fill:url(#' + gradientTag.getAttribute('id') + ')', rectTag0.getAttribute('style'),
+ gradient = doc.getElementsByTagName('linearGradient')[0]
+ rects = doc.getElementsByTagName('rect')
+ self.assertEqual('fill:url(#' + gradient.getAttribute('id') + ')', rects[0].getAttribute('style'),
'Either of #duplicate-one or #duplicate-two was removed, but style="fill:" was not updated to reflect this')
- self.assertEqual('fill:url(#' + gradientTag.getAttribute('id') + ')', rectTag1.getAttribute('style'),
+ self.assertEqual('fill:url(#' + gradient.getAttribute('id') + ')', rects[1].getAttribute('style'),
'Either of #duplicate-one or #duplicate-two was removed, but style="fill:" was not updated to reflect this')
+ self.assertEqual('fill:url(#' + gradient.getAttribute('id') + ') #fff', rects[2].getAttribute('style'),
+ 'Either of #duplicate-one or #duplicate-two was removed, but style="fill:" (with fallback) was not updated to reflect this')
class DocWithFlowtext(unittest.TestCase):
def runTest(self):
diff --git a/unittests/duplicate-gradients-update-style.svg b/unittests/duplicate-gradients-update-style.svg
index c28070c..b18d7b9 100644
--- a/unittests/duplicate-gradients-update-style.svg
+++ b/unittests/duplicate-gradients-update-style.svg
@@ -12,4 +12,5 @@
+
\ No newline at end of file
diff --git a/unittests/remove-duplicate-gradients.svg b/unittests/remove-duplicate-gradients.svg
index f986bdd..d84c089 100644
--- a/unittests/remove-duplicate-gradients.svg
+++ b/unittests/remove-duplicate-gradients.svg
@@ -20,4 +20,5 @@
+