#!/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 <http://www.gnu.org/licenses/>. import argparse import os.path import sys from xml.sax.saxutils import quoteattr try: import boxes.generators except ImportError: sys.path.append(os.path.dirname(__file__) + "/..") import boxes.generators class Boxes2INX: def __init__(self) -> None: 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) #see boxes.__init__.py elif a.dest == "layout": return "" val = a.default.split("\n") input = """<textarea name="%s" cols="%s" rows="%s">%s</textarea>""" % \ (name, max(len(l) for l in val)+10, len(val)+1, a.default) elif a.choices: uniqueChoices = [] for e in a.choices: if e not in uniqueChoices: uniqueChoices.append(e) return (''' <param name="%s" type="optiongroup" appearance="combo" gui-text="%s" gui-description=%s>\n''' % (name, viewname, quoteattr(a.help or viewname)) + "".join(' <option value="%s">%s</option>\n' % (e, e) for e in uniqueChoices) + ' </param>\n') else: default = a.default if isinstance(a.type, boxes.BoolArg): t = '"bool"' default = str(a.default).lower() elif a.type is boxes.argparseSections: t = '"string"' else: t = { int : '"int"', float : '"float" precision="2"', str : '"string"', }.get(a.type, '"string"') if t == '"int"' or t == '"float" precision="2"': return ''' <param name="%s" type=%s max="9999" gui-text="%s" gui-description=%s>%s</param>\n''' % (name, t, viewname, quoteattr(a.help or viewname), default) else: return ''' <param name="%s" type=%s gui-text="%s" gui-description=%s>%s</param>\n''' % (name, t, viewname, quoteattr(a.help or viewname), default) def generator2inx(self, name, box): result = [ """<?xml version="1.0" encoding="UTF-8"?> <inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension"> <name>%s</name> <id>info.festi.boxes.py.%s</id> <param name="generator" type="string" gui-hidden="true">%s</param> <param name="tab" type="notebook">""" % (name, name, name.lower())] groupid = 0 for group in box.argparser._action_groups: if not group._group_actions: continue prefix = getattr(group, "prefix", None) title = group.title if title.startswith("Settings for "): title = title[len("Settings for "):] if title.endswith(" Settings"): title = title[:-len(" Settings")] pageParams = [] for a in group._group_actions: if a.dest in ("input", "output", "format"): continue if self.arg2inx(a, prefix) != "": pageParams.append(self.arg2inx(a, prefix)) if len(pageParams) > 0: result.append(""" <page name="tab_%s" gui-text="%s"> """ % (groupid, title)) result.extend(pageParams) result.append(" </page>") groupid += 1 result.append(""" <page name="tab_%s" gui-text="Example"> """ % (groupid)) result.append(" <image>./" + name + "-thumb.jpg</image>\n") result.append(" </page>\n") result.append("""</param> <label appearance="url">https://www.festi.info/boxes.py/""" + name + """</label> <effect> <object-type>all</object-type> <effects-menu> <submenu name="Boxes.py"> <submenu name="%s"/> </submenu> </effects-menu> </effect> <script> <command location="inx" interpreter="python">boxes_proxy.py</command> </script> </inkscape-extension>""" % 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(): if name.startswith("TrayLayout"): # The two stage thing does not work (yet?) continue self.writeINX(name, box, path) if __name__=="__main__": if len(sys.argv) != 2: print("Usage: boxes2inkscape TARGETPATH") b = Boxes2INX() b.writeAllINX(sys.argv[1])