Code

begin converting python extensions to use lxml. this might take me a while and it...
authoracspike <acspike@users.sourceforge.net>
Tue, 19 Jun 2007 03:45:13 +0000 (03:45 +0000)
committeracspike <acspike@users.sourceforge.net>
Tue, 19 Jun 2007 03:45:13 +0000 (03:45 +0000)
share/extensions/addnodes.py
share/extensions/coloreffect.py
share/extensions/cubicsuperpath.py
share/extensions/dots.py
share/extensions/dxf_outlines.py
share/extensions/edge3d.py
share/extensions/embedimage.py
share/extensions/gears.py
share/extensions/inkex.py
share/extensions/lindenmayer.py

index e57c7566dae00809d91427365c9c92b3cdeef52a..bc5ae4030bc1fc39231f95ee622bc3b477c2ae37 100644 (file)
@@ -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()
index 2708b48f3930fc8bad575265db962bbc242eabcc..fcb20dde4f8497c11c8977d1189dc7ce59e41047 100644 (file)
@@ -1,6 +1,7 @@
 #!/usr/bin/env python \r
 '''\r
 Copyright (C) 2006 Jos Hirth, kaioa.com\r
+Copyright (C) 2007 Aaron C. Spike\r
 \r
 This program is free software; you can redistribute it and/or modify\r
 it under the terms of the GNU General Public License as published by\r
@@ -18,8 +19,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 '''\r
 import sys, copy, optparse, simplestyle, inkex\r
 \r
-import xml.xpath\r
-\r
 import random\r
 \r
 color_props_fill=('fill:','stop-color:','flood-color:','lighting-color:')\r
@@ -29,26 +28,24 @@ color_props = color_props_fill + color_props_stroke
 \r
 class ColorEffect(inkex.Effect):\r
   def __init__(self):\r
-    inkex.Effect.__init__(self,use_minidom=True)\r
+    inkex.Effect.__init__(self)\r
     self.visited = []\r
 \r
   def effect(self):\r
     if len(self.selected)==0:\r
-      self.getAttribs(self.document)\r
+      self.getAttribs(self.document.getroot())\r
     else:\r
       for id,node in self.selected.iteritems():\r
         self.getAttribs(node)\r
 \r
   def getAttribs(self,node):\r
     self.changeStyle(node)\r
-    if node.hasChildNodes():\r
-      childs=node.childNodes\r
-      for child in childs:\r
-        self.getAttribs(child)\r
+    for child in node:\r
+      self.getAttribs(child)\r
   \r
   def changeStyle(self,node):\r
-    if node.hasAttributes():\r
-      style=node.getAttribute('style') # fixme: this will break for presentation attributes!\r
+    if node.attrib.has_key('style'):\r
+      style=node.get('style') # fixme: this will break for presentation attributes!\r
       if style!='':\r
         #inkex.debug('old style:'+style)\r
         styles=style.split(';')\r
@@ -57,7 +54,7 @@ class ColorEffect(inkex.Effect):
             if styles[i].startswith(color_props[c]):\r
               styles[i]=color_props[c]+self.process_prop(styles[i][len(color_props[c]):])\r
         #inkex.debug('new style:'+';'.join(styles))\r
-        node.setAttribute('style',';'.join(styles))\r
+        node.set('style',';'.join(styles))\r
 \r
   def process_prop(self,col):\r
     #debug('got:'+col)\r
@@ -66,13 +63,13 @@ class ColorEffect(inkex.Effect):
       col='#'+self.colmod(c[0],c[1],c[2])\r
       #debug('made:'+col)\r
     if col.startswith('url(#'):\r
-       id = col[len('url(#'):col.find(')')]\r
-       newid = '%s-%d' % (id, int(random.random() * 1000))\r
-       #inkex.debug('ID:' + id )\r
-       path = '//*[@id="%s"]' % id\r
-       for node in xml.xpath.Evaluate(path,self.document):\r
-         self.process_gradient(node, newid)\r
-       col = 'url(#%s)' % newid\r
+      id = col[len('url(#'):col.find(')')]\r
+      newid = '%s-%d' % (id, int(random.random() * 1000))\r
+      #inkex.debug('ID:' + id )\r
+      path = '//*[@id="%s"]' % id\r
+      for node in self.document.xpath(path, inkex.NSS):\r
+        self.process_gradient(node, newid)\r
+      col = 'url(#%s)' % newid\r
     return col\r
 \r
   def process_gradient(self, node, newid):\r
@@ -84,22 +81,22 @@ class ColorEffect(inkex.Effect):
          #return\r
        #self.visited.append(this_id)\r
        #inkex.debug("visited: " + str(self.visited))\r
