Work on width/height/viewBox parsing (no doc changes yet)

This commit is contained in:
JSCHILL1 2009-04-12 22:33:13 -05:00
parent fb84759f0c
commit c8fdeb2136

View file

@ -58,6 +58,7 @@ import sys
import string import string
import xml.dom.minidom import xml.dom.minidom
import re import re
import math
APP = 'scour' APP = 'scour'
VER = '0.06' VER = '0.06'
@ -245,13 +246,11 @@ def removeNamespacedElements(node, namespaces):
# TODO: create a class for a SVGLength type (including value and unit) # TODO: create a class for a SVGLength type (including value and unit)
coord = re.compile("\\-?\\d+\\.?\\d*") coord = re.compile("\\-?\\d+\\.?\\d*")
number = re.compile("[\\-\\+]?(\\d*\\.?)?\\d+")
scinumber = re.compile("[\\-\\+]?(\\d*\\.?)?\\d+[eE][\\-\\+]?\\d+") scinumber = re.compile("[\\-\\+]?(\\d*\\.?)?\\d+[eE][\\-\\+]?\\d+")
number = re.compile("[\\-\\+]?(\\d*\\.?)?\\d+")
sciExponent = re.compile("[eE]([\\-\\+]?\\d+)")
unit = re.compile("(em|ex|px|pt|pc|cm|mm|in|\\%){1,1}$") unit = re.compile("(em|ex|px|pt|pc|cm|mm|in|\\%){1,1}$")
# QRegExp coorde("[\\-\\+]?\\d+\\.?\\d*([eE][\\-\\+]?\\d+)?");
# QRegExp separateExp("([\\-\\+\\d\\.]+)[eE]([\\-\\+\\d\\.]+)");
class Unit: class Unit:
INVALID = -1 INVALID = -1
NONE = 0 NONE = 0
@ -281,30 +280,43 @@ class Unit:
class SVGLength: class SVGLength:
def __init__(self, str): def __init__(self, str):
# print "Parsing '%s'" % str
try: # simple unitless and no scientific notation try: # simple unitless and no scientific notation
self.value = string.atof(str) self.value = string.atof(str)
self.units = Unit.NONE self.units = Unit.NONE
# print " Value =", self.value
except ValueError: except ValueError:
# we know that the length string has an exponent, a unit, both or is invalid # we know that the length string has an exponent, a unit, both or is invalid
# TODO: parse out number, exponent and unit # TODO: parse out number, exponent and unit
exponent = 0 unitBegin = 0
scinum = scinumber.match(str) scinum = scinumber.match(str)
if scinum != None: if scinum != None:
print 'Scientific Notation' # this will always match, no need to check it
pass numMatch = number.match(str)
expMatch = sciExponent.search(str, numMatch.start(0))
self.value = string.atof(numMatch.group(0)) * math.pow(10, string.atof(expMatch.group(1)))
unitBegin = expMatch.end(1)
else:
# unit or invalid
numMatch = number.match(str)
if numMatch != None:
self.value = numMatch.group(0)
unitBegin = numMatch.end(0)
# unit or invalid if unitBegin != 0 :
numMatch = number.match(str) # print " Value =", self.value
if numMatch != None: unitMatch = unit.search(str, unitBegin)
unitMatch = unit.search(str, numMatch.start(0)) if unitMatch != None :
if unitMatch != None:
self.units = Unit.get(unitMatch.group(0)) self.units = Unit.get(unitMatch.group(0))
# print " Units =", self.units
# invalid # invalid
else: else:
# TODO: this needs to set the default for the given attribute (how?) # TODO: this needs to set the default for the given attribute (how?)
# print " Invalid: ", str
self.value = 0 self.value = 0
self.units = INVALID self.units = Unit.INVALID
# returns the length of a property # returns the length of a property
# TODO: eventually use the above class once it is complete # TODO: eventually use the above class once it is complete
@ -314,10 +326,7 @@ def getSVGLength(value):
except ValueError: except ValueError:
coordMatch = coord.match(value) coordMatch = coord.match(value)
if coordMatch != None: if coordMatch != None:
print "Coord found:", coordMatch.group(0)
unitMatch = unit.search(value, coordMatch.start(0)) unitMatch = unit.search(value, coordMatch.start(0))
if unitMatch != None:
print "Unit found:", unitMatch.group(0)
v = value v = value
return v return v
@ -443,9 +452,24 @@ def cleanPath(element) :
path = element.getAttribute('d') path = element.getAttribute('d')
def properlySizeDoc(docElement): def properlySizeDoc(docElement):
w = docElement.getAttribute('width') # get doc width and height
h = docElement.getAttribute('height') w = SVGLength(docElement.getAttribute('width'))
vb = docElement.getAttribute('viewBox') h = SVGLength(docElement.getAttribute('height'))
if ((w.units == Unit.PCT or w.units == Unit.INVALID) and
(h.units == Unit.PCT or h.units == Unit.INVALID)):
return
# else we have a statically sized image and we should try to remedy that
# parse viewBox attribute
vbSep = re.split("\\s*\\,?\\s*", docElement.getAttribute('viewBox'), 3)
# if we have a valid viewBox we probably shouldn't change anything unless
# the viewbox width/height matches the doc width/height
# if len(vbSep) == 4:
# vbWidth =
# parse command-line arguments # parse command-line arguments
args = sys.argv[1:] args = sys.argv[1:]
@ -512,8 +536,6 @@ while bContinueLooping:
referencedIDs = findReferencedElements(doc.documentElement, {}) referencedIDs = findReferencedElements(doc.documentElement, {})
bContinueLooping = ((removeUnreferencedIDs(referencedIDs, identifiedElements) + vacuumDefs(doc)) > 0) bContinueLooping = ((removeUnreferencedIDs(referencedIDs, identifiedElements) + vacuumDefs(doc)) > 0)
# repair style (remove unnecessary style properties and change them into XML attributes) # repair style (remove unnecessary style properties and change them into XML attributes)
numStylePropsFixed = repairStyle(doc.documentElement) numStylePropsFixed = repairStyle(doc.documentElement)
@ -533,6 +555,9 @@ for tag in ['defs', 'metadata', 'g'] :
elem.parentNode.removeChild(elem) elem.parentNode.removeChild(elem)
numElemsRemoved += 1 numElemsRemoved += 1
# properly size the SVG document (width/height should be 100% with a viewBox)
properlySizeDoc(doc.documentElement)
# clean path data # clean path data
for elem in doc.documentElement.getElementsByTagNameNS(NS['SVG'], 'path') : for elem in doc.documentElement.getElementsByTagNameNS(NS['SVG'], 'path') :
cleanPath(elem) cleanPath(elem)