diff --git a/boxes/__init__.py b/boxes/__init__.py
index 19e3847..80f543d 100755
--- a/boxes/__init__.py
+++ b/boxes/__init__.py
@@ -26,6 +26,8 @@ import argparse
from argparse import ArgumentParser
import re
from functools import wraps
+from xml.sax.saxutils import quoteattr
+
from boxes import edges
from boxes import formats
from boxes import gears
@@ -178,6 +180,14 @@ class ArgparseEdgeType:
e, self.names.get(e, "")) for e in self.edges))
return """\n""" % (name, options)
+ def inx(self, name, viewname, arg):
+ return (' \n' %
+ (name, viewname, quoteattr(arg.help or "")) +
+ ''.join((' %s %s\n' % (
+ e, e, self.names.get(e, ""))
+ for e in self.edges)) +
+ ' \n')
+
class BoolArg:
def __call__(self, arg):
if not arg or arg.lower() in ("none", "0", "off", "false"):
diff --git a/scripts/boxes2inkscape b/scripts/boxes2inkscape
new file mode 100755
index 0000000..7da7090
--- /dev/null
+++ b/scripts/boxes2inkscape
@@ -0,0 +1,132 @@
+#!/usr/bin/env python3
+# Copyright (C) 2017 Florian Festi
+#
+# 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 3 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, see .
+
+import sys
+import argparse
+import os.path
+from xml.sax.saxutils import quoteattr
+
+# Python 2 vs Python 3 compat
+try:
+ from urllib.parse import unquote_plus
+except ImportError:
+ from urllib import unquote_plus
+
+try:
+ import boxes.generators
+except ImportError:
+ sys.path.append(os.path.dirname(__file__) + "/..")
+ import boxes.generators
+
+class Boxes2INX:
+ def __init__(self):
+ self.boxes = {b.__name__ : b() for b in boxes.generators.getAllBoxGenerators().values() if b.webinterface}
+ self.groups = boxes.generators.ui_groups
+ self.groups_by_name = boxes.generators.ui_groups_by_name
+
+ for name, box in self.boxes.items():
+ self.groups_by_name.get(box.ui_group,
+ self.groups_by_name["Misc"]).add(box)
+
+ def arg2inx(self, a, prefix):
+ name = a.option_strings[0].replace("-", "")
+ if isinstance(a, argparse._HelpAction):
+ return ""
+ viewname = name
+ if prefix and name.startswith(prefix + '_'):
+ viewname = name[len(prefix)+1:]
+
+ if (isinstance(a, argparse._StoreAction) and
+ hasattr(a.type, "inx")):
+ return a.type.inx(name, viewname, a)
+
+ elif a.dest == "layout": # XXX
+ return ""
+ val = a.default.split("\n")
+ input = """""" % \
+ (name, max((len(l) for l in val))+10, len(val)+1, a.default)
+ elif a.choices:
+ return (''' \n'''
+ % (name, viewname, quoteattr(a.help or "")) +
+ "".join(' %s\n' %
+ (e, ' selected="selected"' if e == a.default else "",
+ e) for e in a.choices) + ' \n')
+ else:
+ if isinstance(a.type, boxes.BoolArg):
+ t = "boolean"
+ elif a.type is boxes.argparseSections:
+ t = "string"
+ else:
+ t = { int : "int",
+ float : "float",
+ str : "string",
+ }.get(a.type, a.type)
+ return ''' %s\n''' % (name, t, viewname, quoteattr(a.help or ""), a.default)
+
+ def generator2inx(self, name, box):
+ result = [ """
+
+ <_name>%s
+ info.festi.boxes.py.%s
+
+ %s
+
+""" % (name, name, name.lower())]
+# boxes
+ groupid = 0
+ for group in box.argparser._action_groups:
+ if not group._group_actions:
+ continue
+ prefix = getattr(group, "prefix", None)
+ result.append("""
+
+""" % (groupid, group.title))
+ for a in group._group_actions:
+ if a.dest in ("input", "output", "format"):
+ continue
+ result.append(self.arg2inx(a, prefix))
+ result.append(" \n")
+ groupid += 1
+ result.append("""
+
+
+ all
+
+
+
+
+
+
+
+
+""" % self.groups_by_name[box.ui_group].title)
+ return b''.join(s.encode("utf-8") for s in result)
+
+ def writeINX(self, name, box, path):
+ with open(os.path.join(path, "boxes.py." + name + '.inx'), "wb") as f:
+ f.write(self.generator2inx(name, box))
+
+ def writeAllINX(self, path):
+ for name, box in self.boxes.items():
+ self.writeINX(name, box, path)
+
+if __name__=="__main__":
+ if len(sys.argv) != 2:
+ print("Usage: boxes2inksacpe TARGETPATH")
+ b = Boxes2INX()
+ b.writeAllINX(sys.argv[1])