effect adding namespaces

General discussions about Inkscape.
pelle
Posts: 53
Joined: Wed Mar 05, 2008 8:23 am

effect adding namespaces

Postby pelle » Thu May 29, 2008 6:43 am

Hi,

I'm not sure yet it is a good idea, but my current work on my Inkscape Boardgames Extensions is adding some extra information to the generated SVG files, to be able to support making game components for SVG-based (web) games. Not sure it will be used much, even by me, but perhaps there are other uses of having metadata in the elements easily accessible to external scripts or other Inkscape effects (ie the hexmap generator is now adding new attributes for many generated objects to describe what coordinate in the grid they have). The problem is adding the new attributes currently requires, I believe, some ugly code (manually adding {http://namespace-url}attribute) and the resulting short namespace identifier becomes an automatically generated ns0, since the new namespace is not in the NSS mapping of inkex.py).

I guess basically what I'm trying to say is that perhaps it would be useful to provide a simple API in inkex.py to add namespaces to the NSS mapping and then use them like the other namespaces already in the mapping. Then perhaps in a future version the code in my effects can look a bit prettier, and it might inspire others to come up with useful ways of adding special information to generated SVG in other effects.

I guess there may be some workaround using some Python feature I have forgotten about.

User avatar
sas
Posts: 404
Joined: Sat Oct 06, 2007 5:42 am

Re: effect adding namespaces

Postby sas » Thu May 29, 2008 7:13 am

pelle wrote:I guess basically what I'm trying to say is that perhaps it would be useful to provide a simple API in inkex.py to add namespaces to the NSS mapping and then use them like the other namespaces already in the mapping.

Why can't you just add them directly to NSS?

inkex.NSS["xyz"] = "http://example.com/some/namespace"

Or have I misunderstood what you're trying to do?

pelle
Posts: 53
Joined: Wed Mar 05, 2008 8:23 am

Re: effect adding namespaces

Postby pelle » Thu May 29, 2008 4:59 pm

That was my first attempt, but it didn't seem to work. I'm not sure if it is somehow related to the way Python handles default values. Perhaps with some experimentation I can make it work, or only small modifications to inkex.py are needed.

User avatar
sas
Posts: 404
Joined: Sat Oct 06, 2007 5:42 am

Re: effect adding namespaces

Postby sas » Thu May 29, 2008 10:53 pm

Yes, you're right, it won't give you the desired prefix when the file is written. The problem is that NSS is irrelevant - it isn't the namespace map that's used for writing the file. There doesn't seem to be any way of modifying the namespace map that's actually used - it's just automatically generated when the file is read in. You can look at it - it's self.document.getroot().nsmap - but you can't change it. So, unless I've missed something, there's nothing you can do to get the prefix you want (short of doing something extravagant such as writing your own serializer, or reconstructing the XML tree node by node).

pelle
Posts: 53
Joined: Wed Mar 05, 2008 8:23 am

Re: effect adding namespaces

Postby pelle » Fri May 30, 2008 1:25 am

Aw. OK, thanks for taking your time to explain that. I will keep the ugly solution then and hope not too many cares
about the slightly ugly resulting SVG code. At least the namespace I add is added when the SVG is generated, only the name is ns0 instead of something descriptive, and this should only be a cosmetic problem to a geek reading the code I hope.

dworkin
Posts: 1
Joined: Sun Nov 20, 2011 8:27 pm

Re: effect adding namespaces

Postby dworkin » Sun Nov 20, 2011 8:31 pm

pelle wrote:Aw. OK, thanks for taking your time to explain that. I will keep the ugly solution then and hope not too many cares
about the slightly ugly resulting SVG code. At least the namespace I add is added when the SVG is generated, only the name is ns0 instead of something descriptive, and this should only be a cosmetic problem to a geek reading the code I hope.


Pelle, did you get any further with this in those 3-4 years?
I'm facing the same issue today, almost 2012 :o

WKR

atamar
Posts: 3
Joined: Tue Jun 17, 2008 11:32 pm

Re: effect adding namespaces

Postby atamar » Tue Jan 31, 2012 9:23 pm

Chiming in to make sure this topic isn't forgotten.

I rely on a custom xmlns and adding identifier attributes to do programmatic manipulation before final display of data. (Wouldn't mind using the id attribute, but that gets tricky sometimes - some operations create new objects with new id's, which surprises the careless user. Simpler to specify a work flow with custom attributes.)

I've been satisfied to add the xmlns with an external editor, but a UI option for this would be much appreciated, and would make it quite a bit simpler to tell other users how to go about creating a visualization.

There are other associated issues: if the custom xmlns is used for attributes only, Inkscape will discard the "unused" namespace (https://bugs.launchpad.net/inkscape/+bug/166004), and apparently deciding how to retain custom attributes when performing grouping/combining/* seems to be a bit tricky.

So, a call remains for custom namespace features.

lingo
Posts: 1
Joined: Sat May 03, 2014 9:37 pm

Re: effect adding namespaces

Postby lingo » Sat May 03, 2014 9:49 pm

I found a work-around (hack) to enable my extension to add custom namespaces.
It's ugly, but due to limits of lxml, this seems to be the only way I could find:

My effect class inherits from inkex.Effect
First, I had to make my own addNS routine (instead of using inkex.addNS):

Code: Select all

 def addNS(self, tag, ns=None):
        val = tag
        if ns!=None and len(ns)>0 and len(tag)>0 and tag[0]!='{':
            if inkex.NSS.has_key(ns):
                val = "{%s}%s" % (inkex.NSS[ns], tag)
            elif self.NSS.has_key(ns):
                val = "{%s}%s" % (self.NSS[ns], tag)
        return val


I have my own NSS map, with {'mynamespace': 'mynamespaceURL'}
Then I had to reparse the document if my namespace wasn't already found:

Code: Select all

 def reparse(self):
        """Filter and reparse document in specified file or on stdin"""
        try:
            try:
                stream = open(file,'r')
            except:
                stream = open(self.svg_file,'r')
        except:
            stream = sys.stdin
        data          = stream.read()
        data          = data.replace('<svg', "<svg\nxmlns:mynamespace=\"%s\" " % self.NSS['mynamespace'])
        self.document = etree.parse(StringIO(data))
        self.getposinlayer()
        self.getselected()
        self.getdocids()
        stream.close()

    def effect(self):
        if not self.document.getroot().nsmap.has_key('mynamespace'):
            self.reparse()
        item.attrib[ self.addNS('tag','mynamespace') ] = value


This is super-ugly, but it seems to work, and Inkscape seems to keep my custom attributes over a save.

My extension isn't finished but will be part of this code: https://github.com/lingo/inkscape_onionskin


Return to “General Discussions”