Code

Fix #344064: Extensions>Color>Replace color... (and probably other items in Extension...
authorpjrm <pjrm@users.sourceforge.net>
Tue, 17 Mar 2009 05:43:33 +0000 (05:43 +0000)
committerpjrm <pjrm@users.sourceforge.net>
Tue, 17 Mar 2009 05:43:33 +0000 (05:43 +0000)
share/extensions/coloreffect.py
share/extensions/simplestyle.py

index c32df4d8de5beda33103508caa4a8f15b86dc771..8f67c6090dee855d5144afe6b444be5659661f84 100644 (file)
@@ -2,6 +2,7 @@
 '''
 Copyright (C) 2006 Jos Hirth, kaioa.com
 Copyright (C) 2007 Aaron C. Spike
+Copyright (C) 2009 Monash University
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -17,12 +18,11 @@ You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 '''
-import sys, copy, optparse, simplestyle, inkex, copy
-
+import sys, copy, simplestyle, inkex
 import random
 
-color_props_fill=('fill:','stop-color:','flood-color:','lighting-color:')
-color_props_stroke=('stroke:',)
+color_props_fill = ('fill', 'stop-color', 'flood-color', 'lighting-color')
+color_props_stroke = ('stroke',)
 color_props = color_props_fill + color_props_stroke
 
 
@@ -42,19 +42,46 @@ class ColorEffect(inkex.Effect):
     self.changeStyle(node)
     for child in node:
       self.getAttribs(child)
-  
+
   def changeStyle(self,node):
+    for attr in color_props:
+        val = node.get(attr)
+        if val:
+            new_val = self.process_prop(val)
+            if new_val != val:
+                node.set(attr, new_val)
+
     if node.attrib.has_key('style'):
-      style=node.get('style') # fixme: this will break for presentation attributes!
-      if style!='':
-        #inkex.debug('old style:'+style)
-        styles=style.split(';')
-        for i in range(len(styles)):
-          for c in range(len(color_props)):
-            if styles[i].startswith(color_props[c]):
-              styles[i]=color_props[c]+self.process_prop(styles[i][len(color_props[c]):])
-        #inkex.debug('new style:'+';'.join(styles))
-        node.set('style',';'.join(styles))
+        # References for style attribute:
+        # http://www.w3.org/TR/SVG11/styling.html#StyleAttribute,
+        # http://www.w3.org/TR/CSS21/syndata.html
+        #
+        # The SVG spec is ambiguous as to how style attributes should be parsed.
+        # For example, it isn't clear whether semicolons are allowed to appear
+        # within strings or comments, or indeed whether comments are allowed to
+        # appear at all.
+        #
+        # The processing here is just something simple that should usually work,
+        # without trying too hard to get everything right.
+        # (Won't work for the pathalogical case that someone escapes a property
+        # name, probably does the wrong thing if colon or semicolon is used inside
+        # a comment or string value.)
+        style = node.get('style') # fixme: this will break for presentation attributes!
+        if style:
+            #inkex.debug('old style:'+style)
+            declarations = style.split(';')
+            for i,decl in enumerate(declarations):
+                parts = decl.split(':', 2)
+                if len(parts) == 2:
+                    (prop, val) = parts
+                    prop = prop.strip().lower()
+                    if prop in color_props:
+                        val = val.strip()
+                        new_val = self.process_prop(val)
+                        if new_val != val:
+                            declarations[i] = prop + ':' + new_val
+            #inkex.debug('new style:'+';'.join(declarations))
+            node.set('style', ';'.join(declarations))
 
   def process_prop(self,col):
     #debug('got:'+col)
@@ -160,3 +187,5 @@ class ColorEffect(inkex.Effect):
         rgb[1] = self.hue_2_rgb (v1, v2, h*6)
         rgb[2] = self.hue_2_rgb (v1, v2, h*6 - 2.0)
     return rgb
+
+# vi: set autoindent shiftwidth=2 tabstop=8 expandtab softtabstop=2 :
index 356d75581c472866e03f56af6964fd78b83a94c0..4dcfd1aba9761c742859e72067f5c3ddf32d80af 100755 (executable)
@@ -170,6 +170,7 @@ svgcolors={
     'yellow':'#ffff00',
     'yellowgreen':'#9acd32'
 }
+
 def parseStyle(s):
     """Create a dictionary from the value of an inline style attribute"""
     return dict([i.split(":") for i in s.split(";") if len(i)])
@@ -180,16 +181,18 @@ def isColor(c):
     """Determine if its a color we can use. If not, leave it unchanged."""
     if c.startswith('#') and (len(c)==4 or len(c)==7):
         return True
-    if c in svgcolors.keys():
+    if c.lower() in svgcolors.keys():
         return True
     #might be "none" or some undefined color constant or rgb()
     #however, rgb() shouldnt occur at this point
     return False
+
 def parseColor(c):
     """Creates a rgb int array"""
-    if c in svgcolors.keys():
-        c=svgcolors[c]
-    if c.startswith('#') and len(c)==4:
+    tmp = svgcolors.get(c.lower())
+    if tmp is not None:
+        c = tmp
+    elif c.startswith('#') and len(c)==4:
         c='#'+c[1:2]+c[1:2]+c[2:3]+c[2:3]+c[3:]+c[3:]
     elif c.startswith('rgb('):
         # remove the rgb(...) stuff
@@ -210,6 +213,7 @@ def parseColor(c):
     g=int(c[3:5],16)
     b=int(c[5:],16)
     return (r,g,b)
+
 def formatColoria(a):
     """int array to #rrggbb"""
     return '#%02x%02x%02x' % (a[0],a[1],a[2])