Adjust inx parser for InkScape 1.0

This is a more recent inx file creator which does not throw errors on console (except the ones where no thumbnail files exist yet)

Resolves: #314
This commit is contained in:
Mario Voigt 2021-04-28 12:07:35 +02:00 committed by Florian Festi
parent 4449c2c2cd
commit ecf14540f5
1 changed files with 158 additions and 142 deletions

View File

@ -1,142 +1,158 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# Copyright (C) 2017 Florian Festi # Copyright (C) 2017 Florian Festi
# #
# This program is free software: you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys import sys
import argparse import argparse
import os.path import os.path
from xml.sax.saxutils import quoteattr from xml.sax.saxutils import quoteattr
from urllib.parse import unquote_plus
# Python 2 vs Python 3 compat
try: try:
from urllib.parse import unquote_plus import boxes.generators
except ImportError: except ImportError:
from urllib import unquote_plus sys.path.append(os.path.dirname(__file__) + "/..")
import boxes.generators
try:
import boxes.generators class Boxes2INX:
except ImportError: def __init__(self):
sys.path.append(os.path.dirname(__file__) + "/..") self.boxes = {b.__name__ : b() for b in boxes.generators.getAllBoxGenerators().values() if b.webinterface}
import boxes.generators self.groups = boxes.generators.ui_groups
self.groups_by_name = boxes.generators.ui_groups_by_name
class Boxes2INX:
def __init__(self): for name, box in self.boxes.items():
self.boxes = {b.__name__ : b() for b in boxes.generators.getAllBoxGenerators().values() if b.webinterface} self.groups_by_name.get(box.ui_group,
self.groups = boxes.generators.ui_groups self.groups_by_name["Misc"]).add(box)
self.groups_by_name = boxes.generators.ui_groups_by_name
def arg2inx(self, a, prefix):
for name, box in self.boxes.items(): name = a.option_strings[0].replace("-", "")
self.groups_by_name.get(box.ui_group,
self.groups_by_name["Misc"]).add(box) if isinstance(a, argparse._HelpAction):
return ""
def arg2inx(self, a, prefix):
name = a.option_strings[0].replace("-", "") viewname = name
if isinstance(a, argparse._HelpAction): if prefix and name.startswith(prefix + '_'):
return "" viewname = name[len(prefix)+1:]
viewname = name
if prefix and name.startswith(prefix + '_'): #returns old enum type. disabled
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
if (isinstance(a, argparse._StoreAction) and
hasattr(a.type, "inx")): #elif a.dest == "layout": # XXX
return a.type.inx(name, viewname, a) if a.dest == "layout": # XXX
return ""
elif a.dest == "layout": # XXX val = a.default.split("\n")
return "" input = """<textarea name="%s" cols="%s" rows="%s">%s</textarea>""" % \
val = a.default.split("\n") (name, max((len(l) for l in val))+10, len(val)+1, a.default)
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 (isinstance(a, argparse._StoreAction) and hasattr(a.type, "inx")) or a.choices:
elif a.choices: uniqueChoices = []
return (''' <param name="%s" type="enum" _gui-text="%s" gui-description=%s>\n''' for e in a.choices:
% (name, viewname, quoteattr(a.help or viewname)) + if e not in uniqueChoices:
"".join(' <item value="%s"%s>%s</item>\n' % uniqueChoices.append(e)
(e, ' selected="selected"' if e == a.default else "", return (''' <param name="%s" type="optiongroup" appearance="combo" gui-text="%s" gui-description=%s>\n'''
e) for e in a.choices) + ' </param>\n') % (name, viewname, quoteattr(a.help or viewname)) +
else: "".join(' <option value="%s">%s</option>\n' % (e, e) for e in uniqueChoices) + ' </param>\n')
default = a.default
if isinstance(a.type, boxes.BoolArg): else:
t = '"boolean"' default = a.default
default = str(a.default).lower() if isinstance(a.type, boxes.BoolArg):
elif a.type is boxes.argparseSections: t = '"bool"'
t = '"string"' default = str(a.default).lower()
else:
t = { int : '"int"', elif a.type is boxes.argparseSections:
float : '"float" precision="2"', t = '"string"'
str : '"string"',
}.get(a.type, '"string"') else:
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) t = { int : '"int"',
float : '"float" precision="2"',
def generator2inx(self, name, box): str : '"string"',
result = [ """<?xml version="1.0" encoding="UTF-8"?> }.get(a.type, '"string"')
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<_name>%s</_name> if t == '"int"' or t == '"float" precision="2"':
<dependency type="executable" location="path">boxes</dependency> 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)
<id>info.festi.boxes.py.%s</id>
else:
<param name="generator" type="string" gui-hidden="true">%s</param> return ''' <param name="%s" type=%s gui-text="%s" gui-description=%s>%s</param>\n''' % (name, t, viewname, quoteattr(a.help or viewname), default)
<param name="tab" type="notebook">
""" % (name, name, name.lower())] def generator2inx(self, name, box):
groupid = 0 result = [ """<?xml version="1.0" encoding="UTF-8"?>
for group in box.argparser._action_groups: <inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
if not group._group_actions: <name>%s</name>
continue <id>info.festi.boxes.py.%s</id>
prefix = getattr(group, "prefix", None) <param name="generator" type="string" gui-hidden="true">%s</param>
title = group.title <param name="tab" type="notebook">""" % (name, name, name.lower())]
if title.startswith("Settings for "): groupid = 0
title = title[len("Settings for "):] for group in box.argparser._action_groups:
if title.endswith(" Settings"): if not group._group_actions:
title = title[:-len(" Settings")] continue
result.append(""" prefix = getattr(group, "prefix", None)
<page name="%s" _gui-text="%s"> title = group.title
""" % (groupid, title)) if title.startswith("Settings for "):
for a in group._group_actions: title = title[len("Settings for "):]
if a.dest in ("input", "output", "format"): if title.endswith(" Settings"):
continue title = title[:-len(" Settings")]
result.append(self.arg2inx(a, prefix))
result.append(" </page>\n") pageParams = []
groupid += 1 for a in group._group_actions:
result.append(""" if a.dest in ("input", "output", "format"):
</param> continue
<effect> if self.arg2inx(a, prefix) != "":
<object-type>all</object-type> pageParams.append(self.arg2inx(a, prefix))
<effects-menu> if len(pageParams) > 0:
<submenu _name="Boxes.py"> result.append("""
<submenu _name="%s"/> <page name="tab_%s" gui-text="%s">
</submenu> """ % (groupid, title))
</effects-menu> result.extend(pageParams)
</effect> result.append(" </page>")
<script>
<command reldir="extensions">boxes</command> groupid += 1
</script> result.append("""
</inkscape-extension> <page name="tab_%s" gui-text="Example">
""" % self.groups_by_name[box.ui_group].title) """ % (groupid))
return b''.join(s.encode("utf-8") for s in result) result.append(" <image>./" + name + "-thumb.jpg</image>\n")
result.append(" </page>\n")
def writeINX(self, name, box, path): result.append("""</param>
with open(os.path.join(path, "boxes.py." + name + '.inx'), "wb") as f: <label appearance="url">https://www.festi.info/boxes.py/""" + name + """</label>
f.write(self.generator2inx(name, box)) <effect>
<object-type>all</object-type>
def writeAllINX(self, path): <effects-menu>
for name, box in self.boxes.items(): <submenu name="Boxes.py">
if name.startswith("TrayLayout"): <submenu name="%s"/>
# The two stage thing does not work (yet?) </submenu>
continue </effects-menu>
self.writeINX(name, box, path) </effect>
<script>
if __name__=="__main__": <command location="inx" interpreter="python">boxes_proxy.py</command>
if len(sys.argv) != 2: </script>
print("Usage: boxes2inksacpe TARGETPATH") </inkscape-extension>""" % self.groups_by_name[box.ui_group].title)
b = Boxes2INX() return b''.join(s.encode("utf-8") for s in result)
b.writeAllINX(sys.argv[1])
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: boxes2inksacpe TARGETPATH")
b = Boxes2INX()
b.writeAllINX(sys.argv[1])