diff -ur v21/ezmd.py v22/ezmd.py --- v21/ezmd.py 2019-10-03 23:45:00.000000000 +0900 +++ v22/ezmd.py 2019-10-04 20:10:13.000000000 +0900 @@ -5,7 +5,7 @@ import nkf heads = [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'h7', 'h8', 'h9' ] -modes = heads + [ 'p', 'pre', 'ul', 'dl', 'tbl', 'index' ] +modes = heads + [ 'p', 'pre', 'ul', 'dl', 'tbl', 'index', 'swbuf' ] is_all_ge_n = lambda s, c, n: all( map( lambda c_: c_ == c, s ) ) and len(s) >= n @@ -35,6 +35,43 @@ setattr(self, k, v) return self +def outbuf_new(): + d = {} + e = Empty() + + def swbuf(name=''): + if not name: + name = 'org' + if name not in d: + d[ name ] = [] + e.name = name + + lst_get = lambda name='': d.get( name if name else e.name, [] ) + append = lambda o: lst_get().append(o) + extend = lambda o: lst_get().extend(o) + + stk = [] + def tmp_name(): + nm_i = lambda i: 'tmp_' + str(i) + i = 0 + while nm_i(i) in d: + i += 1 + return nm_i(i) + def push_tmp(): + stk.append( e.name ) + swbuf( tmp_name() ) + def pop_tmp(): + if not e.name.startswith('tmp_') or not stk: + return [] + lst = d.pop(e.name) + swbuf( stk.pop() ) + return lst + + swbuf() + return e.to_attr( locals() ) + +outbuf = outbuf_new() + def tag_new(name, prop, v): return Empty( locals() ) @@ -119,6 +156,8 @@ return tag_new('s', {}, v2) if v1 == 'name': return tag_new('a', {'name': v2}, '') + if v1 == 'paste': + return outbuf.lst_get(v2) return tag_new('a', {'href': v1}, v2) if v1 else v2 def do_br(s): @@ -158,7 +197,7 @@ sol = map_sol(cv, sol) return sol -def do_mode_ul(buf, res): +def do_mode_ul(buf): buf = esc_join(buf) buf = list( filter( lambda s: s.strip(), buf ) ) buf = list( map(idt_cnt, buf) ) # (i, s) @@ -191,9 +230,9 @@ lst = list( map(f, lst) ) return tag_new('ul', {}, lst) - res.extend( list( map(lst_to, lsts) ) ) + outbuf.extend( list( map(lst_to, lsts) ) ) -def do_mode_dl(buf, res): +def do_mode_dl(buf): buf = lst_to_empty(buf) buf = cut_ht_empty(buf) if buf: @@ -212,7 +251,7 @@ e = buf_loop_new(buf, is_call, func) e.run() - res.append( tag_new('dl', {}, lst) ) + outbuf.append( tag_new('dl', {}, lst) ) def do_tr(s): tgl = lambda md, n: md if n == 1 else ('th' if md == 'td' else 'td') @@ -254,13 +293,13 @@ tbl_prop = { 'border': 1, 'cellspacing': 0 } -def do_tbl_org(buf, res): +def do_tbl_org(buf): buf = esc_join(buf) buf = lst_strip(buf) buf = cut_empty(buf) if buf: v = list( map(do_tr, buf) ) - res.append( tag_new('table', tbl_prop, v) ) + outbuf.append( tag_new('table', tbl_prop, v) ) def ul_to_tbl(ul): def pack_ul(ul): @@ -329,11 +368,12 @@ trs.pop() return tbl -def do_tbl_ul(buf, res): - uls = [] - do_mode_ul(buf, uls) +def do_tbl_ul(buf): + outbuf.push_tmp() + do_mode_ul(buf) + uls = outbuf.pop_tmp() for ul in uls: - res.append( ul_to_tbl(ul) ) + outbuf.append( ul_to_tbl(ul) ) def tbls_join(tbls): def w_get(tag): @@ -361,8 +401,8 @@ prop = tbls[0].prop return tag_new('table', prop, trs) -def do_mode_tbl(buf, res): - res_ = [] +def do_mode_tbl(buf): + outbuf.push_tmp() def is_call(e): if e.s in ('tbl_org', 'tbl_ul'): @@ -373,24 +413,24 @@ def func(e): if e.mode == 'tbl_org': - do_tbl_org(e.tmp, res_) + do_tbl_org(e.tmp) elif e.mode == 'tbl_ul': - do_tbl_ul(e.tmp, res_) + do_tbl_ul(e.tmp) e = buf_loop_new(buf, is_call, func) e.mode = 'tbl_org' e.run() - res.append( tbls_join(res_) ) + outbuf.append( tbls_join( outbuf.pop_tmp() ) ) -def do_mode(mode, buf, res, hd_names): +def do_mode(mode, buf, hd_names): if mode in heads: buf = lst_strip(buf) buf = cut_empty(buf) s = ''.join(buf) (h_i, n) = ( int(mode[1:]), len(hd_names) ) name = 'c_{}_{}'.format(h_i, n) - res.append( tag_new( mode, {}, tag_new('a', {'name': name}, s) ) ) + outbuf.append( tag_new( mode, {}, tag_new('a', {'name': name}, s) ) ) hd_names.append( (h_i, n, name, s) ) elif mode == 'p': @@ -406,27 +446,33 @@ lst = [] for lst in lsts: lst = flat_map(do_str, lst) - res.append( tag_new('p', {}, lst) ) + if lst: + outbuf.append( tag_new('p', {}, lst) ) elif mode == 'pre': buf = cut_ht_empty(buf) if buf: buf = cut_verb_idt(buf) s = '\n'.join(buf) + '\n' - res.append( tag_new('pre', {}, s) ) + outbuf.append( tag_new('pre', {}, s) ) elif mode == 'ul': - do_mode_ul(buf, res) + do_mode_ul(buf) elif mode == 'dl': - do_mode_dl(buf, res) + do_mode_dl(buf) elif mode == 'tbl': - do_mode_tbl(buf, res) + do_mode_tbl(buf) elif mode == 'hr': - res.extend( [ tag_new('p', {}, tag_new('hr', {}, '/') ) ] * len(buf) ) + outbuf.extend( [ tag_new('p', {}, tag_new('hr', {}, '/') ) ] * len(buf) ) elif mode == 'index': buf = lst_strip(buf) buf = cut_empty(buf) - res.append( tag_new('index', {}, buf) ) # continue to 2 pass + outbuf.append( tag_new('index', {}, buf) ) # continue to 2 pass + elif mode == 'swbuf': + buf = lst_strip(buf) + buf = cut_empty(buf) + name = buf[0] if buf else '' + outbuf.swbuf(name) -def do_index(lst, hd_names): +def do_index(hd_names): def slice_get(buf): slc = ':' @@ -453,26 +499,26 @@ func = lambda h_i, n, name, s: ' ' * h_i + '[[#{}|'.format(name) + s + ']]' buf = list( map( lambda vs: func(*vs), names ) ) - ul_res = [] - do_mode_ul(buf, ul_res) - return ul_res + outbuf.push_tmp() + do_mode_ul(buf) + return outbuf.pop_tmp() - return flat_map( lambda tag: f(tag.v) if tag.name == 'index' else tag, lst ) + return flat_map( lambda tag: f(tag.v) if tag.name == 'index' else tag, outbuf.lst_get() ) def ezmd(lst): lst = ['p'] + lst - (buf, res, hd_names) = ( [], [], [] ) + (buf, hd_names) = ( [], [] ) def is_call(e): (e.s, e.next_mode) = next_mode_switch(e.s, e.mode) return e.next_mode != e.mode - func = lambda e: do_mode(e.mode, e.tmp, res, hd_names) + func = lambda e: do_mode(e.mode, e.tmp, hd_names) e = buf_loop_new(lst, is_call, func) e.run() - res = do_index(res, hd_names) + res = do_index(hd_names) return res def yaml_dump(o):