python3inizing scripts

This commit is contained in:
Ville Rantanen
2020-10-12 11:37:33 +03:00
parent 877acc0d35
commit 52db6b9bf4
8 changed files with 1328 additions and 934 deletions

View File

@@ -1,6 +1,7 @@
# Python library for ansi colorization # Python library for ansi colorization
import re, sys import re, sys
class code: class code:
K = "\033[1;30m" K = "\033[1;30m"
R = "\033[1;31m" R = "\033[1;31m"
@@ -29,27 +30,68 @@ class code:
bc = "\033[46m" bc = "\033[46m"
bw = "\033[47m" bw = "\033[47m"
S = '\033[1m'#strong S = "\033[1m" # strong
s = '\033[2m'#strong off s = "\033[2m" # strong off
U = '\033[4m'#underline U = "\033[4m" # underline
u = '\033[24m'#underline off u = "\033[24m" # underline off
Z = '\033[0m'#zero colors Z = "\033[0m" # zero colors
ic = '\033[7m'#inverse colors ic = "\033[7m" # inverse colors
io = '\033[27m'#inverse off io = "\033[27m" # inverse off
st = '\033[9m'#strike on st = "\033[9m" # strike on
so = '\033[29m'#strike off so = "\033[29m" # strike off
CLR = '\033[2J' CLR = "\033[2J"
CLREND = '\033[K' CLREND = "\033[K"
CLRBEG = '\033[1K' CLRBEG = "\033[1K"
CLRSCR = CLR + "\033[0;0H" 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_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_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 """ """ Go to absolute position """
return "\033[" + str(y) + ";" + str(x) + "H" return "\033[" + str(y) + ";" + str(x) + "H"
def column(self, x): def column(self, x):
""" Go to absolute column """ """ Go to absolute column """
return "\033[" + str(x) + "G" return "\033[" + str(x) + "G"
@@ -61,27 +103,35 @@ class code:
def clear(self): def clear(self):
sys.stdout.write(self.CLRSCR + self.pos(0, 0)) sys.stdout.write(self.CLRSCR + self.pos(0, 0))
def clear_to_end(self): def clear_to_end(self):
sys.stdout.write(self.CLREND) sys.stdout.write(self.CLREND)
def clear_to_beginning(self): def clear_to_beginning(self):
sys.stdout.write(self.CLRBEG) sys.stdout.write(self.CLRBEG)
def up(self, n=1): def up(self, n=1):
sys.stdout.write("\033[" + str(n) + "A") sys.stdout.write("\033[" + str(n) + "A")
def down(self, n=1): def down(self, n=1):
sys.stdout.write("\033[" + str(n) + "B") sys.stdout.write("\033[" + str(n) + "B")
def right(self, n=1): def right(self, n=1):
sys.stdout.write("\033[" + str(n) + "C") sys.stdout.write("\033[" + str(n) + "C")
def left(self, n=1): def left(self, n=1):
sys.stdout.write("\033[" + str(n) + "D") sys.stdout.write("\033[" + str(n) + "D")
def up_line(self, n=1): def up_line(self, n=1):
sys.stdout.write("\033[" + str(n) + "F") sys.stdout.write("\033[" + str(n) + "F")
def down_line(self, n=1): def down_line(self, n=1):
sys.stdout.write("\033[" + str(n) + "E") sys.stdout.write("\033[" + str(n) + "E")
def save(self): def save(self):
""" Save cursor position """ """ Save cursor position """
sys.stdout.write("\033[s") sys.stdout.write("\033[s")
def restore(self): def restore(self):
""" Restore cursor position """ """ Restore cursor position """
sys.stdout.write("\033[u") sys.stdout.write("\033[u")
@@ -90,15 +140,17 @@ class code:
for i, c in enumerate(self.color_keys): for i, c in enumerate(self.color_keys):
s = s.replace("${" + c + "}", self.color_list[i]) s = s.replace("${" + c + "}", self.color_list[i])
return self.custom_color(s) return self.custom_color(s)
def nocolor_string(self, s): def nocolor_string(self, s):
for i, c in enumerate(self.color_keys): for i, c in enumerate(self.color_keys):
s = s.replace("${" + c + "}", "") s = s.replace("${" + c + "}", "")
return self.custom_nocolor(s) return self.custom_nocolor(s)
def custom_color(self, s): def custom_color(self, s):
return self.custom_match.sub('\033[\\2',s) return self.custom_match.sub("\033[\\2", s)
def custom_nocolor(self, s): def custom_nocolor(self, s):
return self.custom_match.sub('',s) return self.custom_match.sub("", s)
def get_keys(self): def get_keys(self):
return self.color_keys return self.color_keys
@@ -142,4 +194,4 @@ ${S}=====================${Z}
C .right() Right y;xH .pos() Absolute Position C .right() Right y;xH .pos() Absolute Position
D .left() Left """ D .left() Left """
return(c.color_string(unformatted)) return c.color_string(unformatted)

View File

@@ -1,36 +1,31 @@
#!/usr/bin/env python #!/usr/bin/env python3
import sys, os import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
import ansicodes import ansicodes
from argparse import ArgumentParser from argparse import ArgumentParser
def setup_options(): def setup_options():
parser = ArgumentParser() parser = ArgumentParser()
parser.add_argument( parser.add_argument("-v", default=False, action="store_true")
"-v",
default = False,
action = "store_true"
)
parser.add_argument( parser.add_argument(
"cs", "cs",
type=str, type=str,
default="cp437", default="cp437",
nargs = '?', nargs="?",
help = "Character set to show, ex. ascii, cp437, cp850, cp1250, latin1 ..." help="Character set to show, ex. ascii, cp437, cp850, cp1250, latin1 ...",
) )
opts = parser.parse_args() opts = parser.parse_args()
return opts return opts
def long_format(table): def long_format(table):
bc = ansicodes.code() bc = ansicodes.code()
for x, col in enumerate(table): for x, col in enumerate(table):
for y, row in enumerate(col): for y, row in enumerate(col):
bc.posprint( bc.posprint(
y + 2, y + 2, 1 + x * 7, bc.color_string("${c}%03d: ${G}%s${Z}" % (row))
1 + x*7,
bc.color_string(
"${c}%03d: ${G}%s${Z}"%( row )
)
) )
@@ -38,22 +33,18 @@ def short_format(table):
bc = ansicodes.code() bc = ansicodes.code()
for x, col in enumerate(table): for x, col in enumerate(table):
for y, row in enumerate(col): for y, row in enumerate(col):
bc.posprint( bc.posprint(x + 3, y * 2 + 1, bc.color_string("${G}%s${Z}" % (row[1],)))
x + 3, print("")
y * 2 + 1,
bc.color_string(
"${G}%s${Z}"%( row[1], )
)
)
print('')
if __name__ == "__main__": if __name__ == "__main__":
opts = setup_options() opts = setup_options()
table = [[] for x in range(8)] table = [[] for x in range(8)]
for c in range(0, 256): for c in range(0, 256):
col = c/32 col = int(c / 32)
table[col].append((c,chr(c).decode(opts.cs,'ignore').encode('utf-8','ignore'))) table[col].append(
(c, chr(c))
)
# sys.stdout.write(chr(c).decode('latin1')) # sys.stdout.write(chr(c).decode('latin1'))
# remove control chars # remove control chars
table.pop(0) table.pop(0)
@@ -68,5 +59,4 @@ if __name__ == "__main__":
long_format(table) long_format(table)
else: else:
short_format(table) short_format(table)
print('') print("")

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python3
import sys import sys
import os import os
import pwd import pwd
@@ -6,13 +6,15 @@ from argparse import ArgumentParser
MINSIZE = 0 MINSIZE = 0
def setup_options(): def setup_options():
parser = ArgumentParser(description="List file usage") parser = ArgumentParser(description="List file usage")
parser.add_argument('startpath', action="append", nargs='+') parser.add_argument("startpath", action="append", nargs="+")
options = parser.parse_args() options = parser.parse_args()
return options return options
def add_recurse(db, options, start): def add_recurse(db, options, start):
for path, dirs, files in os.walk(start, followlinks=False): for path, dirs, files in os.walk(start, followlinks=False):
files = clean_syms(files, path) files = clean_syms(files, path)
@@ -26,6 +28,7 @@ def add_recurse(db,options,start):
db[owner] += size db[owner] += size
return db return db
def clean_syms(files, path): def clean_syms(files, path):
nonsyms = [] nonsyms = []
for f in files: for f in files:
@@ -33,6 +36,7 @@ def clean_syms(files,path):
nonsyms.append(f) nonsyms.append(f)
return nonsyms return nonsyms
def print_db(db): def print_db(db):
namedb = dict() namedb = dict()
for u in db: for u in db:
@@ -40,15 +44,16 @@ def print_db(db):
namedb[pwd.getpwuid(u).pw_name] = humanize_size(db[u]) namedb[pwd.getpwuid(u).pw_name] = humanize_size(db[u])
except: except:
namedb[str(u)] = humanize_size(db[u]) namedb[str(u)] = humanize_size(db[u])
names=namedb.keys() names = list(namedb.keys())
names.sort() names.sort()
for n in names: for n in names:
print(n + ": " + namedb[n]) print(n + ": " + namedb[n])
def humanize_size(size, precision=1): def humanize_size(size, precision=1):
if size == None: if size == None:
return 'nan' return "nan"
suffixes=['B','KB','MB','GB','TB'] suffixes = ["B", "KB", "MB", "GB", "TB"]
suffixIndex = 0 suffixIndex = 0
defPrecision = 0 defPrecision = 0
while size > 1024: while size > 1024:
@@ -57,13 +62,14 @@ def humanize_size(size,precision=1):
defPrecision = precision defPrecision = precision
return "%.*f%s" % (defPrecision, size, suffixes[suffixIndex]) return "%.*f%s" % (defPrecision, size, suffixes[suffixIndex])
def main(): def main():
options=setup_options(); options = setup_options()
db = dict() db = dict()
for f in options.startpath[0]: for f in options.startpath[0]:
db = add_recurse(db, options, f) db = add_recurse(db, options, f)
print_db(db) print_db(db)
sys.exit(0) sys.exit(0)
main()
main()

View File

@@ -17,7 +17,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
'''Markslider: a slideshow engine based on markdown.''' """Markslider: a slideshow engine based on markdown."""
__author__ = "Ville Rantanen <ville.q.rantanen@gmail.com>" __author__ = "Ville Rantanen <ville.q.rantanen@gmail.com>"
__version__ = "1.3" __version__ = "1.3"
@@ -25,12 +25,14 @@ __version__ = "1.3"
import sys, os, argparse, re, datetime import sys, os, argparse, re, datetime
from argparse import ArgumentParser 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__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
import ansicodes, md_color import ansicodes, md_color
HL = ">" HL = ">"
EOS = "# End of Slides" EOS = "# End of Slides"
class getch: class getch:
def get(self): def get(self):
fd = sys.stdin.fileno() fd = sys.stdin.fileno()
@@ -44,11 +46,14 @@ class getch:
class EndProgram(Exception): class EndProgram(Exception):
''' Nice exit ''' """ Nice exit """
pass pass
class slide_reader: class slide_reader:
""" Class for reading files. """ """ Class for reading files. """
def __init__(self, files, opts): def __init__(self, files, opts):
self.filename = files[0] self.filename = files[0]
self.files = files self.files = files
@@ -71,16 +76,12 @@ class slide_reader:
self.pygments = False self.pygments = False
if opts.syntax_pygments: if opts.syntax_pygments:
try: try:
self.pygments = Pygmentizer( self.pygments = Pygmentizer(opts.syntax_formatter, opts.syntax_style)
opts.syntax_formatter,
opts.syntax_style
)
except ImportError as e: except ImportError as e:
self.pygments = False self.pygments = False
def read(self): def read(self):
''' Read a file, set pages and data ''' """ Read a file, set pages and data """
self.pages = 0 self.pages = 0
self.background = [] self.background = []
@@ -89,7 +90,7 @@ class slide_reader:
first_slide_found = False first_slide_found = False
for fname in self.files: for fname in self.files:
first_slide_found = False first_slide_found = False
f=open(fname,'r') f = open(fname, "r")
new_page = [] new_page = []
in_code = False in_code = False
for row in f: for row in f:
@@ -131,11 +132,13 @@ class slide_reader:
def get_data(self): def get_data(self):
return self.data return self.data
def get_current_filename(self): def get_current_filename(self):
for i, offset in enumerate(self.file_start_page): for i, offset in enumerate(self.file_start_page):
if offset > self.page: if offset > self.page:
return self.files[i] return self.files[i]
return "NA" return "NA"
def get_filename(self): def get_filename(self):
return self.filename return self.filename
@@ -153,6 +156,7 @@ class slide_reader:
def get_page_no(self): def get_page_no(self):
return self.page return self.page
def inc_page_no(self, inc=1, loop=False): def inc_page_no(self, inc=1, loop=False):
self.page += inc self.page += inc
if self.page < 0: if self.page < 0:
@@ -165,16 +169,22 @@ class slide_reader:
self.page = 0 self.page = 0
self.width = max([len(x) for x in self.data[self.page]]) self.width = max([len(x) for x in self.data[self.page]])
self.height = len(self.data[self.page]) self.height = len(self.data[self.page])
def last_page(self): def last_page(self):
self.page = self.pages - 1 self.page = self.pages - 1
def first_page(self): def first_page(self):
self.page = 0 self.page = 0
def get_page_height(self): def get_page_height(self):
return self.height return self.height
def get_page_width(self): def get_page_width(self):
return self.width return self.width
def get_max_height(self): def get_max_height(self):
return self.max_height return self.max_height
def get_max_width(self): def get_max_width(self):
return self.max_width return self.max_width
@@ -194,14 +204,21 @@ class slide_reader:
if re.search("^##[^#]", line): if re.search("^##[^#]", line):
subh = [subh[0] + 1, 0, 0] subh = [subh[0] + 1, 0, 0]
TOC.append(" %d.%d. %s" % (h1 + 1, subh[0], title)) TOC.append(" %d.%d. %s" % (h1 + 1, subh[0], title))
if self.opts.toc_depth==2: continue if self.opts.toc_depth == 2:
continue
if re.search("^###[^#]", line): if re.search("^###[^#]", line):
subh = [subh[0], subh[1] + 1, 0] subh = [subh[0], subh[1] + 1, 0]
TOC.append(" %d.%d.%d. %s"%(h1+1,subh[0],subh[1],title)) TOC.append(
if self.opts.toc_depth==3: continue " %d.%d.%d. %s" % (h1 + 1, subh[0], subh[1], title)
)
if self.opts.toc_depth == 3:
continue
if re.search("^####[^#]", line): if re.search("^####[^#]", line):
subh = [subh[0], subh[1], subh[2] + 1] subh = [subh[0], subh[1], subh[2] + 1]
TOC.append(" %d.%d.%d.%d. %s"%(h1+1,subh[0],subh[1],subh[2],title)) TOC.append(
" %d.%d.%d.%d. %s"
% (h1 + 1, subh[0], subh[1], subh[2], title)
)
return TOC return TOC
def toc(self): def toc(self):
@@ -227,18 +244,17 @@ class slide_reader:
"""Launch in a string using tags `command`> """Launch in a string using tags `command`>
Remove empty lines from beginning and end of stdout. Remove empty lines from beginning and end of stdout.
""" """
output = subprocess.check_output( output = subprocess.check_output(command.group(2).strip(), shell=True)
command.group(2).strip(),
shell = True
)
if type(output) == bytes: if type(output) == bytes:
output = output.decode('utf-8') output = output.decode("utf-8")
output = output.split("\n") output = output.split("\n")
while len(output[0].strip()) == 0: while len(output[0].strip()) == 0:
if len(output)==1: return [""] if len(output) == 1:
return [""]
del output[0] del output[0]
while len(output[-1].strip()) == 0: while len(output[-1].strip()) == 0:
if len(output)==1: return [""] if len(output) == 1:
return [""]
del output[-1] del output[-1]
return_value = [command.group(1)] return_value = [command.group(1)]
return_value.extend(output) return_value.extend(output)
@@ -254,16 +270,18 @@ class slide_reader:
# ~ 3=image command # ~ 3=image command
output = subprocess.check_output( output = subprocess.check_output(
"convert %s JPEG:- | jp2a --colors --width=70 -" % (image.group(3),), "convert %s JPEG:- | jp2a --colors --width=70 -" % (image.group(3),),
shell=True shell=True,
) )
if type(output) == bytes: if type(output) == bytes:
output = output.decode('utf-8') output = output.decode("utf-8")
output = output.split("\n") output = output.split("\n")
while len(output[0].strip()) == 0: while len(output[0].strip()) == 0:
if len(output)==1: return [""] if len(output) == 1:
return [""]
del output[0] del output[0]
while len(output[-1].strip()) == 0: while len(output[-1].strip()) == 0:
if len(output)==1: return [""] if len(output) == 1:
return [""]
del output[-1] del output[-1]
return_value = [image.group(1)] return_value = [image.group(1)]
return_value.extend(output) return_value.extend(output)
@@ -288,12 +306,14 @@ class slide_reader:
if titles[page[0]] > 1: if titles[page[0]] > 1:
page[0] += " [%d/%d]" % (page_no, titles[page[0]]) page[0] += " [%d/%d]" % (page_no, titles[page[0]])
class Pygmentizer():
class Pygmentizer:
def __init__(self, formatter, style): def __init__(self, formatter, style):
import pygments import pygments
import pygments.lexers import pygments.lexers
import pygments.formatters import pygments.formatters
import pygments.styles import pygments.styles
self.pygments = pygments self.pygments = pygments
self.lexers = pygments.lexers self.lexers = pygments.lexers
self.formatters = pygments.formatters self.formatters = pygments.formatters
@@ -301,12 +321,10 @@ class Pygmentizer():
self.style = self.styles.get_style_by_name(style) self.style = self.styles.get_style_by_name(style)
self.formatter = self.formatters.get_formatter_by_name( self.formatter = self.formatters.get_formatter_by_name(
formatter, formatter, style=self.style
style = self.style
) )
self.lexer = None self.lexer = None
def format(self, code): def format(self, code):
in_block = False in_block = False
blocks = [] blocks = []
@@ -318,11 +336,7 @@ class Pygmentizer():
if len(lexer_name) == 0: if len(lexer_name) == 0:
in_block = False in_block = False
if in_block: if in_block:
blocks.append({ blocks.append({"lexer": lexer_name, "code": [], "rows": []})
"lexer": lexer_name,
"code": [],
"rows": []
})
current_block += 1 current_block += 1
else: else:
if in_block: if in_block:
@@ -343,7 +357,7 @@ class Pygmentizer():
def get_interactive_help_text(): def get_interactive_help_text():
return ''' left/right,page up/down,home,end return """ left/right,page up/down,home,end
change page change page
c list contents (toc) c list contents (toc)
M modify file with VIM M modify file with VIM
@@ -354,11 +368,13 @@ def get_interactive_help_text():
,/. scroll page ,/. scroll page
up/down move highlight up/down move highlight
enter execute highlighted line enter execute highlighted line
h help''' h help"""
def setup_options(): def setup_options():
''' Create command line options ''' """ Create command line options """
usage=''' usage = (
"""
MarkSlider: a markdown based slideshow engine MarkSlider: a markdown based slideshow engine
Special syntaxes: Special syntaxes:
* Colors: insert string ${C}, where C is one of KRGBYMCWkrgbymcwSUZ * Colors: insert string ${C}, where C is one of KRGBYMCWkrgbymcwSUZ
@@ -369,67 +385,171 @@ Special syntaxes:
* Convert images to ASCII, with jp2a: ![](file.jpg)> * Convert images to ASCII, with jp2a: ![](file.jpg)>
Keyboard shortcuts: Keyboard shortcuts:
'''+get_interactive_help_text() """
+ get_interactive_help_text()
)
parser=ArgumentParser(description=usage, parser = ArgumentParser(
description=usage,
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=__author__) epilog=__author__,
)
parser.add_argument("-v", "--version", action="version", version=__version__) parser.add_argument("-v", "--version", action="version", version=__version__)
parser.add_argument("--export",action="store",dest="screenshots",default=False, parser.add_argument(
type=str, help="Take screenshots of the slideshow in the given folder.") "--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') content = parser.add_argument_group("content")
execution = parser.add_argument_group('execution') execution = parser.add_argument_group("execution")
control = parser.add_argument_group('controls') control = parser.add_argument_group("controls")
content.add_argument("--background",action="store_true",dest="background",default = False, content.add_argument(
help="Use the rows before the first # header as slide background") "--background",
content.add_argument("--center",action="store_true",dest="center",default=False, action="store_true",
help="Center slides on screen.") dest="background",
content.add_argument("--dc",action="store_true",dest="dark_colors",default=False, default=False,
help="Use dark colorscheme, better for white background terminals.") help="Use the rows before the first # header as slide background",
content.add_argument("-m",action="store_false",dest="autocolor",default=True, )
help="Disable color by markdown structure.") content.add_argument(
content.add_argument("--no-color","-n",action="store_false",dest="color",default=True, "--center",
help="Disable color.") action="store_true",
content.add_argument("--no-rename","--nr",action="store_false",dest="rename_title", default=True, dest="center",
help="Disable automatic renaming of duplicate titles.") default=False,
content.add_argument("--toc",action="store",dest="toc",default=False, help="Center slides on screen.",
const="Table of Contents", type=str, nargs='?', )
help="Insert table of contents. Define the header, or use default: %(const)s") content.add_argument(
content.add_argument("--toc-page",action="store",dest="toc_page",default=2, type=int, "--dc",
help="Insert table of contents on a chosen page. default: %(const)s") action="store_true",
content.add_argument("--toc-depth",action="store",dest="toc_depth",default=2, type=int, 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)), choices=list(range(1, 5)),
help="Table of contents display depth. default: %(const)s") help="Table of contents display depth. default: %(const)s",
)
content.add_argument("--no-pygments",action="store_false",dest="syntax_pygments",default = True, content.add_argument(
help="Disable autocoloring syntax with Pygments. Used only for ``` code blocks, if language is mentioned, ex.: ```python . Note! Do not have empty lines after ```") "--no-pygments",
content.add_argument("--syntax-formatter",action="store",dest="syntax_formatter",default = "terminal256", action="store_false",
choices=['terminal', 'terminal256', 'terminal16m'], dest="syntax_pygments",
help="Syntax highlighter formatter. default: %(default)s") default=True,
content.add_argument("--syntax-style",action="store",dest="syntax_style",default = "monokai", help="Disable autocoloring syntax with Pygments. Used only for ``` code blocks, if language is mentioned, ex.: ```python . Note! Do not have empty lines after ```",
help="Syntax highlighter style, see Pygments styles. default: %(default)s") )
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, control.add_argument(
help="Execute commands in `! or `> tags at show time with Enter key. WARNING: Potentially very dangerous to run others' slides with this switch!") "--exit",
execution.add_argument("-E",action="store_true",dest="execute_read",default=False, action="store_true",
help="Execute commands in ``> tags at file read time. WARNING: Potentially very dangerous to run others' slides with this switch!") dest="exit_last",
default=False,
help="Exit after last slide.",
)
control.add_argument("--exit",action="store_true",dest="exit_last",default=False, control.add_argument(
help="Exit after last slide.") "-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, parser.add_argument("files", type=str, nargs="+", help="File(s) to show")
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 = parser.parse_args()
opts.slideShow = not not opts.slideTimer opts.slideShow = not not opts.slideTimer
if opts.screenshots: if opts.screenshots:
@@ -440,7 +560,7 @@ Keyboard shortcuts:
def page_print(reader, opts, offset): def page_print(reader, opts, offset):
''' Print a page ''' """ Print a page """
page = reader.get_current_page() page = reader.get_current_page()
scrsize = opts.size scrsize = opts.size
@@ -459,23 +579,21 @@ def page_print(reader,opts,offset):
coloring = "${b}${U}" coloring = "${b}${U}"
else: else:
coloring = "${U}${Y}" coloring = "${U}${Y}"
print( print(align_pad + colorify(coloring + page[0], opts) + bc.Z)
align_pad +
colorify(
coloring + page[0],
opts) +
bc.Z
)
if opts.background: if opts.background:
bc.save() bc.save()
if opts.color: 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: 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() bc.restore()
if (sys.version_info < (3, 0)): if sys.version_info < (3, 0):
# python2 magic # python2 magic
page = [row.decode('utf-8') for row in page] page = [row.decode("utf-8") for row in page]
# Print page rows # Print page rows
if not opts.wrap: 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]
@@ -495,13 +613,9 @@ def page_print(reader,opts,offset):
) )
for row_i in preformatted_rows: for row_i in preformatted_rows:
parsed[row_i][0] = 'preformatted' parsed[row_i][0] = "preformatted"
parsed[row_i][1] = preformatted[row_i] parsed[row_i][1] = preformatted[row_i]
colored = md_color.colorize( colored = md_color.colorize(parsed, not opts.color, opts.dark_colors)
parsed,
not opts.color,
opts.dark_colors
)
else: else:
if opts.color: if opts.color:
colored = [bc.color_string(row[1]) for row in parsed] colored = [bc.color_string(row[1]) for row in parsed]
@@ -509,8 +623,10 @@ def page_print(reader,opts,offset):
colored = [bc.nocolor_string(row[1]) for row in parsed] colored = [bc.nocolor_string(row[1]) for row in parsed]
r = 0 r = 0
for row_i in range(len(page)): for row_i in range(len(page)):
if row_i == 0: continue if row_i == 0:
if row_i < offset[0]: continue continue
if row_i < offset[0]:
continue
row = page[row_i] row = page[row_i]
# page[1+offset[0]:]: # page[1+offset[0]:]:
if opts.wrap: if opts.wrap:
@@ -533,13 +649,20 @@ def page_print(reader,opts,offset):
def print_menu(reader, opts): def print_menu(reader, opts):
bc.posprint( opts.size[0], 0, bc.posprint(
colorify("${y}%d${Z}/%d %s|%s"%( opts.size[0],
0,
colorify(
"${y}%d${Z}/%d %s|%s"
% (
1 + reader.get_page_no(), 1 + reader.get_page_no(),
reader.get_pages(), reader.get_pages(),
os.path.basename(reader.get_current_filename()), os.path.basename(reader.get_current_filename()),
"slideshow" if opts.slideShow else ""), "slideshow" if opts.slideShow else "",
opts)) ),
opts,
),
)
def print_time(opts): def print_time(opts):
@@ -547,22 +670,22 @@ def print_time(opts):
bc.posprint( bc.posprint(
opts.size[0], opts.size[0],
opts.size[1] - 5, opts.size[1] - 5,
colorify( colorify("%02d:%02d" % (now.hour, now.minute), opts),
"%02d:%02d"%(
now.hour,
now.minute
),
opts
)
) )
def print_help(reader, opts): def print_help(reader, opts):
''' Create a window with help message ''' """ Create a window with help message """
helptext=get_interactive_help_text().split('\n') helptext = get_interactive_help_text().split("\n")
maxlen = max([len(x) for x in helptext]) maxlen = max([len(x) for x in helptext])
bc.posprint(3, 5, " +" + "-" * maxlen + "+ ") bc.posprint(3, 5, " +" + "-" * maxlen + "+ ")
bc.posprint(4,5,colorify(" |${U}${Y}"+("{:^"+str(maxlen)+"}").format("Help")+"${Z}| ",opts)) bc.posprint(
4,
5,
colorify(
" |${U}${Y}" + ("{:^" + str(maxlen) + "}").format("Help") + "${Z}| ", opts
),
)
for y, row in enumerate(helptext): for y, row in enumerate(helptext):
bc.posprint(5 + y, 5, (" |{:<" + str(maxlen) + "}| ").format(row)) bc.posprint(5 + y, 5, (" |{:<" + str(maxlen) + "}| ").format(row))
bc.posprint(6 + y, 5, " +" + "-" * maxlen + "+ ") bc.posprint(6 + y, 5, " +" + "-" * maxlen + "+ ")
@@ -571,7 +694,7 @@ def print_help(reader,opts):
def print_toc(reader, opts): def print_toc(reader, opts):
''' Create a window with TOC ''' """ Create a window with TOC """
text = reader.get_toc(display_position=True) text = reader.get_toc(display_position=True)
title = opts.toc if opts.toc else "Table of Contents" title = opts.toc if opts.toc else "Table of Contents"
maxlen = max([len(x) for x in text]) maxlen = max([len(x) for x in text])
@@ -594,7 +717,7 @@ def print_toc(reader,opts):
def offset_change(opts, reader, offset, new_offset): def offset_change(opts, reader, offset, new_offset):
''' Change the display position of page ''' """ Change the display position of page """
new_offset = (offset[0] + new_offset[0], offset[1] + new_offset[1]) new_offset = (offset[0] + new_offset[0], offset[1] + new_offset[1])
offsety = min(reader.get_page_height() - 1, new_offset[0]) offsety = min(reader.get_page_height() - 1, new_offset[0])
offseth = min(reader.get_page_height(), new_offset[1]) offseth = min(reader.get_page_height(), new_offset[1])
@@ -614,7 +737,7 @@ def getkeypress():
def browser(opts, files): def browser(opts, files):
''' Main function for printing ''' """ Main function for printing """
try: try:
reader = slide_reader(files, opts) reader = slide_reader(files, opts)
@@ -675,24 +798,24 @@ def browser(opts,files):
if inkey == 70 or inkey == 52: # END if inkey == 70 or inkey == 52: # END
reader.last_page() reader.last_page()
offset = (0, 0) offset = (0, 0)
if inkey==ord('c'): if inkey == ord("c"):
print_toc(reader, opts) print_toc(reader, opts)
if inkey==ord('h'): if inkey == ord("h"):
print_help(reader, opts) print_help(reader, opts)
if inkey==ord('s'): if inkey == ord("s"):
opts.menu = not opts.menu opts.menu = not opts.menu
if inkey==ord('t'): if inkey == ord("t"):
opts.slideShow = not opts.slideShow opts.slideShow = not opts.slideShow
if inkey==ord('r'): if inkey == ord("r"):
reader.read() reader.read()
offset = offset_change(opts, reader, offset, (0, 0)) offset = offset_change(opts, reader, offset, (0, 0))
if inkey==ord('M'): if inkey == ord("M"):
modify_file(reader, offset) modify_file(reader, offset)
reader.read() reader.read()
offset = offset_change(opts, reader, offset, (0, 0)) offset = offset_change(opts, reader, offset, (0, 0))
if inkey==ord(','): if inkey == ord(","):
offset = offset_change(opts, reader, offset, (-1, 0)) offset = offset_change(opts, reader, offset, (-1, 0))
if inkey==ord('.'): if inkey == ord("."):
offset = offset_change(opts, reader, offset, (1, 0)) offset = offset_change(opts, reader, offset, (1, 0))
if inkey == 65: # up if inkey == 65: # up
offset = offset_change(opts, reader, offset, (0, -1)) offset = offset_change(opts, reader, offset, (0, -1))
@@ -702,7 +825,6 @@ def browser(opts,files):
launch(reader, opts, offset) launch(reader, opts, offset)
break break
except IOError: except IOError:
pass pass
except KeyboardInterrupt: except KeyboardInterrupt:
@@ -716,7 +838,7 @@ def browser(opts,files):
def get_console_size(): def get_console_size():
rows, columns = os.popen('stty size', 'r').read().split() rows, columns = os.popen("stty size", "r").read().split()
return (int(rows), int(columns)) return (int(rows), int(columns))
@@ -731,10 +853,7 @@ def colorify(s,opts):
def cut_line(s, i): def cut_line(s, i):
""" cut a color tagged string, and remove control chars """ """ cut a color tagged string, and remove control chars """
s = s[:i] s = s[:i]
s=re.sub("\$$","", s = re.sub("\$$", "", re.sub("\$\{$", "", re.sub("\$\{.$", "", s)))
re.sub("\$\{$","",
re.sub("\$\{.$","",
s)))
return s return s
@@ -754,16 +873,15 @@ def launch(reader,opts,offset):
Detects URLS and markdown images ![Alt text](/path/to/img.jpg) Detects URLS and markdown images ![Alt text](/path/to/img.jpg)
""" """
if not opts.execute: if not opts.execute:
bc.posprint( bc.posprint(offset[1] - offset[0] + 1, 0, "Execution not enabled!")
offset[1]-offset[0]+1,
0,
"Execution not enabled!"
)
inkey = getch.get() inkey = getch.get()
return return
s = reader.get_current_page()[offset[1]] 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) urls = re.findall(
images = re.findall('!\[[^]]+\]\([^\)]+\)', s) "http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+",
s,
)
images = re.findall("!\[[^]]+\]\([^\)]+\)", s)
# sanity check # sanity check
if s.find("`") == -1 and len(urls) == 0 and len(images) == 0: if s.find("`") == -1 and len(urls) == 0 and len(images) == 0:
return return
@@ -771,56 +889,53 @@ def launch(reader,opts,offset):
run_command = re.match("(.*)`(.*)`!(.*)", s) run_command = re.match("(.*)`(.*)`!(.*)", s)
show_command = re.match("(.*)`(.*)`>(.*)", s) show_command = re.match("(.*)`(.*)`>(.*)", s)
if show_command != None: if show_command != None:
output = subprocess.check_output( output = subprocess.check_output(show_command.group(2).strip(), shell=True)
show_command.group(2).strip(),
shell = True
)
if type(output) == bytes: if type(output) == bytes:
output = output.decode('utf-8') output = output.decode("utf-8")
output = output.split("\n") output = output.split("\n")
while len(output[0].strip()) == 0: while len(output[0].strip()) == 0:
if len(output)==1: return if len(output) == 1:
return
del output[0] del output[0]
while len(output[-1].strip()) == 0: while len(output[-1].strip()) == 0:
if len(output)==1: return if len(output) == 1:
return
del output[-1] del output[-1]
for y, l in enumerate(output): for y, l in enumerate(output):
bc.posprint(y+offset[1]-offset[0]+2,0,' '*len(l)) bc.posprint(y + offset[1] - offset[0] + 2, 0, " " * len(l))
bc.clear_to_end() bc.clear_to_end()
bc.posprint(y + offset[1] - offset[0] + 2, 0, l) bc.posprint(y + offset[1] - offset[0] + 2, 0, l)
inkey = getch.get() inkey = getch.get()
return return
if run_command != None: if run_command != None:
subprocess.call( subprocess.call(run_command.group(2), shell=True, executable="/bin/bash")
run_command.group(2),
shell = True,
executable = "/bin/bash"
)
inkey = getch.get() inkey = getch.get()
return return
# Open URLS last # Open URLS last
if len(urls) > 0: if len(urls) > 0:
# Remove ) at the end of url: [name](link) markdown syntax # Remove ) at the end of url: [name](link) markdown syntax
subprocess.call( subprocess.call(
"%s '%s' &"%( "%s '%s' &"
% (
get_open_command(), get_open_command(),
urls[0].rstrip(")"), urls[0].rstrip(")"),
), ),
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, stderr=subprocess.PIPE,
shell = True shell=True,
) )
return return
if len(images) > 0: if len(images) > 0:
image = re.sub('.*\(([^\)]+)\).*', "\\1",images[0]) image = re.sub(".*\(([^\)]+)\).*", "\\1", images[0])
subprocess.call( subprocess.call(
"%s '%s' &"%( "%s '%s' &"
% (
get_open_command(), get_open_command(),
image, image,
), ),
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, stderr=subprocess.PIPE,
shell = True shell=True,
) )
return return
return return
@@ -836,30 +951,21 @@ def modify_file(reader,offset):
if (page + 1) in row_restarts: if (page + 1) in row_restarts:
row = 1 row = 1
subprocess.call( subprocess.call(
"vim +%d -c 'exe \"normal! zt\"' -c %d %s"%( "vim +%d -c 'exe \"normal! zt\"' -c %d %s"
row, % (row, row + offset[1], reader.get_current_filename()),
row + offset[1], shell=True,
reader.get_current_filename()
),
shell = True
) )
def take_screenshot(reader, opts): def take_screenshot(reader, opts):
out_file = os.path.join( out_file = os.path.join(opts.screenshots, "slide%03d.png" % (reader.page + 1,))
opts.screenshots,
"slide%03d.png"%(reader.page + 1,)
)
if not os.path.exists(opts.screenshots): if not os.path.exists(opts.screenshots):
os.mkdir(opts.screenshots) os.mkdir(opts.screenshots)
subprocess.call( subprocess.call(
"sleep 0.5; import -window %s '%s'"%( "sleep 0.5; import -window %s '%s'" % (opts.xwinid, out_file),
opts.xwinid,
out_file
),
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, stderr=subprocess.PIPE,
shell = True shell=True,
) )
@@ -879,29 +985,26 @@ def main():
opts = setup_options() opts = setup_options()
if opts.screenshots: if opts.screenshots:
print("Click the terminal window to read window ID") print("Click the terminal window to read window ID")
xwininfo = subprocess.check_output( xwininfo = subprocess.check_output("xwininfo", shell=True)
"xwininfo",
shell = True
)
if type(xwininfo) == bytes: if type(xwininfo) == bytes:
xwininfo = xwininfo.decode('utf-8') xwininfo = xwininfo.decode("utf-8")
xwininfo = re.search(r"Window id: (0x[0-9]+)", xwininfo) xwininfo = re.search(r"Window id: (0x[0-9]+)", xwininfo)
if xwininfo: if xwininfo:
opts.xwinid = xwininfo.group(1) opts.xwinid = xwininfo.group(1)
else: else:
print("Cannot parse window ID") print("Cannot parse window ID")
sys.exit(1) sys.exit(1)
browser( browser(opts, opts.files)
opts,
opts.files
)
print("\n\n") print("\n\n")
if opts.screenshots: 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,
opts.screenshots, opts.screenshots,
os.path.basename(opts.screenshots), os.path.basename(opts.screenshots),
)) )
)
if __name__ == "__main__": if __name__ == "__main__":

