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.
effect adding namespaces
Re: effect adding namespaces
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?
Re: effect adding namespaces
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.
Re: effect adding namespaces
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).
Re: effect adding namespaces
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.
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.
Re: effect adding namespaces
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
WKR
Re: effect adding namespaces
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.
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.
Re: effect adding namespaces
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):
I have my own NSS map, with {'mynamespace': 'mynamespaceURL'}
Then I had to reparse the document if my namespace wasn't already found:
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
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