Skip to content

Instantly share code, notes, and snippets.

@larscwallin
Last active December 16, 2015 19:59
Show Gist options
  • Select an option

  • Save larscwallin/5489140 to your computer and use it in GitHub Desktop.

Select an option

Save larscwallin/5489140 to your computer and use it in GitHub Desktop.
larscwallin.inx.extractelements version 0.1 extracts all selected SVG Elements to file and/or displayed as a string in the Inkscape GUI.
<inkscape-extension>
<_name>Extract Elements</_name>
<id>com.larscwallin.inx.extractelements</id>
<dependency type="executable" location="extensions">larscwallin.inx.extractelements.py</dependency>
<dependency type="executable" location="extensions">inkex.py</dependency>
<param name="where" type="string" _gui-text="Output path"></param>
<param name="encode" type="boolean" _gui-text="Do you wish to Base64 encode the SVG?">false</param>
<param name="viewresult" type="boolean" _gui-text="Do you wish to view the resulting?">true</param>
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu _name="Export"/>
</effects-menu>
</effect>
<script>
<command reldir="extensions" interpreter="python">larscwallin.inx.extractelements.py</command>
</script>
</inkscape-extension>
#!/usr/bin/env python
# These two lines are only needed if you don't put the script directly into
# the installation directory
import sys
import base64
import string
import webbrowser
import threading
import os.path
sys.path.append('/usr/share/inkscape/extensions')
import SvgDocument
import inkex
import simpletransform
import simplepath
import simplestyle
class ElementsToSVG(inkex.Effect):
exportTemplate = """<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="{{element.width}}" height="{{element.height}}">
{{element.source}}
</svg>"""
def __init__(self):
"""
Constructor.
Defines the "--what" option of a script.
"""
# Call the base class constructor.
inkex.Effect.__init__(self)
self.OptionParser.add_option('-w', '--where', action = 'store',
type = 'string', dest = 'where', default = '',
help = '')
self.OptionParser.add_option('--encode', action = 'store',
type = 'inkbool', dest = 'encode', default = False,
help = 'Do you want to Base64 encode the result?')
self.OptionParser.add_option('--viewresult', action = 'store',
type = 'inkbool', dest = 'viewresult', default = False,
help = 'Do you want to view the resulting document?')
def effect(self):
"""
Effect behaviour.
"""
self.where = self.options.where
self.base64Encode = self.options.encode
self.viewResult = self.options.encode
self.getselected()
if(self.selected.__len__() > 0):
selected = []
# Iterate through all selected elements
for element in self.selected.values():
elementLabel = str(element.get(inkex.addNS('label', 'inkscape'),''))
elementId = element.get('id')
tag_name = self.getTagName(element)
if(tag_name == 'path'):
pathData = self.movePath(element,0,0,'tl')
if(pathData):
element.set('d',pathData)
elementBox = list(simpletransform.computeBBox([element]))
elementBox[1] = (elementBox[1]-elementBox[0])
elementBox[3] = (elementBox[3]-elementBox[2])
elementSource = inkex.etree.tostring(element)
if(elementSource!=''):
# Wrap the node in an SVG doc
tplResult = string.replace(self.exportTemplate,'{{element.width}}',str(elementBox[1]))
tplResult = string.replace(tplResult,'{{element.height}}',str(elementBox[3]))
tplResult = string.replace(tplResult,'{{element.source}}',elementSource)
# If the result of the operation is valid, add the SVG source to the selected array
if(tplResult):
selected.append({
'id':elementId,
'label':elementLabel,
'source':tplResult,
'box':elementBox
})
for node in selected:
#'data:image/svg+xml;base64,'+
# Cache this in a local var
content = node['source']
if(content!=''):
if(self.base64Encode):
content = (base64.b64encode(content))
if(self.where!=''):
# The easiest way to name rendered elements is by using their id since we can trust that this is always unique.
filename = os.path.join(self.where, (node['id']+node['label']+'.svg'))
success = self.saveToFile(content,filename)
if(success and self.viewResult):
self.viewOutput(filename)
else:
inkex.debug('Unable to write to file "' + filename + '"')
else:
if(self.viewResult):
if(self.base64Encode):
inkex.debug('data:image/svg+xml;base64,'+content)
#self.viewOutput('data:image/svg+xml;base64,'+content)
else:
inkex.debug(content)
#self.viewOutput('data:image/svg+xml,'+content)
else:
if(self.base64Encode):
inkex.debug('data:image/svg+xml;base64,'+content)
else:
inkex.debug(content)
else:
inkex.debug('No SVG source available for element ' + node['id'])
def getTagName(self,node):
type = node.get(inkex.addNS('type', 'sodipodi'))
if(type == None):
#remove namespace data {....}
tag_name = node.tag
tag_name = tag_name.split('}')[1]
else:
tag_name = str(type)
return tag_name
def movePath(self,node,x,y,origin):
tag_name = self.getTagName(node)
if(tag_name != 'path'):
inkex.debug('movePath only works on SVG Path elements. Argument was of type "' + tag_name + '"')
return False
path = simplepath.parsePath(node.get('d'))
id = node.get('id')
box = list(simpletransform.computeBBox([node]))
#inkex.debug(path)
offset_x = (box[0] - x)
offset_y = (box[2] - (y))
#inkex.debug('Will move path "'+id+'" from x, y ' + str(box[0]) + ', ' + str(box[2]))
#inkex.debug('to x, y ' + str(x) + ', ' + str(y))
#inkex.debug('The x offset is ' + str(offset_x))
#inkex.debug('The y offset is = ' + str(offset_y))
for cmd in path:
params = cmd[1]
i = 0
while(i < len(params)):
if(i % 2 == 0):
#inkex.debug('x point at ' + str( round( params[i] )))
params[i] = (params[i] - offset_x)
#inkex.debug('moved to ' + str( round( params[i] )))
else:
#inkex.debug('y point at ' + str( round( params[i]) ))
params[i] = (params[i] - offset_y)
#inkex.debug('moved to ' + str( round( params[i] )))
i = i + 1
#inkex.debug(simplepath.formatPath(path))
return simplepath.formatPath(path)
def saveToFile(self,content,filename):
FILE = open(filename,'w')
if(FILE):
FILE.write(content)
FILE.close()
return True
else:
return False
def viewOutput(self,url):
runner = BrowserRunner()
runner.url = url
runner.start()
class BrowserRunner(threading.Thread):
url = ''
def __init__(self):
threading.Thread.__init__ (self)
def run(self):
webbrowser.open('file://' + self.url)
# Create effect instance and apply it.
effect = ElementsToSVG()
effect.affect(output=False)
#inkex.errormsg(_("This will be written to Python stderr"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment