diff --git a/reporting/ansicodes.py b/reporting/ansicodes.py index baf47dc..7dbfebe 100644 --- a/reporting/ansicodes.py +++ b/reporting/ansicodes.py @@ -1,104 +1,156 @@ # Python library for ansi colorization -import re,sys +import re, sys + class code: - K="\033[1;30m" - R="\033[1;31m" - G="\033[1;32m" - B="\033[1;34m" - Y="\033[1;33m" - M="\033[1;35m" - C="\033[1;36m" - W="\033[1;37m" + K = "\033[1;30m" + R = "\033[1;31m" + G = "\033[1;32m" + B = "\033[1;34m" + Y = "\033[1;33m" + M = "\033[1;35m" + C = "\033[1;36m" + W = "\033[1;37m" - k="\033[0;30m" - r="\033[0;31m" - g="\033[0;32m" - b="\033[0;34m" - y="\033[0;33m" - m="\033[0;35m" - c="\033[0;36m" - w="\033[0;37m" + k = "\033[0;30m" + r = "\033[0;31m" + g = "\033[0;32m" + b = "\033[0;34m" + y = "\033[0;33m" + m = "\033[0;35m" + c = "\033[0;36m" + w = "\033[0;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" + 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'#strong - s = '\033[2m'#strong off - U = '\033[4m'#underline - u = '\033[24m'#underline off - Z = '\033[0m'#zero colors - ic = '\033[7m'#inverse colors - io = '\033[27m'#inverse off - st = '\033[9m'#strike on - so = '\033[29m'#strike off - CLR = '\033[2J' - CLREND = '\033[K' - CLRBEG = '\033[1K' - CLRSCR = CLR+"\033[0;0H" + S = "\033[1m" # strong + s = "\033[2m" # strong off + U = "\033[4m" # underline + u = "\033[24m" # underline off + Z = "\033[0m" # zero colors + ic = "\033[7m" # inverse colors + io = "\033[27m" # inverse off + st = "\033[9m" # strike on + so = "\033[29m" # strike off + CLR = "\033[2J" + CLREND = "\033[K" + CLRBEG = "\033[1K" + CLRSCR = CLR + "\033[0;0H" - color_keys="K,R,G,B,Y,M,C,W,k,r,g,b,y,m,c,w,S,s,U,u,Z,ic,io,st,so,bk,br,bg,by,bb,bm,bc,bw,CLR,CLREND,CLRBEG,CLRSCR".split(",") - color_list=[K,R,G,B,Y,M,C,W,k,r,g,b,y,m,c,w,S,s,U,u,Z,ic,io,st,so,bk,br,bg,by,bb,bm,bc,bw,CLR,CLREND,CLRBEG,CLRSCR] - custom_match=re.compile(r'(\${)([0-9;]*[ABCDEFGHJKSTfminsu]+)(})') + color_keys = "K,R,G,B,Y,M,C,W,k,r,g,b,y,m,c,w,S,s,U,u,Z,ic,io,st,so,bk,br,bg,by,bb,bm,bc,bw,CLR,CLREND,CLRBEG,CLRSCR".split( + "," + ) + color_list = [ + K, + R, + G, + B, + Y, + M, + C, + W, + k, + r, + g, + b, + y, + m, + c, + w, + S, + s, + U, + u, + Z, + ic, + io, + st, + so, + bk, + br, + bg, + by, + bb, + bm, + bc, + bw, + CLR, + CLREND, + CLRBEG, + CLRSCR, + ] + custom_match = re.compile(r"(\${)([0-9;]*[ABCDEFGHJKSTfminsu]+)(})") - def pos(self,y,x): + def pos(self, y, x): """ Go to absolute position """ - return "\033["+str(y)+";"+str(x)+"H" - def column(self,x): - """ Go to absolute column """ - return "\033["+str(x)+"G" + return "\033[" + str(y) + ";" + str(x) + "H" - def posprint(self, y,x,s): + def column(self, x): + """ Go to absolute column """ + return "\033[" + str(x) + "G" + + def posprint(self, y, x, s): """ Print string at a location """ - sys.stdout.write( self.pos(y,x) + str(s) ) + sys.stdout.write(self.pos(y, x) + str(s)) self.flush() def clear(self): - sys.stdout.write( self.CLRSCR+self.pos(0,0) ) - def clear_to_end(self): - sys.stdout.write( self.CLREND ) - def clear_to_beginning(self): - sys.stdout.write( self.CLRBEG ) + sys.stdout.write(self.CLRSCR + self.pos(0, 0)) - def up(self,n=1): - sys.stdout.write( "\033["+str(n)+"A" ) - def down(self,n=1): - sys.stdout.write( "\033["+str(n)+"B" ) - def right(self,n=1): - sys.stdout.write( "\033["+str(n)+"C" ) - def left(self,n=1): - sys.stdout.write( "\033["+str(n)+"D" ) - def up_line(self,n=1): - sys.stdout.write( "\033["+str(n)+"F" ) - def down_line(self,n=1): - sys.stdout.write( "\033["+str(n)+"E" ) + def clear_to_end(self): + sys.stdout.write(self.CLREND) + + def clear_to_beginning(self): + sys.stdout.write(self.CLRBEG) + + def up(self, n=1): + sys.stdout.write("\033[" + str(n) + "A") + + def down(self, n=1): + sys.stdout.write("\033[" + str(n) + "B") + + def right(self, n=1): + sys.stdout.write("\033[" + str(n) + "C") + + def left(self, n=1): + sys.stdout.write("\033[" + str(n) + "D") + + def up_line(self, n=1): + sys.stdout.write("\033[" + str(n) + "F") + + def down_line(self, n=1): + sys.stdout.write("\033[" + str(n) + "E") def save(self): """ Save cursor position """ - sys.stdout.write( "\033[s" ) + sys.stdout.write("\033[s") + def restore(self): """ Restore cursor position """ - sys.stdout.write( "\033[u" ) + sys.stdout.write("\033[u") - def color_string(self,s): - for i,c in enumerate(self.color_keys): - s=s.replace("${"+c+"}",self.color_list[i]) + def color_string(self, s): + for i, c in enumerate(self.color_keys): + s = s.replace("${" + c + "}", self.color_list[i]) return self.custom_color(s) - def nocolor_string(self,s): - for i,c in enumerate(self.color_keys): - s=s.replace("${"+c+"}","") + + def nocolor_string(self, s): + for i, c in enumerate(self.color_keys): + s = s.replace("${" + c + "}", "") return self.custom_nocolor(s) - def custom_color(self,s): - return self.custom_match.sub('\033[\\2',s) - def custom_nocolor(self,s): - return self.custom_match.sub('',s) + def custom_color(self, s): + return self.custom_match.sub("\033[\\2", s) + + def custom_nocolor(self, s): + return self.custom_match.sub("", s) def get_keys(self): return self.color_keys @@ -109,8 +161,8 @@ class code: def demo(): """ Print all control sequences """ - c=code() - unformatted="""${S}ANSI CODES + c = code() + unformatted = """${S}ANSI CODES ==========${Z} ${S}Fo${U}rm${st}at${u}ti${ic}ng${Z} ${S}==========${Z} @@ -142,4 +194,4 @@ ${S}=====================${Z} C .right() Right y;xH .pos() Absolute Position D .left() Left """ - return(c.color_string(unformatted)) + return c.color_string(unformatted) diff --git a/reporting/ascii-codes.py b/reporting/ascii-codes.py index d6da7b3..e93be67 100755 --- a/reporting/ascii-codes.py +++ b/reporting/ascii-codes.py @@ -1,72 +1,62 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import sys, os + sys.path.append(os.path.dirname(os.path.realpath(__file__))) import ansicodes from argparse import ArgumentParser + def setup_options(): parser = ArgumentParser() - parser.add_argument( - "-v", - default = False, - action = "store_true" - ) + parser.add_argument("-v", default=False, action="store_true") parser.add_argument( "cs", - type = str, - default = "cp437", - nargs = '?', - help = "Character set to show, ex. ascii, cp437, cp850, cp1250, latin1 ..." + type=str, + default="cp437", + nargs="?", + help="Character set to show, ex. ascii, cp437, cp850, cp1250, latin1 ...", ) - opts=parser.parse_args() + opts = parser.parse_args() return opts + def long_format(table): bc = ansicodes.code() - for x,col in enumerate(table): - for y,row in enumerate(col): + for x, col in enumerate(table): + for y, row in enumerate(col): bc.posprint( - y + 2, - 1 + x*7, - bc.color_string( - "${c}%03d: ${G}%s${Z}"%( row ) - ) + y + 2, 1 + x * 7, bc.color_string("${c}%03d: ${G}%s${Z}" % (row)) ) def short_format(table): bc = ansicodes.code() - for x,col in enumerate(table): - for y,row in enumerate(col): - bc.posprint( - x + 3, - y * 2 + 1, - bc.color_string( - "${G}%s${Z}"%( row[1], ) - ) - ) - print('') + for x, col in enumerate(table): + for y, row in enumerate(col): + bc.posprint(x + 3, y * 2 + 1, bc.color_string("${G}%s${Z}" % (row[1],))) + print("") if __name__ == "__main__": opts = setup_options() - table=[[] for x in range(8)] - for c in range(0,256): - col = c/32 - table[col].append((c,chr(c).decode(opts.cs,'ignore').encode('utf-8','ignore'))) - #sys.stdout.write(chr(c).decode('latin1')) + table = [[] for x in range(8)] + for c in range(0, 256): + col = int(c / 32) + table[col].append( + (c, chr(c)) + ) + # sys.stdout.write(chr(c).decode('latin1')) # remove control chars table.pop(0) bc = ansicodes.code() bc.clear() if opts.v: - lines = int(25 - len(opts.cs)/2 - 2) + lines = int(25 - len(opts.cs) / 2 - 2) else: - lines = int(32 - len(opts.cs)/2 - 2) - print(bc.color_string("="*lines + " ${Y}%s${Z} "%( opts.cs, ) + "="*lines)) + lines = int(32 - len(opts.cs) / 2 - 2) + print(bc.color_string("=" * lines + " ${Y}%s${Z} " % (opts.cs,) + "=" * lines)) if opts.v: long_format(table) else: short_format(table) - print('') - + print("") diff --git a/reporting/file_usage_by_name.py b/reporting/file_usage_by_name.py index 94d16f1..8ad9463 100755 --- a/reporting/file_usage_by_name.py +++ b/reporting/file_usage_by_name.py @@ -1,69 +1,75 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import sys import os import pwd -from argparse import ArgumentParser +from argparse import ArgumentParser + +MINSIZE = 0 -MINSIZE=0 def setup_options(): - parser=ArgumentParser(description="List file usage") - parser.add_argument('startpath', action="append", nargs='+') + parser = ArgumentParser(description="List file usage") + parser.add_argument("startpath", action="append", nargs="+") - options=parser.parse_args() + options = parser.parse_args() return options -def add_recurse(db,options,start): - for path,dirs,files in os.walk(start,followlinks=False): - files=clean_syms(files,path) + +def add_recurse(db, options, start): + for path, dirs, files in os.walk(start, followlinks=False): + files = clean_syms(files, path) for f in files: - filename=os.path.join(path,f) - stats=os.stat(filename) - owner=stats.st_uid - size=stats.st_size + filename = os.path.join(path, f) + stats = os.stat(filename) + owner = stats.st_uid + size = stats.st_size if not owner in db: - db[owner]=0 - db[owner]+=size + db[owner] = 0 + db[owner] += size return db -def clean_syms(files,path): - nonsyms=[] + +def clean_syms(files, path): + nonsyms = [] for f in files: - if not os.path.islink(os.path.join(path,f)): + if not os.path.islink(os.path.join(path, f)): nonsyms.append(f) return nonsyms + def print_db(db): - namedb=dict() + namedb = dict() for u in db: try: - namedb[pwd.getpwuid(u).pw_name]=humanize_size(db[u]) + namedb[pwd.getpwuid(u).pw_name] = humanize_size(db[u]) except: - namedb[str(u)]=humanize_size(db[u]) - names=namedb.keys() + namedb[str(u)] = humanize_size(db[u]) + names = list(namedb.keys()) names.sort() - for n in names: - print(n+": "+namedb[n]) + for n in names: + print(n + ": " + namedb[n]) -def humanize_size(size,precision=1): - if size==None: - return 'nan' - suffixes=['B','KB','MB','GB','TB'] + +def humanize_size(size, precision=1): + if size == None: + return "nan" + suffixes = ["B", "KB", "MB", "GB", "TB"] suffixIndex = 0 - defPrecision=0 + defPrecision = 0 while size > 1024: - suffixIndex += 1 #increment the index of the suffix - size = size/1024.0 #apply the division - defPrecision=precision - return "%.*f%s"%(defPrecision,size,suffixes[suffixIndex]) + suffixIndex += 1 # increment the index of the suffix + size = size / 1024.0 # apply the division + defPrecision = precision + return "%.*f%s" % (defPrecision, size, suffixes[suffixIndex]) + def main(): - options=setup_options(); - db=dict() + options = setup_options() + db = dict() for f in options.startpath[0]: - db=add_recurse(db,options,f) + db = add_recurse(db, options, f) print_db(db) sys.exit(0) -main() +main() diff --git a/reporting/markslider.py b/reporting/markslider.py index 65c42fc..c0e4a51 100755 --- a/reporting/markslider.py +++ b/reporting/markslider.py @@ -17,19 +17,21 @@ # along with this program. If not, see . # -'''Markslider: a slideshow engine based on markdown.''' +"""Markslider: a slideshow engine based on markdown.""" __author__ = "Ville Rantanen " __version__ = "1.3" -import sys,os,argparse,re,datetime +import sys, os, argparse, re, datetime from argparse import ArgumentParser -import traceback,tty,termios,subprocess,signal +import traceback, tty, termios, subprocess, signal + sys.path.append(os.path.dirname(os.path.realpath(__file__))) import ansicodes, md_color -HL=">" -EOS="# End of Slides" +HL = ">" +EOS = "# End of Slides" + class getch: def get(self): @@ -43,12 +45,15 @@ class getch: return ch -class EndProgram( Exception ): - ''' Nice exit ''' +class EndProgram(Exception): + """ Nice exit """ + pass + class slide_reader: """ Class for reading files. """ + def __init__(self, files, opts): self.filename = files[0] self.files = files @@ -64,23 +69,19 @@ class slide_reader: self.data = [] self.re_image_convert = re.compile("(.*)(!\[.*\])\((.*)\)>") self.re_command = re.compile("(.*)`(.*)`>(.*)") - #~ self.control_chars = ''.join(map(unichr, range(0,32) + range(127,160))) - #~ self.control_char_re = re.compile('[%s]' % re.escape(self.control_chars)) + # ~ self.control_chars = ''.join(map(unichr, range(0,32) + range(127,160))) + # ~ self.control_char_re = re.compile('[%s]' % re.escape(self.control_chars)) self.background = [] self.read() self.pygments = False if opts.syntax_pygments: - try: - self.pygments = Pygmentizer( - opts.syntax_formatter, - opts.syntax_style - ) - except ImportError as e: - self.pygments = False - + try: + self.pygments = Pygmentizer(opts.syntax_formatter, opts.syntax_style) + except ImportError as e: + self.pygments = False def read(self): - ''' Read a file, set pages and data ''' + """ Read a file, set pages and data """ self.pages = 0 self.background = [] @@ -89,22 +90,22 @@ class slide_reader: first_slide_found = False for fname in self.files: first_slide_found = False - f=open(fname,'r') - new_page=[] + f = open(fname, "r") + new_page = [] in_code = False for row in f: if not row: continue - row=row.rstrip("\n\r ") + row = row.rstrip("\n\r ") # find end of show if row == EOS: break # find header to start a new page if row.startswith("#") and not row.startswith("##") and not in_code: - first_slide_found=True - if len(new_page)>0: + first_slide_found = True + if len(new_page) > 0: self.data.append(new_page) - new_page=[] + new_page = [] if row.startswith("```"): in_code = not in_code # if first slide havent been found yet: @@ -112,30 +113,32 @@ class slide_reader: self.background.append(row) continue new_page.extend(self.generate_content(row)) - if len(new_page)>0: + if len(new_page) > 0: self.data.append(new_page) f.close() self.file_start_page.append(len(self.data)) - if len(self.data)==0: + if len(self.data) == 0: raise ValueError("File does not have a # header") self.rename_duplicates() self.toc() - self.pages=len(self.data) + self.pages = len(self.data) self.inc_page_no(0) - self.max_width=0 - self.max_height=0 + self.max_width = 0 + self.max_height = 0 for page in self.data: - self.max_height=max(self.max_height, len(page)) + self.max_height = max(self.max_height, len(page)) for row in page: - self.max_width=max(self.max_width, len(row)) + self.max_width = max(self.max_width, len(row)) def get_data(self): return self.data + def get_current_filename(self): - for i,offset in enumerate(self.file_start_page): - if offset>self.page: + for i, offset in enumerate(self.file_start_page): + if offset > self.page: return self.files[i] return "NA" + def get_filename(self): return self.filename @@ -153,121 +156,136 @@ class slide_reader: def get_page_no(self): return self.page - def inc_page_no(self,inc=1,loop=False): - self.page+=inc - if self.page<0: - self.page=0 + + def inc_page_no(self, inc=1, loop=False): + self.page += inc + if self.page < 0: + self.page = 0 if loop: - self.page=self.pages-1 - if self.page>=self.pages: - self.page=self.pages-1 + self.page = self.pages - 1 + if self.page >= self.pages: + self.page = self.pages - 1 if loop: - self.page=0 - self.width=max([len(x) for x in self.data[self.page]]) - self.height=len(self.data[self.page]) + self.page = 0 + self.width = max([len(x) for x in self.data[self.page]]) + self.height = len(self.data[self.page]) + def last_page(self): - self.page=self.pages-1 + self.page = self.pages - 1 + def first_page(self): - self.page=0 + self.page = 0 + def get_page_height(self): return self.height + def get_page_width(self): return self.width + def get_max_height(self): return self.max_height + def get_max_width(self): return self.max_width - def get_toc(self,display_position=False): - title=self.opts.toc if self.opts.toc else "Table of Contents" - TOC=["# "+title,""] - offset=(self.opts.toc_page-1) if self.opts.toc else 0 - for h1,page in enumerate(self.data[offset:]): - title=page[0].strip("# ") - if display_position and h1==self.page-offset: - title="_%s_"%(title,) - TOC.append("%d. %s"%(h1+1,title)) - subh=[0,0,0] - if self.opts.toc_depth>1: + def get_toc(self, display_position=False): + title = self.opts.toc if self.opts.toc else "Table of Contents" + TOC = ["# " + title, ""] + offset = (self.opts.toc_page - 1) if self.opts.toc else 0 + for h1, page in enumerate(self.data[offset:]): + title = page[0].strip("# ") + if display_position and h1 == self.page - offset: + title = "_%s_" % (title,) + TOC.append("%d. %s" % (h1 + 1, title)) + subh = [0, 0, 0] + if self.opts.toc_depth > 1: for line in page: - title=line.strip("# ") + title = line.strip("# ") if re.search("^##[^#]", line): - subh=[ subh[0]+1, 0, 0 ] - TOC.append(" %d.%d. %s"%(h1+1,subh[0],title)) - if self.opts.toc_depth==2: continue + subh = [subh[0] + 1, 0, 0] + TOC.append(" %d.%d. %s" % (h1 + 1, subh[0], title)) + if self.opts.toc_depth == 2: + continue if re.search("^###[^#]", line): - subh=[ subh[0], subh[1]+1, 0 ] - TOC.append(" %d.%d.%d. %s"%(h1+1,subh[0],subh[1],title)) - if self.opts.toc_depth==3: continue + subh = [subh[0], subh[1] + 1, 0] + TOC.append( + " %d.%d.%d. %s" % (h1 + 1, subh[0], subh[1], title) + ) + if self.opts.toc_depth == 3: + continue if re.search("^####[^#]", line): - subh=[ subh[0], subh[1], subh[2]+1 ] - TOC.append(" %d.%d.%d.%d. %s"%(h1+1,subh[0],subh[1],subh[2],title)) + subh = [subh[0], subh[1], subh[2] + 1] + TOC.append( + " %d.%d.%d.%d. %s" + % (h1 + 1, subh[0], subh[1], subh[2], title) + ) return TOC def toc(self): if self.opts.toc: - TOC=self.get_toc() - self.data.insert(self.opts.toc_page-1,TOC) + TOC = self.get_toc() + self.data.insert(self.opts.toc_page - 1, TOC) # adding 1 is not fullproof, if toc page is after the first document - self.file_start_page=[1+i for i in self.file_start_page] + self.file_start_page = [1 + i for i in self.file_start_page] - def generate_content(self,s): + def generate_content(self, s): """ Check for launchable items, or converted images """ if self.opts.execute_read: - if s.find("`>")>-1: - command=self.re_command.match(s) - if command !=None: + if s.find("`>") > -1: + command = self.re_command.match(s) + if command != None: return self.launch(command) image = self.re_image_convert.match(s) if image != None: return self.convert_image(image) return [s] - def launch(self,command): - """ Launch in a string using tags `command`> - Remove empty lines from beginning and end of stdout. + def launch(self, command): + """Launch in a string using tags `command`> + Remove empty lines from beginning and end of stdout. """ - output = subprocess.check_output( - command.group(2).strip(), - shell = True - ) + output = subprocess.check_output(command.group(2).strip(), shell=True) if type(output) == bytes: - output = output.decode('utf-8') + output = output.decode("utf-8") output = output.split("\n") - while len(output[0].strip())==0: - if len(output)==1: return [""] + while len(output[0].strip()) == 0: + if len(output) == 1: + return [""] del output[0] - while len(output[-1].strip())==0: - if len(output)==1: return [""] + while len(output[-1].strip()) == 0: + if len(output) == 1: + return [""] del output[-1] - return_value=[command.group(1)] + return_value = [command.group(1)] return_value.extend(output) return_value.append(command.group(3)) return return_value # return [s] - def convert_image(self,image): - """ comnvert image using tags ![]()> - Remove empty lines from beginning and end of stdout. + def convert_image(self, image): + """comnvert image using tags ![]()> + Remove empty lines from beginning and end of stdout. """ - #~ 2=title - #~ 3=image command + # ~ 2=title + # ~ 3=image command output = subprocess.check_output( - "convert %s JPEG:- | jp2a --colors --width=70 -"%( image.group(3),), - shell=True + "convert %s JPEG:- | jp2a --colors --width=70 -" % (image.group(3),), + shell=True, ) if type(output) == bytes: - output = output.decode('utf-8') + output = output.decode("utf-8") output = output.split("\n") - while len(output[0].strip())==0: - if len(output)==1: return [""] + while len(output[0].strip()) == 0: + if len(output) == 1: + return [""] del output[0] - while len(output[-1].strip())==0: - if len(output)==1: return [""] + while len(output[-1].strip()) == 0: + if len(output) == 1: + return [""] del output[-1] - return_value=[image.group(1)] + return_value = [image.group(1)] return_value.extend(output) - #~ return_value.append(image.group(4)) + # ~ return_value.append(image.group(4)) return return_value # return [s] @@ -286,64 +304,60 @@ class slide_reader: for page, page_no in zip(self.data, page_nos): if titles[page[0]] > 1: - page[0] += " [%d/%d]"%( page_no, titles[page[0]] ) - -class Pygmentizer(): - def __init__(self, formatter, style): - import pygments - import pygments.lexers - import pygments.formatters - import pygments.styles - self.pygments = pygments - self.lexers = pygments.lexers - self.formatters = pygments.formatters - self.styles = pygments.styles - - self.style = self.styles.get_style_by_name(style) - self.formatter = self.formatters.get_formatter_by_name( - formatter, - style = self.style - ) - self.lexer = None + page[0] += " [%d/%d]" % (page_no, titles[page[0]]) - def format(self, code): - in_block = False - blocks = [] - current_block = -1 - for i, row in enumerate(code): - if row.startswith("```"): - in_block = not in_block - lexer_name = row.replace("```","").strip() - if len(lexer_name) == 0: - in_block = False - if in_block: - blocks.append({ - "lexer": lexer_name, - "code": [], - "rows": [] - }) - current_block += 1 - else: - if in_block: - blocks[current_block]["code"].append(row) - blocks[current_block]["rows"].append(i) +class Pygmentizer: + def __init__(self, formatter, style): + import pygments + import pygments.lexers + import pygments.formatters + import pygments.styles - preformatted_rows = [] - for block in blocks: - lexer = self.lexers.get_lexer_by_name(block["lexer"]) - tokens = self.pygments.lex("\n".join(block["code"]), lexer) - formatted = self.pygments.format(tokens, self.formatter) - # ~ print(block["rows"]) - # ~ print(formatted.split("\n")) - for row, formatted_row in zip(block["rows"], formatted.split("\n")): - code[row] = formatted_row - preformatted_rows.append(row) - return code, preformatted_rows + self.pygments = pygments + self.lexers = pygments.lexers + self.formatters = pygments.formatters + self.styles = pygments.styles + + self.style = self.styles.get_style_by_name(style) + self.formatter = self.formatters.get_formatter_by_name( + formatter, style=self.style + ) + self.lexer = None + + def format(self, code): + in_block = False + blocks = [] + current_block = -1 + for i, row in enumerate(code): + if row.startswith("```"): + in_block = not in_block + lexer_name = row.replace("```", "").strip() + if len(lexer_name) == 0: + in_block = False + if in_block: + blocks.append({"lexer": lexer_name, "code": [], "rows": []}) + current_block += 1 + else: + if in_block: + blocks[current_block]["code"].append(row) + blocks[current_block]["rows"].append(i) + + preformatted_rows = [] + for block in blocks: + lexer = self.lexers.get_lexer_by_name(block["lexer"]) + tokens = self.pygments.lex("\n".join(block["code"]), lexer) + formatted = self.pygments.format(tokens, self.formatter) + # ~ print(block["rows"]) + # ~ print(formatted.split("\n")) + for row, formatted_row in zip(block["rows"], formatted.split("\n")): + code[row] = formatted_row + preformatted_rows.append(row) + return code, preformatted_rows def get_interactive_help_text(): - return ''' left/right,page up/down,home,end + return """ left/right,page up/down,home,end change page c list contents (toc) M modify file with VIM @@ -354,11 +368,13 @@ def get_interactive_help_text(): ,/. scroll page up/down move highlight enter execute highlighted line - h help''' + h help""" + def setup_options(): - ''' Create command line options ''' - usage=''' + """ Create command line options """ + usage = ( + """ MarkSlider: a markdown based slideshow engine Special syntaxes: * Colors: insert string ${C}, where C is one of KRGBYMCWkrgbymcwSUZ @@ -369,88 +385,192 @@ Special syntaxes: * Convert images to ASCII, with jp2a: ![](file.jpg)> Keyboard shortcuts: -'''+get_interactive_help_text() +""" + + get_interactive_help_text() + ) - parser=ArgumentParser(description=usage, - formatter_class=argparse.RawDescriptionHelpFormatter, - epilog=__author__) - parser.add_argument("-v","--version",action="version",version=__version__) - parser.add_argument("--export",action="store",dest="screenshots",default=False, - type=str, help="Take screenshots of the slideshow in the given folder.") + parser = ArgumentParser( + description=usage, + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=__author__, + ) + parser.add_argument("-v", "--version", action="version", version=__version__) + parser.add_argument( + "--export", + action="store", + dest="screenshots", + default=False, + type=str, + help="Take screenshots of the slideshow in the given folder.", + ) - content = parser.add_argument_group('content') - execution = parser.add_argument_group('execution') - control = parser.add_argument_group('controls') + content = parser.add_argument_group("content") + execution = parser.add_argument_group("execution") + control = parser.add_argument_group("controls") - content.add_argument("--background",action="store_true",dest="background",default = False, - help="Use the rows before the first # header as slide background") - content.add_argument("--center",action="store_true",dest="center",default=False, - help="Center slides on screen.") - content.add_argument("--dc",action="store_true",dest="dark_colors",default=False, - help="Use dark colorscheme, better for white background terminals.") - content.add_argument("-m",action="store_false",dest="autocolor",default=True, - help="Disable color by markdown structure.") - content.add_argument("--no-color","-n",action="store_false",dest="color",default=True, - help="Disable color.") - content.add_argument("--no-rename","--nr",action="store_false",dest="rename_title", default=True, - help="Disable automatic renaming of duplicate titles.") - content.add_argument("--toc",action="store",dest="toc",default=False, - const="Table of Contents", type=str, nargs='?', - help="Insert table of contents. Define the header, or use default: %(const)s") - content.add_argument("--toc-page",action="store",dest="toc_page",default=2, type=int, - help="Insert table of contents on a chosen page. default: %(const)s") - content.add_argument("--toc-depth",action="store",dest="toc_depth",default=2, type=int, - choices=list(range(1,5)), - help="Table of contents display depth. default: %(const)s") + content.add_argument( + "--background", + action="store_true", + dest="background", + default=False, + help="Use the rows before the first # header as slide background", + ) + content.add_argument( + "--center", + action="store_true", + dest="center", + default=False, + help="Center slides on screen.", + ) + content.add_argument( + "--dc", + action="store_true", + dest="dark_colors", + default=False, + help="Use dark colorscheme, better for white background terminals.", + ) + content.add_argument( + "-m", + action="store_false", + dest="autocolor", + default=True, + help="Disable color by markdown structure.", + ) + content.add_argument( + "--no-color", + "-n", + action="store_false", + dest="color", + default=True, + help="Disable color.", + ) + content.add_argument( + "--no-rename", + "--nr", + action="store_false", + dest="rename_title", + default=True, + help="Disable automatic renaming of duplicate titles.", + ) + content.add_argument( + "--toc", + action="store", + dest="toc", + default=False, + const="Table of Contents", + type=str, + nargs="?", + help="Insert table of contents. Define the header, or use default: %(const)s", + ) + content.add_argument( + "--toc-page", + action="store", + dest="toc_page", + default=2, + type=int, + help="Insert table of contents on a chosen page. default: %(const)s", + ) + content.add_argument( + "--toc-depth", + action="store", + dest="toc_depth", + default=2, + type=int, + choices=list(range(1, 5)), + help="Table of contents display depth. default: %(const)s", + ) - content.add_argument("--no-pygments",action="store_false",dest="syntax_pygments",default = True, - help="Disable autocoloring syntax with Pygments. Used only for ``` code blocks, if language is mentioned, ex.: ```python . Note! Do not have empty lines after ```") - content.add_argument("--syntax-formatter",action="store",dest="syntax_formatter",default = "terminal256", - choices=['terminal', 'terminal256', 'terminal16m'], - help="Syntax highlighter formatter. default: %(default)s") - content.add_argument("--syntax-style",action="store",dest="syntax_style",default = "monokai", - help="Syntax highlighter style, see Pygments styles. default: %(default)s") + content.add_argument( + "--no-pygments", + action="store_false", + dest="syntax_pygments", + default=True, + help="Disable autocoloring syntax with Pygments. Used only for ``` code blocks, if language is mentioned, ex.: ```python . Note! Do not have empty lines after ```", + ) + content.add_argument( + "--syntax-formatter", + action="store", + dest="syntax_formatter", + default="terminal256", + choices=["terminal", "terminal256", "terminal16m"], + help="Syntax highlighter formatter. default: %(default)s", + ) + content.add_argument( + "--syntax-style", + action="store", + dest="syntax_style", + default="monokai", + help="Syntax highlighter style, see Pygments styles. default: %(default)s", + ) + execution.add_argument( + "-e", + action="store_true", + dest="execute", + default=False, + help="Execute commands in `! or `> tags at show time with Enter key. WARNING: Potentially very dangerous to run others' slides with this switch!", + ) + execution.add_argument( + "-E", + action="store_true", + dest="execute_read", + default=False, + help="Execute commands in ``> tags at file read time. WARNING: Potentially very dangerous to run others' slides with this switch!", + ) - execution.add_argument("-e",action="store_true",dest="execute",default=False, - help="Execute commands in `! or `> tags at show time with Enter key. WARNING: Potentially very dangerous to run others' slides with this switch!") - execution.add_argument("-E",action="store_true",dest="execute_read",default=False, - help="Execute commands in ``> tags at file read time. WARNING: Potentially very dangerous to run others' slides with this switch!") + control.add_argument( + "--exit", + action="store_true", + dest="exit_last", + default=False, + help="Exit after last slide.", + ) - control.add_argument("--exit",action="store_true",dest="exit_last",default=False, - help="Exit after last slide.") + control.add_argument( + "-s", + action="store_false", + dest="menu", + default=True, + help="Disable status bar.", + ) + control.add_argument( + "--timer", + action="store", + dest="slideTimer", + default=False, + type=int, + help="Timer for slideshow. If set, starts automatic slide changing.", + ) + content.add_argument( + "-w", + action="store_false", + dest="wrap", + default=True, + help="Disable line wrapping. Cuts long lines.", + ) - control.add_argument("-s",action="store_false",dest="menu",default=True, - help="Disable status bar.") - control.add_argument("--timer",action="store",dest="slideTimer",default=False, type=int, - help="Timer for slideshow. If set, starts automatic slide changing.") - content.add_argument("-w",action="store_false",dest="wrap",default=True, - help="Disable line wrapping. Cuts long lines.") - - - parser.add_argument("files",type=str, nargs='+', - help="File(s) to show") - opts=parser.parse_args() - opts.slideShow=not not opts.slideTimer + parser.add_argument("files", type=str, nargs="+", help="File(s) to show") + opts = parser.parse_args() + opts.slideShow = not not opts.slideTimer if opts.screenshots: - opts.slideShow=True - opts.slideTimer=1 - opts.exit_last=True + opts.slideShow = True + opts.slideTimer = 1 + opts.exit_last = True return opts -def page_print(reader,opts,offset): - ''' Print a page ''' +def page_print(reader, opts, offset): + """ Print a page """ page = reader.get_current_page() scrsize = opts.size # clear page bc.clear() - if opts.center: # Placeholder for 80x25 center alignment + if opts.center: # Placeholder for 80x25 center alignment align_width = reader.get_max_width() - align_x_offset = int(scrsize[1]/2 - align_width/2) + align_x_offset = int(scrsize[1] / 2 - align_width / 2) align_pad = " " * align_x_offset - align_y_offset = int(scrsize[0]/2 - reader.get_max_height()/2) + align_y_offset = int(scrsize[0] / 2 - reader.get_max_height() / 2) bc.down_line(align_y_offset) else: align_pad = "" @@ -459,26 +579,24 @@ def page_print(reader,opts,offset): coloring = "${b}${U}" else: coloring = "${U}${Y}" - print( - align_pad + - colorify( - coloring + page[0], - opts) + - bc.Z - ) + print(align_pad + colorify(coloring + page[0], opts) + bc.Z) if opts.background: bc.save() if opts.color: - sys.stdout.write("\n".join([align_pad + bc.color_string(x) for x in reader.background])) + sys.stdout.write( + "\n".join([align_pad + bc.color_string(x) for x in reader.background]) + ) else: - sys.stdout.write("\n".join([align_pad + bc.nocolor_string(x) for x in reader.background])) + sys.stdout.write( + "\n".join([align_pad + bc.nocolor_string(x) for x in reader.background]) + ) bc.restore() - if (sys.version_info < (3, 0)): + if sys.version_info < (3, 0): # python2 magic - page = [row.decode('utf-8') for row in page] + page = [row.decode("utf-8") for row in page] # Print page rows if not opts.wrap: - page = [cut_line(row,scrsize[1]-1) for row in page] + page = [cut_line(row, scrsize[1] - 1) for row in page] parsed = md_color.parse(page) if opts.autocolor: if reader.pygments: @@ -486,41 +604,39 @@ def page_print(reader,opts,offset): # ~ to_pygmentize = [] # ~ pygmented_rows = [] # ~ for token_i in range(len(parsed)): - # ~ if parsed[token_i][0] == 'multiline_code': - # ~ to_pygmentize.append(parsed[token_i][1]) - # ~ pygmented_rows.append(token_i) + # ~ if parsed[token_i][0] == 'multiline_code': + # ~ to_pygmentize.append(parsed[token_i][1]) + # ~ pygmented_rows.append(token_i) # ~ if len(to_pygmentize) > 0: preformatted, preformatted_rows = reader.pygments.format( - [x[1] for x in parsed] + [x[1] for x in parsed] ) for row_i in preformatted_rows: - parsed[row_i][0] = 'preformatted' + parsed[row_i][0] = "preformatted" parsed[row_i][1] = preformatted[row_i] - colored = md_color.colorize( - parsed, - not opts.color, - opts.dark_colors - ) + colored = md_color.colorize(parsed, not opts.color, opts.dark_colors) else: if opts.color: - colored=[bc.color_string(row[1]) for row in parsed] + colored = [bc.color_string(row[1]) for row in parsed] else: - colored=[bc.nocolor_string(row[1]) for row in parsed] + colored = [bc.nocolor_string(row[1]) for row in parsed] r = 0 for row_i in range(len(page)): - if row_i == 0: continue - if row_i < offset[0]: continue + if row_i == 0: + continue + if row_i < offset[0]: + continue row = page[row_i] - #page[1+offset[0]:]: + # page[1+offset[0]:]: if opts.wrap: - row_lines = int(float(len(row))/scrsize[1]) + row_lines = int(float(len(row)) / scrsize[1]) else: row_lines = 0 row_lines = 0 - colored_row = colored[row_i]#=colorify(row,opts) + colored_row = colored[row_i] # =colorify(row,opts) if offset[1] == r + 1 + offset[0]: - colored_row = add_highlight(row,opts) + colored_row = add_highlight(row, opts) sys.stdout.write(align_pad + colored_row) if r >= scrsize[0] - 2: @@ -531,78 +647,85 @@ def page_print(reader,opts,offset): return -def print_menu(reader,opts): +def print_menu(reader, opts): - bc.posprint( opts.size[0], 0, - colorify("${y}%d${Z}/%d %s|%s"%( - 1+reader.get_page_no(), - reader.get_pages(), - os.path.basename(reader.get_current_filename()), - "slideshow" if opts.slideShow else ""), - opts)) - - -def print_time(opts): - now=datetime.datetime.now() bc.posprint( opts.size[0], - opts.size[1]-5, + 0, colorify( - "%02d:%02d"%( - now.hour, - now.minute + "${y}%d${Z}/%d %s|%s" + % ( + 1 + reader.get_page_no(), + reader.get_pages(), + os.path.basename(reader.get_current_filename()), + "slideshow" if opts.slideShow else "", ), - opts - ) + opts, + ), ) -def print_help(reader,opts): - ''' Create a window with help message ''' - helptext=get_interactive_help_text().split('\n') - maxlen=max([len(x) for x in helptext]) - bc.posprint(3,5," +"+"-"*maxlen+"+ ") - bc.posprint(4,5,colorify(" |${U}${Y}"+("{:^"+str(maxlen)+"}").format("Help")+"${Z}| ",opts)) - for y,row in enumerate(helptext): - bc.posprint(5+y,5,(" |{:<"+str(maxlen)+"}| ").format(row)) - bc.posprint(6+y,5," +"+"-"*maxlen+"+ ") +def print_time(opts): + now = datetime.datetime.now() + bc.posprint( + opts.size[0], + opts.size[1] - 5, + colorify("%02d:%02d" % (now.hour, now.minute), opts), + ) + + +def print_help(reader, opts): + """ Create a window with help message """ + helptext = get_interactive_help_text().split("\n") + maxlen = max([len(x) for x in helptext]) + bc.posprint(3, 5, " +" + "-" * maxlen + "+ ") + bc.posprint( + 4, + 5, + colorify( + " |${U}${Y}" + ("{:^" + str(maxlen) + "}").format("Help") + "${Z}| ", opts + ), + ) + for y, row in enumerate(helptext): + bc.posprint(5 + y, 5, (" |{:<" + str(maxlen) + "}| ").format(row)) + bc.posprint(6 + y, 5, " +" + "-" * maxlen + "+ ") sys.stdout.write(bc.pos(opts.size[0], opts.size[1])) - inkey=getch.get() + inkey = getch.get() -def print_toc(reader,opts): - ''' Create a window with TOC ''' - text=reader.get_toc(display_position=True) - title=opts.toc if opts.toc else "Table of Contents" - maxlen=max([len(x) for x in text]) - bc.posprint(3,2," +"+"-"*maxlen+"+ ") - parsed=md_color.parse(text) +def print_toc(reader, opts): + """ Create a window with TOC """ + text = reader.get_toc(display_position=True) + title = opts.toc if opts.toc else "Table of Contents" + maxlen = max([len(x) for x in text]) + bc.posprint(3, 2, " +" + "-" * maxlen + "+ ") + parsed = md_color.parse(text) if opts.autocolor: - colored=md_color.colorize(parsed,not opts.color,opts.dark_colors) + colored = md_color.colorize(parsed, not opts.color, opts.dark_colors) else: if opts.color: - colored=[bc.color_string(row[1]) for row in parsed] + colored = [bc.color_string(row[1]) for row in parsed] else: - colored=[bc.nocolor_string(row[1]) for row in parsed] - for y,row in enumerate(colored): - bc.posprint(4+y,2,(" |{:<"+str(maxlen)+"}| ").format(" ")) - bc.posprint(4+y,3,("|{:<"+str(maxlen)+"}").format(row)) - bc.posprint(5+y,2," +"+"-"*maxlen+"+ ") + colored = [bc.nocolor_string(row[1]) for row in parsed] + for y, row in enumerate(colored): + bc.posprint(4 + y, 2, (" |{:<" + str(maxlen) + "}| ").format(" ")) + bc.posprint(4 + y, 3, ("|{:<" + str(maxlen) + "}").format(row)) + bc.posprint(5 + y, 2, " +" + "-" * maxlen + "+ ") sys.stdout.write(bc.pos(opts.size[0], opts.size[1])) - inkey=getch.get() + inkey = getch.get() -def offset_change(opts,reader,offset,new_offset): - ''' Change the display position of page ''' - new_offset=(offset[0]+new_offset[0], offset[1]+new_offset[1]) - offsety=min(reader.get_page_height()-1,new_offset[0]) - offseth=min(reader.get_page_height(),new_offset[1]) - return [max(0,o) for o in (offsety,offseth)] +def offset_change(opts, reader, offset, new_offset): + """ Change the display position of page """ + new_offset = (offset[0] + new_offset[0], offset[1] + new_offset[1]) + offsety = min(reader.get_page_height() - 1, new_offset[0]) + offseth = min(reader.get_page_height(), new_offset[1]) + return [max(0, o) for o in (offsety, offseth)] -def timeouthandler(sig,frame): - #~ print(sig,frame) +def timeouthandler(sig, frame): + # ~ print(sig,frame) raise IOError("Input timeout") @@ -613,28 +736,28 @@ def getkeypress(): return False -def browser(opts,files): - ''' Main function for printing ''' +def browser(opts, files): + """ Main function for printing """ try: - reader=slide_reader(files,opts) + reader = slide_reader(files, opts) except: print("Error in reading the file:") for o in sys.exc_info(): print(o) sys.exit(1) - offset=(0,0) + offset = (0, 0) try: while 1: - opts.size=get_console_size() - page_print(reader,opts,offset) + opts.size = get_console_size() + page_print(reader, opts, offset) if opts.menu: - print_menu(reader,opts) + print_menu(reader, opts) print_time(opts) sys.stdout.write(bc.pos(opts.size[0], opts.size[1])) sys.stdout.flush() if opts.screenshots: - take_screenshot(reader,opts) + take_screenshot(reader, opts) while True: if opts.slideTimer and opts.slideShow: signal.signal(signal.SIGALRM, timeouthandler) @@ -642,7 +765,7 @@ def browser(opts,files): elif opts.menu: signal.signal(signal.SIGALRM, timeouthandler) signal.alarm(15) - inkey=getkeypress() + inkey = getkeypress() signal.alarm(0) if not inkey and not opts.slideShow and opts.menu: # normal operation, just update the time @@ -651,58 +774,57 @@ def browser(opts,files): if not inkey and opts.slideShow: # slideshow mode if opts.exit_last: - if reader.page+1==reader.pages: + if reader.page + 1 == reader.pages: return - reader.inc_page_no(1,True) - offset=(0,0) + reader.inc_page_no(1, True) + offset = (0, 0) break - #~ print(inkey) - if inkey in [113,3,120]: - #print('Exited in: ') + # ~ print(inkey) + if inkey in [113, 3, 120]: + # print('Exited in: ') return - if inkey in [67,54,32]: # PGDN or space + if inkey in [67, 54, 32]: # PGDN or space if opts.exit_last: - if reader.page+1==reader.pages: + if reader.page + 1 == reader.pages: return reader.inc_page_no(1) - offset=(0, 0) - if inkey in [68,53,127]: + offset = (0, 0) + if inkey in [68, 53, 127]: reader.inc_page_no(-1) - offset=(0, 0) - if inkey==72 or inkey==49: # HOME + offset = (0, 0) + if inkey == 72 or inkey == 49: # HOME reader.first_page() - offset=(0, 0) - if inkey==70 or inkey==52: # END + offset = (0, 0) + if inkey == 70 or inkey == 52: # END reader.last_page() - offset=(0, 0) - if inkey==ord('c'): - print_toc(reader,opts) - if inkey==ord('h'): - print_help(reader,opts) - if inkey==ord('s'): - opts.menu=not opts.menu - if inkey==ord('t'): - opts.slideShow=not opts.slideShow - if inkey==ord('r'): + offset = (0, 0) + if inkey == ord("c"): + print_toc(reader, opts) + if inkey == ord("h"): + print_help(reader, opts) + if inkey == ord("s"): + opts.menu = not opts.menu + if inkey == ord("t"): + opts.slideShow = not opts.slideShow + if inkey == ord("r"): reader.read() - offset=offset_change(opts,reader,offset,(0, 0)) - if inkey==ord('M'): - modify_file(reader,offset) + offset = offset_change(opts, reader, offset, (0, 0)) + if inkey == ord("M"): + modify_file(reader, offset) reader.read() - offset=offset_change(opts,reader,offset,(0, 0)) - if inkey==ord(','): - offset=offset_change(opts,reader,offset,(-1, 0)) - if inkey==ord('.'): - offset=offset_change(opts,reader,offset,(1, 0)) - if inkey==65: # up - offset=offset_change(opts,reader,offset,(0, -1)) - if inkey==66: # down - offset=offset_change(opts,reader,offset,(0, 1)) - if inkey==13: # enter - launch(reader,opts,offset) + offset = offset_change(opts, reader, offset, (0, 0)) + if inkey == ord(","): + offset = offset_change(opts, reader, offset, (-1, 0)) + if inkey == ord("."): + offset = offset_change(opts, reader, offset, (1, 0)) + if inkey == 65: # up + offset = offset_change(opts, reader, offset, (0, -1)) + if inkey == 66: # down + offset = offset_change(opts, reader, offset, (0, 1)) + if inkey == 13: # enter + launch(reader, opts, offset) break - except IOError: pass except KeyboardInterrupt: @@ -716,150 +838,134 @@ def browser(opts,files): def get_console_size(): - rows, columns = os.popen('stty size', 'r').read().split() - return (int(rows),int(columns)) + rows, columns = os.popen("stty size", "r").read().split() + return (int(rows), int(columns)) -def colorify(s,opts): +def colorify(s, opts): """ Add colors to string """ if not opts.color: return bc.nocolor_string(s) - c=bc.color_string(s)#+bc.Z + c = bc.color_string(s) # +bc.Z return c -def cut_line(s,i): +def cut_line(s, i): """ cut a color tagged string, and remove control chars """ - s=s[:i] - s=re.sub("\$$","", - re.sub("\$\{$","", - re.sub("\$\{.$","", - s))) + s = s[:i] + s = re.sub("\$$", "", re.sub("\$\{$", "", re.sub("\$\{.$", "", s))) return s -def add_highlight(s,opts): +def add_highlight(s, opts): """ Add cursor position highlight """ - if len(s.strip())==0: - cleaned=HL + if len(s.strip()) == 0: + cleaned = HL else: - cleaned=bc.nocolor_string(s) - tagged="${Y}"+cleaned+"${Z}" - return colorify(tagged,opts) + cleaned = bc.nocolor_string(s) + tagged = "${Y}" + cleaned + "${Z}" + return colorify(tagged, opts) -def launch(reader,opts,offset): - """ Launch in a string using tags $!command$! or $>command$> - Remove empty lines from beginning and end of stdout in $> commands. - Detects URLS and markdown images ![Alt text](/path/to/img.jpg) +def launch(reader, opts, offset): + """Launch in a string using tags $!command$! or $>command$> + Remove empty lines from beginning and end of stdout in $> commands. + Detects URLS and markdown images ![Alt text](/path/to/img.jpg) """ if not opts.execute: - bc.posprint( - offset[1]-offset[0]+1, - 0, - "Execution not enabled!" - ) + bc.posprint(offset[1] - offset[0] + 1, 0, "Execution not enabled!") inkey = getch.get() return s = reader.get_current_page()[offset[1]] - urls = re.findall('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', s) - images = re.findall('!\[[^]]+\]\([^\)]+\)', s) + urls = re.findall( + "http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+", + s, + ) + images = re.findall("!\[[^]]+\]\([^\)]+\)", s) # sanity check if s.find("`") == -1 and len(urls) == 0 and len(images) == 0: return - run_command=re.match("(.*)`(.*)`!(.*)",s) - show_command=re.match("(.*)`(.*)`>(.*)",s) + run_command = re.match("(.*)`(.*)`!(.*)", s) + show_command = re.match("(.*)`(.*)`>(.*)", s) if show_command != None: - output = subprocess.check_output( - show_command.group(2).strip(), - shell = True - ) + output = subprocess.check_output(show_command.group(2).strip(), shell=True) if type(output) == bytes: - output = output.decode('utf-8') + output = output.decode("utf-8") output = output.split("\n") - while len(output[0].strip())==0: - if len(output)==1: return + while len(output[0].strip()) == 0: + if len(output) == 1: + return del output[0] - while len(output[-1].strip())==0: - if len(output)==1: return + while len(output[-1].strip()) == 0: + if len(output) == 1: + return del output[-1] - for y,l in enumerate(output): - bc.posprint(y+offset[1]-offset[0]+2,0,' '*len(l)) + for y, l in enumerate(output): + bc.posprint(y + offset[1] - offset[0] + 2, 0, " " * len(l)) bc.clear_to_end() - bc.posprint(y+offset[1]-offset[0]+2,0,l) - inkey=getch.get() + bc.posprint(y + offset[1] - offset[0] + 2, 0, l) + inkey = getch.get() return if run_command != None: - subprocess.call( - run_command.group(2), - shell = True, - executable = "/bin/bash" - ) - inkey=getch.get() + subprocess.call(run_command.group(2), shell=True, executable="/bin/bash") + inkey = getch.get() return # Open URLS last - if len(urls)>0: + if len(urls) > 0: # Remove ) at the end of url: [name](link) markdown syntax subprocess.call( - "%s '%s' &"%( + "%s '%s' &" + % ( get_open_command(), urls[0].rstrip(")"), ), - stdout = subprocess.PIPE, - stderr = subprocess.PIPE, - shell = True + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + shell=True, ) return - if len(images)>0: - image = re.sub('.*\(([^\)]+)\).*', "\\1",images[0]) + if len(images) > 0: + image = re.sub(".*\(([^\)]+)\).*", "\\1", images[0]) subprocess.call( - "%s '%s' &"%( + "%s '%s' &" + % ( get_open_command(), image, ), - stdout = subprocess.PIPE, - stderr = subprocess.PIPE, - shell = True + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + shell=True, ) return return -def modify_file(reader,offset): - row=1 - row_restarts=reader.file_start_page +def modify_file(reader, offset): + row = 1 + row_restarts = reader.file_start_page for page in range(reader.page): - if opts.toc_page==page+1 and opts.toc: + if opts.toc_page == page + 1 and opts.toc: continue - row+=len(reader.data[page]) - if (page+1) in row_restarts: - row=1 + row += len(reader.data[page]) + if (page + 1) in row_restarts: + row = 1 subprocess.call( - "vim +%d -c 'exe \"normal! zt\"' -c %d %s"%( - row, - row + offset[1], - reader.get_current_filename() - ), - shell = True + "vim +%d -c 'exe \"normal! zt\"' -c %d %s" + % (row, row + offset[1], reader.get_current_filename()), + shell=True, ) -def take_screenshot(reader,opts): - out_file = os.path.join( - opts.screenshots, - "slide%03d.png"%(reader.page + 1,) - ) +def take_screenshot(reader, opts): + out_file = os.path.join(opts.screenshots, "slide%03d.png" % (reader.page + 1,)) if not os.path.exists(opts.screenshots): os.mkdir(opts.screenshots) subprocess.call( - "sleep 0.5; import -window %s '%s'"%( - opts.xwinid, - out_file - ), - stdout = subprocess.PIPE, - stderr = subprocess.PIPE, - shell = True + "sleep 0.5; import -window %s '%s'" % (opts.xwinid, out_file), + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + shell=True, ) @@ -879,29 +985,26 @@ def main(): opts = setup_options() if opts.screenshots: print("Click the terminal window to read window ID") - xwininfo = subprocess.check_output( - "xwininfo", - shell = True - ) + xwininfo = subprocess.check_output("xwininfo", shell=True) if type(xwininfo) == bytes: - xwininfo = xwininfo.decode('utf-8') + xwininfo = xwininfo.decode("utf-8") xwininfo = re.search(r"Window id: (0x[0-9]+)", xwininfo) if xwininfo: opts.xwinid = xwininfo.group(1) else: print("Cannot parse window ID") sys.exit(1) - browser( - opts, - opts.files - ) + browser(opts, opts.files) print("\n\n") if opts.screenshots: - print("Crop the images for terminal tabs, and PDFize e.g.:\n- mogrify -chop 0x50 %s/*png\n- convert %s/*png %s.pdf"%( + print( + "Crop the images for terminal tabs, and PDFize e.g.:\n- mogrify -chop 0x50 %s/*png\n- convert %s/*png %s.pdf" + % ( opts.screenshots, opts.screenshots, os.path.basename(opts.screenshots), - )) + ) + ) if __name__ == "__main__": diff --git a/reporting/markslider.tar.gz b/reporting/markslider.tar.gz index 11ce773..b3ccc18 100644 Binary files a/reporting/markslider.tar.gz and b/reporting/markslider.tar.gz differ diff --git a/reporting/md_color.py b/reporting/md_color.py index 975fb36..9b82aeb 100755 --- a/reporting/md_color.py +++ b/reporting/md_color.py @@ -1,108 +1,149 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -import sys,os,re +import sys, os, re from argparse import ArgumentParser, RawDescriptionHelpFormatter + sys.path.append(os.path.dirname(os.path.realpath(__file__))) import ansicodes as ansi __author__ = "Ville Rantanen " __version__ = "0.3" -''' Rules modified from mistune project ''' +""" Rules modified from mistune project """ + def setup_options(): bc = ansi.code() - ''' Create command line options ''' - usage = ''' + """ Create command line options """ + usage = ( + """ Markdown syntax color in ansi codes. Special syntaxes: - Colors: insert string e.g. ${C}. - Any ANSI control code: ${3A}, ${1;34;42m}, see the table.. -''' + ansi.demo() - - parser = ArgumentParser( - formatter_class = RawDescriptionHelpFormatter, - description = usage, - epilog = __author__ +""" + + ansi.demo() ) - parser.add_argument("-v","--version",action="version",version=__version__) - parser.add_argument("-D",action="store_true",dest="debug",default=False, - help="Debug mode") - parser.add_argument("--dc",action="store_true",dest="dark_colors",default=False, - help="Use dark colorscheme, better for white background terminals.") - parser.add_argument("--no-color","-n",action="store_false",dest="color",default=True, - help="Disable color.") - parser.add_argument("--print-template",action="store_true",dest="print_template",default=False, - help="Print customizable color template.") - parser.add_argument("--template",action="store",type=str,dest="template",default=None, - help="Use a custom template file for colorization.") - parser.add_argument("-z",action="store_true",dest="zero",default=False, - help="Reset coloring 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("filename",type=str, nargs='?', - help="File to show, - for stdin") - opts=parser.parse_args() + parser = ArgumentParser( + formatter_class=RawDescriptionHelpFormatter, + description=usage, + epilog=__author__, + ) + + parser.add_argument("-v", "--version", action="version", version=__version__) + parser.add_argument( + "-D", action="store_true", dest="debug", default=False, help="Debug mode" + ) + parser.add_argument( + "--dc", + action="store_true", + dest="dark_colors", + default=False, + help="Use dark colorscheme, better for white background terminals.", + ) + parser.add_argument( + "--no-color", + "-n", + action="store_false", + dest="color", + default=True, + help="Disable color.", + ) + parser.add_argument( + "--print-template", + action="store_true", + dest="print_template", + default=False, + help="Print customizable color template.", + ) + parser.add_argument( + "--template", + action="store", + type=str, + dest="template", + default=None, + help="Use a custom template file for colorization.", + ) + parser.add_argument( + "-z", + action="store_true", + dest="zero", + default=False, + help="Reset coloring 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( + "filename", type=str, nargs="?", help="File to show, - for stdin" + ) + opts = parser.parse_args() return opts + def parse(data): - data=[[None,row] for row in data] - block='text' - new_block='text' - multiline_block=False + data = [[None, row] for row in data] + block = "text" + new_block = "text" + multiline_block = False # Parse styles - for i,line in enumerate(data): - row=line[1] + for i, line in enumerate(data): + row = line[1] if line[0] is not None: # Previous lines have set the style already continue for match in blocks: - if block_match[match]['re'].match(row): - new_block=match - if match.startswith('multiline'): + if block_match[match]["re"].match(row): + new_block = match + if match.startswith("multiline"): if multiline_block: - multiline_block=False + multiline_block = False else: - multiline_block=match + multiline_block = match break if multiline_block: - new_block=multiline_block + new_block = multiline_block # Lists must end with empty line - if new_block not in ('empty','list_bullet') and block.startswith('list_'): - new_block='list_loose' + if new_block not in ("empty", "list_bullet") and block.startswith("list_"): + new_block = "list_loose" - if 'mod' in block_match[match]: + if "mod" in block_match[match]: # Style sets block in previous or next lines - data[i+block_match[match]['mod']['pos']][0]=block_match[match]['mod']['name'] - data[i][0]=new_block - if new_block!=block: - block=new_block + data[i + block_match[match]["mod"]["pos"]][0] = block_match[match]["mod"][ + "name" + ] + data[i][0] = new_block + if new_block != block: + block = new_block return data -def colorize(data, remove_colors = False, dark_colors = False, debug = False): +def colorize(data, remove_colors=False, dark_colors=False, debug=False): # Start inserting colors, and printing bc = ansi.code() colorized = [] - cs = 'dc' if dark_colors else 'bc' - csc = cs + 'c' + cs = "dc" if dark_colors else "bc" + csc = cs + "c" for i, line in enumerate(data): row = line[1] block = line[0] - multiline_block = block.startswith('multiline') + multiline_block = block.startswith("multiline") if multiline_block: row = block_match[block][csc] + row if block_match[block][cs]: - row = block_match[block]['re'].sub(block_match[block][cs], row) + row = block_match[block]["re"].sub(block_match[block][cs], row) # No coloring inside block_code, nor multiline - if not (multiline_block or block == 'block_code'): + if not (multiline_block or block == "block_code"): for match in inlines: - if inline_match[match]['re'].search(row): - row = inline_match[match]['re'].sub( - inline_match[match][cs] + block_match[block][csc], - row + if inline_match[match]["re"].search(row): + row = inline_match[match]["re"].sub( + inline_match[match][cs] + block_match[block][csc], row ) if remove_colors: colored = bc.nocolor_string(row) @@ -114,31 +155,34 @@ def colorize(data, remove_colors = False, dark_colors = False, debug = False): colorized.append(colored) return colorized + def md_re_compile(d): - ''' Returns a re.compiled dict ''' - n={} + """ Returns a re.compiled dict """ + n = {} for t in d: - n[t]={} + n[t] = {} for i in d[t]: - n[t][i]=d[t][i] + n[t][i] = d[t][i] try: - if n[t]['re']: - n[t]['re']=re.compile(n[t]['re']) + if n[t]["re"]: + n[t]["re"] = re.compile(n[t]["re"]) except err: - print("Error compiling: %s"%(n[t]['re'])) + print("Error compiling: %s" % (n[t]["re"])) sys.exit(1) return n + def read_data2(fp): data = [] # Read data for row in f: if not row: continue - row = row.decode('utf-8').rstrip("\n\r ") + row = row.decode("utf-8").rstrip("\n\r ") data.append(row) return data + def read_data3(fp): data = [] # Read data @@ -149,14 +193,16 @@ def read_data3(fp): data.append(row) return data + def write_colored2(colored, opts): for c in colored: - sys.stdout.write(c.encode('utf-8')) + sys.stdout.write(c.encode("utf-8")) if opts.zero: sys.stdout.write(bc.Z) sys.stdout.write("\n") if opts.zero_final: - sys.stdout.write(bc.Z.encode('utf-8')) + sys.stdout.write(bc.Z.encode("utf-8")) + def write_colored3(colored, opts): for c in colored: @@ -168,112 +214,207 @@ def write_colored3(colored, opts): sys.stdout.write(bc.Z) - # re: regular expression, bc: bright colors, bcc: continue with this color after inline # dc: dark colors, dcc: continued color after inline -block_match_str={ - 'block_code': {'re':'^( {4}[^*])(.*)$', - 'bc' :'${Z}${c}\\1\\2', 'bcc':'${Z}${c}', - 'dc' :'${Z}${m}\\1\\2', 'dcc':'${Z}${m}'}, # code - 'multiline_code' : {'re':'^ *(`{3,}|~{3,}) *(\S*)', - 'bc' :'${Z}${c}\\1\\2', 'bcc':'${Z}${c}', - 'dc' :'${Z}${m}\\1\\2', 'dcc':'${Z}${m}'}, # ```lang - 'block_quote': {'re':'^(>[ >]* )', - 'bc':'${K}\\1${Z}','bcc':'${Z}', - 'dc':'${Y}\\1${Z}','dcc':'${Z}'}, # > > quote - 'hrule': {'re':'^ {0,3}[-*_]([-*_]){2,}$', - 'bc':'False','bcc':'${Z}', - 'dc':'False','dcc':'${Z}'}, # ---- - 'heading' : {'re':'^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)', - 'bc':'${W}\\1 ${U}\\2${Z}','bcc':'${W}${U}', - 'dc':'${B}\\1 ${U}\\2${Z}','dcc':'${B}${U}'}, # # heading - 'lheading' : {'re':'^(=+|-+)$', - 'bc':'${W}\\1', 'bcc':'${W}', - 'dc':'${B}\\1', 'dcc':'${B}', - 'mod':{'pos':-1,'name':'lheading.mod'}}, # ======= under header - 'lheading.mod' : {'re':'^([^\n]+)', - 'bc':'${W}\\1', 'bcc':'${W}', - 'dc':'${B}\\1', 'dcc':'${B}'}, # over the ======= under header - 'list_bullet': {'re':'^( *)([*+-]|[\d\.]+)( +)', - 'bc':'\\1${y}\\2${Z}\\3','bcc':'${Z}', - 'dc':'\\1${r}\\2${Z}\\3','dcc':'${Z}'}, # * or 1. - 'list_loose': {'re':'None', - 'bc':'False','bcc':'${Z}', - 'dc':'False','dcc':'${Z}'}, - 'text': {'re':'^([^\n]+)', - 'bc':'${Z}\\1','bcc':'${Z}', - 'dc':'${Z}\\1','dcc':'${Z}'}, - 'empty': {'re':'(^$)', - 'bc':'${Z}\\1','bcc':'${Z}', - 'dc':'${Z}\\1','dcc':'${Z}'}, - 'preformatted': {'re': 'a^', # Never matches anything - 'bc':'','bcc':'', - 'dc':'','dcc':''}, +block_match_str = { + "block_code": { + "re": "^( {4}[^*])(.*)$", + "bc": "${Z}${c}\\1\\2", + "bcc": "${Z}${c}", + "dc": "${Z}${m}\\1\\2", + "dcc": "${Z}${m}", + }, # code + "multiline_code": { + "re": "^ *(`{3,}|~{3,}) *(\S*)", + "bc": "${Z}${c}\\1\\2", + "bcc": "${Z}${c}", + "dc": "${Z}${m}\\1\\2", + "dcc": "${Z}${m}", + }, # ```lang + "block_quote": { + "re": "^(>[ >]* )", + "bc": "${K}\\1${Z}", + "bcc": "${Z}", + "dc": "${Y}\\1${Z}", + "dcc": "${Z}", + }, # > > quote + "hrule": { + "re": "^ {0,3}[-*_]([-*_]){2,}$", + "bc": "False", + "bcc": "${Z}", + "dc": "False", + "dcc": "${Z}", + }, # ---- + "heading": { + "re": "^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)", + "bc": "${W}\\1 ${U}\\2${Z}", + "bcc": "${W}${U}", + "dc": "${B}\\1 ${U}\\2${Z}", + "dcc": "${B}${U}", + }, # # heading + "lheading": { + "re": "^(=+|-+)$", + "bc": "${W}\\1", + "bcc": "${W}", + "dc": "${B}\\1", + "dcc": "${B}", + "mod": {"pos": -1, "name": "lheading.mod"}, + }, # ======= under header + "lheading.mod": { + "re": "^([^\n]+)", + "bc": "${W}\\1", + "bcc": "${W}", + "dc": "${B}\\1", + "dcc": "${B}", + }, # over the ======= under header + "list_bullet": { + "re": "^( *)([*+-]|[\d\.]+)( +)", + "bc": "\\1${y}\\2${Z}\\3", + "bcc": "${Z}", + "dc": "\\1${r}\\2${Z}\\3", + "dcc": "${Z}", + }, # * or 1. + "list_loose": { + "re": "None", + "bc": "False", + "bcc": "${Z}", + "dc": "False", + "dcc": "${Z}", + }, + "text": { + "re": "^([^\n]+)", + "bc": "${Z}\\1", + "bcc": "${Z}", + "dc": "${Z}\\1", + "dcc": "${Z}", + }, + "empty": { + "re": "(^$)", + "bc": "${Z}\\1", + "bcc": "${Z}", + "dc": "${Z}\\1", + "dcc": "${Z}", + }, + "preformatted": { + "re": "a^", # Never matches anything + "bc": "", + "bcc": "", + "dc": "", + "dcc": "", + }, } -block_match=md_re_compile(block_match_str) -blocks=['block_quote', 'multiline_code','hrule', 'heading','lheading','list_bullet', 'block_code', 'text', 'empty'] +block_match = md_re_compile(block_match_str) +blocks = [ + "block_quote", + "multiline_code", + "hrule", + "heading", + "lheading", + "list_bullet", + "block_code", + "text", + "empty", +] -inline_match_str={ - 'bold1': {'re':r'(^| |})(_[^_]+_)', - 'bc':'\\1${W}\\2','dc':'\\1${W}\\2'}, # _bold_ - 'bold2': {'re':r'(^| |})(\*{1,2}[^\*]+\*{1,2})', - 'bc':'\\1${W}\\2','dc':'\\1${W}\\2'}, # **bold** - 'code': {'re':r'([`]+[^`]+[`]+)', - 'bc':'${c}\\1','dc':'${m}\\1'}, # `code` - 'code_special': {'re':r'([`]+[^`]+[`]+)([!>])', - 'bc':'${c}\\1${g}\\2','dc':'${m}\\1${r}\\2'}, # `code`! or `code`> for markslider - 'link': {'re':r'(\[)([^\]]+)(\])\(([^\)]+)\)', - 'bc':'${B}\\1${Z}\\2${B}\\3(${U}\\4${u})', - 'dc':'${b}\\1${Z}\\2${b}\\3(${U}\\4${u})'}, # [text](link) - 'image': {'re':r'(!\[[^\]]+\]\([^\)]+\))', - 'bc':'${r}\\1','dc':'${g}\\1'}, # ![text](image) - 'underline': {'re':r'(^|\W)(__)([^_]+)(__)', - 'bc':'\\1\\2${U}\\3${Z}\\4','dc':'\\1\\2${U}\\3${Z}\\4'}, # __underline__ - 'strikethrough': {'re':r'(~~)([^~]+)(~~)', - 'bc':'\\1${st}\\2${so}\\3','dc':'\\1${st}\\2${so}\\3'}, # ~~strike~~ - 'checkbox': {'re':r'(\[[x ]\])', - 'bc':'${y}\\1','dc':'${r}\\1'}, # [x] [ ] +inline_match_str = { + "bold1": { + "re": r"(^| |})(_[^_]+_)", + "bc": "\\1${W}\\2", + "dc": "\\1${W}\\2", + }, # _bold_ + "bold2": { + "re": r"(^| |})(\*{1,2}[^\*]+\*{1,2})", + "bc": "\\1${W}\\2", + "dc": "\\1${W}\\2", + }, # **bold** + "code": {"re": r"([`]+[^`]+[`]+)", "bc": "${c}\\1", "dc": "${m}\\1"}, # `code` + "code_special": { + "re": r"([`]+[^`]+[`]+)([!>])", + "bc": "${c}\\1${g}\\2", + "dc": "${m}\\1${r}\\2", + }, # `code`! or `code`> for markslider + "link": { + "re": r"(\[)([^\]]+)(\])\(([^\)]+)\)", + "bc": "${B}\\1${Z}\\2${B}\\3(${U}\\4${u})", + "dc": "${b}\\1${Z}\\2${b}\\3(${U}\\4${u})", + }, # [text](link) + "image": { + "re": r"(!\[[^\]]+\]\([^\)]+\))", + "bc": "${r}\\1", + "dc": "${g}\\1", + }, # ![text](image) + "underline": { + "re": r"(^|\W)(__)([^_]+)(__)", + "bc": "\\1\\2${U}\\3${Z}\\4", + "dc": "\\1\\2${U}\\3${Z}\\4", + }, # __underline__ + "strikethrough": { + "re": r"(~~)([^~]+)(~~)", + "bc": "\\1${st}\\2${so}\\3", + "dc": "\\1${st}\\2${so}\\3", + }, # ~~strike~~ + "checkbox": {"re": r"(\[[x ]\])", "bc": "${y}\\1", "dc": "${r}\\1"}, # [x] [ ] } inline_match = md_re_compile(inline_match_str) -inlines = ['bold1','bold2','code_special','code','image','link','underline','strikethrough', 'checkbox'] +inlines = [ + "bold1", + "bold2", + "code_special", + "code", + "image", + "link", + "underline", + "strikethrough", + "checkbox", +] if __name__ == "__main__": - opts=setup_options() + opts = setup_options() if opts.print_template: import json - print(json.dumps({'about':'re: regular expression, bc: bright colors, bcc: continue with this color after inline, dc: dark colors, dcc: continued color after inline. "blocks" and "inlines" list keys of matchers. ', - 'blocks':blocks, - 'block_match':block_match_str, - 'inline_match':inline_match_str, - 'inlines':inlines}, - indent=2,sort_keys=True)) + + print( + json.dumps( + { + "about": 're: regular expression, bc: bright colors, bcc: continue with this color after inline, dc: dark colors, dcc: continued color after inline. "blocks" and "inlines" list keys of matchers. ', + "blocks": blocks, + "block_match": block_match_str, + "inline_match": inline_match_str, + "inlines": inlines, + }, + indent=2, + sort_keys=True, + ) + ) sys.exit(0) if opts.template: import json - template=json.load(open(opts.template,'r')) - if 'inlines' in template: inlines=template['inlines'] - if 'blocks' in template: blocks=template['blocks'] - if 'block_match' in template: - block_match_str=template['block_match'] - block_match=md_re_compile(block_match_str) - if 'inline_match' in template: - inline_match_str=template['inline_match'] - inline_match=md_re_compile(inline_match_str) + + template = json.load(open(opts.template, "r")) + if "inlines" in template: + inlines = template["inlines"] + if "blocks" in template: + blocks = template["blocks"] + if "block_match" in template: + block_match_str = template["block_match"] + block_match = md_re_compile(block_match_str) + if "inline_match" in template: + inline_match_str = template["inline_match"] + inline_match = md_re_compile(inline_match_str) bc = ansi.code() if opts.filename == "-" or opts.filename == None: f = sys.stdin else: - f = open(opts.filename, 'r') - if (sys.version_info > (3, 0)): + f = open(opts.filename, "r") + if sys.version_info > (3, 0): data = read_data3(f) else: data = read_data2(f) data = parse(data) colored = colorize(data, not opts.color, opts.dark_colors, opts.debug) - if (sys.version_info > (3, 0)): + if sys.version_info > (3, 0): write_colored3(colored, opts) else: write_colored2(colored, opts) - diff --git a/reporting/src2ans b/reporting/src2ans index a262204..c8ead41 100755 --- a/reporting/src2ans +++ b/reporting/src2ans @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # coding=utf-8 # # Copyright 2016 Ville Rantanen @@ -17,61 +17,83 @@ # along with this program. If not, see . # -'''Color by ${X} notation.''' +"""Color by ${X} notation.""" __author__ = "Ville Rantanen " __version__ = "0.1" -import sys,os,argparse,re +import sys, os, argparse, re from argparse import ArgumentParser + sys.path.append(os.path.dirname(os.path.realpath(__file__))) import ansicodes as ansi + def setup_options(): - ''' Create command line options ''' - usage=''' + """ Create command line options """ + usage = ( + """ Color notation renderer in ANSI codes Special syntaxes: * Colors: insert string ${X}, where X values in the table below. -''' + ansi.demo() +""" + + ansi.demo() + ) - parser=ArgumentParser(description=usage, - formatter_class=argparse.RawDescriptionHelpFormatter, - epilog=__author__) + 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("-z",action="store_true",dest="zero",default=False, - help="Reset coloring 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("filename",type=str, - help="File to show, - for stdin") - opts=parser.parse_args() + 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( + "-z", + action="store_true", + dest="zero", + default=False, + help="Reset coloring 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("filename", type=str, help="File to show, - for stdin") + opts = parser.parse_args() return opts -bc=ansi.code() -opts=setup_options() -if opts.filename=="-": - f=sys.stdin + +bc = ansi.code() +opts = setup_options() +if opts.filename == "-": + f = sys.stdin else: - f=open(opts.filename,'r') + f = open(opts.filename, "r") for row in f: if not row: continue if type(row) == bytes: - row = row.decode('utf-8') - row=row.rstrip("\n\r ") + row = row.decode("utf-8") + row = row.rstrip("\n\r ") if opts.color: - colored=bc.color_string(row) + colored = bc.color_string(row) else: - colored=bc.nocolor_string(row) + colored = bc.nocolor_string(row) sys.stdout.write(colored) if opts.zero and opts.color: sys.stdout.write(bc.Z) sys.stdout.write("\n") if opts.zero_final and opts.color: sys.stdout.write(bc.Z) - diff --git a/reporting/srcframes2ans b/reporting/srcframes2ans index b4521ba..023a956 100755 --- a/reporting/srcframes2ans +++ b/reporting/srcframes2ans @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # coding=utf-8 # # Copyright 2016 Ville Rantanen @@ -17,115 +17,163 @@ # along with this program. If not, see . # -'''Color by notation.''' +"""Color by notation.""" __author__ = "Ville Rantanen " __version__ = "0.2" -NEWCHAR="====CHAR" -NEWCOLOR="====COLOR" -NEWIMAGE="====EOI" -ENDOFFILE="====EOF" -PAUSE="====PAUSE" +NEWCHAR = "====CHAR" +NEWCOLOR = "====COLOR" +NEWIMAGE = "====EOI" +ENDOFFILE = "====EOF" +PAUSE = "====PAUSE" + +import sys, os, argparse, re, time +from argparse import ArgumentParser + -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] + 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" - def pos(self,y,x): - return "\033["+str(y)+";"+str(x)+"H" + 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" - def posprint(self, y,x,s): - sys.stdout.write( (self.pos(y,x) + str(s)).encode('utf-8') ) + 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') ) + sys.stdout.write((self.CLR + self.pos(0, 0)).encode("utf-8")) - def color_char(self,s): - for i,c in enumerate(self.color_keys): + 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]) + s = s.replace(c, self.color_list[i]) return s return "" - def nocolor_string(self,s): + + def nocolor_string(self, s): return "" + def end_drawing(opts): if opts.zero_final: - sys.stdout.write(bc.Z.encode('utf-8')) + 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=='-': + if opts.filename == "-": return sys.stdin - return open(opts.filename,'r') + return open(opts.filename, "r") + def setup_options(): - ''' Create command line options ''' - usage=''' + """ Create command line options """ + usage = """ Color image renderer in ANSI codes. Example file: first layer of characters ====CHAR - more characters + more characters go here ====COLOR color codes go here (letters 1-7,0 and keys below like a piano) @@ -145,45 +193,75 @@ Color image renderer in ANSI codes. Example file: ====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 = 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 - _ _ _ ____ ___ + testimage = ''' NOT VISIBLE + _ _ _ ____ ___ 1 red 5 magenta / \ | \ | / ___|_ _| - 2 green 6 cyan / _ \ | \| \___ \| | - 3 yellow 7 white / ___ \| |\ |___) | | + 2 green 6 cyan / _ \ | \| \___ \| | + 3 yellow 7 white / ___ \| |\ |___) | | 4 blue 0 black /_/ \_\_| \_|____/___| - - ,ad8888ba, 88 88888888ba - d8"' `"8b 88 88 "8b -d8' 88 88 ,8P + + ,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, +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 @@ -191,7 +269,7 @@ Y8, 8b d8 88 8b d8 88 `8b `"Y8ba, ====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 + 1 5 1 2 6 1 3 7 1 R P Q @@ -221,98 +299,100 @@ u f u ; f U ; f U ====EOI -Outputs:'''.encode('utf-8') - return testimage.split('\n') +Outputs:'''.encode( + "utf-8" + ) + return testimage.split("\n") -bc=bc() -opts=setup_options() -f=open_data_file(opts) -endoffile=False + +bc = bc() +opts = setup_options() +f = open_data_file(opts) +endoffile = False if opts.clear: bc.clear() if opts.test_image: for row in f: print(row) while True: - pause=0 - gray=[] + pause = 0 + gray = [] gray.append([]) - colors=[] - colorFrame=0 - grayFrame=0 - maxRow=0 + 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") + row = row.decode("utf-8").rstrip("\n\r") if row.startswith(NEWIMAGE): break if row.startswith(ENDOFFILE): - endoffile=True + endoffile = True if endoffile: break if row.startswith(PAUSE): try: - new_value=row[len(PAUSE):].strip() - pause=float(new_value) + new_value = row[len(PAUSE) :].strip() + pause = float(new_value) except: - pause=0 + pause = 0 continue if row.startswith(NEWCOLOR): - colorFrame+=1 + colorFrame += 1 colors.append([]) continue - - if colorFrame==0: + + if colorFrame == 0: if row.startswith(NEWCHAR): - grayFrame+=1 + grayFrame += 1 gray.append([]) continue gray[grayFrame].append(row) - - maxRow=max(maxRow, len(row)) + + maxRow = max(maxRow, len(row)) else: - colors[colorFrame-1].append(row) - if len(gray[0])==0: + 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]+" " + 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: + if len(frame) < i + 1: + frame.append("") + while len(gray[0][i]) > 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]+" " - + if len(layer) < i + 1: + layer.append("") + while len(gray[0][i]) > 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: + for frame in colors: try: - if frame[i][c]!=" ": - sys.stdout.write(bc.color_char(frame[i][c]).encode('utf-8')) + if frame[i][c] != " ": + sys.stdout.write(bc.color_char(frame[i][c]).encode("utf-8")) except IndexError: pass - char=" " + char = " " for layer in gray: - if layer[i][c]==" ": continue - char=layer[i][c] - - sys.stdout.write(char.encode('utf-8')) + 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(bc.Z.encode("utf-8")) sys.stdout.write("\n") - if pause>0: + if pause > 0: time.sleep(pause) if opts.test_image: end_drawing(opts) -