diff -ur v16/ezmd.py v17/ezmd.py --- v16/ezmd.py 2019-10-02 04:11:00.000000000 +0900 +++ v17/ezmd.py 2019-10-02 20:42:54.000000000 +0900 @@ -246,14 +246,126 @@ lst = flat_map( lambda s_md: th_td(*s_md), lst ) return tag_new('tr', {}, lst) -def do_mode_tbl(buf, res): +tbl_prop = { 'border': 1, 'cellspacing': 0 } + +def do_tbl_org(buf, res): buf = esc_join(buf) buf = lst_strip(buf) buf = cut_empty(buf) if buf: - prop = {'border': 1, 'cellspacing': 0} v = list( map(do_tr, buf) ) - res.append( tag_new('table', prop, v) ) + res.append( tag_new('table', tbl_prop, v) ) + +def ul_to_tbl(ul): + def pack_ul(ul): + (lst, last) = ([], None) + for tag in ul.v: + if tag.name == 'li': + last = tag + lst.append(tag) + elif tag.name == 'ul' and last: + pack_ul(tag) + last.prop['sub_ul'] = tag + ul.v = lst + + pack_ul(ul) + + def sz_get(tag): + if tag.name == 'li': + k = 'sub_ul' + (w, h) = sz_get( tag.prop.get(k) ) if k in tag.prop else (0, 1) + return ( w + 1, max(h, 1) ) + if tag.name == 'ul': + (ws, hs) = zip( *map(sz_get, tag.v) ) + return ( max(ws), sum(hs) ) + return (0, 0) + + (gw, gh) = sz_get(ul) + + def cv_to_tbl(tag, x, tbl): + if tag.name == 'ul': + for tag_ in tag.v: + cv_to_tbl(tag_, x, tbl) + elif tag.name == 'li': + prop = {} + tr = tbl.v[-1] + tr.v.append( tag_new('td', prop, tag.v) ) + + (w, h) = sz_get(tag) + if h > 1: + prop['rowspan'] = h + + k = 'sub_ul' + if k in tag.prop: + cv_to_tbl( tag.prop.get(k), x+1, tbl ) + else: + w = w - x + 1 + if w > 1: + prop['colspan'] = w + tbl.v.append( tag_new('tr', {}, []) ) + + trs = [ tag_new('tr', {}, []) ] + tbl = tag_new( 'table', tbl_prop, trs ) + + cv_to_tbl(ul, 0, tbl) + + if trs[-1].v == []: + trs.pop() + return tbl + +def do_tbl_ul(buf, res): + uls = [] + do_mode_ul(buf, uls) + for ul in uls: + res.append( ul_to_tbl(ul) ) + +def tbls_join(tbls): + def w_get(tag): + if tag.name in ('th', 'td'): + return tag.prop.get('colspan', 1) + if tag.name == 'tr': + return sum( map(w_get, tag.v) ) + if tag.name == 'table': + return max( map(w_get, tag.v) ) + return 0 + + w_max = max( map(w_get, tbls) ) + + trs = [] + for tbl in tbls: + for tr in tbl.v: + add = w_max - w_get(tr) + tail = tr.v[-1] + k = 'colspan' + w = tail.prop.get(k, 1) + add + if w > 1: + tail.prop[k] = w + trs.append(tr) + + prop = tbls[0].prop + return tag_new('table', prop, trs) + +def do_mode_tbl(buf, res): + res_ = [] + + def is_call(e): + if e.s in ('tbl_org', 'tbl_ul'): + e.next_mode = e.s # ok + e.s = None + return e.next_mode != e.mode + return False + + def func(e): + if e.mode == 'tbl_org': + do_tbl_org(e.tmp, res_) + elif e.mode == 'tbl_ul': + do_tbl_ul(e.tmp, res_) + + e = buf_loop_new(buf, is_call, func) + e.mode = 'tbl_org' + e.run() + + res.append( tbls_join(res_) ) def do_mode(mode, buf, res, hd_names): if mode in heads: