1#!/usr/local/bin/python3.8 2# 3# Copyright 2008, 2009 Hannes Hochreiner 4# 5# This program is free software: you can redistribute it and/or modify 6# it under the terms of the GNU General Public License as published by 7# the Free Software Foundation, either version 3 of the License, or 8# (at your option) any later version. 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with this program. If not, see http://www.gnu.org/licenses/. 17# 18"""Effect to print out jessyInk summary""" 19 20from collections import defaultdict 21import inkex 22 23from jessyink_install import JessyInkMixin, _ 24 25class Summary(JessyInkMixin, inkex.EffectExtension): 26 """Print of jessyInk summary""" 27 def add_arguments(self, pars): 28 pars.add_argument('--tab') 29 30 def effect(self): 31 self.is_installed() 32 33 # Find the script node, if present 34 for node in self.svg.xpath("//svg:script[@id='JessyInk']"): 35 version = node.get("jessyink:version") 36 if version: 37 self.msg(_(f"JessyInk script version {version} installed.")) 38 else: 39 self.msg(_("JessyInk script installed.")) 40 41 slides = [] 42 master_slide = None 43 44 for node in self.svg.descendants().get(inkex.Layer): 45 if node.get("jessyink:master_slide"): 46 master_slide = node 47 else: 48 slides.append(node) 49 50 if master_slide is not None: 51 self.msg(_("\nMaster slide:")) 52 self.describe_node(master_slide, "\t",\ 53 ["<the number of the slide>", len(slides), "<the title of the slide>"]) 54 55 for i, slide in enumerate(slides): 56 self.msg(_("\nSlide {0!s}:").format(i+1)) 57 self.describe_node(slide, "\t", [i + 1, len(slides), slide.label]) 58 59 def describe_node(self, node, prefix, dat): 60 """Standard print out formatter""" 61 62 self.msg(_(f"{prefix}Layer name: {node.label}")) 63 self.describe_transition(node, prefix, "In") 64 self.describe_transition(node, prefix, "Out") 65 self.describe_autotext(node, prefix, dat) 66 self.describe_effects(node, prefix) 67 68 def describe_transition(self, node, prefix, transition): 69 """Display information about transitions.""" 70 trans = inkex.Style(node.get(f"jessyink:transition{transition}")) 71 if trans: 72 name = trans["name"] 73 if name != "appear" and "length" in trans: 74 length = int(trans["length"] / 1000.0) 75 self.msg(_(f"{prefix}Transition {transition}: {name} ({length!s} s)")) 76 else: 77 self.msg(_(f"{prefix}Transition {transition}: {name}")) 78 79 def describe_autotext(self, node, prefix, dat): 80 """Display information about auto-texts.""" 81 auto_texts = {"slide_num" : dat[0], "num" : dat[1], "title" : dat[2]} 82 for x, child in enumerate(node.xpath(".//*[@jessyink:autoText]")): 83 if not x: 84 self.msg(_(f"\n{prefix}Auto-texts:")) 85 86 pid = child.getparent().get("id") 87 val = auto_texts[child.get('jessyink:autoText')] 88 self.msg(_( 89 f'{prefix}\t"{child.text}" (object id "{pid}") will be replaced by "{val}".')) 90 91 def describe_effects(self, node, prefix): 92 """Display information about effects.""" 93 effects = sorted(self.collect_effects(node), key=lambda val: val[0]) 94 for x, (enum, effect) in enumerate(effects): 95 ret = "" 96 97 order = effect[0]["order"] 98 if not x: 99 ret += _(f"\n{prefix}Initial effect (order number {order}):") 100 else: 101 ret += _(f"\n{prefix}Effect {enum!s} (order number {order}):") 102 103 for item in effect: 104 eid = item["id"] 105 if item["type"] == "view": 106 ret += _(f"{prefix}\tView will be set according to object \"{eid}\"") 107 else: 108 ret += _(f"{prefix}\tObject \"{eid}\"") 109 110 if item["direction"] == "in": 111 ret += _(" will appear") 112 elif item["direction"] == "out": 113 ret += _(" will disappear") 114 115 if item["name"] != "appear": 116 ret += _(" using effect \"{0}\"").format(item["name"]) 117 118 if "length" in item: 119 ret += _(" in {0!s} s").format(int(item["length"]) / 1000.0) 120 121 self.msg(ret + ".\n") 122 123 @staticmethod 124 def collect_effects(node): 125 """Collect information about effects.""" 126 effects = defaultdict(list) 127 for child in node.xpath(".//*[@jessyink:effectIn]"): 128 effect_data = inkex.Style(child.get('jessyink:effectIn')) 129 effect_data["direction"] = "in" 130 effect_data["id"] = child.get("id") 131 effect_data["type"] = "effect" 132 effects[effect_data["order"]].append(effect_data) 133 134 for child in node.xpath(".//*[@jessyink:effectOut]"): 135 effect_data = inkex.Style(child.get('jessyink:effectOut')) 136 effect_data["direction"] = "out" 137 effect_data["id"] = child.get("id") 138 effect_data["type"] = "effect" 139 effects[effect_data["order"]].append(effect_data) 140 141 for child in node.xpath(".//*[@jessyink:view]"): 142 effect_data = inkex.Style(child.get('jessyink:view')) 143 effect_data["id"] = child.get("id") 144 effect_data["type"] = "view" 145 effects[effect_data["order"]].append(effect_data) 146 return effects 147 148if __name__ == '__main__': 149 Summary().run() 150