Code

scour extension update (v0.23)
authorJazzyNico <nicoduf@yahoo.fr>
Tue, 19 Jan 2010 19:47:56 +0000 (20:47 +0100)
committerJazzyNico <nicoduf@yahoo.fr>
Tue, 19 Jan 2010 19:47:56 +0000 (20:47 +0100)
share/extensions/scour.inkscape.py
share/extensions/scour.inx
share/extensions/scour.py

index 9e87757826210bd724de8e536b6a0d995c2479ba..f21e223a06ecad69c81341288c9c72d6d3c90fc7 100755 (executable)
@@ -37,10 +37,13 @@ class ScourInkscape (inkex.Effect):
         self.OptionParser.add_option("--indent",
             action="store", type="string", dest="indent_type", default="space",
             help="indentation of the output: none, space, tab (default: %default)")
+        self.OptionParser.add_option("--enable-viewboxing", type="inkbool",
+            action="store", dest="enable_viewboxing", default=False,
+            help="changes document width/height to 100%/100% and creates viewbox coordinates")
 
 
     def effect(self):   
-        input = file(sys.argv[11], "r")
+        input = file(sys.argv[12], "r")
         sys.stdout.write(scourString(input.read(), self.options).encode("UTF-8"))
         input.close()
         sys.stdout.close()
index d5cddeea578d920ddd15079ca5a5b886a6962f5b..ee310c5036bad4fc33608a76f15471f334998c9e 100644 (file)
@@ -13,6 +13,7 @@
             <param name="enable-id-stripping"  type="boolean" _gui-text="Enable id stripping">false</param>
             <param name="embed-rasters"  type="boolean" _gui-text="Embed rasters">true</param>
             <param name="keep-editor-data"  type="boolean" _gui-text="Keep editor data">false</param>
+            <param name="enable-viewboxing" type="boolean" _gui-text="Enable viewboxing">false</param>
             <param name="strip-xml-prolog"  type="boolean" _gui-text="Strip xml prolog">false</param>
             <param name="set-precision"  type="int" _gui-text="Set precision">5</param>
            <param name="indent" type="enum" _gui-text="Indent">
@@ -29,6 +30,7 @@
     * Enable id stripping: remove all un-referenced ID attributes.
     * Embed rasters: embed rasters as base64-encoded data.
     * Keep editor data: don't remove Inkscape, Sodipodi or Adobe Illustrator elements and attributes.
+    * Enable viewboxing: size image to 100%/100% and introduce a viewBox
     * Strip xml prolog: don't output the xml prolog.
     * Set precision: set number of significant digits (default: 5).
     * Indent: indentation of the output: none, space, tab (default: space).</_param>
index c68295c15f4424b3e700a0ef5cda417250ac46de..700a0349fba3e3659133592911c4ac2222d66919 100755 (executable)
@@ -3,7 +3,7 @@
 
 #  Scour
 #
-#  Copyright 2009 Jeff Schiller
+#  Copyright 2010 Jeff Schiller
 #
 #  This file is part of Scour, http://www.codedread.com/scour/
 #
@@ -34,6 +34,7 @@
 #    at rounded corners)
 
 # Next Up:
+# - only remove unreferenced elements if they are not children of a referenced element
 # - TODO: fix the removal of comment elements (between <?xml?> and <svg>)
 # - add an option to remove ids if they match the Inkscape-style of IDs
 # - investigate point-reducing algorithms
@@ -63,9 +64,16 @@ except ImportError:
        from fixedpoint import *
        Decimal = FixedPoint    
 
+# Import Psyco if available
+try:
+       import psyco
+       psyco.full()
+except ImportError:
+       pass
+
 APP = 'scour'
-VER = '0.22'
-COPYRIGHT = 'Copyright Jeff Schiller, 2009'
+VER = '0.23'
+COPYRIGHT = 'Copyright Jeff Schiller, 2010'
 
 NS = {         'SVG':          'http://www.w3.org/2000/svg', 
                'XLINK':        'http://www.w3.org/1999/xlink', 
@@ -499,16 +507,20 @@ def removeUnusedDefs(doc, defElem, elemsToRemove=None):
 
        identifiedElements = findElementsWithId(doc.documentElement)
        referencedIDs = findReferencedElements(doc.documentElement)
-       
+
        keepTags = ['font', 'style', 'metadata', 'script', 'title', 'desc']
        for elem in defElem.childNodes:
-               if elem.nodeName == 'g' and elem.namespaceURI == NS['SVG']:
-                       elemsToRemove = removeUnusedDefs(doc, elem, elemsToRemove)
-                       continue
+               # only look at it if an element and not referenced anywhere else
                if elem.nodeType == 1 and (elem.getAttribute('id') == '' or \
-                               (not elem.getAttribute('id') in referencedIDs)) and \
-                               not elem.nodeName in keepTags:
-                       elemsToRemove.append(elem)
+                               (not elem.getAttribute('id') in referencedIDs)):
+
+                       # we only inspect the children of a group in a defs if the group
+                       # is not referenced anywhere else
+                       if elem.nodeName == 'g' and elem.namespaceURI == NS['SVG']:
+                               elemsToRemove = removeUnusedDefs(doc, elem, elemsToRemove)
+                       # we only remove if it is not one of our tags we always keep (see above)
+                       elif not elem.nodeName in keepTags:
+                               elemsToRemove.append(elem)
        return elemsToRemove
 
 def removeUnreferencedElements(doc):
