109 lines
3.8 KiB
Python
Executable File
109 lines
3.8 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
import sys,os,re
|
|
from argparse import ArgumentParser
|
|
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
|
|
import bc
|
|
|
|
__author__ = "Ville Rantanen <ville.q.rantanen@gmail.com>"
|
|
__version__ = "0.1"
|
|
|
|
''' Rules modified from mistune project '''
|
|
|
|
def setup_options():
|
|
''' Create command line options '''
|
|
usage='''
|
|
Color notation renderer in ANSI codes
|
|
Special syntaxes:
|
|
* Colors: insert string ${C}, where C is one of KRGBYMCWkrgbymcwSUZ
|
|
|
|
'''
|
|
|
|
parser=ArgumentParser(description=usage,
|
|
epilog=__author__)
|
|
|
|
parser.add_argument("-v","--version",action="version",version=__version__)
|
|
parser.add_argument("--no-color","-n",action="store_false",dest="color",default=True,
|
|
help="Disable color.")
|
|
parser.add_argument("-z",action="store_true",dest="zero",default=False,
|
|
help="Reset coloring at the end of each line.")
|
|
parser.add_argument("filename",type=str,
|
|
help="File to show, - for stdin")
|
|
opts=parser.parse_args()
|
|
return opts
|
|
|
|
block_match={
|
|
'block_code': (re.compile(r'^( {4}[^*])(.*)$'),'${c}\\1\\2','${Z}${c}'),
|
|
'multiline_code' : (re.compile(r'^ *(`{3,}|~{3,}) *(\S*)?'),'${c}\\1\\2','${Z}${c}'), # ```lang
|
|
'block_quote': (re.compile(r'^(>[ >]* )'),'${K}\\1${Z}','${Z}'),
|
|
|
|
'hrule': (re.compile(r'^ {0,3}[-*_]([-*_]){2,}$'),False,'${Z}'),
|
|
'heading' : (re.compile(r'^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)'),'${W}\\1 \\2','${W}'),
|
|
'lheading' : (re.compile(r'^(=+|-+)$'),'${W}\\1','${W}'),
|
|
'list_bullet':(re.compile(r'^( *)([*+-]|\d+\.)( +)'),'\\1${y}\\2${Z}\\3','${Z}'),
|
|
'text': (re.compile(r'^[^\n]+'),False,'${Z}'),
|
|
'empty': (re.compile(r'^$'),False,'${Z}'),
|
|
}
|
|
blocks=['block_code', 'block_quote', 'multiline_code','hrule', 'heading','lheading','list_bullet', 'text', 'empty']
|
|
|
|
inline_match={
|
|
'bold1': (re.compile(r'(^| )(_[^_]+_)'), '${W}\\1\\2'), # _bold_
|
|
'bold2': (re.compile(r'(^| )(\*{1,2}[^\*]+\*{1,2})'), '${W}\\1\\2'), # **bold**
|
|
'code': (re.compile(r'([`]+[^`]+[`]+)'),'${c}\\1'), # `code`
|
|
'link': (re.compile(r'(\[[^\]]+\]\([^\)]+\))'),'${B}${U}\\1'), # [text](link)
|
|
'image': (re.compile(r'(!\[[^\]]+\]\([^\)]+\))'),'${r}\\1'), # 
|
|
'underline': (re.compile(r'(^|\W)(__)([^_]+)(__)'), '\\1\\2${U}\\3${Z}\\4'), # __underline__
|
|
'strikethrough': (re.compile(r'(~~)([^~]+)(~~)'),'\\1${st}\\2${so}\\3'), # ~~strike~~
|
|
}
|
|
inlines=['bold1','bold2','code','image','link','underline','strikethrough']
|
|
|
|
|
|
bc=bc.ansi()
|
|
opts=setup_options()
|
|
if opts.filename=="-":
|
|
f=sys.stdin
|
|
else:
|
|
f=open(opts.filename,'r')
|
|
block='text'
|
|
new_block='text'
|
|
multiline_block=False
|
|
for row in f:
|
|
if not row:
|
|
continue
|
|
row=row.decode('utf-8').rstrip("\n\r ")
|
|
for match in blocks:
|
|
if block_match[match][0].match(row):
|
|
new_block=match
|
|
if match.startswith('multiline'):
|
|
if multiline_block:
|
|
multiline_block=False
|
|
else:
|
|
multiline_block=match
|
|
break
|
|
if multiline_block:
|
|
new_block=multiline_block
|
|
if new_block!=block:
|
|
block=new_block
|
|
if not multiline_block:
|
|
sys.stdout.write(bc.Z)
|
|
#print(multiline_block)
|
|
#~ print(block)
|
|
if block_match[block][1]:
|
|
row=block_match[block][0].sub(block_match[block][1],row)
|
|
if not (multiline_block or match=='block_code'):
|
|
for match in inlines:
|
|
if inline_match[match][0].search(row):
|
|
row=inline_match[match][0].sub(inline_match[match][1]+block_match[block][2],row)
|
|
|
|
#print(row)
|
|
if opts.color:
|
|
colored=bc.color_string(row)
|
|
else:
|
|
colored=bc.nocolor_string(row)
|
|
sys.stdout.write(colored.encode('utf-8'))
|
|
if opts.zero:
|
|
sys.stdout.write(bc.Z)
|
|
sys.stdout.write("\n")
|
|
|
|
|