From 4bb312683b0a2933a4e16a368007affc203093da Mon Sep 17 00:00:00 2001 From: aszlig Date: Wed, 5 Nov 2014 16:15:01 +0100 Subject: pkgs: Add new aacolorize script to colorize ASCII. Basically this is just an old script I wrote to separate and merge color information from the actual ASCII arts. Signed-off-by: aszlig --- pkgs/aacolorize/aacolorize.py | 182 ++++++++++++++++++++++++++++++++++++++++++ pkgs/aacolorize/default.nix | 13 +++ 2 files changed, 195 insertions(+) create mode 100755 pkgs/aacolorize/aacolorize.py create mode 100644 pkgs/aacolorize/default.nix (limited to 'pkgs/aacolorize') diff --git a/pkgs/aacolorize/aacolorize.py b/pkgs/aacolorize/aacolorize.py new file mode 100755 index 00000000..ff19b687 --- /dev/null +++ b/pkgs/aacolorize/aacolorize.py @@ -0,0 +1,182 @@ +#!/usr/bin/env python +import os +import sys + +from optparse import Option, OptionParser + +COLORS = { + "k": (30, "Black"), + "r": (31, "Red"), + "g": (32, "Green"), + "y": (33, "Yellow"), + "b": (34, "Blue"), + "p": (35, "Pink"), + "c": (36, "Cyan"), + "w": (37, "White"), +} + +ESC = chr(27) + +class ColorizeError(Exception): + pass + +class Color(object): + def __init__(self, ident=None): + """ + Initialize a color object, if no `ident` is given or it's invalid, + the Color object represents "no color". + """ + if ident is not None: + spec = COLORS.get(ident.lower(), None) + else: + spec = None + + if spec is None: + self.ident = None + self.bold = False + self.code = None + self.name = "None" + else: + self.ident = ident + self.code, self.name = spec + + if ident.isupper(): + self.bold = True + else: + self.bold = False + + @property + def attrs(self): + """ + A tuple consisting of the SGR attributes. + """ + if self.ident is None: + return () + + if self.bold: + return (1, self.code) + else: + return (self.code,) + + def sgr_attrs(self, *attrs): + """ + Return the attributes specified by `attrs` formatted according + to the CSI specification. + """ + return ';'.join(map(lambda c: str(c), attrs)) + + def sgr(self, *attrs): + """ + Start Set Graphics Rendition + Return the CSI escape code for `attrs`. + """ + return "%s[%sm" % (ESC, self.sgr_attrs(*attrs)) + + def sgr_start(self): + """ + Start Set Graphics Rendition + Return the CSI start escape code for the current color. + """ + return self.sgr(*self.attrs) + + def sgr_stop(self): + """ + Clear Set Graphics Rendition + """ + return self.sgr() + + def apply(self, value): + """ + Apply the current color to the string in `value`. + """ + return "%s%s%s" % (self.sgr_start(), value, self.sgr_stop()) + + def describe(self): + """ + Return the description of the current color IN color :-) + """ + fmt = "%c: [%sm -> [%s]" + return fmt % ( + self.ident, + self.sgr_attrs(*self.attrs), + self.apply(self.name) + ) + + def transform_to(self, new_color): + """ + Return the CSI sequences needed to transform into `new_color`. + """ + if self.ident is None and new_color.ident is not None: + return new_color.sgr_start() + elif self.ident is not None and new_color.ident is None: + return self.sgr_stop() + elif self.ident is None and new_color.ident is None: + return '' + elif self.code == new_color.code: + if not self.bold and new_color.bold: + return self.sgr(1) + elif self.bold and not new_color.bold: + return self.sgr(22) + elif self.bold == new_color.bold: + return '' + else: + if self.bold and new_color.bold: + return new_color.sgr(new_color.code) + + return self.sgr_stop()+new_color.sgr_start() + + def __repr__(self): + if self.bold: + return "" % self.name.lower() + else: + return "" % self.name.lower() + +def print_colortable(): + for ident in COLORS.iterkeys(): + normal = Color(ident).describe() + bold = Color(ident.upper()).describe() + sys.stdout.write("%-35s%s\n" % (normal, bold)) + +def colorize_art(art, colmap): + if len(art) != len(colmap): + raise ColorizeError("Art and colormap differ in size!") + + no_color = Color() + + out = "" + last_color = no_color + for i, char in enumerate(colmap): + color = Color(char) + out += last_color.transform_to(color) + art[i] + last_color = color + + last_color.transform_to(no_color) + + return out + +def colorize_file(artfile, mapfile=None): + if mapfile is None: + mapfile = os.path.splitext(artfile)[0]+'.colmap' + + asciiart = open(artfile, 'r').read() + colormap = open(mapfile, 'r').read() + + return colorize_art(asciiart, colormap) + +if __name__ == "__main__": + parser = OptionParser(usage="%prog [options] artfile [mapfile]") + parser.add_option("-t", "--table", action="store_true", dest="table", + help="Show color table and exit.") + + (options, args) = parser.parse_args() + + if options.table: + print_colortable() + parser.exit() + + if not len(args) in (1, 2): + parser.print_help() + parser.exit() + else: + colorized = colorize_file(*args) + sys.stdout.write(colorized) diff --git a/pkgs/aacolorize/default.nix b/pkgs/aacolorize/default.nix new file mode 100644 index 00000000..a7a3c3f1 --- /dev/null +++ b/pkgs/aacolorize/default.nix @@ -0,0 +1,13 @@ +{ buildPythonPackage, runCommand }: + +buildPythonPackage { + name = "aacolorize"; + src = runCommand "aacolorize-src" {} '' + mkdir -p "$out" + cp "${./aacolorize.py}" "$out/aacolorize" + cat > "$out/setup.py" <