diff --git a/extensions/fablabchemnitz/braille-l18n/braille-l18n.inx b/extensions/fablabchemnitz/braille_l18n/braille_l18n.inx
similarity index 86%
rename from extensions/fablabchemnitz/braille-l18n/braille-l18n.inx
rename to extensions/fablabchemnitz/braille_l18n/braille_l18n.inx
index 92ad17c9..e36574e0 100644
--- a/extensions/fablabchemnitz/braille-l18n/braille-l18n.inx
+++ b/extensions/fablabchemnitz/braille_l18n/braille_l18n.inx
@@ -1,7 +1,7 @@
Convert To Localized Braille
- fablabchemnitz.de.braille-l18n
+ fablabchemnitz.de.braille_l18n
@@ -20,6 +20,6 @@
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/braille-l18n/braille-l18n.py b/extensions/fablabchemnitz/braille_l18n/braille_l18n.py
similarity index 100%
rename from extensions/fablabchemnitz/braille-l18n/braille-l18n.py
rename to extensions/fablabchemnitz/braille_l18n/braille_l18n.py
diff --git a/extensions/fablabchemnitz/braille-l18n/meta.json b/extensions/fablabchemnitz/braille_l18n/meta.json
similarity index 91%
rename from extensions/fablabchemnitz/braille-l18n/meta.json
rename to extensions/fablabchemnitz/braille_l18n/meta.json
index 5a66fb74..57eb291d 100644
--- a/extensions/fablabchemnitz/braille-l18n/meta.json
+++ b/extensions/fablabchemnitz/braille_l18n/meta.json
@@ -1,8 +1,8 @@
[
{
"name": "Convert To Localized Braille",
- "id": "fablabchemnitz.de.braille-l18n",
- "path": "braille-l18n",
+ "id": "fablabchemnitz.de.braille_l18n",
+ "path": "braille_l18n",
"original_name": "Convert to localized Braille",
"original_id": "org.inkscape.text.braille-l18n",
"license": "BSD-3-Clause License",
diff --git a/extensions/fablabchemnitz/paths_to_lowlevel_strokes/meta.json b/extensions/fablabchemnitz/paths_to_lowlevel_strokes/meta.json
new file mode 100644
index 00000000..28ca7913
--- /dev/null
+++ b/extensions/fablabchemnitz/paths_to_lowlevel_strokes/meta.json
@@ -0,0 +1,19 @@
+[
+ {
+ "name": "Paths To Lowlevel Strokes",
+ "id": "fablabchemnitz.de.paths_to_lowlevel_strokes",
+ "path": "paths_to_lowlevel_strokes",
+ "original_name": "Paths To Lowlevel Strokes",
+ "original_id": "fablabchemnitz.de.paths_to_lowlevel_strokes",
+ "license": "GNU GPL v3",
+ "license_url": "https://gitea.fablabchemnitz.de/FabLab_Chemnitz/mightyscape-1.X/src/branch/master/LICENSE",
+ "comment": "Created by Mario Voigt",
+ "source_url": "https://gitea.fablabchemnitz.de/FabLab_Chemnitz/mightyscape-1.X/src/branch/master/extensions/fablabchemnitz/paths_to_strokes",
+ "fork_url": null,
+ "documentation_url": "https://stadtfabrikanten.org/display/IFM/Paths+To+Lowlevel+Strokes",
+ "inkscape_gallery_url": null,
+ "main_authors": [
+ "github.com/vmario89"
+ ]
+ }
+]
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/paths_to_lowlevel_strokes/paths_to_lowlevel_strokes.inx b/extensions/fablabchemnitz/paths_to_lowlevel_strokes/paths_to_lowlevel_strokes.inx
new file mode 100644
index 00000000..23f63431
--- /dev/null
+++ b/extensions/fablabchemnitz/paths_to_lowlevel_strokes/paths_to_lowlevel_strokes.inx
@@ -0,0 +1,19 @@
+
+
+ Paths To Lowlevel Strokes
+ fablabchemnitz.de.paths_to_lowlevel_strokes
+ true
+ 0.100
+ 3
+
+ path
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/paths_to_lowlevel_strokes/paths_to_lowlevel_strokes.py b/extensions/fablabchemnitz/paths_to_lowlevel_strokes/paths_to_lowlevel_strokes.py
new file mode 100644
index 00000000..395e794a
--- /dev/null
+++ b/extensions/fablabchemnitz/paths_to_lowlevel_strokes/paths_to_lowlevel_strokes.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python3
+
+
+from lxml import etree
+import inkex
+from inkex import bezier, PathElement
+from inkex.paths import CubicSuperPath, Path
+import copy
+
+class PathsToStrokes(inkex.EffectExtension):
+
+ def add_arguments(self, pars):
+ pars.add_argument("--flattenbezier", type=inkex.Boolean, default=False, help="Flatten bezier curves to polylines")
+ pars.add_argument("--flatness", type=float, default=0.1, help="Minimum flatness = 0.1. The smaller the value the more fine segments you will get (quantization).")
+ pars.add_argument("--decimals", type=int, default=3)
+
+ def effect(self):
+
+ def flatten(node):
+ path = node.path.transform(node.composed_transform()).to_superpath()
+ bezier.cspsubdiv(path, self.options.flatness)
+ newpath = []
+ for subpath in path:
+ first = True
+ for csp in subpath:
+ cmd = 'L'
+ if first:
+ cmd = 'M'
+ first = False
+ newpath.append([cmd, [csp[1][0], csp[1][1]]])
+ node.path = newpath
+
+ def break_contours(element, breakelements = None):
+ if breakelements == None:
+ breakelements = []
+ if element.tag == inkex.addNS('path','svg'):
+ if self.options.flattenbezier is True:
+ flatten(element)
+ parent = element.getparent()
+ idx = parent.index(element)
+ idSuffix = 0
+ raw = element.path.to_arrays()
+ subPaths = []
+ prev = 0
+ for i in range(len(raw)): # Breaks compound paths into simple paths
+ if raw[i][0] == 'M' and i != 0:
+ subPath = raw[prev:i]
+ subPaths.append(Path(subPath))
+ prev = i
+ subPaths.append(Path(raw[prev:])) #finally add the last path
+ for subPath in subPaths:
+ replacedelement = copy.copy(element)
+ oldId = replacedelement.get('id')
+ csp = CubicSuperPath(subPath)
+ if len(subPath) > 1 and csp[0][0] != csp[0][1]: #avoids pointy paths like M "31.4794 57.6024 Z"
+ replacedelement.path = subPath
+ if len(subPaths) == 1:
+ replacedelement.set('id', oldId)
+ else:
+ replacedelement.set('id', oldId + str(idSuffix))
+ idSuffix += 1
+ parent.insert(idx, replacedelement)
+ breakelements.append(replacedelement)
+ element.delete()
+ for child in element.getchildren():
+ break_contours(child, breakelements)
+ return breakelements
+
+ if len(self.svg.selected) == 0:
+ elementsToWork = break_contours(self.document.getroot())
+ else:
+ elementsToWork = None
+ for element in self.svg.selected.values():
+ elementsToWork = break_contours(element, elementsToWork)
+
+ for element in elementsToWork:
+ oldId = element.get('id')
+ oldStyle = element.style
+ path = element.path.to_absolute().to_arrays() #to_arrays() is deprecated. How to make more modern?
+ pathIsClosed = False
+ if path[-1][0] == 'Z' or \
+ (path[-1][0] == 'L' and path[0][1] == path[-1][1]) or \
+ (path[-1][0] == 'C' and path[0][1] == [path[-1][1][-2], path[-1][1][-1]]) \
+ : #if first is last point the path is also closed. The "Z" command is not required
+ pathIsClosed = True
+ parent = element.getparent()
+ idx = parent.index(element)
+ element.delete()
+
+ if len(path) == 2 and pathIsClosed is False:
+ line = inkex.Line(id=oldId)
+ line.set('x1', '{:0.{dec}f}'.format(path[0][1][0], dec=self.options.decimals))
+ line.set('y1', '{:0.{dec}f}'.format(path[0][1][1], dec=self.options.decimals))
+ line.set('x2', '{:0.{dec}f}'.format(path[1][1][0], dec=self.options.decimals))
+ line.set('y2', '{:0.{dec}f}'.format(path[1][1][1], dec=self.options.decimals))
+ line.style = oldStyle
+ parent.insert(idx, line)
+
+ if len(path) > 2 and pathIsClosed is False:
+ polyline = inkex.Polyline(id=oldId)
+ points = ""
+ for i in range(0, len(path)):
+ points += '{:0.{dec}f},{:0.{dec}f} '.format(path[i][1][0], path[i][1][1], dec=self.options.decimals)
+ polyline.set('points', points)
+ polyline.style = oldStyle
+ parent.insert(idx, polyline)
+
+ if len(path) > 2 and pathIsClosed is True:
+ polygon = inkex.Polygon(id=oldId)
+ points = ""
+ for i in range(0, len(path) - 1):
+ points += '{:0.{dec}f},{:0.{dec}f} '.format(path[i][1][0], path[i][1][1], dec=self.options.decimals)
+ polygon.set('points', points)
+ polygon.style = oldStyle
+ parent.insert(idx, polygon)
+
+if __name__ == '__main__':
+ PathsToStrokes().run()
\ No newline at end of file