diff options
-rwxr-xr-x | unpixelterm.py | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/unpixelterm.py b/unpixelterm.py new file mode 100755 index 0000000..b5a9bf4 --- /dev/null +++ b/unpixelterm.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python + +import os, sys, argparse +#NOTE: This script uses pygments for X256->RGB conversion since pygments is +#readily available. If you do not like pygments (e.g. because it is large), +#you could patch in something like https://github.com/magarcia/python-x256 +#(but don't forget to send me a pull request ;) +from pygments.formatters import terminal256 +from PIL import Image, PngImagePlugin +try: + import re2 as re +except: + import re + +formatter = terminal256.Terminal256Formatter() + +def parse_escape_sequence(seq): + codes = list(map(int, seq.lstrip('\x1b[').rstrip('m').split(';'))) + fg, bg = None, None + i = 0 + while i<len(codes): + if codes[i] in [38, 48]: + if codes[i+1] == 5: + c = formatter.xterm_colors[codes[i+2]] + fg, bg = (c, bg) if codes[i] == 38 else (fg, c) + i += 2 + elif codes[i] == 39: + fg = (0,0,0,0) + elif codes[i] == 49: + bg = (0,0,0,0) + i += 1 + return fg, bg + +def unpixelterm(text): + lines = text.split('\n') + h = len(lines)*2 + w = max([ len(re.sub(r'\x1b\[[0-9;]+m|\$.*\$', '', line)) for line in lines ]) + img = Image.new('RGBA', (w, h)) + fg, bg = (0,0,0,0), (0,0,0,0) + x, y = 0, 0 + for escapeseq, specialstr, char, newline in re.findall(r'(\x1b\[[0-9;]+m)|(\$.*\$)|(.)|(\n)', text): + if escapeseq: + nfg, nbg = parse_escape_sequence(escapeseq) + fg, bg = nfg or fg, nbg or bg + elif specialstr: + if specialstr.startswith('$$$'): #metadata + pass + elif specialstr == '$\\$': + img.putpixel((x, y), (255, 0, 0, 127)) + img.putpixel((x, y+1), (255, 0, 0, 127)) + x += 1 + elif specialstr == '$/$': + img.putpixel((x, y), (0, 0, 255, 127)) + img.putpixel((x, y+1), (0, 0, 255, 127)) + x += 1 + else: #(should be a) balloon + bw = int(re.match(r'\$balloon([0-9]*)\$', specialstr).group(1)) + for i in range(x, x+bw): + img.putpixel((i, y), (0, 255, 0, 127)) + img.putpixel((i, y+1), (0, 255, 0, 127)) + x += bw + elif char: + #Da magicks: ▀█▄ + c = {' ': (bg, bg), + '█': (fg, fg), + '▀': (fg, bg), + '▄': (bg, fg)}[char] + img.putpixel((x, y), c[0]) + img.putpixel((x, y+1), c[1]) + x += 1 + else: #newline + x, y = 0, y+2 + return img + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Convert images rendered by pixelterm-like utilities back to PNG') + parser.add_argument('input', type=argparse.FileType('r')) + parser.add_argument('output', type=str) + args = parser.parse_args() + img = unpixelterm(args.input.read()) + img.save(args.output) |