Binary file not shown.

View File

@@ -1,56 +1,96 @@
#!/usr/bin/env python #!/usr/bin/env python3
import sys, os, re import sys, os, re
from argparse import ArgumentParser, RawDescriptionHelpFormatter from argparse import ArgumentParser, RawDescriptionHelpFormatter
sys.path.append(os.path.dirname(os.path.realpath(__file__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
import ansicodes as ansi import ansicodes as ansi
__author__ = "Ville Rantanen <ville.q.rantanen@gmail.com>" __author__ = "Ville Rantanen <ville.q.rantanen@gmail.com>"
__version__ = "0.3" __version__ = "0.3"
''' Rules modified from mistune project ''' """ Rules modified from mistune project """
def setup_options(): def setup_options():
bc = ansi.code() bc = ansi.code()
''' Create command line options ''' """ Create command line options """
usage = ''' usage = (
"""
Markdown syntax color in ansi codes. Markdown syntax color in ansi codes.
Special syntaxes: Special syntaxes:
- Colors: insert string e.g. ${C}. - Colors: insert string e.g. ${C}.
- Any ANSI control code: ${3A}, ${1;34;42m}, see the table.. - Any ANSI control code: ${3A}, ${1;34;42m}, see the table..
''' + ansi.demo() """
+ ansi.demo()
)
parser = ArgumentParser( parser = ArgumentParser(
formatter_class=RawDescriptionHelpFormatter, formatter_class=RawDescriptionHelpFormatter,
description=usage, description=usage,
epilog = __author__ epilog=__author__,
) )
parser.add_argument("-v", "--version", action="version", version=__version__) parser.add_argument("-v", "--version", action="version", version=__version__)
parser.add_argument("-D",action="store_true",dest="debug",default=False, parser.add_argument(
help="Debug mode") "-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(
parser.add_argument("--no-color","-n",action="store_false",dest="color",default=True, "--dc",
help="Disable color.") action="store_true",
parser.add_argument("--print-template",action="store_true",dest="print_template",default=False, dest="dark_colors",
help="Print customizable color template.") default=False,
parser.add_argument("--template",action="store",type=str,dest="template",default=None, help="Use dark colorscheme, better for white background terminals.",
help="Use a custom template file for colorization.") )
parser.add_argument("-z",action="store_true",dest="zero",default=False, parser.add_argument(
help="Reset coloring at the end of each line.") "--no-color",
parser.add_argument("-Z",action="store_false",dest="zero_final",default=True, "-n",
help="Disable reset of colors at the end of file.") action="store_false",
parser.add_argument("filename",type=str, nargs='?', dest="color",
help="File to show, - for stdin") 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() opts = parser.parse_args()
return opts return opts
def parse(data): def parse(data):
data = [[None, row] for row in data] data = [[None, row] for row in data]
block='text' block = "text"
new_block='text' new_block = "text"
multiline_block = False multiline_block = False
# Parse styles # Parse styles
for i, line in enumerate(data): for i, line in enumerate(data):
@@ -59,9 +99,9 @@ def parse(data):
# Previous lines have set the style already # Previous lines have set the style already
continue continue
for match in blocks: for match in blocks:
if block_match[match]['re'].match(row): if block_match[match]["re"].match(row):
new_block = match new_block = match
if match.startswith('multiline'): if match.startswith("multiline"):
if multiline_block: if multiline_block:
multiline_block = False multiline_block = False
else: else:
@@ -70,12 +110,14 @@ def parse(data):
if multiline_block: if multiline_block:
new_block = multiline_block new_block = multiline_block
# Lists must end with empty line # Lists must end with empty line
if new_block not in ('empty','list_bullet') and block.startswith('list_'): if new_block not in ("empty", "list_bullet") and block.startswith("list_"):
new_block='list_loose' new_block = "list_loose"
if 'mod' in block_match[match]: if "mod" in block_match[match]:
# Style sets block in previous or next lines # Style sets block in previous or next lines
data[i+block_match[match]['mod']['pos']][0]=block_match[match]['mod']['name'] data[i + block_match[match]["mod"]["pos"]][0] = block_match[match]["mod"][
"name"
]
data[i][0] = new_block data[i][0] = new_block
if new_block != block: if new_block != block:
block = new_block block = new_block
@@ -86,23 +128,22 @@ def colorize(data, remove_colors = False, dark_colors = False, debug = False):
# Start inserting colors, and printing # Start inserting colors, and printing
bc = ansi.code() bc = ansi.code()
colorized = [] colorized = []
cs = 'dc' if dark_colors else 'bc' cs = "dc" if dark_colors else "bc"
csc = cs + 'c' csc = cs + "c"
for i, line in enumerate(data): for i, line in enumerate(data):
row = line[1] row = line[1]
block = line[0] block = line[0]
multiline_block = block.startswith('multiline') multiline_block = block.startswith("multiline")
if multiline_block: if multiline_block:
row = block_match[block][csc] + row row = block_match[block][csc] + row
if block_match[block][cs]: 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 # 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: for match in inlines:
if inline_match[match]['re'].search(row): if inline_match[match]["re"].search(row):
row = inline_match[match]['re'].sub( row = inline_match[match]["re"].sub(
inline_match[match][cs] + block_match[block][csc], inline_match[match][cs] + block_match[block][csc], row
row
) )
if remove_colors: if remove_colors:
colored = bc.nocolor_string(row) colored = bc.nocolor_string(row)
@@ -114,31 +155,34 @@ def colorize(data, remove_colors = False, dark_colors = False, debug = False):
colorized.append(colored) colorized.append(colored)
return colorized return colorized
def md_re_compile(d): def md_re_compile(d):
''' Returns a re.compiled dict ''' """ Returns a re.compiled dict """
n = {} n = {}
for t in d: for t in d:
n[t] = {} n[t] = {}
for i in d[t]: for i in d[t]:
n[t][i] = d[t][i] n[t][i] = d[t][i]
try: try:
if n[t]['re']: if n[t]["re"]:
n[t]['re']=re.compile(n[t]['re']) n[t]["re"] = re.compile(n[t]["re"])
except err: except err:
print("Error compiling: %s"%(n[t]['re'])) print("Error compiling: %s" % (n[t]["re"]))
sys.exit(1) sys.exit(1)
return n return n
def read_data2(fp): def read_data2(fp):
data = [] data = []
# Read data # Read data
for row in f: for row in f:
if not row: if not row:
continue continue
row = row.decode('utf-8').rstrip("\n\r ") row = row.decode("utf-8").rstrip("\n\r ")
data.append(row) data.append(row)
return data return data
def read_data3(fp): def read_data3(fp):
data = [] data = []
# Read data # Read data
@@ -149,14 +193,16 @@ def read_data3(fp):
data.append(row) data.append(row)
return data return data
def write_colored2(colored, opts): def write_colored2(colored, opts):
for c in colored: for c in colored:
sys.stdout.write(c.encode('utf-8')) sys.stdout.write(c.encode("utf-8"))
if opts.zero: if opts.zero:
sys.stdout.write(bc.Z) sys.stdout.write(bc.Z)
sys.stdout.write("\n") sys.stdout.write("\n")
if opts.zero_final: 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): def write_colored3(colored, opts):
for c in colored: for c in colored:
@@ -168,112 +214,207 @@ def write_colored3(colored, opts):
sys.stdout.write(bc.Z) sys.stdout.write(bc.Z)
# re: regular expression, bc: bright colors, bcc: continue with this color after inline # re: regular expression, bc: bright colors, bcc: continue with this color after inline
# dc: dark colors, dcc: continued color after inline # dc: dark colors, dcc: continued color after inline
block_match_str = { block_match_str = {
'block_code': {'re':'^( {4}[^*])(.*)$', "block_code": {
'bc' :'${Z}${c}\\1\\2', 'bcc':'${Z}${c}', "re": "^( {4}[^*])(.*)$",
'dc' :'${Z}${m}\\1\\2', 'dcc':'${Z}${m}'}, # code "bc": "${Z}${c}\\1\\2",
'multiline_code' : {'re':'^ *(`{3,}|~{3,}) *(\S*)', "bcc": "${Z}${c}",
'bc' :'${Z}${c}\\1\\2', 'bcc':'${Z}${c}', "dc": "${Z}${m}\\1\\2",
'dc' :'${Z}${m}\\1\\2', 'dcc':'${Z}${m}'}, # ```lang "dcc": "${Z}${m}",
'block_quote': {'re':'^(>[ >]* )', }, # code
'bc':'${K}\\1${Z}','bcc':'${Z}', "multiline_code": {
'dc':'${Y}\\1${Z}','dcc':'${Z}'}, # > > quote "re": "^ *(`{3,}|~{3,}) *(\S*)",
'hrule': {'re':'^ {0,3}[-*_]([-*_]){2,}$', "bc": "${Z}${c}\\1\\2",
'bc':'False','bcc':'${Z}', "bcc": "${Z}${c}",
'dc':'False','dcc':'${Z}'}, # ---- "dc": "${Z}${m}\\1\\2",
'heading' : {'re':'^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)', "dcc": "${Z}${m}",
'bc':'${W}\\1 ${U}\\2${Z}','bcc':'${W}${U}', }, # ```lang
'dc':'${B}\\1 ${U}\\2${Z}','dcc':'${B}${U}'}, # # heading "block_quote": {
'lheading' : {'re':'^(=+|-+)$', "re": "^(>[ >]* )",
'bc':'${W}\\1', 'bcc':'${W}', "bc": "${K}\\1${Z}",
'dc':'${B}\\1', 'dcc':'${B}', "bcc": "${Z}",
'mod':{'pos':-1,'name':'lheading.mod'}}, # ======= under header "dc": "${Y}\\1${Z}",
'lheading.mod' : {'re':'^([^\n]+)', "dcc": "${Z}",
'bc':'${W}\\1', 'bcc':'${W}', }, # > > quote
'dc':'${B}\\1', 'dcc':'${B}'}, # over the ======= under header "hrule": {
'list_bullet': {'re':'^( *)([*+-]|[\d\.]+)( +)', "re": "^ {0,3}[-*_]([-*_]){2,}$",
'bc':'\\1${y}\\2${Z}\\3','bcc':'${Z}', "bc": "False",
'dc':'\\1${r}\\2${Z}\\3','dcc':'${Z}'}, # * or 1. "bcc": "${Z}",
'list_loose': {'re':'None', "dc": "False",
'bc':'False','bcc':'${Z}', "dcc": "${Z}",
'dc':'False','dcc':'${Z}'}, }, # ----
'text': {'re':'^([^\n]+)', "heading": {
'bc':'${Z}\\1','bcc':'${Z}', "re": "^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)",
'dc':'${Z}\\1','dcc':'${Z}'}, "bc": "${W}\\1 ${U}\\2${Z}",
'empty': {'re':'(^$)', "bcc": "${W}${U}",
'bc':'${Z}\\1','bcc':'${Z}', "dc": "${B}\\1 ${U}\\2${Z}",
'dc':'${Z}\\1','dcc':'${Z}'}, "dcc": "${B}${U}",
'preformatted': {'re': 'a^', # Never matches anything }, # # heading
'bc':'','bcc':'', "lheading": {
'dc':'','dcc':''}, "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) block_match = md_re_compile(block_match_str)
blocks=['block_quote', 'multiline_code','hrule', 'heading','lheading','list_bullet', 'block_code', 'text', 'empty'] blocks = [
"block_quote",
"multiline_code",
"hrule",
"heading",
"lheading",
"list_bullet",
"block_code",
"text",
"empty",
]
inline_match_str = { inline_match_str = {
'bold1': {'re':r'(^| |})(_[^_]+_)', "bold1": {
'bc':'\\1${W}\\2','dc':'\\1${W}\\2'}, # _bold_ "re": r"(^| |})(_[^_]+_)",
'bold2': {'re':r'(^| |})(\*{1,2}[^\*]+\*{1,2})', "bc": "\\1${W}\\2",
'bc':'\\1${W}\\2','dc':'\\1${W}\\2'}, # **bold** "dc": "\\1${W}\\2",
'code': {'re':r'([`]+[^`]+[`]+)', }, # _bold_
'bc':'${c}\\1','dc':'${m}\\1'}, # `code` "bold2": {
'code_special': {'re':r'([`]+[^`]+[`]+)([!>])', "re": r"(^| |})(\*{1,2}[^\*]+\*{1,2})",
'bc':'${c}\\1${g}\\2','dc':'${m}\\1${r}\\2'}, # `code`! or `code`> for markslider "bc": "\\1${W}\\2",
'link': {'re':r'(\[)([^\]]+)(\])\(([^\)]+)\)', "dc": "\\1${W}\\2",
'bc':'${B}\\1${Z}\\2${B}\\3(${U}\\4${u})', }, # **bold**
'dc':'${b}\\1${Z}\\2${b}\\3(${U}\\4${u})'}, # [text](link) "code": {"re": r"([`]+[^`]+[`]+)", "bc": "${c}\\1", "dc": "${m}\\1"}, # `code`
'image': {'re':r'(!\[[^\]]+\]\([^\)]+\))', "code_special": {
'bc':'${r}\\1','dc':'${g}\\1'}, # ![text](image) "re": r"([`]+[^`]+[`]+)([!>])",
'underline': {'re':r'(^|\W)(__)([^_]+)(__)', "bc": "${c}\\1${g}\\2",
'bc':'\\1\\2${U}\\3${Z}\\4','dc':'\\1\\2${U}\\3${Z}\\4'}, # __underline__ "dc": "${m}\\1${r}\\2",
'strikethrough': {'re':r'(~~)([^~]+)(~~)', }, # `code`! or `code`> for markslider
'bc':'\\1${st}\\2${so}\\3','dc':'\\1${st}\\2${so}\\3'}, # ~~strike~~ "link": {
'checkbox': {'re':r'(\[[x ]\])', "re": r"(\[)([^\]]+)(\])\(([^\)]+)\)",
'bc':'${y}\\1','dc':'${r}\\1'}, # [x] [ ] "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) 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__": if __name__ == "__main__":
opts = setup_options() opts = setup_options()
if opts.print_template: if opts.print_template:
import json 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, print(
'block_match':block_match_str, json.dumps(
'inline_match':inline_match_str, {
'inlines':inlines}, "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. ',
indent=2,sort_keys=True)) "blocks": blocks,
"block_match": block_match_str,
"inline_match": inline_match_str,
"inlines": inlines,
},
indent=2,
sort_keys=True,
)
)
sys.exit(0) sys.exit(0)
if opts.template: if opts.template:
import json import json
template=json.load(open(opts.template,'r'))
if 'inlines' in template: inlines=template['inlines'] template = json.load(open(opts.template, "r"))
if 'blocks' in template: blocks=template['blocks'] if "inlines" in template:
if 'block_match' in template: inlines = template["inlines"]
block_match_str=template['block_match'] 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) block_match = md_re_compile(block_match_str)
if 'inline_match' in template: if "inline_match" in template:
inline_match_str=template['inline_match'] inline_match_str = template["inline_match"]
inline_match = md_re_compile(inline_match_str) inline_match = md_re_compile(inline_match_str)
bc = ansi.code() bc = ansi.code()
if opts.filename == "-" or opts.filename == None: if opts.filename == "-" or opts.filename == None:
f = sys.stdin f = sys.stdin
else: else:
f = open(opts.filename, 'r') f = open(opts.filename, "r")
if (sys.version_info > (3, 0)): if sys.version_info > (3, 0):
data = read_data3(f) data = read_data3(f)
else: else:
data = read_data2(f) data = read_data2(f)
data = parse(data) data = parse(data)
colored = colorize(data, not opts.color, opts.dark_colors, opts.debug) 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) write_colored3(colored, opts)
else: else:
write_colored2(colored, opts) write_colored2(colored, opts)

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python3
# coding=utf-8 # coding=utf-8
# #
# Copyright 2016 Ville Rantanen # Copyright 2016 Ville Rantanen
@@ -17,52 +17,75 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
'''Color by ${X} notation.''' """Color by ${X} notation."""
__author__ = "Ville Rantanen <ville.q.rantanen@gmail.com>" __author__ = "Ville Rantanen <ville.q.rantanen@gmail.com>"
__version__ = "0.1" __version__ = "0.1"
import sys, os, argparse, re import sys, os, argparse, re
from argparse import ArgumentParser from argparse import ArgumentParser
sys.path.append(os.path.dirname(os.path.realpath(__file__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
import ansicodes as ansi import ansicodes as ansi
def setup_options(): def setup_options():
''' Create command line options ''' """ Create command line options """
usage=''' usage = (
"""
Color notation renderer in ANSI codes Color notation renderer in ANSI codes
Special syntaxes: Special syntaxes:
* Colors: insert string ${X}, where X values in the table below. * Colors: insert string ${X}, where X values in the table below.
''' + ansi.demo() """
+ ansi.demo()
)
parser=ArgumentParser(description=usage, parser = ArgumentParser(
description=usage,
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=__author__) epilog=__author__,
)
parser.add_argument("-v", "--version", action="version", version=__version__) parser.add_argument("-v", "--version", action="version", version=__version__)
parser.add_argument("--no-color","-n",action="store_false",dest="color",default=True, parser.add_argument(
help="Disable color.") "--no-color",
parser.add_argument("-z",action="store_true",dest="zero",default=False, "-n",
help="Reset coloring at the end of each line.") action="store_false",
parser.add_argument("-Z",action="store_false",dest="zero_final",default=True, dest="color",
help="Disable reset of colors at the end of file.") default=True,
parser.add_argument("filename",type=str, help="Disable color.",
help="File to show, - for stdin") )
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() opts = parser.parse_args()
return opts return opts
bc = ansi.code() bc = ansi.code()
opts = setup_options() opts = setup_options()
if opts.filename == "-": if opts.filename == "-":
f = sys.stdin f = sys.stdin
else: else:
f=open(opts.filename,'r') f = open(opts.filename, "r")
for row in f: for row in f:
if not row: if not row:
continue continue
if type(row) == bytes: if type(row) == bytes:
row = row.decode('utf-8') row = row.decode("utf-8")
row = row.rstrip("\n\r ") row = row.rstrip("\n\r ")
if opts.color: if opts.color:
colored = bc.color_string(row) colored = bc.color_string(row)
@@ -74,4 +97,3 @@ for row in f:
sys.stdout.write("\n") sys.stdout.write("\n")
if opts.zero_final and opts.color: if opts.zero_final and opts.color:
sys.stdout.write(bc.Z) sys.stdout.write(bc.Z)

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python3
# coding=utf-8 # coding=utf-8
# #
# Copyright 2016 Ville Rantanen # Copyright 2016 Ville Rantanen
@@ -17,7 +17,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
'''Color by notation.''' """Color by notation."""
__author__ = "Ville Rantanen <ville.q.rantanen@gmail.com>" __author__ = "Ville Rantanen <ville.q.rantanen@gmail.com>"
__version__ = "0.2" __version__ = "0.2"
@@ -30,6 +30,8 @@ PAUSE="====PAUSE"
import sys, os, argparse, re, time import sys, os, argparse, re, time
from argparse import ArgumentParser from argparse import ArgumentParser
class bc: class bc:
K = "\033[1;30m" K = "\033[1;30m"
R = "\033[1;31m" R = "\033[1;31m"
@@ -67,35 +69,77 @@ class bc:
bc = "\033[46m" bc = "\033[46m"
bw = "\033[47m" bw = "\033[47m"
S = '\033[1m' S = "\033[1m"
s = '\033[2m'#strong off s = "\033[2m" # strong off
U = '\033[4m'#underline U = "\033[4m" # underline
u = '\033[24m'#underline off u = "\033[24m" # underline off
ic = '\033[7m'#inverse colors ic = "\033[7m" # inverse colors
io = '\033[27m'#inverse off io = "\033[27m" # inverse off
st = '\033[9m'#strike on st = "\033[9m" # strike on
so = '\033[29m'#strike off so = "\033[29m" # strike off
Z = '\033[0m' Z = "\033[0m"
CLR = '\033[2J' CLR = "\033[2J"
CLREND = '\033[K' CLREND = "\033[K"
CLRSCR = CLR + "\033[0;0H" CLRSCR = CLR + "\033[0;0H"
color_keys = "pqwertyu01234567;asdfghjPQWERTYUxXczvVbBnN" color_keys = "pqwertyu01234567;asdfghjPQWERTYUxXczvVbBnN"
color_list=[K, R, G, Y, B, M, C, W, k, r, g, y, b, m, c, w, color_list = [
bk,br,bg,by,bb,bm,bc,bw,nk,nr,ng,ny,nb,nm,nc,nw, K,
S,s,CLRSCR,Z,U,u,st,so,ic,io] 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): def pos(self, y, x):
return "\033[" + str(y) + ";" + str(x) + "H" return "\033[" + str(y) + ";" + str(x) + "H"
def posprint(self, y, x, s): def posprint(self, y, x, s):
sys.stdout.write( (self.pos(y,x) + str(s)).encode('utf-8') ) sys.stdout.write((self.pos(y, x) + str(s)).encode("utf-8"))
def clear(self): def clear(self):
sys.stdout.write( (self.CLR+self.pos(0,0)).encode('utf-8') ) sys.stdout.write((self.CLR + self.pos(0, 0)).encode("utf-8"))
def clear_to_end(self): def clear_to_end(self):
sys.stdout.write( self.CLREND.encode('utf-8') ) sys.stdout.write(self.CLREND.encode("utf-8"))
def color_char(self, s): def color_char(self, s):
for i, c in enumerate(self.color_keys): for i, c in enumerate(self.color_keys):
@@ -103,24 +147,28 @@ class bc:
s = s.replace(c, self.color_list[i]) s = s.replace(c, self.color_list[i])
return s return s
return "" return ""
def nocolor_string(self, s): def nocolor_string(self, s):
return "" return ""
def end_drawing(opts): def end_drawing(opts):
if opts.zero_final: if opts.zero_final:
sys.stdout.write(bc.Z.encode('utf-8')) sys.stdout.write(bc.Z.encode("utf-8"))
sys.exit(0) sys.exit(0)
def open_data_file(opts): def open_data_file(opts):
if opts.test_image: if opts.test_image:
return test_data() return test_data()
if opts.filename=='-': if opts.filename == "-":
return sys.stdin return sys.stdin
return open(opts.filename,'r') return open(opts.filename, "r")
def setup_options(): def setup_options():
''' Create command line options ''' """ Create command line options """
usage=''' usage = """
Color image renderer in ANSI codes. Example file: Color image renderer in ANSI codes. Example file:
first layer of characters first layer of characters
@@ -145,31 +193,61 @@ Color image renderer in ANSI codes. Example file:
====EOF ====EOF
end of file end of file
''' """
parser=ArgumentParser(description=usage, parser = ArgumentParser(
description=usage,
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=__author__) epilog=__author__,
)
parser.add_argument("-v", "--version", action="version", version=__version__) parser.add_argument("-v", "--version", action="version", version=__version__)
parser.add_argument("--no-color","-n",action="store_false",dest="color",default=True, parser.add_argument(
help="Disable color.") "--no-color",
parser.add_argument("--test",action="store_true",dest="test_image",default=False, "-n",
help="Show test image showing features.") action="store_false",
parser.add_argument("-z",action="store_true",dest="zero",default=False, dest="color",
help="Reset color codes at the end of each line.") default=True,
parser.add_argument("-Z",action="store_false",dest="zero_final",default=True, help="Disable color.",
help="Disable reset of colors at the end of file.") )
parser.add_argument("-c",action="store_true",dest="clear",default=False, parser.add_argument(
help="Clear screen first") "--test",
parser.add_argument("filename",type=str, nargs='?', default=None, action="store_true",
help="File to show, - for stdin") 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() opts = parser.parse_args()
if not opts.test_image and opts.filename == None: if not opts.test_image and opts.filename == None:
parser.error("Need a file or - as argument") parser.error("Need a file or - as argument")
return opts return opts
def test_data(): def test_data():
testimage = ''' NOT VISIBLE testimage = ''' NOT VISIBLE
_ _ _ ____ ___ _ _ _ ____ ___
@@ -221,8 +299,11 @@ u f u
; f U ; f U
; f U ; f U
====EOI ====EOI
Outputs:'''.encode('utf-8') Outputs:'''.encode(
return testimage.split('\n') "utf-8"
)
return testimage.split("\n")
bc = bc() bc = bc()
opts = setup_options() opts = setup_options()
@@ -244,7 +325,7 @@ while True:
for row in f: for row in f:
if not row: if not row:
end_drawing(opts) end_drawing(opts)
row=row.decode('utf-8').rstrip("\n\r") row = row.decode("utf-8").rstrip("\n\r")
if row.startswith(NEWIMAGE): if row.startswith(NEWIMAGE):
break break
if row.startswith(ENDOFFILE): if row.startswith(ENDOFFILE):
@@ -282,37 +363,36 @@ while True:
for i in range(len(gray[0])): for i in range(len(gray[0])):
for frame in colors: for frame in colors:
if len(frame) < i + 1: if len(frame) < i + 1:
frame.append('') frame.append("")
while len(gray[0][i]) > len(frame[i]): while len(gray[0][i]) > len(frame[i]):
frame[i] = frame[i] + " " frame[i] = frame[i] + " "
if len(gray) > 1: if len(gray) > 1:
for layer in gray[1:]: for layer in gray[1:]:
if len(layer) < i + 1: if len(layer) < i + 1:
layer.append('') layer.append("")
while len(gray[0][i]) > len(layer[i]): while len(gray[0][i]) > len(layer[i]):
layer[i] = layer[i] + " " layer[i] = layer[i] + " "
for i in range(len(gray[0])): for i in range(len(gray[0])):
for c in range(len(gray[0][i])): for c in range(len(gray[0][i])):
if opts.color: if opts.color:
for frame in colors: for frame in colors:
try: try:
if frame[i][c] != " ": if frame[i][c] != " ":
sys.stdout.write(bc.color_char(frame[i][c]).encode('utf-8')) sys.stdout.write(bc.color_char(frame[i][c]).encode("utf-8"))
except IndexError: except IndexError:
pass pass
char = " " char = " "
for layer in gray: for layer in gray:
if layer[i][c]==" ": continue if layer[i][c] == " ":
continue
char = layer[i][c] char = layer[i][c]
sys.stdout.write(char.encode('utf-8')) sys.stdout.write(char.encode("utf-8"))
if opts.color and opts.zero: 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") sys.stdout.write("\n")
if pause > 0: if pause > 0:
time.sleep(pause) time.sleep(pause)
if opts.test_image: if opts.test_image:
end_drawing(opts) end_drawing(opts)