-    newnode = node.cloneNode(True)\r
-    newnode.setAttribute('id', newid)\r
-    node.parentNode.appendChild(newnode)\r
+    newnode = inkex.etree.fromstring(inkex.etree.tostring(node))\r
+    newnode.set('id', newid)\r
+    node.xpath('..')[0].append(newnode)\r
     self.changeStyle(newnode)\r
-    if newnode.hasChildNodes():\r
-      for child in newnode.childNodes:\r
-        self.changeStyle(child)\r
-    if newnode.hasAttributes():                                \r
-      href=newnode.getAttribute('xlink:href')\r
+    for child in newnode:\r
+      self.changeStyle(child)\r
+    xlink = inkex.addNS('href','xlink')\r
+    if newnode.attrib.has_key(xlink):\r
+      href=newnode.get(xlink)\r
       if href.startswith('#'):\r
         id = href[len('#'):len(href)]\r
         #inkex.debug('ID:' + id )\r
-       newhref = '%s-%d' % (id, int(random.random() * 1000))\r
-       newnode.setAttribute('xlink:href', '#%s' % newhref)\r
+        newhref = '%s-%d' % (id, int(random.random() * 1000))\r
+        newnode.set(xlink, '#%s' % newhref)\r
         path = '//*[@id="%s"]' % id\r
-        for node in xml.xpath.Evaluate(path,self.document):\r
+        for node in self.document.xpath(path,inkex.NSS):\r
           self.process_gradient(node, newhref)\r
  \r
   def colmod(self,r,g,b):\r
index a151084eb39b41bcf4bb7a60aff430c8bd5072c9..cc59905abc03fd7a9e74db0b4a629474dc182c75 100755 (executable)
@@ -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):
index c5f6e8149b9f167ad1af65f01942d864c54c32a6..ca235861c8ae6026369037d55bd9a1a15e8fbdc1 100755 (executable)
@@ -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()
index e8eff2c01f892b8c5ce19e21b5a536aae0089cbb..40beee95cfab46064b7ef19cfaa16b26c8123282 100755 (executable)
@@ -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")\r
         \r
         scale = 25.4/90.0
-        h = inkex.unittouu(inkex.xml.xpath.Evaluate('/svg/@height',self.document)[0].value)\r
-
-        path = '//path'
-        for node in inkex.xml.xpath.Evaluate(path,self.document):\r
-            d = node.attributes.getNamedItem('d').value\r
+        h = inkex.unittouu(self.document.getroot().xpath('@height',inkex.NSS)[0])\r
+        
+        path = '//svg:path'
+        for node in self.document.getroot().xpath(path,inkex.NSS):\r
+            d = node.get('d')\r
             sim = simplepath.parsePath(d)\r
             simplepath.scalePath(sim,scale,-scale)\r
             simplepath.translatePath(sim,0,h*scale)            
index f48dd2f4fa8c95aed81cfc8562cc6742f931ae57..bcb69237a92821519ae42a7d3c9262c27ba4be49 100644 (file)
@@ -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])\r
+        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)\r
+                        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:\r
             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')\r
+            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'))\r
+            g.append(node)
 
         return g
 
index 4cab6c0a907a30a812b08447320b22f7311691bd..75400aebbf767f7634dfb2815b80b40d8504fb71 100644 (file)
@@ -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:
index 060cfdbc2f484c706ba6b554fc8195d07ed5b56e..9a69bf06eaf60a7ddcd74e3e7dcb94e6e9f9eb0c 100644 (file)
@@ -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
-'''
+'''\r
 
-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.\r
+        t = 'translate(' + str( self.view_center[0] ) + ',' + str( self.view_center[1] ) + ')'\r
+        g_attribs = {'inkscape:label':'Gear' + str( teeth ),\r
+                   'transform':t }
+        g = inkex.etree.SubElement(self.current_layer, 'g', g_attribs)
+
+        # Create SVG Path for gear\r
+        style = { 'stroke': '#000000', 'fill': 'none' }\r
+        gear_attribs = {'style':simplestyle.formatStyle(style), 'd':path}
+        gear = inkex.etree.SubElement(g, 'svg:path', gear_attribs )\r
 
 e = Gears()
 e.affect()
index 8be7b5282869fa4355d7ae6d30a28730a68d0a25..a4ffd8bd3fa48db11798c68069fad753cadf0581 100755 (executable)
@@ -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 <http://pyxml.sourceforge.net/>.')
+    sys.exit('The fantabulous lxml wrapper for libxml2 is required by inkex_lxml.py and therefore this extension. Please download the latest version from <http://cheeseshop.python.org/pypi/lxml/>.')
 
 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
-    
+            
index df63f38fd5bde7d814a1e903a7aa5a043c79952d..5912201d2b4562a75dcb74667c4b607feaada4f0 100755 (executable)
@@ -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()