markdown launch code
This commit is contained in:
27
highbeam
27
highbeam
@@ -27,10 +27,12 @@ Underline: $U
|
||||
|
||||
Usage: highbeam [-c] [-h] [-f config]
|
||||
-c Be case sensitive
|
||||
-D Print current rules, not the input
|
||||
-h Help
|
||||
-f Define config file (default ~/.highbeamrc)
|
||||
-r Define rules with a string, replaces the other rules
|
||||
-r '\''"land[^[:space:]]\+" "$G" "sky" "$B"'\''
|
||||
|
||||
'
|
||||
|
||||
}
|
||||
@@ -72,7 +74,8 @@ U="${E}4m"
|
||||
CONF_FILE=~/.highbeamrc
|
||||
CONF_LINE=""
|
||||
FLAGS="ig"
|
||||
while getopts chf:r: opt
|
||||
PRINT=0
|
||||
while getopts chf:r:D opt
|
||||
do case "$opt" in
|
||||
c)
|
||||
FLAGS="g"
|
||||
@@ -87,6 +90,9 @@ do case "$opt" in
|
||||
r)
|
||||
CONF_LINE=( $( eval echo $OPTARG ) )
|
||||
;;
|
||||
D)
|
||||
PRINT=1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
@@ -118,9 +124,28 @@ done
|
||||
rIndex=$(( $rIndex + 1 ))
|
||||
done
|
||||
}
|
||||
[[ $PRINT -eq 1 ]] && {
|
||||
echo "From $CONF_FILE:"
|
||||
for (( rIndex=0; rIndex<${#RULES[@]}; rIndex++ ));
|
||||
do printf "%s\\t%s" "${RULES[$rIndex]}" "${RULES[$(( $rIndex + 1 ))]}"
|
||||
rIndex=$(( $rIndex + 1 ))
|
||||
done
|
||||
echo "From argument switches:"
|
||||
for (( rIndex=0; rIndex<${#CONF_LINE[@]}; rIndex++ ));
|
||||
do printf "%s\\t%s" "${CONF_LINE[$rIndex]}" "${CONF_LINE[$(( $rIndex + 1 ))]}"
|
||||
rIndex=$(( $rIndex + 1 ))
|
||||
done
|
||||
echo "From HB_RULES environment:"
|
||||
for (( rIndex=0; rIndex<${#CONF_ENV[@]}; rIndex++ ));
|
||||
do printf "%s\\t%s" "${CONF_ENV[$rIndex]}" "${CONF_ENV[$(( $rIndex + 1 ))]}"
|
||||
rIndex=$(( $rIndex + 1 ))
|
||||
done
|
||||
#~ echo ${CONF_ENV[@]}
|
||||
#~ echo $HB_RULES
|
||||
#~ echo $REGEX
|
||||
exit
|
||||
}
|
||||
|
||||
[[ -z "$REGEX" ]] && {
|
||||
cat -
|
||||
} || {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# coding=utf-8
|
||||
#
|
||||
# Copyright 2015 Ville Rantanen
|
||||
#
|
||||
@@ -19,12 +20,14 @@
|
||||
'''Markslider: a slideshow engine based on markdown.'''
|
||||
|
||||
__author__ = "Ville Rantanen <ville.q.rantanen@gmail.com>"
|
||||
|
||||
__version__ = "0.1"
|
||||
__version__ = "0.6"
|
||||
|
||||
import sys,os,argparse,re
|
||||
from argparse import ArgumentParser
|
||||
import traceback,tty,termios
|
||||
import traceback,tty,termios,subprocess
|
||||
|
||||
HL=">"
|
||||
EOS="# End of Slides"
|
||||
|
||||
class bc:
|
||||
K="\033[1;30m"
|
||||
@@ -47,6 +50,7 @@ class bc:
|
||||
U = '\033[4m'
|
||||
Z = '\033[0m'
|
||||
CLR = '\033[2J'
|
||||
CLREND = '\033[K'
|
||||
|
||||
color_keys="KRGBYMCWkrgbymcwSUZ"
|
||||
color_list=[K,R,G,B,Y,M,C,W,k,r,g,b,y,m,c,w,S,U,Z]
|
||||
@@ -59,6 +63,8 @@ class bc:
|
||||
|
||||
def clear(self):
|
||||
sys.stdout.write( self.CLR+self.pos(0,0) )
|
||||
def clear_to_end(self):
|
||||
sys.stdout.write( self.CLREND )
|
||||
|
||||
def color_string(self,s):
|
||||
for i,c in enumerate(self.color_keys):
|
||||
@@ -68,7 +74,6 @@ class bc:
|
||||
for i,c in enumerate(self.color_keys):
|
||||
s=s.replace("${"+c+"}","")
|
||||
return s
|
||||
|
||||
|
||||
class getch:
|
||||
def get(self):
|
||||
@@ -83,7 +88,7 @@ class getch:
|
||||
|
||||
|
||||
class EndProgram( Exception ):
|
||||
''' Nice way of exiting the program '''
|
||||
''' Nice exit '''
|
||||
pass
|
||||
|
||||
class slide_reader:
|
||||
@@ -108,17 +113,27 @@ class slide_reader:
|
||||
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=[]
|
||||
new_page.append(row)
|
||||
# if first slide havent been found yet:
|
||||
if not first_slide_found:
|
||||
continue
|
||||
new_page.extend(self.launch(row))
|
||||
if len(new_page)>0:
|
||||
self.data.append(new_page)
|
||||
|
||||
self.toc()
|
||||
self.pages=len(self.data)
|
||||
self.inc_page_no(0)
|
||||
@@ -180,15 +195,36 @@ class slide_reader:
|
||||
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.append(" %d.%d.%d.%d. %s"%(h1+1,subh[0],subh[1],subh[2],title))
|
||||
self.data.insert(self.opts.toc_page-1,TOC)
|
||||
|
||||
def launch(self,s):
|
||||
""" Launch in a string using tags $!command$!
|
||||
Remove empty lines from beginning and end of stdout.
|
||||
"""
|
||||
if not self.opts.execute_read:
|
||||
return [s]
|
||||
if s.find("$>")==-1:
|
||||
return [s]
|
||||
command=re.match("(.*)\$>(.*)\$>(.*)",s)
|
||||
if command != None:
|
||||
output = subprocess.check_output(command.group(2).strip(),shell=True).split("\n")
|
||||
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 [""]
|
||||
del output[-1]
|
||||
return_value=[command.group(1)]
|
||||
return_value.extend(output)
|
||||
return_value.append(command.group(3))
|
||||
return return_value
|
||||
return [s]
|
||||
|
||||
|
||||
def get_interactive_help_text():
|
||||
return ''' left/right,page up/down,home,end
|
||||
return ''' left/right,page up/down,home,end
|
||||
change page
|
||||
m toggle page numbers
|
||||
s toggle status bar
|
||||
q exit browser
|
||||
r reload the file
|
||||
,/. scroll page
|
||||
@@ -198,14 +234,20 @@ def get_interactive_help_text():
|
||||
def setup_options():
|
||||
''' Create command line options '''
|
||||
usage='''
|
||||
|
||||
Interactive mode keymap:
|
||||
MarkSlider: a markdown based slideshow engine
|
||||
Special syntaxes:
|
||||
* Colors: insert string ${C}, where C is one of KRGBYMCWkrgbymcwSUZ
|
||||
* Text before first "# header" is not shown
|
||||
* Text after a "# End of Slides" is not shown
|
||||
* Execute shell: "$! command -switch $!" Beware of malicious code!
|
||||
* Execute and print output: "$> command $>" Beware of malicious code!
|
||||
|
||||
Keyboard shortcuts:
|
||||
'''+get_interactive_help_text()
|
||||
|
||||
parser=ArgumentParser(description=usage,
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog=__author__)
|
||||
|
||||
|
||||
parser.add_argument("-v","--version",action="version",version=__version__)
|
||||
|
||||
@@ -219,8 +261,12 @@ def setup_options():
|
||||
help="Disable status bar.")
|
||||
parser.add_argument("-w",action="store_false",dest="wrap",default=True,
|
||||
help="Disable line wrapping. Cuts long lines.")
|
||||
parser.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!")
|
||||
parser.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!")
|
||||
parser.add_argument("--toc",action="store",dest="toc",default=False,
|
||||
const="Table of contents", type=str, nargs='?',
|
||||
const="Table of Contents", type=str, nargs='?',
|
||||
help="Insert table of contents. Define the header, or use default: %(const)s")
|
||||
parser.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")
|
||||
@@ -232,7 +278,6 @@ def setup_options():
|
||||
opts=parser.parse_args()
|
||||
return opts
|
||||
|
||||
|
||||
def page_print(reader,opts,offset):
|
||||
''' Print a page '''
|
||||
|
||||
@@ -256,8 +301,8 @@ def page_print(reader,opts,offset):
|
||||
else:
|
||||
row_lines=int(float(len(row))/scrsize[1])
|
||||
colored=colorify(row,opts)
|
||||
if offset[1]==r+1:
|
||||
colored=colorify("${Y}>"+bc.nocolor_string(row),opts)
|
||||
if offset[1]==r+1+offset[0]:
|
||||
colored=add_highlight(row,opts)
|
||||
sys.stdout.write(colored)
|
||||
|
||||
if r>=scrsize[0]-2:
|
||||
@@ -292,13 +337,8 @@ 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])
|
||||
offsety=max(0,offsety)
|
||||
if offsety==0 and new_offset[0]!=0:
|
||||
return (offsety,offset[1])
|
||||
offseth=min(opts.size[0]-1,new_offset[1])
|
||||
offseth=min(reader.get_page_height(),offseth)
|
||||
offseth=max(0,offseth)
|
||||
return (offsety, offseth)
|
||||
offseth=min(reader.get_page_height(),new_offset[1])
|
||||
return [max(0,o) for o in (offsety,offseth)]
|
||||
|
||||
def browser(opts,filename):
|
||||
''' Main function for printing '''
|
||||
@@ -338,32 +378,30 @@ def browser(opts,filename):
|
||||
offset=(0, 0)
|
||||
if inkey==ord('h'):
|
||||
print_help(reader,opts)
|
||||
if inkey==ord('m'):
|
||||
if inkey==ord('s'):
|
||||
opts.menu=not opts.menu
|
||||
if inkey==ord('r'):
|
||||
reader.read()
|
||||
offset=(0, 0)
|
||||
offset=offset_change(opts,reader,offset,(0, 0))
|
||||
if inkey==ord(','):
|
||||
offset=offset_change(opts,reader,offset,(-1, 1))
|
||||
offset=offset_change(opts,reader,offset,(-1, 0))
|
||||
if inkey==ord('.'):
|
||||
offset=offset_change(opts,reader,offset,(1, -1))
|
||||
offset=offset_change(opts,reader,offset,(1, 0))
|
||||
if inkey==65:
|
||||
offset=offset_change(opts,reader,offset,(0, -1))
|
||||
if inkey==66:
|
||||
offset=offset_change(opts,reader,offset,(0, 1))
|
||||
if inkey==13:
|
||||
launch(reader,opts,offset)
|
||||
break
|
||||
#~ stdscr.refresh()
|
||||
|
||||
|
||||
except IOError:
|
||||
pass
|
||||
except KeyboardInterrupt:
|
||||
#~ reset_curses(stdscr)
|
||||
sys.exit(0)
|
||||
except EndProgram:
|
||||
pass
|
||||
except:
|
||||
#~ reset_curses(stdscr)
|
||||
print "Unexpected error:"
|
||||
print traceback.format_exc()
|
||||
sys.exit(1)
|
||||
@@ -382,6 +420,7 @@ def colorify(s,opts):
|
||||
"(^#.*)", ## Header
|
||||
"(^\s\s\s\s[^\*0-9\s].*)", # code block
|
||||
"(\`[^\s]*[^\`]+\`)", # code inline
|
||||
"(\$[>!].*\$[>!])", # code tags
|
||||
"(\[[^]]+\]\([^\)]+\))", # [link](url)
|
||||
"(\*{1,2}[^\s]*[^\*\s]+\*{1,2})", # *bold*
|
||||
"(_[^\s]*[^_\s]+_)", # _bold_
|
||||
@@ -392,6 +431,7 @@ def colorify(s,opts):
|
||||
"${U}${b}\\1", ## Header
|
||||
"${m}\\1", # code block
|
||||
"${m}\\1${Z}", # code inline
|
||||
"${m}\\1${Z}", # code tags
|
||||
"${B}${U}\\1${Z}", # [link](url)
|
||||
"${W}\\1${Z}", # *bold*
|
||||
"${W}\\1${Z}", # _bold_
|
||||
@@ -402,6 +442,7 @@ def colorify(s,opts):
|
||||
"${U}${Y}\\1", ## Header
|
||||
"${c}\\1", # code block
|
||||
"${c}\\1${Z}", # code inline
|
||||
"${c}\\1${Z}", # code tags
|
||||
"${B}${U}\\1${Z}", # [link](url)
|
||||
"${W}\\1${Z}", # *bold*
|
||||
"${W}\\1${Z}", # _bold_
|
||||
@@ -419,7 +460,48 @@ def cut_line(s,i):
|
||||
re.sub("\$\{.$","",
|
||||
s)))
|
||||
return s
|
||||
def add_highlight(s,opts):
|
||||
if len(s.strip())==0:
|
||||
cleaned=HL
|
||||
else:
|
||||
cleaned=bc.nocolor_string(s)
|
||||
tagged="${Y}"+cleaned
|
||||
return colorify(tagged,opts)
|
||||
|
||||
def launch(reader,opts,offset):
|
||||
""" Launch in a string using tags $!command$!
|
||||
Used with highlight
|
||||
Remove empty lines from beginning and end of stdout.
|
||||
"""
|
||||
if not opts.execute:
|
||||
return
|
||||
s=reader.get_current_page()[offset[1]]
|
||||
if s.find("$!")+s.find("$>")==-2:
|
||||
return
|
||||
|
||||
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).split("\n")
|
||||
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 [""]
|
||||
del output[-1]
|
||||
for y,l in enumerate(output):
|
||||
bc.posprint(y+offset[1]-offset[0]+2,0,l)
|
||||
bc.clear_to_end()
|
||||
inkey=getch.get()
|
||||
return
|
||||
if run_command != None:
|
||||
subprocess.call(run_command.group(2),
|
||||
#~ stdout=subprocess.PIPE,
|
||||
#~ stderr=subprocess.PIPE,
|
||||
shell=True,executable="/bin/bash")
|
||||
inkey=getch.get()
|
||||
return
|
||||
return
|
||||
bc=bc()
|
||||
getch=getch()
|
||||
opts=setup_options()
|
||||
|
||||
Reference in New Issue
Block a user