jessyInk_video.py revision a00a58fc3850b7b52549322b31e8b943ee16fed7
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler#!/usr/bin/env python
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler# Copyright 2008, 2009 Hannes Hochreiner
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler# This program is free software: you can redistribute it and/or modify
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler# it under the terms of the GNU General Public License as published by
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler# the Free Software Foundation, either version 3 of the License, or
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler# (at your option) any later version.
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler#
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler# This program is distributed in the hope that it will be useful,
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler# but WITHOUT ANY WARRANTY; without even the implied warranty of
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler# GNU General Public License for more details.
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler#
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler# You should have received a copy of the GNU General Public License
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler# along with this program. If not, see http://www.gnu.org/licenses/.
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler# These lines are only needed if you don't put the script directly into
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler# the installation directory
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andlerimport sys
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler# Unix
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andlersys.path.append('/usr/share/inkscape/extensions')
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler# OS X
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andlersys.path.append('/Applications/Inkscape.app/Contents/Resources/extensions')
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler# Windows
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andlersys.path.append('C:\Program Files\Inkscape\share\extensions')
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler# We will use the inkex module with the predefined Effect base class.
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andlerimport inkex
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andlerimport os
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andlerimport re
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andlerfrom lxml import etree
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andlerfrom copy import deepcopy
4d761440b84b78f6af14bb66f2fd52b69641bfd2Hannes Hochreinerimport gettext
4d761440b84b78f6af14bb66f2fd52b69641bfd2Hannes Hochreiner_ = gettext.gettext
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andlerclass JessyInk_Effects(inkex.Effect):
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler def __init__(self):
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler # Call the base class constructor.
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler inkex.Effect.__init__(self)
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler self.OptionParser.add_option('--tab', action = 'store', type = 'string', dest = 'what')
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler inkex.NSS[u"jessyink"] = u"https://launchpad.net/jessyink"
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler def effect(self):
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler # Check version.
a00a58fc3850b7b52549322b31e8b943ee16fed7Hannes Hochreiner scriptNodes = self.document.xpath("//svg:script[@jessyink:version='1.5.5']", namespaces=inkex.NSS)
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler if len(scriptNodes) != 1:
4d761440b84b78f6af14bb66f2fd52b69641bfd2Hannes Hochreiner 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"))
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler baseView = self.document.xpath("//sodipodi:namedview[@id='base']", namespaces=inkex.NSS)
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler if len(baseView) != 1:
4d761440b84b78f6af14bb66f2fd52b69641bfd2Hannes Hochreiner inkex.errormsg(_("Could not obtain the selected layer for inclusion of the video element.\n\n"))
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler layer = self.document.xpath("//svg:g[@id='" + baseView[0].attrib["{" + inkex.NSS["inkscape"] + "}current-layer"] + "']", namespaces=inkex.NSS)
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler if (len(layer) != 1):
4d761440b84b78f6af14bb66f2fd52b69641bfd2Hannes Hochreiner inkex.errormsg(_("Could not obtain the selected layer for inclusion of the video element.\n\n"))
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler # Parse template file.
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler tmplFile = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'jessyInk_video.svg'), 'r')
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler tmplRoot = etree.fromstring(tmplFile.read())
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler tmplFile.close()
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler elem = deepcopy(tmplRoot.xpath("//svg:g[@jessyink:element='core.video']", namespaces=inkex.NSS)[0])
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler nodeDict = findInternalLinks(elem, tmplRoot)
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler deleteIds(elem)
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler idSubst = {}
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler for key in nodeDict:
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler idSubst[key] = getNewId("jessyink.core.video", self.document)
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler deleteIds(nodeDict[key])
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler nodeDict[key].attrib['id'] = idSubst[key]
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler elem.insert(0, nodeDict[key])
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler for ndIter in elem.iter():
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler for attrIter in ndIter.attrib:
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler for entryIter in idSubst:
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler ndIter.attrib[attrIter] = ndIter.attrib[attrIter].replace("#" + entryIter, "#" + idSubst[entryIter])
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler # Append element.
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler layer[0].append(elem)
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andlerdef findInternalLinks(node, docRoot, nodeDict = {}):
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler for entry in re.findall("url\(#.*\)", etree.tostring(node)):
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler linkId = entry[5:len(entry) - 1]
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler if not nodeDict.has_key(linkId):
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler nodeDict[linkId] = deepcopy(docRoot.xpath("//*[@id='" + linkId + "']", namespaces=inkex.NSS)[0])
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler nodeDict = findInternalLinks(nodeDict[linkId], docRoot, nodeDict)
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler for entry in node.iter():
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler if entry.attrib.has_key('{' + inkex.NSS['xlink'] + '}href'):
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler linkId = entry.attrib['{' + inkex.NSS['xlink'] + '}href'][1:len(entry.attrib['{' + inkex.NSS['xlink'] + '}href'])]
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler if not nodeDict.has_key(linkId):
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler nodeDict[linkId] = deepcopy(docRoot.xpath("//*[@id='" + linkId + "']", namespaces=inkex.NSS)[0])
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler nodeDict = findInternalLinks(nodeDict[linkId], docRoot, nodeDict)
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler return nodeDict
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andlerdef getNewId(prefix, docRoot):
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler import datetime
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler number = datetime.datetime.now().microsecond
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler while len(docRoot.xpath("//*[@id='" + prefix + str(number) + "']", namespaces=inkex.NSS)) > 0:
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler number += 1
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler return prefix + str(number)
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andlerdef deleteIds(node):
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler for entry in node.iter():
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler if entry.attrib.has_key('id'):
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler del entry.attrib['id']
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler# Create effect instance
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andlereffect = JessyInk_Effects()
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andlereffect.affect()
1b1107ddff011fb4b14c466805d0f3b75a1bae3cJosh Andler