From f7b0333ae47d4fc60289eacf17d13898b77900e7 Mon Sep 17 00:00:00 2001 From: Ville Rantanen Date: Tue, 7 Mar 2017 13:43:34 +0200 Subject: [PATCH] multiple file support. TOC print while presentation --- reporting/markslider.py | 150 +++++++++++++++++++++++++--------------- 1 file changed, 95 insertions(+), 55 deletions(-) diff --git a/reporting/markslider.py b/reporting/markslider.py index c27d501..8206e3c 100755 --- a/reporting/markslider.py +++ b/reporting/markslider.py @@ -20,7 +20,7 @@ '''Markslider: a slideshow engine based on markdown.''' __author__ = "Ville Rantanen " -__version__ = "0.8" +__version__ = "0.9" import sys,os,argparse,re from argparse import ArgumentParser @@ -49,12 +49,14 @@ class EndProgram( Exception ): class slide_reader: """ Class for reading files. """ - def __init__(self,filename,opts): - self.filename=filename + def __init__(self,files,opts): + self.filename=files[0] + self.files=files self.reader=None self.opts=opts self.pages=0 self.page=0 + self.file_start_page=[] self.width=None self.height=None self.max_width=None @@ -69,31 +71,34 @@ class slide_reader: def read(self): ''' Read a file, set pages and data ''' - f=open(self.filename,'r') self.pages=0 self.data=[] - new_page=[] - first_slide_found=False - for row in f: - if not row: - continue - row=row.decode('utf-8').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("##"): - first_slide_found=True - if len(new_page)>0: - self.data.append(new_page) - new_page=[] - # if first slide havent been found yet: - if not first_slide_found: - continue - new_page.extend(self.generate_content(row)) - if len(new_page)>0: - self.data.append(new_page) - + self.file_start_page=[] + for fname in self.files: + f=open(fname,'r') + new_page=[] + first_slide_found=False + for row in f: + if not row: + continue + row=row.decode('utf-8').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("##"): + first_slide_found=True + if len(new_page)>0: + self.data.append(new_page) + new_page=[] + # if first slide havent been found yet: + if not first_slide_found: + continue + new_page.extend(self.generate_content(row)) + if len(new_page)>0: + self.data.append(new_page) + f.close() + self.file_start_page.append(len(self.data)) self.toc() self.pages=len(self.data) self.inc_page_no(0) @@ -106,6 +111,11 @@ class slide_reader: 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: + return self.files[i] + return "NA" def get_filename(self): return self.filename @@ -148,27 +158,32 @@ class slide_reader: def get_max_width(self): return self.max_width + def get_toc(self): + title=self.opts.toc if self.opts.toc else "Table of Contents" + TOC=["# "+title,""] + for h1,page in enumerate(self.data[(self.opts.toc_page-1):]): + title=page[0].strip("# ") + TOC.append("%d. %s"%(h1+1,title)) + subh=[0,0,0] + if self.opts.toc_depth>1: + for line in page: + 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 + 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 + 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)) + return TOC + def toc(self): if self.opts.toc: - TOC=["# "+self.opts.toc,""] - for h1,page in enumerate(self.data[(self.opts.toc_page-1):]): - title=page[0].strip("# ") - TOC.append("%d. %s"%(h1+1,title)) - subh=[0,0,0] - if self.opts.toc_depth>1: - for line in page: - 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 - 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 - 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)) + TOC=self.get_toc() self.data.insert(self.opts.toc_page-1,TOC) def generate_content(self,s): @@ -229,9 +244,10 @@ class slide_reader: def get_interactive_help_text(): return ''' left/right,page up/down,home,end change page - q exit browser + c list contents (toc) M modify file with VIM - r reload the file + q exit browser + r reload the presentation s toggle status bar t toggle timer (reqs. --timer switch) ,/. scroll page @@ -279,11 +295,9 @@ Keyboard shortcuts: 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("-s",action="store_false",dest="menu",default=True, help="Disable status bar.") control.add_argument("--timer",action="store",dest="slideTimer",default=False, type=int, @@ -298,8 +312,8 @@ Keyboard shortcuts: content.add_argument("--toc-depth",action="store",dest="toc_depth",default=2, type=int, choices=xrange(1,5), help="Table of contents display depth. default: %(const)s") - parser.add_argument("filename",type=str, - help="File to show") + 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: @@ -370,7 +384,7 @@ def menu_print(reader,opts): colorify("${y}%d${Z}/%d %s|%s"%( 1+reader.get_page_no(), reader.get_pages(), - reader.get_filename(), + os.path.basename(reader.get_current_filename()), "slideshow" if opts.slideShow else ""), opts)) @@ -386,6 +400,28 @@ def print_help(reader,opts): sys.stdout.write(bc.pos(opts.size[0], opts.size[1])) inkey=getch.get() +def print_toc(reader,opts): + ''' Create a window with TOC ''' + text=reader.get_toc() + title=opts.toc if opts.toc else "Table of Contents" + maxlen=max([len(x) for x in text]) + bc.posprint(3,3,"+"+"-"*maxlen+"+") + parsed=md_color.parse(text) + if opts.autocolor: + 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] + else: + colored=[bc.nocolor_string(row[1]) for row in parsed] + for y,row in enumerate(colored): + bc.posprint(4+y,3,("|{:<"+str(maxlen)+"}|").format(" ")) + bc.posprint(4+y,3,("|{:<"+str(maxlen)+"}").format(row)) + bc.posprint(5+y,3,"+"+"-"*maxlen+"+") + sys.stdout.write(bc.pos(opts.size[0], opts.size[1])) + 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]) @@ -403,11 +439,11 @@ def getkeypress(): except: return False -def browser(opts,filename): +def browser(opts,files): ''' Main function for printing ''' try: - reader=slide_reader(filename,opts) + reader=slide_reader(files,opts) except: print "Error in reading the file:" for o in sys.exc_info(): @@ -456,6 +492,8 @@ def browser(opts,filename): 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'): @@ -527,6 +565,8 @@ def launch(reader,opts,offset): 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!") + 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) @@ -587,4 +627,4 @@ def take_screenshot(reader,opts): bc=ansi.code() getch=getch() opts=setup_options() -browser(opts,opts.filename) +browser(opts,opts.files)