#! /usr/bin/env python3 import os import sys import inkex def log(text): inkex.utils.debug(text) def abort(text): inkex.errormsg(_(text)) exit() class GeneratePalette(inkex.EffectExtension): def add_arguments(self, pars): pars.add_argument('--name', help='Palette name') pars.add_argument('--property', help='Color property') pars.add_argument('--default', type=inkex.Boolean, help='Default grays') pars.add_argument('--sort', help='Sort type') pars.add_argument('--replace', type=inkex.Boolean, dest='replace', help='Replace existing') def get_palettes_path(self): if sys.platform.startswith('win'): path = os.path.join(os.environ['APPDATA'], 'inkscape', 'palettes') else: path = os.environ.get('XDG_CONFIG_HOME', '~/.config') path = os.path.join(path, 'inkscape', 'palettes') return os.path.expanduser(path) def get_file_path(self): name = str(self.options.name).replace(' ', '-') return "%s/%s.gpl" % (self.palettes_path, name) def get_default_colors(self): colors = [ " 0 0 0 Black", " 26 26 26 90% Gray", " 51 51 51 80% Gray", " 77 77 77 70% Gray", "102 102 102 60% Gray", "128 128 128 50% Gray", "153 153 153 40% Gray", "179 179 179 30% Gray", "204 204 204 20% Gray", "230 230 230 10% Gray", "236 236 236 7.5% Gray", "242 242 242 5% Gray", "249 249 249 2.5% Gray", "255 255 255 White" ] return colors if self.options.default else [] def get_node_prop(self, node, property): attr = node.attrib.get('style') style = dict(inkex.Style.parse_str(attr)) return style.get(property, 'none') def get_node_index(self, item): node = item[1] id = node.attrib.get('id') return self.options.ids.index(id) def get_node_x(self, item): node = item[1] return node.bounding_box().center_x def get_node_y(self, item): node = item[1] return node.bounding_box().center_y def get_formatted_color(self, color): rgb = inkex.Color(color).to_rgb() if self.options.sort == 'hsl': key = inkex.Color(color).to_hsl() key = "{:03d}{:03d}{:03d}".format(*key) else: key = "{:03d}{:03d}{:03d}".format(*rgb) rgb = "{:3d} {:3d} {:3d}".format(*rgb) color = str(color).upper() name = str(inkex.Color(color).to_named()).upper() if name != color: name = "%s (%s)" % (name.capitalize(), color) return "%s %s %s" % (key, rgb, name) def get_selected_colors(self): colors = [] selected = list(self.svg.selected.items()) if self.options.sort == 'y_location': selected.sort(key=self.get_node_x) selected.sort(key=self.get_node_y) elif self.options.sort == 'x_location': selected.sort(key=self.get_node_y) selected.sort(key=self.get_node_x) else: selected.sort(key=self.get_node_index) for id, node in selected: if self.options.property in ['fill', 'both']: fill = self.get_node_prop(node, 'fill') if inkex.colors.is_color(fill): if fill != 'none' and fill not in colors: colors.append(fill) if self.options.property in ['stroke', 'both']: stroke = self.get_node_prop(node, 'stroke') if inkex.colors.is_color(stroke): if stroke != 'none' and stroke not in colors: colors.append(stroke) colors = list(map(self.get_formatted_color, colors)) if self.options.sort == 'hsl' or self.options.sort == 'rgb': colors.sort() return list(map(lambda x : x[11:], colors)) def write_palette(self): file = open(self.file_path, 'w') try: file.write("GIMP Palette\n") file.write("Name: %s\n" % self.options.name) file.write("#\n# Generated with Inkscape Generate Palette\n#\n") for color in self.default_colors: file.write("%s\n" % color) for color in self.selected_colors: if color[:11] not in list(map(lambda x : x[:11], self.default_colors)): file.write("%s\n" % color) finally: file.close() def effect(self): self.palettes_path = self.get_palettes_path() self.file_path = self.get_file_path() self.default_colors = self.get_default_colors() self.selected_colors = self.get_selected_colors() if not self.options.replace and os.path.exists(self.file_path): abort('Palette already exists!') if not self.options.name: abort('Please enter a palette name.') if len(self.options.ids) < 2: abort('Please select at least 2 objects.') if not len(self.selected_colors): abort('No colors found in selected objects!') self.write_palette() if __name__ == '__main__': GeneratePalette().run()