added open closed path and export selection as svg
This commit is contained in:
parent
5dda2bedc3
commit
b496df017d
19
extensions/fablabchemnitz/export_selection.inx
Normal file
19
extensions/fablabchemnitz/export_selection.inx
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<_name>Export selection as SVG</_name>
|
||||
<id>fablabchemnitz.de.export_selection_as_svg</id>
|
||||
<param name="wrap_transform" type="boolean" _gui-text="Wrap final document in transform">false</param>
|
||||
<param name="export_dir" type="path" mode="folder" gui-text="Location to save exported documents">./inkscape_export/</param>
|
||||
<effect needs-document="true" needs-live-preview="false">
|
||||
<object-type>all</object-type>
|
||||
<menu-tip>Export selection to separate SVG file.</menu-tip>
|
||||
<effects-menu>
|
||||
<submenu name="FabLab Chemnitz">
|
||||
<submenu name="Import/Export/Transfer"/>
|
||||
</submenu>
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
<command reldir="inx" interpreter="python">export_selection.py</command>
|
||||
</script>
|
||||
</inkscape-extension>
|
100
extensions/fablabchemnitz/export_selection.py
Normal file
100
extensions/fablabchemnitz/export_selection.py
Normal file
@ -0,0 +1,100 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from copy import deepcopy
|
||||
from pathlib import Path
|
||||
import logging
|
||||
import math
|
||||
import os
|
||||
|
||||
import inkex
|
||||
import inkex.command
|
||||
from lxml import etree
|
||||
from scour.scour import scourString
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
GROUP_ID = 'export_selection_transform'
|
||||
|
||||
|
||||
class ExportObject(inkex.EffectExtension):
|
||||
def add_arguments(self, pars):
|
||||
pars.add_argument("--wrap_transform", type=inkex.Boolean, default=False, help="Wrap final document in transform")
|
||||
pars.add_argument("--export_dir", default="~/inkscape_export/", help="Location to save exported documents")
|
||||
|
||||
def effect(self):
|
||||
if not self.svg.selected:
|
||||
return
|
||||
|
||||
export_dir = Path(self.absolute_href(self.options.export_dir))
|
||||
os.makedirs(export_dir, exist_ok=True)
|
||||
|
||||
bbox = inkex.BoundingBox()
|
||||
for elem in self.svg.selected.values():
|
||||
transform = inkex.Transform()
|
||||
parent = elem.getparent()
|
||||
if parent is not None and isinstance(parent, inkex.ShapeElement):
|
||||
transform = parent.composed_transform()
|
||||
try:
|
||||
bbox += elem.bounding_box(transform)
|
||||
except Exception:
|
||||
logger.exception("Bounding box not computed")
|
||||
logger.info("Skipping bounding box")
|
||||
transform = elem.composed_transform()
|
||||
x1, y1 = transform.apply_to_point([0, 0])
|
||||
x2, y2 = transform.apply_to_point([1, 1])
|
||||
bbox += inkex.BoundingBox((x1, x2), (y1, y2))
|
||||
|
||||
template = self.create_document()
|
||||
filename = None
|
||||
|
||||
group = etree.SubElement(template, '{http://www.w3.org/2000/svg}g')
|
||||
group.attrib['id'] = GROUP_ID
|
||||
group.attrib['transform'] = str(inkex.Transform(((1, 0, -bbox.left), (0, 1, -bbox.top))))
|
||||
|
||||
for elem in self.svg.selected.values():
|
||||
|
||||
elem_copy = deepcopy(elem)
|
||||
elem_copy.attrib['transform'] = str(elem.composed_transform())
|
||||
group.append(elem_copy)
|
||||
|
||||
width = math.ceil(bbox.width)
|
||||
height = math.ceil(bbox.height)
|
||||
template.attrib['viewBox'] = f'0 0 {width} {height}'
|
||||
template.attrib['width'] = f'{width}'
|
||||
template.attrib['height'] = f'{height}'
|
||||
|
||||
if filename is None:
|
||||
filename = elem.attrib.get('id', None)
|
||||
if filename:
|
||||
filename = filename.replace(os.sep, '_') + '.svg'
|
||||
if not filename:
|
||||
filename = 'element.svg'
|
||||
|
||||
template.append(group)
|
||||
|
||||
if not self.options.wrap_transform:
|
||||
self.load(inkex.command.inkscape_command(template.tostring(), select=GROUP_ID, verbs=['SelectionUnGroup']))
|
||||
template = self.svg
|
||||
for child in template.getchildren():
|
||||
if child.tag == '{http://www.w3.org/2000/svg}metadata':
|
||||
template.remove(child)
|
||||
|
||||
self.save_document(template, export_dir / filename)
|
||||
|
||||
def create_document(self):
|
||||
document = self.svg.copy()
|
||||
for child in document.getchildren():
|
||||
if child.tag == '{http://www.w3.org/2000/svg}defs':
|
||||
continue
|
||||
document.remove(child)
|
||||
return document
|
||||
|
||||
def save_document(self, document, filename):
|
||||
with open(filename, 'wb') as fp:
|
||||
document = document.tostring()
|
||||
fp.write(scourString(document).encode('utf8'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
ExportObject().run()
|
15
extensions/fablabchemnitz/openClosedPath.inx
Normal file
15
extensions/fablabchemnitz/openClosedPath.inx
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>Open closed Path</name>
|
||||
<id>fablabchemnitz.de.openClosedPath</id>
|
||||
<effect>
|
||||
<effects-menu>
|
||||
<submenu name="FabLab Chemnitz">
|
||||
<submenu name="Modify existing Path(s)"/>
|
||||
</submenu>
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
<command location="inx" interpreter="python">openClosedPath.py</command>
|
||||
</script>
|
||||
</inkscape-extension>
|
37
extensions/fablabchemnitz/openClosedPath.py
Normal file
37
extensions/fablabchemnitz/openClosedPath.py
Normal file
@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env python3
|
||||
# coding=utf-8
|
||||
#
|
||||
# Copyright (C) 2020 Ellen Wasboe, ellen@wasbo.net
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
"""
|
||||
Remove all z-s from all selected paths
|
||||
My purpose: to open paths of single line fonts with a temporary closing to fit into .ttf/.otf format files
|
||||
"""
|
||||
|
||||
import inkex, re
|
||||
from inkex import PathElement
|
||||
|
||||
class OpenClosedPath(inkex.EffectExtension):
|
||||
# Extension to open a closed path by z or by last node
|
||||
|
||||
def effect(self):
|
||||
elements = self.svg.selection.filter(PathElement).values()
|
||||
for elem in elements:
|
||||
pp=elem.path.to_absolute() #remove transformation matrix
|
||||
elem.path = re.sub(r"Z","",str(pp))
|
||||
|
||||
if __name__ == '__main__':
|
||||
OpenClosedPath().run()
|
Reference in New Issue
Block a user