From ec7d06f925de03271a3f0f7a9816de7fa331cd3b Mon Sep 17 00:00:00 2001 From: doom-goober Date: Sun, 20 Dec 2020 10:50:42 -0800 Subject: [PATCH 1/8] Add style argument. --- scour/scour.py | 31 +++++++++++++++++++++++------- test_scour.py | 38 +++++++++++++++++++++++++++++++++++++ unittests/attr-to-style.svg | 10 ++++++++++ 3 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 unittests/attr-to-style.svg diff --git a/scour/scour.py b/scour/scour.py index c987bb0..e1c3ef4 100644 --- a/scour/scour.py +++ b/scour/scour.py @@ -1800,15 +1800,27 @@ def repairStyle(node, options): del styleMap['overflow'] num += 1 + if node.nodeType == Node.ELEMENT_NODE: + if options.style_type == "inline": + # Prefer inline style + # Remove known SVG attributes and store their values in style attribute + attributes = [node.attributes.item(i).nodeName for i in range(node.attributes.length)] + for attribute in attributes: + if attribute in svgAttributes: + styleMap[attribute] = node.getAttribute(attribute) + node.removeAttribute(attribute) + elif options.style_type == "preserve": + # Keep whatever style of attribute versus style the file currently has + pass + elif options.style_to_xml or options.style_type == "attributes": # now if any of the properties match known SVG attributes we prefer attributes # over style so emit them and remove them from the style map - if options.style_to_xml: - for propName in list(styleMap): - if propName in svgAttributes: - node.setAttribute(propName, styleMap[propName]) - del styleMap[propName] - - _setStyle(node, styleMap) + for propName in list(styleMap): + if propName in svgAttributes: + node.setAttribute(propName, styleMap[propName]) + del styleMap[propName] + + _setStyle(node, styleMap) # recurse for our child elements for child in node.childNodes: @@ -3985,6 +3997,9 @@ def format_usage(self, usage): _option_group_optimization.add_option("--disable-style-to-xml", action="store_false", dest="style_to_xml", default=True, help="won't convert styles into XML attributes") +_option_group_optimization.add_option("--style", + action="store", type="string", dest="style_type", default="none", metavar="TYPE", + help="styles type (override style_to_xml): none, preserve, inline, attributes (default: %none)") _option_group_optimization.add_option("--disable-group-collapsing", action="store_false", dest="group_collapse", default=True, help="won't collapse elements") @@ -4101,6 +4116,8 @@ def parse_args(args=None, ignore_additional_args=False): _options_parser.error("Value for --nindent should be positive (or zero), see --help") if options.infilename and options.outfilename and options.infilename == options.outfilename: _options_parser.error("Input filename is the same as output filename") + if options.style_type not in ['none', 'preserve', 'attributes', 'inline']: + _options_parser.error("Invalid value for --style, see --help") return options diff --git a/test_scour.py b/test_scour.py index 549333f..da2aebe 100755 --- a/test_scour.py +++ b/test_scour.py @@ -2212,6 +2212,44 @@ def runTest(self): self.assertEqual(line.getAttribute('marker-mid'), 'url(#m)') self.assertEqual(line.getAttribute('marker-end'), 'url(#m)') +class AttrToStyle(unittest.TestCase): + + def runTest(self): + doc = scourXmlFile('unittests/attr-to-style.svg', + parse_args(['--style=inline'])) + line = doc.getElementsByTagName('line')[0] + self.assertEqual(line.getAttribute('stroke'), '') + self.assertEqual(line.getAttribute('marker-start'), '') + self.assertEqual(line.getAttribute('marker-mid'), '') + self.assertEqual(line.getAttribute('marker-end'), '') + + style_attribute = line.getAttribute('style') + rawStyles = style_attribute.split(';') + self.assertTrue("color:#FF0000" in rawStyles) + self.assertTrue("stroke:#000" in rawStyles) + self.assertTrue("marker-start:url(#m)" in rawStyles) + self.assertTrue("marker-end:url(#m)" in rawStyles) + self.assertTrue("marker-mid:url(#m)" in rawStyles) + +class StylePreserve(unittest.TestCase): + + def runTest(self): + doc = scourXmlFile('unittests/attr-to-style.svg', + parse_args(['--style=preserve'])) + + #First line uses attributes. + line = doc.getElementsByTagName('line')[0] + self.assertNotEqual(line.getAttribute('stroke'), '') + self.assertNotEqual(line.getAttribute('marker-start'), '') + self.assertNotEqual(line.getAttribute('marker-mid'), '') + self.assertNotEqual(line.getAttribute('marker-end'), '') + + #Second line uses style attribute. + line = doc.getElementsByTagName('line')[1] + self.assertEqual(line.getAttribute('stroke'), '') + self.assertEqual(line.getAttribute('marker-start'), '') + self.assertEqual(line.getAttribute('marker-mid'), '') + self.assertEqual(line.getAttribute('marker-end'), '') class PathCommandRewrites(unittest.TestCase): diff --git a/unittests/attr-to-style.svg b/unittests/attr-to-style.svg new file mode 100644 index 0000000..9173b0b --- /dev/null +++ b/unittests/attr-to-style.svg @@ -0,0 +1,10 @@ + + + + + + + + + + From 798eb299e530119d244f3cec89b12be0baf2d47a Mon Sep 17 00:00:00 2001 From: doom-goober Date: Sun, 20 Dec 2020 12:06:25 -0800 Subject: [PATCH 2/8] Fix flake errors. --- scour/scour.py | 41 +++++++++++++++++++++-------------------- test_scour.py | 11 +++++++---- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/scour/scour.py b/scour/scour.py index e1c3ef4..82b7f5b 100644 --- a/scour/scour.py +++ b/scour/scour.py @@ -1801,26 +1801,26 @@ def repairStyle(node, options): num += 1 if node.nodeType == Node.ELEMENT_NODE: - if options.style_type == "inline": - # Prefer inline style - # Remove known SVG attributes and store their values in style attribute - attributes = [node.attributes.item(i).nodeName for i in range(node.attributes.length)] - for attribute in attributes: - if attribute in svgAttributes: - styleMap[attribute] = node.getAttribute(attribute) - node.removeAttribute(attribute) - elif options.style_type == "preserve": - # Keep whatever style of attribute versus style the file currently has - pass - elif options.style_to_xml or options.style_type == "attributes": - # now if any of the properties match known SVG attributes we prefer attributes - # over style so emit them and remove them from the style map - for propName in list(styleMap): - if propName in svgAttributes: - node.setAttribute(propName, styleMap[propName]) - del styleMap[propName] + if options.style_type == "inline": + # Prefer inline style + # Remove known SVG attributes and store their values in style attribute + attributes = [node.attributes.item(i).nodeName for i in range(node.attributes.length)] + for attribute in attributes: + if attribute in svgAttributes: + styleMap[attribute] = node.getAttribute(attribute) + node.removeAttribute(attribute) + elif options.style_type == "preserve": + # Keep whatever style of attribute versus style the file currently has + pass + elif options.style_to_xml or options.style_type == "attributes": + # now if any of the properties match known SVG attributes we prefer attributes + # over style so emit them and remove them from the style map + for propName in list(styleMap): + if propName in svgAttributes: + node.setAttribute(propName, styleMap[propName]) + del styleMap[propName] - _setStyle(node, styleMap) + _setStyle(node, styleMap) # recurse for our child elements for child in node.childNodes: @@ -3999,7 +3999,8 @@ def format_usage(self, usage): help="won't convert styles into XML attributes") _option_group_optimization.add_option("--style", action="store", type="string", dest="style_type", default="none", metavar="TYPE", - help="styles type (override style_to_xml): none, preserve, inline, attributes (default: %none)") + help="style type (overrides style-to-xml): none, preserve, inline,"\ + "attributes (default: %none)") _option_group_optimization.add_option("--disable-group-collapsing", action="store_false", dest="group_collapse", default=True, help="won't collapse elements") diff --git a/test_scour.py b/test_scour.py index da2aebe..ee12efd 100755 --- a/test_scour.py +++ b/test_scour.py @@ -2212,11 +2212,12 @@ def runTest(self): self.assertEqual(line.getAttribute('marker-mid'), 'url(#m)') self.assertEqual(line.getAttribute('marker-end'), 'url(#m)') + class AttrToStyle(unittest.TestCase): def runTest(self): doc = scourXmlFile('unittests/attr-to-style.svg', - parse_args(['--style=inline'])) + parse_args(['--style=inline'])) line = doc.getElementsByTagName('line')[0] self.assertEqual(line.getAttribute('stroke'), '') self.assertEqual(line.getAttribute('marker-start'), '') @@ -2231,26 +2232,28 @@ def runTest(self): self.assertTrue("marker-end:url(#m)" in rawStyles) self.assertTrue("marker-mid:url(#m)" in rawStyles) + class StylePreserve(unittest.TestCase): def runTest(self): doc = scourXmlFile('unittests/attr-to-style.svg', - parse_args(['--style=preserve'])) + parse_args(['--style=preserve'])) - #First line uses attributes. + # First line uses attributes. line = doc.getElementsByTagName('line')[0] self.assertNotEqual(line.getAttribute('stroke'), '') self.assertNotEqual(line.getAttribute('marker-start'), '') self.assertNotEqual(line.getAttribute('marker-mid'), '') self.assertNotEqual(line.getAttribute('marker-end'), '') - #Second line uses style attribute. + # Second line uses style attribute. line = doc.getElementsByTagName('line')[1] self.assertEqual(line.getAttribute('stroke'), '') self.assertEqual(line.getAttribute('marker-start'), '') self.assertEqual(line.getAttribute('marker-mid'), '') self.assertEqual(line.getAttribute('marker-end'), '') + class PathCommandRewrites(unittest.TestCase): def runTest(self): From cebd259a781b8f2ba48a055d2a3b583450627c05 Mon Sep 17 00:00:00 2001 From: doom-goober Date: Sun, 20 Dec 2020 12:26:11 -0800 Subject: [PATCH 3/8] More flake fixes. --- scour/scour.py | 4 ++-- test_scour.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scour/scour.py b/scour/scour.py index 82b7f5b..8effdb1 100644 --- a/scour/scour.py +++ b/scour/scour.py @@ -1819,7 +1819,7 @@ def repairStyle(node, options): if propName in svgAttributes: node.setAttribute(propName, styleMap[propName]) del styleMap[propName] - + _setStyle(node, styleMap) # recurse for our child elements @@ -3999,7 +3999,7 @@ def format_usage(self, usage): help="won't convert styles into XML attributes") _option_group_optimization.add_option("--style", action="store", type="string", dest="style_type", default="none", metavar="TYPE", - help="style type (overrides style-to-xml): none, preserve, inline,"\ + help="style type (overrides style-to-xml): none, preserve, inline," "attributes (default: %none)") _option_group_optimization.add_option("--disable-group-collapsing", action="store_false", dest="group_collapse", default=True, diff --git a/test_scour.py b/test_scour.py index ee12efd..4cd82a1 100755 --- a/test_scour.py +++ b/test_scour.py @@ -2217,7 +2217,7 @@ class AttrToStyle(unittest.TestCase): def runTest(self): doc = scourXmlFile('unittests/attr-to-style.svg', - parse_args(['--style=inline'])) + parse_args(['--style=inline'])) line = doc.getElementsByTagName('line')[0] self.assertEqual(line.getAttribute('stroke'), '') self.assertEqual(line.getAttribute('marker-start'), '') @@ -2237,7 +2237,7 @@ class StylePreserve(unittest.TestCase): def runTest(self): doc = scourXmlFile('unittests/attr-to-style.svg', - parse_args(['--style=preserve'])) + parse_args(['--style=preserve'])) # First line uses attributes. line = doc.getElementsByTagName('line')[0] From 528cd1578e9595e095379c2d37d1fddb82dcc0b2 Mon Sep 17 00:00:00 2001 From: doom-goober Date: Sat, 4 Dec 2021 09:20:43 -0800 Subject: [PATCH 4/8] inline use attribute name for lookup --- scour/scour.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/scour/scour.py b/scour/scour.py index 8effdb1..400828a 100644 --- a/scour/scour.py +++ b/scour/scour.py @@ -1804,11 +1804,12 @@ def repairStyle(node, options): if options.style_type == "inline": # Prefer inline style # Remove known SVG attributes and store their values in style attribute - attributes = [node.attributes.item(i).nodeName for i in range(node.attributes.length)] + attributes = [node.attributes.item(i) for i in range(node.attributes.length)] for attribute in attributes: - if attribute in svgAttributes: - styleMap[attribute] = node.getAttribute(attribute) - node.removeAttribute(attribute) + attributeName = attribute.nodeName + if attributeName in svgAttributes: + styleMap[attributeName] = attribute.nodeValue + node.removeAttribute(attributeName) elif options.style_type == "preserve": # Keep whatever style of attribute versus style the file currently has pass From e9fd11abd7e70a688b31e7f8f515d9bf95f48013 Mon Sep 17 00:00:00 2001 From: doom-goober Date: Sat, 4 Dec 2021 09:23:15 -0800 Subject: [PATCH 5/8] Change argument from inline to inline-css --- scour/scour.py | 6 +++--- test_scour.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scour/scour.py b/scour/scour.py index 0419922..b85d499 100644 --- a/scour/scour.py +++ b/scour/scour.py @@ -1793,7 +1793,7 @@ def repairStyle(node, options): num += 1 if node.nodeType == Node.ELEMENT_NODE: - if options.style_type == "inline": + if options.style_type == "inline-css": # Prefer inline style # Remove known SVG attributes and store their values in style attribute attributes = [node.attributes.item(i) for i in range(node.attributes.length)] @@ -3963,7 +3963,7 @@ def format_usage(self, usage): help="won't convert styles into XML attributes") _option_group_optimization.add_option("--style", action="store", type="string", dest="style_type", default="none", metavar="TYPE", - help="style type (overrides style-to-xml): none, preserve, inline," + help="style type (overrides style-to-xml): none, preserve, inline-css," "attributes (default: %none)") _option_group_optimization.add_option("--disable-group-collapsing", action="store_false", dest="group_collapse", default=True, @@ -4081,7 +4081,7 @@ def parse_args(args=None, ignore_additional_args=False): _options_parser.error("Value for --nindent should be positive (or zero), see --help") if options.infilename and options.outfilename and options.infilename == options.outfilename: _options_parser.error("Input filename is the same as output filename") - if options.style_type not in ['none', 'preserve', 'attributes', 'inline']: + if options.style_type not in ['none', 'preserve', 'attributes', 'inline-css']: _options_parser.error("Invalid value for --style, see --help") return options diff --git a/test_scour.py b/test_scour.py index 4cd82a1..5ca0cc5 100755 --- a/test_scour.py +++ b/test_scour.py @@ -2217,7 +2217,7 @@ class AttrToStyle(unittest.TestCase): def runTest(self): doc = scourXmlFile('unittests/attr-to-style.svg', - parse_args(['--style=inline'])) + parse_args(['--style=inline-css'])) line = doc.getElementsByTagName('line')[0] self.assertEqual(line.getAttribute('stroke'), '') self.assertEqual(line.getAttribute('marker-start'), '') From 6e1afe74d1dd4e4344f2987efefce64027451417 Mon Sep 17 00:00:00 2001 From: doom-goober Date: Sat, 4 Dec 2021 09:35:28 -0800 Subject: [PATCH 6/8] move logic to options.style_type not style_to_xml. --- scour/scour.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scour/scour.py b/scour/scour.py index b85d499..73981b2 100644 --- a/scour/scour.py +++ b/scour/scour.py @@ -1805,7 +1805,7 @@ def repairStyle(node, options): elif options.style_type == "preserve": # Keep whatever style of attribute versus style the file currently has pass - elif options.style_to_xml or options.style_type == "attributes": + elif options.style_type == "attributes": # now if any of the properties match known SVG attributes we prefer attributes # over style so emit them and remove them from the style map for propName in list(styleMap): @@ -4084,6 +4084,10 @@ def parse_args(args=None, ignore_additional_args=False): if options.style_type not in ['none', 'preserve', 'attributes', 'inline-css']: _options_parser.error("Invalid value for --style, see --help") + #For backwards compatibility, we support style_to_xml but style_type can override it. + if options.style_type == 'none' and options.style_to_xml: + options.style_type = 'attributes' + return options From 5a62f888cdd39a1bcddc14face4dad8047260709 Mon Sep 17 00:00:00 2001 From: doom-goober Date: Thu, 23 Dec 2021 16:45:54 -0800 Subject: [PATCH 7/8] Move options style_type to sanitizeOptions. --- scour/scour.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scour/scour.py b/scour/scour.py index 73981b2..5774428 100644 --- a/scour/scour.py +++ b/scour/scour.py @@ -4084,10 +4084,6 @@ def parse_args(args=None, ignore_additional_args=False): if options.style_type not in ['none', 'preserve', 'attributes', 'inline-css']: _options_parser.error("Invalid value for --style, see --help") - #For backwards compatibility, we support style_to_xml but style_type can override it. - if options.style_type == 'none' and options.style_to_xml: - options.style_type = 'attributes' - return options @@ -4104,6 +4100,10 @@ def sanitizeOptions(options=None): sanitizedOptions = _options_parser.get_default_values() sanitizedOptions._update_careful(optionsDict) + #For backwards compatibility, we support style_to_xml but style_type can override it. + if sanitizedOptions.style_type == 'none' and sanitizedOptions.style_to_xml: + sanitizedOptions.style_type = 'attributes' + return sanitizedOptions From 56c36e3592d17439bd3054e8929ec929547b81bf Mon Sep 17 00:00:00 2001 From: doom-goober Date: Sat, 25 Dec 2021 16:05:36 -0800 Subject: [PATCH 8/8] Fix typos in help --- scour/scour.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/scour/scour.py b/scour/scour.py index 5774428..22b3958 100644 --- a/scour/scour.py +++ b/scour/scour.py @@ -61,7 +61,7 @@ from decimal import Context, Decimal, InvalidOperation, getcontext import six -from six.moves import range, urllib +import urllib from scour.stats import ScourStats from scour.svg_regex import svg_parser @@ -3963,8 +3963,8 @@ def format_usage(self, usage): help="won't convert styles into XML attributes") _option_group_optimization.add_option("--style", action="store", type="string", dest="style_type", default="none", metavar="TYPE", - help="style type (overrides style-to-xml): none, preserve, inline-css," - "attributes (default: %none)") + help="style type (overrides style-to-xml): none, preserve, inline-css, " + "attributes (default: none)") _option_group_optimization.add_option("--disable-group-collapsing", action="store_false", dest="group_collapse", default=True, help="won't collapse elements") @@ -4208,4 +4208,5 @@ def run(): if __name__ == '__main__': + print('running') run()