diff -ur v26/ezmd.py v27/ezmd.py --- v26/ezmd.py 2019-10-08 20:57:18.000000000 +0900 +++ v27/ezmd.py 2019-10-10 00:20:14.000000000 +0900 @@ -94,7 +94,7 @@ return { k: v_get(tag.v) } to_lst = lambda o: o if type(o) == list else [o] -from_lst = lambda lst: lst[0] if len(lst) == 1 else lst +from_lst = lambda lst: lst[0] if len(lst) == 1 else ( lst if lst else '' ) flat_map = lambda f, lst: sum( map( lambda o: to_lst( f(o) ), lst ), [] ) lst_strip = lambda lst: list( map( lambda s: s.strip(), lst ) ) @@ -146,6 +146,16 @@ return lst[:1] + esc_join( lst[1:] ) s_idx = lambda s, p, dv=-1: s.index(p) if p in s else dv +r_idx = lambda o, p, dv=-1: len(o) - 1 - s_idx( o[::-1], p ) if p in o else dv +div_idx = lambda o, i: ( o[:i], o[i:] ) + +def div_delim(o, delim): + i = s_idx(o, delim) + n = 1 if type(o) == list else len(delim) + return ( o[:i], o[i+n:] ) + +is_str = lambda o: type(o) != list and not isinstance(o, Empty) # !!! +lst_strip_is_str = lambda lst: list( map( lambda o: o.strip() if is_str(o) else o, lst ) ) def delim_pop(s, delim): f = lambda lst: ( lst[0], delim.join( lst[1:] ) ) @@ -162,6 +172,23 @@ pass return [] +def do_detail(v2): + if '|' in v2: + v2 = lst_strip_is_str( div_delim(v2, '|') ) + elif type(v2) == list and v2 and is_str( v2[0] ) and '|' in v2[0]: + (a, b) = lst_strip_is_str( div_delim(v2[0], '|') ) + v2 = ( a, ( [b] if b else [] ) + v2[1:] ) + elif type(v2) == list and v2 and is_str( v2[-1] ) and '|' in v2[-1]: + (a, b) = lst_strip_is_str( div_delim(v2[-1], '|') ) + v2 = ( v2[:-1] + ( [a] if a else [] ), b ) + else: + return None + (summary, detail) = v2 + if is_str(detail): + detail = outbuf.lst_get(detail) + v = [ tag_new('summary', {}, summary) ] + to_lst(detail) + return tag_new('details', {}, v) + def do_v1v2(v1, v2): lst = ('s', 'em', 'strong', 'u', 'i', 'b') if v1 in lst: @@ -181,10 +208,10 @@ return outbuf.lst_get(v2) if v1 == 'prop': return do_prop(v1, v2) - if v1 == 'detail' and '|' in v2: - (summary, buf_name) = lst_strip( delim_pop(v2, '|') ) - v = [ tag_new('summary', {}, summary) ] + outbuf.lst_get(buf_name) - return tag_new('details', {}, v) + if v1 == 'detail': + r = do_detail(v2) + if r: + return r return tag_new('a', {'href': v1}, v2) if v1 else v2 def do_br(s): @@ -194,19 +221,58 @@ return from_lst( cut_empty(lst) ) return s +def get_token(s, ks): + idxs = list( map( lambda k: s_idx(s, k), ks ) ) + i_s = list( filter( lambda i: idxs[i] >= 0, range( len(ks) ) ) ) + if not i_s: + return ( s.strip(), '' ) + zs = list( filter( lambda i: idxs[i] == 0, i_s ) ) + if zs: + return div_idx( s, len( ks[ zs[0] ] ) ) + + i = min( map( lambda i: idxs[i], i_s ) ) + (w, s) = div_idx(s, i) + w = w.strip() + return (w, s) if w else get_token(s, ks) # ! + +def join_str(lst): + if len(lst) < 2: + return lst + (v, lst) = ( lst[0], join_str( lst[1:] ) ) + if is_str(v) and lst and is_str( lst[0] ): + return [ v + lst[0] ] + lst[1:] + return [v] + lst + def do_a_href(s): - (h, t) = ('[[', ']]') - (ih, it) = list( map( lambda p: s_idx(s, p), (h, t) ) ) - if 0 <= ih and ih < it: - s3 = lst_strip( ( s[:ih], s[ih+len(h):it], s[it+len(t):] ) ) - - def mcv(s): - (v1, v2) = lst_strip( delim_pop(s, '|') ) if '|' in s else (s, s) - return do_v1v2(v1, v2) - - cvs = ( (lambda s: s), mcv, do_a_href ) - f = lambda i: cvs[i]( s3[i] ) - return from_lst( cut_empty( flat_map( f, range(3) ) ) ) + def eval_targ(lst): + lst_ = lst[1:-1] + if not lst_: + return lst + + vs = [ lst_, lst_ ] # default + i = s_idx(lst_, '|') + if i >= 0: + vs = [ lst_[:i], lst_[i+1:] ] + + (v1, v2) = vs = list( map( from_lst, vs ) ) + if not is_str(v1): + return lst + (v1, v2) = lst_strip_is_str(vs) + if type(v2) == list: + v2 = from_lst( join_str(v2) ) + + return do_v1v2(v1, v2) + + if s and '[[' in s and ']]' in s: + lst = [] + while s: + (k, s) = get_token( s, ('[[', '|', ']]') ) + lst.append(k) + if k == ']]' and '[[' in lst: + (lst, targ) = div_idx( lst, r_idx(lst, '[[') ) + lst = lst + to_lst( eval_targ(targ) ) + lst = join_str(lst) + return from_lst(lst) if lst else [] return s do_out_quote = lambda s: s [1:-1] if len(s) >= 2 and s[0] == s[-1] and s[0] in ("'", '"') else s @@ -216,7 +282,7 @@ # def map_sol(f_s_ret_sol, sol): f = lambda o: o if isinstance(o, Empty) else f_s_ret_sol(o) - return flat_map(f, sol) if type(sol) == list else f_s_ret_sol(sol) + return flat_map(f, sol) if type(sol) == list else f(sol) def do_str(sol): # str or list cvs = (do_out_quote, do_br, do_a_href)