From: acspike Date: Tue, 19 Jun 2007 03:45:13 +0000 (+0000) Subject: begin converting python extensions to use lxml. this might take me a while and it... X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=cc6fa1a3e6d71df2944a8bc64ed739f1f34d0359;p=inkscape.git begin converting python extensions to use lxml. this might take me a while and it will break unconverted extensions in the meanwhile. --- diff --git a/share/extensions/addnodes.py b/share/extensions/addnodes.py index e57c7566d..bc5ae4030 100644 --- a/share/extensions/addnodes.py +++ b/share/extensions/addnodes.py @@ -1,6 +1,6 @@ #!/usr/bin/env python ''' -Copyright (C) 2005 Aaron Spike, aaron@ekips.org +Copyright (C) 2005,2007 Aaron Spike, aaron@ekips.org 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 @@ -64,9 +64,8 @@ class SplitIt(inkex.Effect): help="maximum segment length") def effect(self): for id, node in self.selected.iteritems(): - if node.tagName == 'path': - d = node.attributes.getNamedItem('d') - p = cubicsuperpath.parsePath(d.value) + if node.tag == inkex.addNS('path','svg'): + p = cubicsuperpath.parsePath(node.get('d')) #lens, total = csplength(p) #avg = total/numlengths(lens) @@ -86,7 +85,7 @@ class SplitIt(inkex.Effect): new[-1].append(sub[i]) i+=1 - d.value = cubicsuperpath.formatPath(new) + node.set('d',cubicsuperpath.formatPath(new)) e = SplitIt() e.affect() diff --git a/share/extensions/coloreffect.py b/share/extensions/coloreffect.py index 2708b48f3..fcb20dde4 100644 --- a/share/extensions/coloreffect.py +++ b/share/extensions/coloreffect.py @@ -1,6 +1,7 @@ #!/usr/bin/env python ''' Copyright (C) 2006 Jos Hirth, kaioa.com +Copyright (C) 2007 Aaron C. Spike 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 @@ -18,8 +19,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ''' import sys, copy, optparse, simplestyle, inkex -import xml.xpath - import random color_props_fill=('fill:','stop-color:','flood-color:','lighting-color:') @@ -29,26 +28,24 @@ color_props = color_props_fill + color_props_stroke class ColorEffect(inkex.Effect): def __init__(self): - inkex.Effect.__init__(self,use_minidom=True) + inkex.Effect.__init__(self) self.visited = [] def effect(self): if len(self.selected)==0: - self.getAttribs(self.document) + self.getAttribs(self.document.getroot()) else: for id,node in self.selected.iteritems(): self.getAttribs(node) def getAttribs(self,node): self.changeStyle(node) - if node.hasChildNodes(): - childs=node.childNodes - for child in childs: - self.getAttribs(child) + for child in node: + self.getAttribs(child) def changeStyle(self,node): - if node.hasAttributes(): - style=node.getAttribute('style') # fixme: this will break for presentation attributes! + 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(';') @@ -57,7 +54,7 @@ class ColorEffect(inkex.Effect): 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.setAttribute('style',';'.join(styles)) + node.set('style',';'.join(styles)) def process_prop(self,col): #debug('got:'+col) @@ -66,13 +63,13 @@ class ColorEffect(inkex.Effect): col='#'+self.colmod(c[0],c[1],c[2]) #debug('made:'+col) if col.startswith('url(#'): - id = col[len('url(#'):col.find(')')] - newid = '%s-%d' % (id, int(random.random() * 1000)) - #inkex.debug('ID:' + id ) - path = '//*[@id="%s"]' % id - for node in xml.xpath.Evaluate(path,self.document): - self.process_gradient(node, newid) - col = 'url(#%s)' % newid + id = col[len('url(#'):col.find(')')] + newid = '%s-%d' % (id, int(random.random() * 1000)) + #inkex.debug('ID:' + id ) + path = '//*[@id="%s"]' % id + for node in self.document.xpath(path, inkex.NSS): + self.process_gradient(node, newid) + col = 'url(#%s)' % newid return col def process_gradient(self, node, newid): @@ -84,22 +81,22 @@ class ColorEffect(inkex.Effect): #return #self.visited.append(this_id) #inkex.debug("visited: " + str(self.visited)) - newnode = node.cloneNode(True) - newnode.setAttribute('id', newid) - node.parentNode.appendChild(newnode) + newnode = inkex.etree.fromstring(inkex.etree.tostring(node)) + newnode.set('id', newid) + node.xpath('..')[0].append(newnode) self.changeStyle(newnode) - if newnode.hasChildNodes(): - for child in newnode.childNodes: - self.changeStyle(child) - if newnode.hasAttributes(): - href=newnode.getAttribute('xlink:href') + for child in newnode: + self.changeStyle(child) + xlink = inkex.addNS('href','xlink') + if newnode.attrib.has_key(xlink): + href=newnode.get(xlink) if href.startswith('#'): id = href[len('#'):len(href)] #inkex.debug('ID:' + id ) - newhref = '%s-%d' % (id, int(random.random() * 1000)) - newnode.setAttribute('xlink:href', '#%s' % newhref) + newhref = '%s-%d' % (id, int(random.random() * 1000)) + newnode.set(xlink, '#%s' % newhref) path = '//*[@id="%s"]' % id - for node in xml.xpath.Evaluate(path,self.document): + for node in self.document.xpath(path,inkex.NSS): self.process_gradient(node, newhref) def colmod(self,r,g,b): diff --git a/share/extensions/cubicsuperpath.py b/share/extensions/cubicsuperpath.py index a151084eb..cc59905ab 100755 --- a/share/extensions/cubicsuperpath.py +++ b/share/extensions/cubicsuperpath.py @@ -22,13 +22,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import simplepath from math import * -class SuperSubpath(list): - def __init__(self, items=[]): - self.closed = False - list.__init__(self, items) - def close(self, state=True): - self.closed = state - def matprod(mlist): prod=mlist[0] for m in mlist[1:]: @@ -111,8 +104,10 @@ def CubicSuperPath(simplepath): for s in simplepath: cmd, params = s if cmd == 'M': + if last: + csp[subpath].append([lastctrl[:],last[:],last[:]]) subpath += 1 - csp.append(SuperSubpath()) + csp.append([]) subpathstart = params[:] last = params[:] lastctrl = params[:] @@ -146,9 +141,11 @@ def CubicSuperPath(simplepath): lastctrl = arcp[-1][0] csp[subpath]+=arcp[:-1] elif cmd == 'Z': - csp[subpath].close() + csp[subpath].append([lastctrl[:],last[:],last[:]]) last = subpathstart[:] lastctrl = subpathstart[:] + #append final superpoint + csp[subpath].append([lastctrl[:],last[:],last[:]]) return csp def unCubicSuperPath(csp): @@ -158,11 +155,6 @@ def unCubicSuperPath(csp): a.append(['M',subpath[0][1][:]]) for i in range(1,len(subpath)): a.append(['C',subpath[i-1][2][:] + subpath[i][0][:] + subpath[i][1][:]]) - try: - if subpath.closed: - a.append(['Z',[]]) - except: - pass return a def parsePath(d): diff --git a/share/extensions/dots.py b/share/extensions/dots.py index c5f6e8149..ca235861c 100755 --- a/share/extensions/dots.py +++ b/share/extensions/dots.py @@ -31,24 +31,23 @@ class Dots(inkex.Effect): help="Size of node label numbers") def effect(self): for id, node in self.selected.iteritems(): - if node.tagName == 'path': - self.group = self.document.createElement('svg:g') - node.parentNode.appendChild(self.group) - new = self.document.createElement('svg:path') + if node.tag == inkex.addNS('path','svg'): + self.group = inkex.etree.SubElement(node.xpath('..')[0],inkex.addNS('g','svg')) + new = inkex.etree.SubElement(self.group,inkex.addNS('path','svg')) try: - t = node.attributes.getNamedItem('transform').value - self.group.setAttribute('transform', t) - except AttributeError: + t = node.get('transform') + self.group.set('transform', t) + except: pass - s = simplestyle.parseStyle(node.attributes.getNamedItem('style').value) + s = simplestyle.parseStyle(node.get('style')) s['stroke-linecap']='round' s['stroke-width']=self.options.dotsize - new.setAttribute('style', simplestyle.formatStyle(s)) + new.set('style', simplestyle.formatStyle(s)) a =[] - p = simplepath.parsePath(node.attributes.getNamedItem('d').value) + p = simplepath.parsePath(node.get('d')) num = 1 for cmd,params in p: if cmd != 'Z': @@ -56,20 +55,18 @@ class Dots(inkex.Effect): a.append(['L',params[-2:]]) self.addText(self.group,params[-2],params[-1],num) num += 1 - new.setAttribute('d', simplepath.formatPath(a)) - self.group.appendChild(new) - node.parentNode.removeChild(node) + new.set('d', simplepath.formatPath(a)) + node.clear() def addText(self,node,x,y,text): - new = self.document.createElement('svg:text') + new = inkex.etree.SubElement(node,inkex.addNS('text','svg')) s = {'font-size': self.options.fontsize, 'fill-opacity': '1.0', 'stroke': 'none', 'font-weight': 'normal', 'font-style': 'normal', 'fill': '#000000'} - new.setAttribute('style', simplestyle.formatStyle(s)) - new.setAttribute('x', str(x)) - new.setAttribute('y', str(y)) - new.appendChild(self.document.createTextNode(str(text))) - node.appendChild(new) + new.set('style', simplestyle.formatStyle(s)) + new.set('x', str(x)) + new.set('y', str(y)) + new.text = str(text) e = Dots() e.affect() diff --git a/share/extensions/dxf_outlines.py b/share/extensions/dxf_outlines.py index e8eff2c01..40beee95c 100755 --- a/share/extensions/dxf_outlines.py +++ b/share/extensions/dxf_outlines.py @@ -1,6 +1,6 @@ #!/usr/bin/env python ''' -Copyright (C) 2005 Aaron Spike, aaron@ekips.org +Copyright (C) 2005,2007 Aaron Spike, aaron@ekips.org 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 @@ -45,11 +45,11 @@ class MyEffect(inkex.Effect): self.dxf_add("999\nDXF created by Inkscape\n0\nSECTION\n2\nENTITIES") scale = 25.4/90.0 - h = inkex.unittouu(inkex.xml.xpath.Evaluate('/svg/@height',self.document)[0].value) - - path = '//path' - for node in inkex.xml.xpath.Evaluate(path,self.document): - d = node.attributes.getNamedItem('d').value + h = inkex.unittouu(self.document.getroot().xpath('@height',inkex.NSS)[0]) + + path = '//svg:path' + for node in self.document.getroot().xpath(path,inkex.NSS): + d = node.get('d') sim = simplepath.parsePath(d) simplepath.scalePath(sim,scale,-scale) simplepath.translatePath(sim,0,h*scale) diff --git a/share/extensions/edge3d.py b/share/extensions/edge3d.py index f48dd2f4f..bcb69237a 100644 --- a/share/extensions/edge3d.py +++ b/share/extensions/edge3d.py @@ -39,7 +39,8 @@ class Edge3d(inkex.Effect): ] for o in opts: self.OptionParser.add_option(o[0], o[1], action="store", type=o[2], - dest=o[3], default=o[4], help=o[5]) + dest=o[3], default=o[4], help=o[5]) + self.filtId = '' def angleBetween(self, start, end, angle): """Return true if angle (degrees, clockwise, 0 = up/north) is between @@ -72,9 +73,9 @@ class Edge3d(inkex.Effect): # size of a wedge for shade i, wedges come in pairs delta = 360. / self.options.shades / 2. for id, node in self.selected.iteritems(): - if node.tagName == 'path': - d = node.attributes.getNamedItem('d') - p = simplepath.parsePath(d.value) + if node.tag == inkex.addNS('path','svg'): + d = node.get('d') + p = simplepath.parsePath(d) g = None for shade in range(0, self.options.shades): if (self.options.bw and shade > 0 and @@ -102,48 +103,41 @@ class Edge3d(inkex.Effect): if result: if not g: g = self.getGroup(node) - nn = g.appendChild(node.cloneNode(True)) - d2 = nn.attributes.getNamedItem('d') - d2.value = simplepath.formatPath(result) - - a = nn.ownerDocument.createAttribute('style') + nn = inkex.etree.fromstring(inkex.etree.tostring(node)) + nn.set('d',simplepath.formatPath(result)) + col = 255 - int(255. * level) - a.value = 'fill:none;stroke:#%02x%02x%02x;stroke-opacity:1;stroke-width:10;%s' % ((col,)*3 + (self.filtId,)) - nn.attributes.setNamedItem(a) - - def setAttr(self, node, name, value): - attr = node.ownerDocument.createAttribute(name) - attr.value = value - node.attributes.setNamedItem(attr) + a = 'fill:none;stroke:#%02x%02x%02x;stroke-opacity:1;stroke-width:10;%s' % ((col,)*3 + (self.filtId,)) + nn.set('style',a) + g.append(nn) def getGroup(self, node): - defs = node.ownerDocument.getElementsByTagName('defs') - if defs: + defs = self.document.getroot().xpath('//svg:defs',inkex.NSS) + if defs: defs = defs[0] - if defs: # make a clipped group, clip with clone of original, clipped group # include original and group of paths - clip = defs.appendChild(node.ownerDocument.createElement('clipPath')) - clip.appendChild(node.cloneNode(True)) + clip = inkex.etree.SubElement(defs,inkex.addNS('clipPath','svg')) + clip.append(inkex.etree.fromstring(inkex.etree.tostring(node))) clipId = self.uniqueId('clipPath') - self.setAttr(clip, 'id', clipId) - clipG = node.parentNode.appendChild(node.ownerDocument.createElement('g')) - clipG.appendChild(node) - g = clipG.appendChild(node.ownerDocument.createElement('g')) - self.setAttr(clipG, 'clip-path', 'url(#'+clipId+')') + clip.set('id', clipId) + clipG = inkex.etree.SubElement(node.xpath('..')[0],inkex.addNS('g','svg')) + g = inkex.etree.SubElement(clipG,inkex.addNS('g','svg')) + clipG.set('clip-path', 'url(#'+clipId+')') # make a blur filter reference by the style of each path - filt = defs.appendChild(node.ownerDocument.createElement('filter')) - filtId = self.uniqueId('filter') + filt = inkex.etree.SubElement(defs,inkex.addNS('filter','svg')) + filtId = self.uniqueId('filter') + self.filtId = 'filter:url(#%s);' % filtId for k, v in [('id', filtId), ('height', str(self.options.blurheight)), ('width', str(self.options.blurwidth)), ('x', '-0.5'), ('y', '-0.5')]: - self.setAttr(filt, k, v) - fe = filt.appendChild(node.ownerDocument.createElement('feGaussianBlur')) - self.setAttr(fe, 'stdDeviation', str(self.options.stddev)) - self.filtId = 'filter:url(#%s);' % filtId + filt.set(k, v) + fe = inkex.etree.SubElement(filt,inkex.addNS('feGaussianBlur','svg')) + fe.set('stdDeviation', str(self.options.stddev)) else: # can't find defs, just group paths - g = node.parentNode.appendChild(node.ownerDocument.createElement('g')) + g = inkex.etree.SubElement(node.xpath('..')[0],inkex.addNS('g','svg')) + g.append(node) return g diff --git a/share/extensions/embedimage.py b/share/extensions/embedimage.py index 4cab6c0a9..75400aebb 100644 --- a/share/extensions/embedimage.py +++ b/share/extensions/embedimage.py @@ -1,6 +1,6 @@ #!/usr/bin/env python ''' -Copyright (C) 2005 Aaron Spike, aaron@ekips.org +Copyright (C) 2005,2007 Aaron Spike, aaron@ekips.org 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 @@ -40,23 +40,22 @@ class Embedder(inkex.Effect): self.selected=selected if (self.options.ids): for id, node in selected.iteritems(): - if node.tagName == 'image': + if node.tag == inkex.addNS('image','svg'): self.embedImage(node) def embedAll(self, document): self.document=document #not that nice... oh well - ctx = inkex.xml.xpath.Context.Context(self.document,processorNss=inkex.NSS) - path = '//image' - for node in inkex.xml.xpath.Evaluate(path, self.document, context=ctx): + path = '//svg:image' + for node in self.document.getroot().xpath(path, inkex.NSS): self.embedImage(node) def embedImage(self, node): - xlink = node.attributes.getNamedItemNS(inkex.NSS[u'xlink'],'href') - if (xlink.value[:4]!='data'): - absref=node.attributes.getNamedItemNS(inkex.NSS[u'sodipodi'],'absref') - href=node.attributes.getNamedItemNS(inkex.NSS[u'xlink'],'href') - svg=self.document.getElementsByTagName('svg')[0] - docbase=svg.attributes.getNamedItemNS(inkex.NSS[u'sodipodi'],'docbase') + xlink = node.get(inkex.addNS('href','xlink')) + if (xlink[:4]!='data'): + absref=node.get(inkex.addNS('absref','sodipodi')) + href=xlink + svg=self.document.getroot().xpath('/svg:svg',inkex.NSS)[0] + docbase=svg.get(inkex.addNS('docbase','sodipodi')) path='' #path selection strategy: @@ -65,15 +64,15 @@ class Embedder(inkex.Effect): # 3. realpath-ified href # 4. absref, only if the above does not point to a file if (href != None): - if (os.path.isabs(href.value)): - path=os.path.realpath(href.value) + if (os.path.isabs(href)): + path=os.path.realpath(href) elif (docbase != None): - path=os.path.join(docbase.value,href.value) + path=os.path.join(docbase,href) else: - path=os.path.realpath(href.value) + path=os.path.realpath(href) if (not os.path.isfile(path)): if (absref != None): - path=absref.value + path=absref if (not os.path.isfile(path)): inkex.debug('No xlink:href or sodipodi:absref attributes found, or they do not point to an existing file! Unable to embed image.') @@ -94,8 +93,8 @@ class Embedder(inkex.Effect): else: embed=False if (embed): - xlink.value = 'data:%s;base64,%s' % (type, base64.encodestring(file)) - node.removeAttributeNS(inkex.NSS[u'sodipodi'],'absref') + node.set(inkex.addNS('href','xlink'), 'data:%s;base64,%s' % (type, base64.encodestring(file))) + del node.attrib[inkex.addNS('absref',u'sodipodi')] else: inkex.debug("%s is not of type image/png, image/jpeg, image/bmp, image/gif or image/x-icon" % path) else: diff --git a/share/extensions/gears.py b/share/extensions/gears.py index 060cfdbc2..9a69bf06e 100644 --- a/share/extensions/gears.py +++ b/share/extensions/gears.py @@ -16,9 +16,10 @@ GNU General Public License for more details. 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 inkex, simplestyle, sys +import inkex +import simplestyle, sys from math import * def involute_intersect_angle(Rb, R): @@ -145,21 +146,17 @@ class Gears(inkex.Effect): path = points_to_svgd( points ) - # Create SVG Path for gear - gear = self.document.createElement( 'svg:path' ) - style = { 'stroke': '#000000', 'fill': 'none' } - gear.setAttribute( 'style', simplestyle.formatStyle(style) ) - gear.setAttribute( 'd', path ) - # Embed gear in group to make animation easier: - # Translate group, Rotate path. - g=self.document.createElement('g') - - g.setAttribute( 'inkscape:label', 'Gear' + str( teeth ) ) - t = 'translate(' + str( self.view_center[0] ) + ',' + str( self.view_center[1] ) + ')' - g.setAttribute( 'transform', t ) - self.current_layer.appendChild( g ) - g.appendChild( gear ) + # Translate group, Rotate path. + t = 'translate(' + str( self.view_center[0] ) + ',' + str( self.view_center[1] ) + ')' + g_attribs = {'inkscape:label':'Gear' + str( teeth ), + 'transform':t } + g = inkex.etree.SubElement(self.current_layer, 'g', g_attribs) + + # Create SVG Path for gear + style = { 'stroke': '#000000', 'fill': 'none' } + gear_attribs = {'style':simplestyle.formatStyle(style), 'd':path} + gear = inkex.etree.SubElement(g, 'svg:path', gear_attribs ) e = Gears() e.affect() diff --git a/share/extensions/inkex.py b/share/extensions/inkex.py index 8be7b5282..a4ffd8bd3 100755 --- a/share/extensions/inkex.py +++ b/share/extensions/inkex.py @@ -3,7 +3,7 @@ inkex.py A helper module for creating Inkscape extensions -Copyright (C) 2005 Aaron Spike, aaron@ekips.org +Copyright (C) 2005,2007 Aaron Spike, aaron@ekips.org 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 @@ -53,12 +53,9 @@ def unittouu(string): return retval try: - import xml.dom.ext - import xml.dom.minidom - import xml.dom.ext.reader.Sax2 - import xml.xpath + from lxml import etree except: - sys.exit('The inkex.py module requires PyXML. Please download the latest version from .') + sys.exit('The fantabulous lxml wrapper for libxml2 is required by inkex_lxml.py and therefore this extension. Please download the latest version from .') def debug(what): sys.stderr.write(str(what) + "\n") @@ -72,12 +69,17 @@ def check_inkbool(option, opt, value): else: raise OptionValueError("option %s: invalid inkbool value: %s" % (opt, value)) +def addNS(tag, ns=None): + val = tag + if ns!=None and len(ns)>0 and NSS.has_key(ns): + val = "{%s}%s" % (NSS[ns], tag) + return val + class InkOption(optparse.Option): TYPES = optparse.Option.TYPES + ("inkbool",) TYPE_CHECKER = copy.copy(optparse.Option.TYPE_CHECKER) TYPE_CHECKER["inkbool"] = check_inkbool - class Effect: """A class for creating Inkscape SVG Effects""" def __init__(self, *args, **kwargs): @@ -88,7 +90,6 @@ class Effect: self.doc_ids={} self.options=None self.args=None - self.use_minidom=kwargs.pop("use_minidom", False) self.OptionParser = optparse.OptionParser(usage="usage: %prog [options] SVGfile",option_class=InkOption) self.OptionParser.add_option("--id", action="append", type="string", dest="ids", default=[], @@ -100,7 +101,6 @@ class Effect: self.options, self.args = self.OptionParser.parse_args(args) def parse(self,file=None): """Parse document in specified file or on stdin""" - reader = xml.dom.ext.reader.Sax2.Reader() try: try: stream = open(file,'r') @@ -108,46 +108,41 @@ class Effect: stream = open(self.args[-1],'r') except: stream = sys.stdin - if self.use_minidom: - self.document = xml.dom.minidom.parse(stream) - else: - self.document = reader.fromStream(stream) - self.ctx = xml.xpath.Context.Context(self.document,processorNss=NSS) + self.document = etree.parse(stream) stream.close() def getposinlayer(self): - ctx = xml.xpath.Context.Context(self.document,processorNss=NSS) #defaults - self.current_layer = self.document.documentElement + self.current_layer = self.document.getroot() self.view_center = (0.0,0.0) - layerattr = xml.xpath.Evaluate('//sodipodi:namedview/@inkscape:current-layer',self.document,context=ctx) + layerattr = self.document.xpath('//sodipodi:namedview/@inkscape:current-layer', NSS) if layerattr: - layername = layerattr[0].value - layer = xml.xpath.Evaluate('//g[@id="%s"]' % layername,self.document,context=ctx) + layername = layerattr[0] + layer = self.document.xpath('//g[@id="%s"]' % layername, NSS) if layer: self.current_layer = layer[0] - xattr = xml.xpath.Evaluate('//sodipodi:namedview/@inkscape:cx',self.document,context=ctx) - yattr = xml.xpath.Evaluate('//sodipodi:namedview/@inkscape:cy',self.document,context=ctx) - doc_height = unittouu(self.document.documentElement.getAttribute('height')) + xattr = self.document.xpath('//sodipodi:namedview/@inkscape:cx', NSS) + yattr = self.document.xpath('//sodipodi:namedview/@inkscape:cy', NSS) + doc_height = unittouu(self.document.getroot().get('height')) if xattr and yattr: - x = xattr[0].value - y = yattr[0].value + x = xattr[0] + y = yattr[0] if x and y: self.view_center = (float(x), doc_height - float(y)) # FIXME: y-coordinate flip, eliminate it when it's gone in Inkscape def getselected(self): """Collect selected nodes""" for id in self.options.ids: path = '//*[@id="%s"]' % id - for node in xml.xpath.Evaluate(path,self.document): + for node in self.document.xpath(path, NSS): self.selected[id] = node def getdocids(self): - docIdNodes = xml.xpath.Evaluate('//@id',self.document,context=self.ctx) + docIdNodes = self.document.xpath('//@id', NSS) for m in docIdNodes: - self.doc_ids[m.value] = 1 + self.doc_ids[m] = 1 def output(self): """Serialize document into XML on stdout""" - xml.dom.ext.Print(self.document) + self.document.write(sys.stdout) def affect(self): """Affect an SVG document with a callback effect""" self.getoptions() @@ -167,9 +162,9 @@ class Effect: return new_id def xpathSingle(self, path): try: - retval = xml.xpath.Evaluate(path,self.document,context=self.ctx)[0] + retval = self.document.xpath(path, NSS)[0] except: debug("No matching node for expression: %s" % path) retval = None return retval - + diff --git a/share/extensions/lindenmayer.py b/share/extensions/lindenmayer.py index df63f38fd..5912201d2 100755 --- a/share/extensions/lindenmayer.py +++ b/share/extensions/lindenmayer.py @@ -101,14 +101,12 @@ class LSystem(inkex.Effect): return level_string def effect(self): - new = self.document.createElement('svg:path') s = {'stroke-linejoin': 'miter', 'stroke-width': '1.0px', 'stroke-opacity': '1.0', 'fill-opacity': '1.0', 'stroke': '#000000', 'stroke-linecap': 'butt', 'fill': 'none'} - new.setAttribute('style', simplestyle.formatStyle(s)) - new.setAttribute('d', self.iterate()) - self.current_layer.appendChild(new) + attribs = {'style':simplestyle.formatStyle(s),'d':self.iterate()} + inkex.etree.SubElement(self.current_layer,inkex.addNS('path','svg'),attribs) e = LSystem() e.affect()