1 #!/usr/bin/env python
2 # Copyright 2008, 2009 Hannes Hochreiner
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation, either version 3 of the License, or
6 # (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see http://www.gnu.org/licenses/.
16 # These lines are only needed if you don't put the script directly into
17 # the installation directory
18 import sys
19 # Unix
20 sys.path.append('/usr/share/inkscape/extensions')
21 # OS X
22 sys.path.append('/Applications/Inkscape.app/Contents/Resources/extensions')
23 # Windows
24 sys.path.append('C:\Program Files\Inkscape\share\extensions')
26 # We will use the inkex module with the predefined Effect base class.
27 import inkex
28 import os
29 import re
30 from lxml import etree
31 from copy import deepcopy
32 import gettext
33 _ = gettext.gettext
35 class JessyInk_Effects(inkex.Effect):
36 def __init__(self):
37 # Call the base class constructor.
38 inkex.Effect.__init__(self)
40 self.OptionParser.add_option('--tab', action = 'store', type = 'string', dest = 'what')
42 inkex.NSS[u"jessyink"] = u"https://launchpad.net/jessyink"
44 def effect(self):
45 # Check version.
46 scriptNodes = self.document.xpath("//svg:script[@jessyink:version='1.5.5']", namespaces=inkex.NSS)
48 if len(scriptNodes) != 1:
49 inkex.errormsg(_("The JessyInk script is not installed in this SVG file or has a different version than the JessyInk extensions. Please select \"install/update...\" from the \"JessyInk\" sub-menu of the \"Extensions\" menu to install or update the JessyInk script.\n\n"))
51 baseView = self.document.xpath("//sodipodi:namedview[@id='base']", namespaces=inkex.NSS)
53 if len(baseView) != 1:
54 inkex.errormsg(_("Could not obtain the selected layer for inclusion of the video element.\n\n"))
56 layer = self.document.xpath("//svg:g[@id='" + baseView[0].attrib["{" + inkex.NSS["inkscape"] + "}current-layer"] + "']", namespaces=inkex.NSS)
58 if (len(layer) != 1):
59 inkex.errormsg(_("Could not obtain the selected layer for inclusion of the video element.\n\n"))
61 # Parse template file.
62 tmplFile = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'jessyInk_video.svg'), 'r')
63 tmplRoot = etree.fromstring(tmplFile.read())
64 tmplFile.close()
66 elem = deepcopy(tmplRoot.xpath("//svg:g[@jessyink:element='core.video']", namespaces=inkex.NSS)[0])
67 nodeDict = findInternalLinks(elem, tmplRoot)
69 deleteIds(elem)
71 idSubst = {}
73 for key in nodeDict:
74 idSubst[key] = getNewId("jessyink.core.video", self.document)
75 deleteIds(nodeDict[key])
76 nodeDict[key].attrib['id'] = idSubst[key]
77 elem.insert(0, nodeDict[key])
79 for ndIter in elem.iter():
80 for attrIter in ndIter.attrib:
81 for entryIter in idSubst:
82 ndIter.attrib[attrIter] = ndIter.attrib[attrIter].replace("#" + entryIter, "#" + idSubst[entryIter])
84 # Append element.
85 layer[0].append(elem)
87 def findInternalLinks(node, docRoot, nodeDict = {}):
88 for entry in re.findall("url\(#.*\)", etree.tostring(node)):
89 linkId = entry[5:len(entry) - 1]
91 if not nodeDict.has_key(linkId):
92 nodeDict[linkId] = deepcopy(docRoot.xpath("//*[@id='" + linkId + "']", namespaces=inkex.NSS)[0])
93 nodeDict = findInternalLinks(nodeDict[linkId], docRoot, nodeDict)
95 for entry in node.iter():
96 if entry.attrib.has_key('{' + inkex.NSS['xlink'] + '}href'):
97 linkId = entry.attrib['{' + inkex.NSS['xlink'] + '}href'][1:len(entry.attrib['{' + inkex.NSS['xlink'] + '}href'])]
99 if not nodeDict.has_key(linkId):
100 nodeDict[linkId] = deepcopy(docRoot.xpath("//*[@id='" + linkId + "']", namespaces=inkex.NSS)[0])
101 nodeDict = findInternalLinks(nodeDict[linkId], docRoot, nodeDict)
103 return nodeDict
105 def getNewId(prefix, docRoot):
106 import datetime
108 number = datetime.datetime.now().microsecond
110 while len(docRoot.xpath("//*[@id='" + prefix + str(number) + "']", namespaces=inkex.NSS)) > 0:
111 number += 1
113 return prefix + str(number)
115 def deleteIds(node):
116 for entry in node.iter():
117 if entry.attrib.has_key('id'):
118 del entry.attrib['id']
120 # Create effect instance
121 effect = JessyInk_Effects()
122 effect.affect()