about summary refs log tree commit diff
path: root/pkgs/aszlig/aacolorize
diff options
context:
space:
mode:
authoraszlig <aszlig@redmoonstudios.org>2017-04-23 22:03:34 +0200
committeraszlig <aszlig@redmoonstudios.org>2017-04-23 23:08:05 +0200
commitb3d9a07086cb81e53e20837c96a3153453b0a123 (patch)
treee6c496d73203465d2ec4265d3200bf32f56362b3 /pkgs/aszlig/aacolorize
parent145a8be2b22a3a0459a46e70e8b5d8f4ecc701aa (diff)
pkgs: Move all of my packages into pkgs/aszlig
This already has started in e0abe1dbbda54c1f048b5d38df05e1a3289216a6
with @Profpatsch putting his packages into its own namespace, so let's
continue on that and move my crap into my own namespace as well.

The only difference in my approach is that I'm now also using a new
function called callPackageScope, which declutters pkgs/default.nix a
bit and moves the individual callPackage invocations into
aszlig/default.nix.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
Diffstat (limited to 'pkgs/aszlig/aacolorize')
-rwxr-xr-xpkgs/aszlig/aacolorize/aacolorize.py182
-rw-r--r--pkgs/aszlig/aacolorize/default.nix13
2 files changed, 195 insertions, 0 deletions
diff --git a/pkgs/aszlig/aacolorize/aacolorize.py b/pkgs/aszlig/aacolorize/aacolorize.py
new file mode 100755
index 00000000..ff19b687
--- /dev/null
+++ b/pkgs/aszlig/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: <ESC>[%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 "<Bold color %s>" % self.name.lower()
+        else:
+            return "<Color %s>" % 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/aszlig/aacolorize/default.nix b/pkgs/aszlig/aacolorize/default.nix
new file mode 100644
index 00000000..ef36f4e0
--- /dev/null
+++ b/pkgs/aszlig/aacolorize/default.nix
@@ -0,0 +1,13 @@
+{ pythonPackages, runCommand }:
+
+pythonPackages.buildPythonPackage {
+  name = "aacolorize";
+  src = runCommand "aacolorize-src" {} ''
+    mkdir -p "$out"
+    cp "${./aacolorize.py}" "$out/aacolorize"
+    cat > "$out/setup.py" <<SETUP
+    from distutils.core import setup
+    setup(name='aacolorize', scripts=['aacolorize'])
+    SETUP
+  '';
+}