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])