153 lines
5.8 KiB
Python
153 lines
5.8 KiB
Python
#!/usr/bin/env python3
|
|
import os
|
|
import sys
|
|
import re
|
|
import subprocess
|
|
|
|
from BaseExtension import BaseExtension
|
|
|
|
# For linting purposes
|
|
from argparse import ArgumentParser
|
|
|
|
"""If syntax error occurs here, change inkscape interpreter to python3"""
|
|
|
|
"""I have yet to find a way for an extension to call another extension with parameters,
|
|
without GUI. This extension can be run as part of a standalone extension (using BaseExtension)
|
|
or imported for use by another extension. This workaround is done via the 'option' arg in
|
|
the 'custom_effect' function"""
|
|
|
|
|
|
def custom_effect(self: BaseExtension):
|
|
"""Note: The init of the BaseExtension class will set its 'custom_effect' attr
|
|
to this function. Hence, the self arg is of type BaseExtension."""
|
|
|
|
|
|
selected = self.svg.selected
|
|
root = self.document.getroot()
|
|
actions_list = []
|
|
|
|
proc = subprocess.run("inkscape --verb-list | grep -oP '^.+?(?=:)'",
|
|
shell=True, capture_output=True)
|
|
valid_actions_and_verbs = proc.stdout.decode().splitlines()
|
|
|
|
proc = subprocess.run("inkscape --action-list | grep -oP '^.+?(?= *:)'",
|
|
shell=True, capture_output=True)
|
|
valid_actions_and_verbs += proc.stdout.decode().splitlines()
|
|
|
|
|
|
self.options.dry_run = self.options.dry_run == 'true'
|
|
|
|
def verify_action(action):
|
|
if ':' in action:
|
|
action = action.split(':')[0]
|
|
if action not in valid_actions_and_verbs:
|
|
raise ValueError(action)
|
|
|
|
def select_do_individually(objs, actions):
|
|
for obj in objs:
|
|
actions_list.append("EditDeselect")
|
|
actions_list.append("select-by-id:" + obj.get_id())
|
|
if isinstance(actions, str):
|
|
actions = [actions]
|
|
for action in actions:
|
|
verify_action(action)
|
|
actions_list.append(action)
|
|
|
|
def select_do_on_all(objs, actions):
|
|
for obj in objs:
|
|
actions_list.append("select-by-id:" + obj.get_id())
|
|
|
|
if isinstance(actions, str):
|
|
actions = [actions]
|
|
for action in actions:
|
|
verify_action(action)
|
|
actions_list.append(action)
|
|
effects = []
|
|
try:
|
|
if self.options.tab_effect is None:
|
|
if self.options.effects is not None:
|
|
self.options.tab_effect = 'Multi'
|
|
elif self.options.effect1 is not None:
|
|
self.options.tab_effect = 'Simple'
|
|
|
|
elif self.options.tab_effect in ('Preset', 'Simple'):
|
|
for attr in ('effect_' + self.options.tab_effect.lower() + str(i) for i in range(1, 4)):
|
|
e = getattr(self.options, attr)
|
|
if e != None:
|
|
effects += [e.strip()]
|
|
if effects == []:
|
|
raise ValueError
|
|
elif self.options.tab_effect == 'Multi':
|
|
if self.options.effects is None:
|
|
raise ValueError
|
|
for line in self.options.effects.split('\\n'):
|
|
effects += [e.strip() for e in line.split(';') if e != '']
|
|
except ValueError:
|
|
self.msg("No effects inputted! Quitting...")
|
|
sys.exit(0)
|
|
|
|
|
|
if self.options.target == 'root':
|
|
objects = self.find(root, '/svg:svg' + self.options.xpath)
|
|
elif self.options.target == 'selected':
|
|
objects = self.find(selected, self.options.xpath)
|
|
if objects == []:
|
|
self.msg(f"No objects satisfies XPath: '{self.options.xpath}'.")
|
|
self.msg("Root:", self.show(root))
|
|
self.msg("Selected:", self.show(selected))
|
|
sys.exit(0)
|
|
|
|
|
|
try:
|
|
if self.options.mode == 'all':
|
|
select_do_on_all(objects, effects)
|
|
elif self.options.mode == 'indiv':
|
|
select_do_individually(objects, effects)
|
|
except ValueError as e:
|
|
self.msg(f"'{e.args[0]}' is not a valid action or verb in inkscape.")
|
|
sys.exit(1)
|
|
|
|
if self.options.dry_run:
|
|
self.msg(f"{'DRY RUN':=^40}")
|
|
self.msg("Root:", self.show(self.find(root, '/*')))
|
|
self.msg("Selected:", self.show(selected))
|
|
self.msg()
|
|
self.msg("XPath:", self.show(objects))
|
|
self.msg()
|
|
self.msg("Actions:", actions_list)
|
|
sys.exit(0)
|
|
return actions_list
|
|
|
|
|
|
def args_adder(arg_parser: ArgumentParser):
|
|
|
|
arg_parser.add_argument("--target", default='root', help="Object to apply xpath find on")
|
|
arg_parser.add_argument("--xpath", default='/*', help="For selection of objects")
|
|
arg_parser.add_argument("--tab_main", default=None)
|
|
arg_parser.add_argument("--Simple", default=None)
|
|
arg_parser.add_argument("--Multi", default=None)
|
|
arg_parser.add_argument("--mode", default="all", help="Mode to apply effects on objects")
|
|
arg_parser.add_argument("--tab_effect", default=None)
|
|
for arg in (*(x + str(y) for x in ('effect_preset', 'effect_simple') for y in range(1, 4)), 'effects'):
|
|
arg_parser.add_argument(f"--{arg}", default=None, help="Inkscape verb for path op")
|
|
arg_parser.add_argument("--dry_run", default='false')
|
|
arg_parser.add_argument("--null_notebook", default='false')
|
|
|
|
#import inkex
|
|
#for key, value in arg_parser.parse_args()._get_kwargs():
|
|
# if value is not None:
|
|
# inkex.utils.debug("{}={}".format(key, value))
|
|
|
|
BatchTask = BaseExtension(custom_effect, args_adder=args_adder)
|
|
|
|
if __name__ == '__main__':
|
|
BatchTask.run()
|
|
|
|
|
|
|
|
|
|
# Namespace(Multi='SelectionDiff', Simple='SelectionDiff', dry_run='false', effect1='SelectionBreakApart', effect2=None, effect3=None, effects=None, ids=['image25'], input_file='/tmp/ink_ext_XXXXXX.svgIDCKU0', mode='all', null='null', output=<_io.BufferedWriter name='<stdout>'>, selected_nodes=[], tab_effect='Simple', tab_main='Options', target='root', xpath='/*')
|
|
|
|
|
|
# Namespace(Multi=None, Simple=None, dry_run='false', effect1='SelectionDelete', effect2=None, effect3=None, effects=None, mode='all', null='false', tab_effect=None, tab_main=None, target='root', xpath='/*')
|