revamping markdown libraries
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# coding=utf-8
|
||||
#
|
||||
# Copyright 2015 Ville Rantanen
|
||||
# Copyright 2016 Ville Rantanen
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published
|
||||
@@ -20,84 +20,17 @@
|
||||
'''Markslider: a slideshow engine based on markdown.'''
|
||||
|
||||
__author__ = "Ville Rantanen <ville.q.rantanen@gmail.com>"
|
||||
__version__ = "0.6"
|
||||
__version__ = "0.7"
|
||||
|
||||
import sys,os,argparse,re
|
||||
from argparse import ArgumentParser
|
||||
import traceback,tty,termios,subprocess,signal
|
||||
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
|
||||
import ansi,md_color
|
||||
|
||||
HL=">"
|
||||
EOS="# End of Slides"
|
||||
|
||||
class bc:
|
||||
K="\033[1;30m"
|
||||
R="\033[1;31m"
|
||||
G="\033[1;32m"
|
||||
B="\033[1;34m"
|
||||
Y="\033[1;33m"
|
||||
M="\033[1;35m"
|
||||
C="\033[1;36m"
|
||||
W="\033[1;37m"
|
||||
k="\033[30m"
|
||||
r="\033[31m"
|
||||
g="\033[32m"
|
||||
b="\033[34m"
|
||||
y="\033[33m"
|
||||
m="\033[35m"
|
||||
c="\033[36m"
|
||||
w="\033[37m"
|
||||
S = '\033[1m'
|
||||
U = '\033[4m'
|
||||
Z = '\033[0m'
|
||||
CLR = '\033[2J'
|
||||
CLREND = '\033[K'
|
||||
CLRBEG = '\033[1K'
|
||||
|
||||
color_keys="KRGBYMCWkrgbymcwSUZ"
|
||||
color_list=[K,R,G,B,Y,M,C,W,k,r,g,b,y,m,c,w,S,U,Z]
|
||||
|
||||
def pos(self,y,x):
|
||||
return "\033["+str(y)+";"+str(x)+"H"
|
||||
def column(self,x):
|
||||
return "\033["+str(x)+"G"
|
||||
|
||||
def posprint(self, y,x,s):
|
||||
sys.stdout.write( self.pos(y,x) + str(s) )
|
||||
|
||||
def clear(self):
|
||||
sys.stdout.write( self.CLR+self.pos(0,0) )
|
||||
def clear_to_end(self):
|
||||
sys.stdout.write( self.CLREND )
|
||||
def clear_to_beginning(self):
|
||||
sys.stdout.write( self.CLRBEG )
|
||||
|
||||
def up(self,n=1):
|
||||
sys.stdout.write( "\033["+str(n)+"A" )
|
||||
def down(self,n=1):
|
||||
sys.stdout.write( "\033["+str(n)+"B" )
|
||||
def right(self,n=1):
|
||||
sys.stdout.write( "\033["+str(n)+"C" )
|
||||
def left(self,n=1):
|
||||
sys.stdout.write( "\033["+str(n)+"D" )
|
||||
def up_line(self,n=1):
|
||||
sys.stdout.write( "\033["+str(n)+"F" )
|
||||
def down_line(self,n=1):
|
||||
sys.stdout.write( "\033["+str(n)+"E" )
|
||||
|
||||
def save(self):
|
||||
sys.stdout.write( "\033[s" )
|
||||
def restore(self):
|
||||
sys.stdout.write( "\033[u" )
|
||||
|
||||
def color_string(self,s):
|
||||
for i,c in enumerate(self.color_keys):
|
||||
s=s.replace("${"+c+"}",self.color_list[i])
|
||||
return s
|
||||
def nocolor_string(self,s):
|
||||
for i,c in enumerate(self.color_keys):
|
||||
s=s.replace("${"+c+"}","")
|
||||
return s
|
||||
|
||||
class getch:
|
||||
def get(self):
|
||||
fd = sys.stdin.fileno()
|
||||
@@ -226,14 +159,14 @@ class slide_reader:
|
||||
self.data.insert(self.opts.toc_page-1,TOC)
|
||||
|
||||
def launch(self,s):
|
||||
""" Launch in a string using tags $!command$!
|
||||
""" 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:
|
||||
if s.find("`>")==-1:
|
||||
return [s]
|
||||
command=re.match("(.*)\$>(.*)\$>(.*)",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:
|
||||
@@ -267,8 +200,8 @@ 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!
|
||||
* Execute shell: "` command -switch `!" Beware of malicious code!
|
||||
* Execute and print output: "` command `>" Beware of malicious code!
|
||||
|
||||
Keyboard shortcuts:
|
||||
'''+get_interactive_help_text()
|
||||
@@ -282,7 +215,7 @@ Keyboard shortcuts:
|
||||
parser.add_argument("--dc",action="store_true",dest="dark_colors",default=False,
|
||||
help="Use dark colorscheme, better for white background terminals.")
|
||||
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!")
|
||||
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("-m",action="store_true",dest="autocolor",default=False,
|
||||
@@ -324,23 +257,28 @@ def page_print(reader,opts,offset):
|
||||
print(colorify(coloring+page[0],opts))
|
||||
|
||||
# Print page rows
|
||||
parsed=md_color.parse(page)
|
||||
colored=md_color.colorize(parsed,not opts.color,opts.dark_colors)
|
||||
r=0
|
||||
for row in page[1+offset[0]:]:
|
||||
for row_i in range(len(page)):
|
||||
if row_i==0: continue
|
||||
if row_i<offset[0]: continue
|
||||
row=page[row_i]
|
||||
#page[1+offset[0]:]:
|
||||
if not opts.wrap:
|
||||
row=cut_line(row,scrsize[1]-1)
|
||||
row_lines=0
|
||||
else:
|
||||
row_lines=int(float(len(row))/scrsize[1])
|
||||
colored=colorify(row,opts)
|
||||
colored_row=colored[row_i]#=colorify(row,opts)
|
||||
if offset[1]==r+1+offset[0]:
|
||||
colored=add_highlight(row,opts)
|
||||
sys.stdout.write(colored)
|
||||
colored_row=add_highlight(row,opts)
|
||||
sys.stdout.write(colored_row)
|
||||
|
||||
if r>=scrsize[0]-2:
|
||||
break
|
||||
r+=row_lines+1
|
||||
sys.stdout.write("\n")
|
||||
|
||||
return
|
||||
|
||||
def menu_print(reader,opts):
|
||||
@@ -466,46 +404,9 @@ def colorify(s,opts):
|
||||
""" Add colors to string """
|
||||
if not opts.color:
|
||||
return bc.nocolor_string(s)
|
||||
if opts.autocolor and not s.startswith("${"):
|
||||
rules=["(^\s*\*.*)", # * bullets
|
||||
"(^\s*[0-9]+\..*)", # 1. ordered
|
||||
"(^#.*)", ## 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_
|
||||
"(<[^>]+>)"] # <Tags>
|
||||
if opts.dark_colors:
|
||||
colors=["${r}\\1", # * bullets
|
||||
"${r}\\1", # 1. ordered
|
||||
"${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_
|
||||
"${K}\\1${Z}"] # <Tags>
|
||||
else:
|
||||
colors=["${y}\\1", # * bullets
|
||||
"${y}\\1", # 1. ordered
|
||||
"${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_
|
||||
"${K}\\1${Z}"] # <Tags>
|
||||
for r in zip(rules,colors):
|
||||
s=re.sub(r[0],r[1],s)
|
||||
# Replace executable commands with $ only in the beginning
|
||||
s=re.sub("\$[>!]","$",s,1)
|
||||
s=re.sub("\$[>!]","",s)
|
||||
c=bc.color_string(s)+bc.Z
|
||||
return c
|
||||
|
||||
def cut_line(s,i):
|
||||
""" cut a color tagged string, and remove control chars """
|
||||
s=s[:i]
|
||||
@@ -533,11 +434,11 @@ def launch(reader,opts,offset):
|
||||
s=reader.get_current_page()[offset[1]]
|
||||
urls = re.findall('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', s)
|
||||
images = re.findall('!\[[^]]+\]\([^\)]+\)', s)
|
||||
if s.find("$!")==-1 and s.find("$>")==-1 and len(urls)==0 and len(images)==0:
|
||||
if s.find("`")==-1 and len(urls)==0 and len(images)==0:
|
||||
return
|
||||
|
||||
run_command=re.match("(.*)\$!(.*)\$!(.*)",s)
|
||||
show_command=re.match("(.*)\$>(.*)\$>(.*)",s)
|
||||
run_command=re.match("(.*)`(.*)`!(.*)",s)
|
||||
show_command=re.match("(.*)`(.*)`>(.*)",s)
|
||||
if show_command != None:
|
||||
output = subprocess.check_output(show_command.group(2).strip(),shell=True).split("\n")
|
||||
while len(output[0].strip())==0:
|
||||
@@ -571,7 +472,7 @@ def launch(reader,opts,offset):
|
||||
shell=True)
|
||||
return
|
||||
return
|
||||
bc=bc()
|
||||
bc=ansi.code()
|
||||
getch=getch()
|
||||
opts=setup_options()
|
||||
browser(opts,opts.filename)
|
||||
|
||||
Reference in New Issue
Block a user