#!/usr/bin/env python # coding=utf-8 # # Copyright 2016 Ville Rantanen # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published # by the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # '''Color by notation.''' __author__ = "Ville Rantanen " __version__ = "0.2" NEWCHAR="====CHAR" NEWCOLOR="====COLOR" NEWIMAGE="====EOI" ENDOFFILE="====EOF" PAUSE="====PAUSE" import sys,os,argparse,re,time from argparse import ArgumentParser class bc: K="\033[1;30m" R="\033[1;31m" G="\033[1;32m" Y="\033[1;33m" B="\033[1;34m" M="\033[1;35m" C="\033[1;36m" W="\033[1;37m" k="\033[0;30m" r="\033[0;31m" g="\033[0;32m" y="\033[0;33m" b="\033[0;34m" m="\033[0;35m" c="\033[0;36m" w="\033[0;37m" nk="\033[30m" nr="\033[31m" ng="\033[32m" ny="\033[33m" nb="\033[34m" nm="\033[35m" nc="\033[36m" nw="\033[37m" bk="\033[40m" br="\033[41m" bg="\033[42m" by="\033[43m" bb="\033[44m" bm="\033[45m" bc="\033[46m" bw="\033[47m" S = '\033[1m' s = '\033[2m'#strong off U = '\033[4m'#underline u = '\033[24m'#underline off ic = '\033[7m'#inverse colors io = '\033[27m'#inverse off st = '\033[9m'#strike on so = '\033[29m'#strike off Z = '\033[0m' CLR = '\033[2J' CLREND = '\033[K' CLRSCR = CLR+"\033[0;0H" color_keys="pqwertyu01234567;asdfghjPQWERTYUxXczvVbBnN" color_list=[K, R, G, Y, B, M, C, W, k, r, g, y, b, m, c, w, bk,br,bg,by,bb,bm,bc,bw,nk,nr,ng,ny,nb,nm,nc,nw, S,s,CLRSCR,Z,U,u,st,so,ic,io] def pos(self,y,x): return "\033["+str(y)+";"+str(x)+"H" def posprint(self, y,x,s): sys.stdout.write( (self.pos(y,x) + str(s)).encode('utf-8') ) def clear(self): sys.stdout.write( (self.CLR+self.pos(0,0)).encode('utf-8') ) def clear_to_end(self): sys.stdout.write( self.CLREND.encode('utf-8') ) def color_char(self,s): for i,c in enumerate(self.color_keys): if c in s: s=s.replace(c,self.color_list[i]) return s return "" def nocolor_string(self,s): return "" def end_drawing(opts): if opts.zero_final: sys.stdout.write(bc.Z.encode('utf-8')) sys.exit(0) def open_data_file(opts): if opts.test_image: return test_data() if opts.filename=='-': return sys.stdin return open(opts.filename,'r') def setup_options(): ''' Create command line options ''' usage=''' Color image renderer in ANSI codes. Example file: first layer of characters ====CHAR more characters go here ====COLOR color codes go here (letters 1-7,0 and keys below like a piano) 12345670 : red green yellow blue magenta cyan white black (darker tone) qwertyup : red green yellow blue magenta cyan white black (bright tone) QWERTYUP : red green yellow blue magenta cyan white black (without changing brightness) asdfghj; : backround colors zc: reset colors, clearscreen xX: bright color on, bright color off vV: underline on, underline off bB: strikethrough on, strikethrough off nN: inverse on, inverse off ====EOI end of image, start another ====PAUSE1.5 another image starts, pause for 1.5 seconds before drawing the next ====EOF end of file ''' parser=ArgumentParser(description=usage, formatter_class=argparse.RawDescriptionHelpFormatter, epilog=__author__) parser.add_argument("-v","--version",action="version",version=__version__) parser.add_argument("--no-color","-n",action="store_false",dest="color",default=True, help="Disable color.") parser.add_argument("--test",action="store_true",dest="test_image",default=False, help="Show test image showing features.") parser.add_argument("-z",action="store_true",dest="zero",default=False, help="Reset color codes at the end of each line.") parser.add_argument("-Z",action="store_false",dest="zero_final",default=True, help="Disable reset of colors at the end of file.") parser.add_argument("-c",action="store_true",dest="clear",default=False, help="Clear screen first") parser.add_argument("filename",type=str, nargs='?', default=None, help="File to show, - for stdin") opts=parser.parse_args() if not opts.test_image and opts.filename==None: parser.error("Need a file or - as argument") return opts def test_data(): testimage=''' NOT VISIBLE _ _ _ ____ ___ 1 red 5 magenta / \ | \ | / ___|_ _| 2 green 6 cyan / _ \ | \| \___ \| | 3 yellow 7 white / ___ \| |\ |___) | | 4 blue 0 black /_/ \_\_| \_|____/___| ,ad8888ba, 88 88888888ba d8"' `"8b 88 88 "8b d8' 88 88 ,8P 88 ,adPPYba, 88 ,adPPYba, 88aaaaaa8P' ,adPPYba, 88 a8" "8a 88 a8" "8a 88""""88' I8[ "" Y8, 8b d8 88 8b d8 88 `8b `"Y8ba, Y8a. .a8P "8a, ,a8" 88 "8a, ,a8" 88 `8b aa ]8I `"Y8888Y"' `"YbbdP"' 8888888888 `"YbbdP"' 88 `8b `"YbbdP"' ====CHAR **************************************************** ====COLOR 1 2 3 4 5 6 7 0 q w e r t y u p Q W EXR TxY U P 1 1 5 1 2 6 1 3 7 1 R P Q ~ E f z e f z w f z w f z w f z u f u 7 f ; 7 f ; ====COLOR ~ ~ ~ ~ ~ v V b B bB v V ~ ~ f E ~ f e ~ f w ~ f w ~ f w ; f ; ; f U ; f U ====EOI Outputs:'''.encode('utf-8') return testimage.split('\n') bc=bc() opts=setup_options() f=open_data_file(opts) if opts.clear: bc.clear() if opts.test_image: for row in f: print(row) while True: pause=0 gray=[] gray.append([]) colors=[] colorFrame=0 grayFrame=0 maxRow=0 for row in f: if not row: end_drawing(opts) row=row.decode('utf-8').rstrip("\n\r") if row.startswith(NEWIMAGE): break if row.startswith(PAUSE): try: new_value=row[len(PAUSE):].strip() pause=float(new_value) except: pause=0 continue if row.startswith(NEWCOLOR): colorFrame+=1 colors.append([]) continue if colorFrame==0: if row.startswith(NEWCHAR): grayFrame+=1 gray.append([]) continue gray[grayFrame].append(row) maxRow=max(maxRow, len(row)) else: colors[colorFrame-1].append(row) if len(gray[0])==0: end_drawing(opts) for i in range(len(gray[0])): while maxRow>len(gray[0][i]): gray[0][i]=gray[0][i]+" " for i in range(len(gray[0])): for frame in colors: if len(frame)len(frame[i]): frame[i]=frame[i]+" " if len(gray)>1: for layer in gray[1:]: if len(layer)len(layer[i]): layer[i]=layer[i]+" " for i in range(len(gray[0])): for c in range(len(gray[0][i])): if opts.color: for frame in colors: try: if frame[i][c]!=" ": sys.stdout.write(bc.color_char(frame[i][c]).encode('utf-8')) except IndexError: pass char=" " for layer in gray: if layer[i][c]==" ": continue char=layer[i][c] sys.stdout.write(char.encode('utf-8')) if opts.color and opts.zero: sys.stdout.write(bc.Z.encode('utf-8')) sys.stdout.write("\n") if pause>0: time.sleep(pause) if opts.test_image: end_drawing(opts)