@@ -2092,7 +2104,7 @@ def serializeXML(element, options, ind = 0, preserveWhitespace = False):
                                if preserveWhitespace:
                                        outString += serializeXML(child, options, 0, preserveWhitespace)
                                else:
-                                       outString += '\n' + serializeXML(child, options, indent + 1, preserveWhitespace)
+                                       outString += os.linesep + serializeXML(child, options, indent + 1, preserveWhitespace)
                                        onNewLine = True
                        # text node
                        elif child.nodeType == 3:
@@ -2114,10 +2126,10 @@ def serializeXML(element, options, ind = 0, preserveWhitespace = False):
                                
                if onNewLine: outString += (I * ind)
                outString += '</' + element.nodeName + '>'
-               if indent > 0: outString += '\n'
+               if indent > 0: outString += os.linesep
        else:
                outString += '/>'
-               if indent > 0: outString += '\n'
+               if indent > 0: outString += os.linesep
                
        return outString
        
@@ -2266,14 +2278,15 @@ def scourString(in_string, options=None):
                        embedRasters(elem, options)             
 
        # properly size the SVG document (ideally width/height should be 100% with a viewBox)
-       properlySizeDoc(doc.documentElement)
+       if options.viewboxing:
+               properlySizeDoc(doc.documentElement)
 
        # output the document as a pretty string with a single space for indent
        # NOTE: removed pretty printing because of this problem:
        # http://ronrothman.com/public/leftbraned/xml-dom-minidom-toprettyxml-and-silly-whitespace/
        # rolled our own serialize function here to save on space, put id first, customize indentation, etc
 #      out_string = doc.documentElement.toprettyxml(' ')
-       out_string = serializeXML(doc.documentElement, options)
+       out_string = serializeXML(doc.documentElement, options) + os.linesep
        
        # now strip out empty lines
        lines = []
@@ -2284,7 +2297,7 @@ def scourString(in_string, options=None):
 
        # return the string stripped of empty lines
        if options.strip_xml_prolog == False:
-               xmlprolog = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n'
+               xmlprolog = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' + os.linesep
        else:
                xmlprolog = ""
                
@@ -2340,6 +2353,9 @@ _options_parser.add_option("--keep-editor-data",
 _options_parser.add_option("--strip-xml-prolog",
        action="store_true", dest="strip_xml_prolog", default=False,
        help="won't output the <?xml ?> prolog")
+_options_parser.add_option("--enable-viewboxing",
+       action="store_true", dest="viewboxing", default=False,
+       help="changes document width/height to 100%/100% and creates viewbox coordinates")
 
 # GZ: this is confusing, most people will be thinking in terms of
 #     decimal places, which is not what decimal precision is doing
@@ -2385,15 +2401,15 @@ def parse_args(args=None):
        return options, [infile, outfile]
 
 def getReport():
-       return ' Number of elements removed: ' + str(numElemsRemoved) + \
-               '\n Number of attributes removed: ' + str(numAttrsRemoved) + \
-               '\n Number of unreferenced id attributes removed: ' + str(numIDsRemoved) + \
-               '\n Number of style properties fixed: ' + str(numStylePropsFixed) + \
-               '\n Number of raster images embedded inline: ' + str(numRastersEmbedded) + \
-               '\n Number of path segments reduced/removed: ' + str(numPathSegmentsReduced) + \
-               '\n Number of bytes saved in path data: ' + str(numBytesSavedInPathData) + \
-               '\n Number of bytes saved in colors: ' + str(numBytesSavedInColors) + \
-               '\n Number of points removed from polygons: ' + str(numPointsRemovedFromPolygon)
+       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)
 
 if __name__ == '__main__':
        if sys.platform == "win32":
@@ -2423,7 +2439,7 @@ if __name__ == '__main__':
        # GZ: unless silenced by -q or something?
        # GZ: not using globals would be good too
        print >>sys.stderr, ' File:', input.name, \
-               '\n Time taken:', str(end-start) + 's\n', \
+               os.linesep + ' Time taken:', str(end-start) + 's' + os.linesep, \
                getReport()
        
        oldsize = len(in_string)