markdown launch code
This commit is contained in:
27
highbeam
27
highbeam
@@ -27,10 +27,12 @@ Underline: $U
|
|||||||
|
|
||||||
Usage: highbeam [-c] [-h] [-f config]
|
Usage: highbeam [-c] [-h] [-f config]
|
||||||
-c Be case sensitive
|
-c Be case sensitive
|
||||||
|
-D Print current rules, not the input
|
||||||
-h Help
|
-h Help
|
||||||
-f Define config file (default ~/.highbeamrc)
|
-f Define config file (default ~/.highbeamrc)
|
||||||
-r Define rules with a string, replaces the other rules
|
-r Define rules with a string, replaces the other rules
|
||||||
-r '\''"land[^[:space:]]\+" "$G" "sky" "$B"'\''
|
-r '\''"land[^[:space:]]\+" "$G" "sky" "$B"'\''
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -72,7 +74,8 @@ U="${E}4m"
|
|||||||
CONF_FILE=~/.highbeamrc
|
CONF_FILE=~/.highbeamrc
|
||||||
CONF_LINE=""
|
CONF_LINE=""
|
||||||
FLAGS="ig"
|
FLAGS="ig"
|
||||||
while getopts chf:r: opt
|
PRINT=0
|
||||||
|
while getopts chf:r:D opt
|
||||||
do case "$opt" in
|
do case "$opt" in
|
||||||
c)
|
c)
|
||||||
FLAGS="g"
|
FLAGS="g"
|
||||||
@@ -87,6 +90,9 @@ do case "$opt" in
|
|||||||
r)
|
r)
|
||||||
CONF_LINE=( $( eval echo $OPTARG ) )
|
CONF_LINE=( $( eval echo $OPTARG ) )
|
||||||
;;
|
;;
|
||||||
|
D)
|
||||||
|
PRINT=1
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -118,9 +124,28 @@ done
|
|||||||
rIndex=$(( $rIndex + 1 ))
|
rIndex=$(( $rIndex + 1 ))
|
||||||
done
|
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 ${CONF_ENV[@]}
|
||||||
#~ echo $HB_RULES
|
#~ echo $HB_RULES
|
||||||
#~ echo $REGEX
|
#~ echo $REGEX
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
[[ -z "$REGEX" ]] && {
|
[[ -z "$REGEX" ]] && {
|
||||||
cat -
|
cat -
|
||||||
} || {
|
} || {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
# coding=utf-8
|
||||||
#
|
#
|
||||||
# Copyright 2015 Ville Rantanen
|
# Copyright 2015 Ville Rantanen
|
||||||
#
|
#
|
||||||
@@ -19,12 +20,14 @@
|
|||||||
'''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__ = "0.6"
|
||||||
__version__ = "0.1"
|
|
||||||
|
|
||||||
import sys,os,argparse,re
|
import sys,os,argparse,re
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
import traceback,tty,termios
|
import traceback,tty,termios,subprocess
|
||||||
|
|
||||||
|
HL=">"
|
||||||
|
EOS="# End of Slides"
|
||||||
|
|
||||||
class bc:
|
class bc:
|
||||||
K="\033[1;30m"
|
K="\033[1;30m"
|
||||||
@@ -47,6 +50,7 @@ class bc:
|
|||||||
U = '\033[4m'
|
U = '\033[4m'
|
||||||
Z = '\033[0m'
|
Z = '\033[0m'
|
||||||
CLR = '\033[2J'
|
CLR = '\033[2J'
|
||||||
|
CLREND = '\033[K'
|
||||||
|
|
||||||
color_keys="KRGBYMCWkrgbymcwSUZ"
|
color_keys="KRGBYMCWkrgbymcwSUZ"
|
||||||
color_list=[K,R,G,B,Y,M,C,W,k,r,g,b,y,m,c,w,S,U,Z]
|
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):
|
def clear(self):
|
||||||
sys.stdout.write( self.CLR+self.pos(0,0) )
|
sys.stdout.write( self.CLR+self.pos(0,0) )
|
||||||
|
def clear_to_end(self):
|
||||||
|
sys.stdout.write( self.CLREND )
|
||||||
|
|
||||||
def color_string(self,s):
|
def color_string(self,s):
|
||||||
for i,c in enumerate(self.color_keys):
|
for i,c in enumerate(self.color_keys):
|
||||||
@@ -69,7 +75,6 @@ class bc:
|
|||||||
s=s.replace("${"+c+"}","")
|
s=s.replace("${"+c+"}","")
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
class getch:
|
class getch:
|
||||||
def get(self):
|
def get(self):
|
||||||
fd = sys.stdin.fileno()
|
fd = sys.stdin.fileno()
|
||||||
@@ -83,7 +88,7 @@ class getch:
|
|||||||
|
|
||||||
|
|
||||||
class EndProgram( Exception ):
|
class EndProgram( Exception ):
|
||||||
''' Nice way of exiting the program '''
|
''' Nice exit '''
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class slide_reader:
|
class slide_reader:
|
||||||
@@ -108,17 +113,27 @@ class slide_reader:
|
|||||||
self.pages=0
|
self.pages=0
|
||||||
self.data=[]
|
self.data=[]
|
||||||
new_page=[]
|
new_page=[]
|
||||||
|
first_slide_found=False
|
||||||
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 ")
|
||||||
|
# find end of show
|
||||||
|
if row==EOS:
|
||||||
|
break
|
||||||
|
# find header to start a new page
|
||||||
if row.startswith("#") and not row.startswith("##"):
|
if row.startswith("#") and not row.startswith("##"):
|
||||||
|
first_slide_found=True
|
||||||
if len(new_page)>0:
|
if len(new_page)>0:
|
||||||
self.data.append(new_page)
|
self.data.append(new_page)
|
||||||
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:
|
if len(new_page)>0:
|
||||||
self.data.append(new_page)
|
self.data.append(new_page)
|
||||||
|
|
||||||
self.toc()
|
self.toc()
|
||||||
self.pages=len(self.data)
|
self.pages=len(self.data)
|
||||||
self.inc_page_no(0)
|
self.inc_page_no(0)
|
||||||
@@ -180,15 +195,36 @@ class slide_reader:
|
|||||||
if self.opts.toc_depth==3: continue
|
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))
|
||||||
self.data.insert(self.opts.toc_page-1,TOC)
|
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():
|
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
|
||||||
m toggle page numbers
|
s toggle status bar
|
||||||
q exit browser
|
q exit browser
|
||||||
r reload the file
|
r reload the file
|
||||||
,/. scroll page
|
,/. scroll page
|
||||||
@@ -198,15 +234,21 @@ def get_interactive_help_text():
|
|||||||
def setup_options():
|
def setup_options():
|
||||||
''' Create command line options '''
|
''' Create command line options '''
|
||||||
usage='''
|
usage='''
|
||||||
|
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!
|
||||||
|
|
||||||
Interactive mode keymap:
|
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("--dc",action="store_true",dest="dark_colors",default=False,
|
parser.add_argument("--dc",action="store_true",dest="dark_colors",default=False,
|
||||||
@@ -219,8 +261,12 @@ def setup_options():
|
|||||||
help="Disable status bar.")
|
help="Disable status bar.")
|
||||||
parser.add_argument("-w",action="store_false",dest="wrap",default=True,
|
parser.add_argument("-w",action="store_false",dest="wrap",default=True,
|
||||||
help="Disable line wrapping. Cuts long lines.")
|
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,
|
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")
|
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,
|
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")
|
help="Insert table of contents on a chosen page. default: %(const)s")
|
||||||
@@ -232,7 +278,6 @@ def setup_options():
|
|||||||
opts=parser.parse_args()
|
opts=parser.parse_args()
|
||||||
return opts
|
return opts
|
||||||
|
|
||||||
|
|
||||||
def page_print(reader,opts,offset):
|
def page_print(reader,opts,offset):
|
||||||
''' Print a page '''
|
''' Print a page '''
|
||||||
|
|
||||||
@@ -256,8 +301,8 @@ def page_print(reader,opts,offset):
|
|||||||
else:
|
else:
|
||||||
row_lines=int(float(len(row))/scrsize[1])
|
row_lines=int(float(len(row))/scrsize[1])
|
||||||
colored=colorify(row,opts)
|
colored=colorify(row,opts)
|
||||||
if offset[1]==r+1:
|
if offset[1]==r+1+offset[0]:
|
||||||
colored=colorify("${Y}>"+bc.nocolor_string(row),opts)
|
colored=add_highlight(row,opts)
|
||||||
sys.stdout.write(colored)
|
sys.stdout.write(colored)
|
||||||
|
|
||||||
if r>=scrsize[0]-2:
|
if r>=scrsize[0]-2:
|
||||||
@@ -292,13 +337,8 @@ 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])
|
||||||
offsety=max(0,offsety)
|
offseth=min(reader.get_page_height(),new_offset[1])
|
||||||
if offsety==0 and new_offset[0]!=0:
|
return [max(0,o) for o in (offsety,offseth)]
|
||||||
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)
|
|
||||||
|
|
||||||
def browser(opts,filename):
|
def browser(opts,filename):
|
||||||
''' Main function for printing '''
|
''' Main function for printing '''
|
||||||
@@ -338,32 +378,30 @@ def browser(opts,filename):
|
|||||||
offset=(0, 0)
|
offset=(0, 0)
|
||||||
if inkey==ord('h'):
|
if inkey==ord('h'):
|
||||||
print_help(reader,opts)
|
print_help(reader,opts)
|
||||||
if inkey==ord('m'):
|
if inkey==ord('s'):
|
||||||
opts.menu=not opts.menu
|
opts.menu=not opts.menu
|
||||||
if inkey==ord('r'):
|
if inkey==ord('r'):
|
||||||
reader.read()
|
reader.read()
|
||||||
offset=(0, 0)
|
offset=offset_change(opts,reader,offset,(0, 0))
|
||||||
if inkey==ord(','):
|
if inkey==ord(','):
|
||||||
offset=offset_change(opts,reader,offset,(-1, 1))
|
offset=offset_change(opts,reader,offset,(-1, 0))
|
||||||
if inkey==ord('.'):
|
if inkey==ord('.'):
|
||||||
offset=offset_change(opts,reader,offset,(1, -1))
|
offset=offset_change(opts,reader,offset,(1, 0))
|
||||||
if inkey==65:
|
if inkey==65:
|
||||||
offset=offset_change(opts,reader,offset,(0, -1))
|
offset=offset_change(opts,reader,offset,(0, -1))
|
||||||
if inkey==66:
|
if inkey==66:
|
||||||
offset=offset_change(opts,reader,offset,(0, 1))
|
offset=offset_change(opts,reader,offset,(0, 1))
|
||||||
|
if inkey==13:
|
||||||
|
launch(reader,opts,offset)
|
||||||
break
|
break
|
||||||
#~ stdscr.refresh()
|
|
||||||
|
|
||||||
|
|
||||||
except IOError:
|
except IOError:
|
||||||
pass
|
pass
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
#~ reset_curses(stdscr)
|
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
except EndProgram:
|
except EndProgram:
|
||||||
pass
|
pass
|
||||||
except:
|
except:
|
||||||
#~ reset_curses(stdscr)
|
|
||||||
print "Unexpected error:"
|
print "Unexpected error:"
|
||||||
print traceback.format_exc()
|
print traceback.format_exc()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
@@ -382,6 +420,7 @@ def colorify(s,opts):
|
|||||||
"(^#.*)", ## Header
|
"(^#.*)", ## Header
|
||||||
"(^\s\s\s\s[^\*0-9\s].*)", # code block
|
"(^\s\s\s\s[^\*0-9\s].*)", # code block
|
||||||
"(\`[^\s]*[^\`]+\`)", # code inline
|
"(\`[^\s]*[^\`]+\`)", # code inline
|
||||||
|
"(\$[>!].*\$[>!])", # code tags
|
||||||
"(\[[^]]+\]\([^\)]+\))", # [link](url)
|
"(\[[^]]+\]\([^\)]+\))", # [link](url)
|
||||||
"(\*{1,2}[^\s]*[^\*\s]+\*{1,2})", # *bold*
|
"(\*{1,2}[^\s]*[^\*\s]+\*{1,2})", # *bold*
|
||||||
"(_[^\s]*[^_\s]+_)", # _bold_
|
"(_[^\s]*[^_\s]+_)", # _bold_
|
||||||
@@ -392,6 +431,7 @@ def colorify(s,opts):
|
|||||||
"${U}${b}\\1", ## Header
|
"${U}${b}\\1", ## Header
|
||||||
"${m}\\1", # code block
|
"${m}\\1", # code block
|
||||||
"${m}\\1${Z}", # code inline
|
"${m}\\1${Z}", # code inline
|
||||||
|
"${m}\\1${Z}", # code tags
|
||||||
"${B}${U}\\1${Z}", # [link](url)
|
"${B}${U}\\1${Z}", # [link](url)
|
||||||
"${W}\\1${Z}", # *bold*
|
"${W}\\1${Z}", # *bold*
|
||||||
"${W}\\1${Z}", # _bold_
|
"${W}\\1${Z}", # _bold_
|
||||||
@@ -402,6 +442,7 @@ def colorify(s,opts):
|
|||||||
"${U}${Y}\\1", ## Header
|
"${U}${Y}\\1", ## Header
|
||||||
"${c}\\1", # code block
|
"${c}\\1", # code block
|
||||||
"${c}\\1${Z}", # code inline
|
"${c}\\1${Z}", # code inline
|
||||||
|
"${c}\\1${Z}", # code tags
|
||||||
"${B}${U}\\1${Z}", # [link](url)
|
"${B}${U}\\1${Z}", # [link](url)
|
||||||
"${W}\\1${Z}", # *bold*
|
"${W}\\1${Z}", # *bold*
|
||||||
"${W}\\1${Z}", # _bold_
|
"${W}\\1${Z}", # _bold_
|
||||||
@@ -419,7 +460,48 @@ def cut_line(s,i):
|
|||||||
re.sub("\$\{.$","",
|
re.sub("\$\{.$","",
|
||||||
s)))
|
s)))
|
||||||
return 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()
|
bc=bc()
|
||||||
getch=getch()
|
getch=getch()
|
||||||
opts=setup_options()
|
opts=setup_options()
|
||||||
|
|||||||
Reference in New Issue
Block a user