diff --git a/gluon/contrib/markmin/markmin2html.py b/gluon/contrib/markmin/markmin2html.py index 0a520b18..211a9e39 100755 --- a/gluon/contrib/markmin/markmin2html.py +++ b/gluon/contrib/markmin/markmin2html.py @@ -7,10 +7,11 @@ import re import urllib from cgi import escape from string import maketrans + try: - from ast import parse as ast_parse - import ast -except ImportError: # python 2.5 + from ast import parse as ast_parse + import ast +except ImportError: # python 2.5 from compiler import parse import compiler.ast as ast @@ -530,41 +531,47 @@ As shown in Ref.!`!`mdipierro`!`!:cite ``
``, ``...
`` around them. """ -html_colors=['aqua', 'black', 'blue', 'fuchsia', 'gray', 'green', - 'lime', 'maroon', 'navy', 'olive', 'purple', 'red', - 'silver', 'teal', 'white', 'yellow'] +html_colors = ['aqua', 'black', 'blue', 'fuchsia', 'gray', 'green', + 'lime', 'maroon', 'navy', 'olive', 'purple', 'red', + 'silver', 'teal', 'white', 'yellow'] META = '\x06' LINK = '\x07' DISABLED_META = '\x08' LATEX = '[^\]]*)\])?)?)',re.S)
-regex_strong=re.compile(r'\*\*(?P [a-zA-Z][_a-zA-Z\-\d]*)\])?)?$')
+regex_URL = re.compile(r'@/(?P\w*)/(?P [^\]]*)\])?)?)',
+ re.S)
+regex_strong = re.compile(r'\*\*(?P [a-zA-Z][_a-zA-Z\-\d]*)\])?)?$')
regex_proto = re.compile(r'(?/=])(?P \w+):(?P popup))?\s*$',re.S)
-regex_media_level2=re.compile(r'^(?P img|IMG|left|right|center|video|audio|blockleft|blockright)(?:\s+(?P popup))?\s*$', re.S)
+regex_media_level2 = re.compile(
+ r'^(?P img|IMG|left|right|center|video|audio|blockleft|blockright)(?:\s+(?P anchor with name \\'NEWLINE\\': newline "
- pend = " "
+ pend = " '
- p_end = ' '
- p_end = ' '
- p_end = '.+?)\]\]',re.S)
-regex_link_level2=re.compile(r'^(?P.+?)\]\]', re.S)
+regex_link_level2 = re.compile(r'^(?P' % url
- elif u_url.endswith(('.mp4','.mpeg','.mov','.ogv')):
+ elif u_url.endswith(('.mp4', '.mpeg', '.mov', '.ogv')):
return '' % url
- elif u_url.endswith(('.mp3','.wav','.ogg')):
+ elif u_url.endswith(('.mp3', '.wav', '.ogg')):
return '' % url
- return '%s' % (url,url)
+ return '%s' % (url, url)
+
def protolinks_simple(proto, url):
"""
@@ -667,16 +684,18 @@ def protolinks_simple(proto, url):
proto="iframe"
url="http://www.example.com/path"
"""
- if proto in ('iframe','embed'): #== 'iframe':
- return ''%url
- #elif proto == 'embed': # NOTE: embed is a synonym to iframe now
+ if proto in ('iframe', 'embed'): # == 'iframe':
+ return '' % url
+ # elif proto == 'embed': # NOTE: embed is a synonym to iframe now
# return '%s>'%(url,class_prefix,url)
elif proto == 'qr':
- return '
'%url
- return proto+':'+url
+ return '
' % url
+ return proto + ':' + url
+
def email_simple(email):
- return '%s' % (email, email)
+ return '%s' % (email, email)
+
def render(text,
extra={},
@@ -925,17 +944,19 @@ def render(text,
>>> render("anchor with name 'NEWLINE': [[NEWLINE [newline] ]]")
'
tag
# - consists '|' -> table
# - consists other characters -> blockquote
- if (lineno+1 >= strings_len or
- not(s.count('-') == len(s) and len(s)>3)):
- return (s, mtag, lineno)
+ if (lineno + 1 >= strings_len or
+ not (s.count('-') == len(s) and len(s) > 3)):
+ return (s, mtag, lineno)
- lineno+=1
+ lineno += 1
s = strings[lineno].strip()
if s:
if '|' in s:
# table
- tout=[]
- thead=[]
- tbody=[]
- rownum=0
+ tout = []
+ thead = []
+ tbody = []
+ rownum = 0
t_id = ''
t_cls = ''
@@ -1104,14 +1130,14 @@ def render(text,
s = strings[lineno].strip()
if s[:1] == '=':
# header or footer
- if s.count('=')==len(s) and len(s)>3:
- if not thead: # if thead list is empty:
+ if s.count('=') == len(s) and len(s) > 3:
+ if not thead: # if thead list is empty:
thead = tout
else:
tbody.extend(tout)
tout = []
- rownum=0
- lineno+=1
+ rownum = 0
+ lineno += 1
continue
m = regex_tq.match(s)
@@ -1121,36 +1147,36 @@ def render(text,
break
if rownum % 2:
- tr = ''
+ tr = ' '
else:
- tr = ' ' if rownum == 0 else ' '
+ tr = ' ' if rownum == 0 else ' '
tout.append(tr + ''.join([' '+pp)
- rownum+=1
- lineno+=1
+ ' class="num"'
+ if regex_num.match(f) else '',
+ f.strip()
+ ) for f in s.split('|')]) + '' + pp)
+ rownum += 1
+ lineno += 1
- t_cls = ' class="%s%s"'%(class_prefix, t_cls) \
+ t_cls = ' class="%s%s"' % (class_prefix, t_cls) \
if t_cls and t_cls != 'id' else ''
- t_id = ' id="%s%s"'%(id_prefix, t_id) if t_id else ''
+ t_id = ' id="%s%s"' % (id_prefix, t_id) if t_id else ''
s = ''
if thead:
- s += ''+pp+''.join([l for l in thead])+''+pp
- if not tbody: # tbody strings are in tout list
+ s += '' + pp + ''.join([l for l in thead]) + '' + pp
+ if not tbody: # tbody strings are in tout list
tbody = tout
tout = []
- if tbody: # if tbody list is not empty:
- s += ''+pp+''.join([l for l in tbody])+''+pp
- if tout: # tfoot is not empty:
- s += ''+pp+''.join([l for l in tout])+''+pp
+ if tbody: # if tbody list is not empty:
+ s += '' + pp + ''.join([l for l in tbody]) + '' + pp
+ if tout: # tfoot is not empty:
+ s += '' + pp + ''.join([l for l in tout]) + '' + pp
s = '%s ' % (
- ' class="num"'
- if regex_num.match(f) else '',
- f.strip()
- ) for f in s.split('|')])+'%s%s
%s' % (t_cls, t_id, pp, s, pp)
- mtag='t'
+ mtag = 't'
else:
# parse blockquote:
- bq_begin=lineno
- t_mode = False # embedded table
+ bq_begin = lineno
+ t_mode = False # embedded table
t_cls = ''
t_id = ''
@@ -1160,57 +1186,57 @@ def render(text,
if not t_mode:
m = regex_tq.match(s)
if m:
- if (lineno+1 == strings_len or
- '|' not in strings[lineno+1]):
- t_cls = m.group('c') or ''
- t_id = m.group('p') or ''
- break
+ if (lineno + 1 == strings_len or
+ '|' not in strings[lineno + 1]):
+ t_cls = m.group('c') or ''
+ t_id = m.group('p') or ''
+ break
if regex_bq_headline.match(s):
- if (lineno+1 < strings_len and
- strings[lineno+1].strip()):
- t_mode = True
- lineno+=1
+ if (lineno + 1 < strings_len and
+ strings[lineno + 1].strip()):
+ t_mode = True
+ lineno += 1
continue
elif regex_tq.match(s):
- t_mode=False
- lineno+=1
+ t_mode = False
+ lineno += 1
continue
- lineno+=1
+ lineno += 1
- t_cls = ' class="%s%s"'%(class_prefix,t_cls) \
+ t_cls = ' class="%s%s"' % (class_prefix, t_cls) \
if t_cls and t_cls != 'id' else ''
- t_id = ' id="%s%s"'%(id_prefix,t_id) \
+ t_id = ' id="%s%s"' % (id_prefix, t_id) \
if t_id else ''
-
+
s = '%s
%s' \
- % (t_cls,
- t_id,
- '\n'.join(strings[bq_begin:lineno]),pp)
- mtag='q'
+ % (t_cls,
+ t_id,
+ '\n'.join(strings[bq_begin:lineno]), pp)
+ mtag = 'q'
else:
s = '
'
- lineno-=1
- mtag='q'
+ lineno -= 1
+ mtag = 'q'
return (s, 'q', lineno)
if sep == 'p':
- pbeg = "
"+pp if sep=='br' else ''
+ pbeg = pend = ''
+ br = "
" + pp if sep == 'br' else ''
- lev = 0 # nesting level of lists
- c0 = '' # first character of current line
- out = [] # list of processed lines
- etags = [] # trailing tags
- ltags = [] # level# correspondent to trailing tag
+ lev = 0 # nesting level of lists
+ c0 = '' # first character of current line
+ out = [] # list of processed lines
+ etags = [] # trailing tags
+ ltags = [] # level# correspondent to trailing tag
tlev = [] # list of tags for each level ('ul' or 'ol')
mtag = '' # marked tag (~last tag) ('l','.','h','p','t'). Used to set
- # and to avoid around tables and blockquotes
+ # and to avoid around tables and blockquotes
lineno = 0
strings_len = len(strings)
while lineno < strings_len:
@@ -1222,65 +1248,67 @@ def render(text,
#### ++++ ---- .... ------- field | field | field <-body
##### +++++ ----- ..... ---------------------:class[id]
"""
- pc0=c0 # first character of previous line
- c0=s[:1]
- if c0: # for non empty strings
- if c0 in "#+-.": # first character is one of: # + - .
- (t1,t2,p,ss) = regex_list.findall(s)[0]
+ pc0 = c0 # first character of previous line
+ c0 = s[:1]
+ if c0: # for non empty strings
+ if c0 in "#+-.": # first character is one of: # + - .
+ (t1, t2, p, ss) = regex_list.findall(s)[0]
# t1 - tag ("###")
# t2 - tag ("+++", "---", "...")
# p - paragraph point ('.')->for "++." or "--."
# ss - other part of string
if t1 or t2:
# headers and lists:
- if c0 == '#': # headers
+ if c0 == '#': # headers
(lev, mtag) = parse_title(t1, ss)
- lineno+=1
+ lineno += 1
continue
- elif c0 == '+': # ordered list
- (lev, mtag, lineno)= parse_list(t2, p, ss, 'ol', lev, mtag, lineno)
- lineno+=1
+ elif c0 == '+': # ordered list
+ (lev, mtag, lineno) = parse_list(t2, p, ss, 'ol', lev, mtag, lineno)
+ lineno += 1
continue
- elif c0 == '-': # unordered list, table or blockquote
+ elif c0 == '-': # unordered list, table or blockquote
if p or ss:
(lev, mtag, lineno) = parse_list(t2, p, ss, 'ul', lev, mtag, lineno)
- lineno+=1
+ lineno += 1
continue
else:
(s, mtag, lineno) = parse_table_or_blockquote(s, mtag, lineno)
- elif lev>0: # and c0 == '.' # paragraph in lists
+ elif lev > 0: # and c0 == '.' # paragraph in lists
(lev, mtag, lineno) = parse_point(t2, ss, lev, mtag, lineno)
- lineno+=1
+ lineno += 1
continue
if lev == 0 and (mtag == 'q' or s == META):
# new paragraph
- pc0=''
+ pc0 = ''
- if pc0 == '' or (mtag != 'p' and s0 not in (' ','\t')):
+ if pc0 == '' or (mtag != 'p' and s0 not in (' ', '\t')):
# paragraph
out.extend(etags[::-1])
- etags=[]
- ltags=[]
- tlev=[]
- lev=0
- if br and mtag == 'p': out.append(br)
+ etags = []
+ ltags = []
+ tlev = []
+ lev = 0
+ if br and mtag == 'p':
+ out.append(br)
if mtag != 'q' and s != META:
- if pend: etags=[pend]
- out.append(pbeg)
- mtag = 'p'
+ if pend:
+ etags = [pend]
+ out.append(pbeg)
+ mtag = 'p'
else:
- mtag = ''
+ mtag = ''
out.append(s)
else:
- if lev>0 and mtag=='.' and s == META:
+ if lev > 0 and mtag == '.' and s == META:
out.append(etags.pop())
ltags.pop()
out.append(s)
mtag = ''
else:
- out.append(' '+s)
- lineno+=1
+ out.append(' ' + s)
+ lineno += 1
out.extend(etags[::-1])
text = ''.join(out)
@@ -1295,7 +1323,7 @@ def render(text,
# deal with images, videos, audios and links
#############################################################
def sub_media(m):
- t,a,k,p,w = m.group('t','a','k','p','w')
+ t, a, k, p, w = m.group('t', 'a', 'k', 'p', 'w')
if not k:
return m.group(0)
k = escape(k)
@@ -1305,40 +1333,40 @@ def render(text,
p_begin = p_end = ''
if p == 'center':
p_begin = '%(end)s' \
- % dict(begin=p_begin, k=k, alt=alt, title=title, style=style, end=p_end)
+ % dict(begin=p_begin, k=k, alt=alt, title=title, style=style, end=p_end)
def sub_link(m):
- t,a,k,p = m.group('t','a','k','p')
+ t, a, k, p = m.group('t', 'a', 'k', 'p')
if not k and not t:
return m.group(0)
t = t or ''
a = escape(a) if a else ''
if k:
- if '#' in k and not ':' in k.split('#')[0]:
+ if '#' in k and ':' not in k.split('#')[0]:
# wikipage, not external url
- k=k.replace('#','#'+id_prefix)
+ k = k.replace('#', '#' + id_prefix)
k = escape(k)
title = ' title="%s"' % a.replace(META, DISABLED_META) if a else ''
target = ' target="_blank"' if p == 'popup' else ''
@@ -1347,18 +1375,18 @@ def render(text,
return '%(t)s' \
% dict(k=k, title=title, target=target, t=t)
if t == 'NEWLINE' and not a:
- return '
'+pp
+ return '
' + pp
return '%s' % (
- escape(id_prefix+t),
- render(a, {},{},'br', URL,
+ escape(id_prefix + t),
+ render(a, {}, {}, 'br', URL,
environment, latex, autolinks,
protolinks, class_prefix,
id_prefix, pretty_print))
-
+
parts = text.split(LINK)
text = parts[0]
- for i,s in enumerate(links):
- if s == None:
+ for i, s in enumerate(links):
+ if s is None:
html = LINK
else:
html = regex_media_level2.sub(sub_media, s)
@@ -1366,51 +1394,53 @@ def render(text,
html = regex_link_level2.sub(sub_link, html)
if html == s:
# return unprocessed string as a signal of an error
- html = '[[%s]]'%s
- text += html + parts[i+1]
+ html = '[[%s]]' % s
+ text += html + parts[i + 1]
#############################################################
# process all code text
#############################################################
def expand_meta(m):
- code,b,p,s = segments.pop(0)
- if code==None or m.group() == DISABLED_META:
+ code, b, p, s = segments.pop(0)
+ if code is None or m.group() == DISABLED_META:
return escape(s)
if b in extra:
- if code[:1]=='\n': code=code[1:]
- if code[-1:]=='\n': code=code[:-1]
+ if code[:1] == '\n':
+ code = code[1:]
+ if code[-1:] == '\n':
+ code = code[:-1]
if p:
- return str(extra[b](code,p))
+ return str(extra[b](code, p))
else:
return str(extra[b](code))
- elif b=='cite':
- return '['+','.join('%s' \
- % (id_prefix+d,b,d) \
- for d in escape(code).split(','))+']'
- elif b=='latex':
+ elif b == 'cite':
+ return '[' + ','.join('%s' %
+ (id_prefix + d, b, d) for d in escape(code).split(',')) + ']'
+ elif b == 'latex':
return LATEX % urllib.quote(code)
elif b in html_colors:
return '%s' \
- % (b, render(code, {}, {}, 'br', URL, environment, latex,
- autolinks, protolinks, class_prefix, id_prefix, pretty_print))
+ % (b, render(code, {}, {}, 'br', URL, environment, latex,
+ autolinks, protolinks, class_prefix, id_prefix, pretty_print))
elif b in ('c', 'color') and p:
- c=p.split(':')
- fg='color: %s;' % c[0] if c[0] else ''
- bg='background-color: %s;' % c[1] if len(c)>1 and c[1] else ''
- return '%s' \
- % (fg, bg, render(code, {}, {}, 'br', URL, environment, latex,
- autolinks, protolinks, class_prefix, id_prefix, pretty_print))
- cls = ' class="%s%s"'%(class_prefix,b) if b and b != 'id' else ''
- id = ' id="%s%s"'%(id_prefix,escape(p)) if p else ''
- beg=(code[:1]=='\n')
- end=[None,-1][code[-1:]=='\n']
+ c = p.split(':')
+ fg = 'color: %s;' % c[0] if c[0] else ''
+ bg = 'background-color: %s;' % c[1] if len(c) > 1 and c[1] else ''
+ return '%s' \
+ % (fg, bg, render(code, {}, {}, 'br', URL, environment, latex,
+ autolinks, protolinks, class_prefix, id_prefix, pretty_print))
+ cls = ' class="%s%s"' % (class_prefix, b) if b and b != 'id' else ''
+ id = ' id="%s%s"' % (id_prefix, escape(p)) if p else ''
+ beg = (code[:1] == '\n')
+ end = [None, -1][code[-1:] == '\n']
if beg and end:
return '
%s' % (cls, id, escape(code[1:-1]), pp)
return '%s%s' % (cls, id, escape(code[beg:end]))
+
text = regex_expand_meta.sub(expand_meta, text)
if environment:
- text = replace_components(text,environment)
+ text = replace_components(text, environment)
return text.translate(ttab_out)
@@ -1423,16 +1453,18 @@ def markmin2html(text, extra={}, allowed={}, sep='p',
class_prefix=class_prefix, id_prefix=id_prefix,
pretty_print=pretty_print)
+
def run_doctests():
import doctest
doctest.testmod()
+
if __name__ == '__main__':
import sys
import doctest
from textwrap import dedent
- html=dedent("""
+ html = dedent("""
@@ -1446,7 +1478,7 @@ if __name__ == '__main__':
""")[1:]
if sys.argv[1:2] == ['-h']:
- style=dedent("""
+ style = dedent("""
"
finally:
@@ -1496,10 +1529,9 @@ if __name__ == '__main__':
fargv.close()
else:
- print "Usage: "+sys.argv[0]+" -h | -t | file.markmin [file.css|@path_to/css]"
+ print "Usage: " + sys.argv[0] + " -h | -t | file.markmin [file.css|@path_to/css]"
print "where: -h - print __doc__"
print " -t - timeit __doc__ (for testing purpuse only)"
print " file.markmin [file.css] - process file.markmin + built in file.css (optional)"
print " file.markmin [@path_to/css] - process file.markmin + link path_to/css (optional)"
run_doctests()
-