From 875ca73b3e6d3f61097ae4c6ccae356743d6abef Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Wed, 8 Sep 2010 17:26:37 +0200 Subject: new table handler finally works --- rst_context.lua | 19 ++- rst_helpers.lua | 446 +++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 329 insertions(+), 136 deletions(-) diff --git a/rst_context.lua b/rst_context.lua index fb69dfd..7a556ab 100644 --- a/rst_context.lua +++ b/rst_context.lua @@ -490,14 +490,21 @@ function rst_context.grid_table (tab) ]] local test = "" for i,r in ipairs(tab.rows) do - --if not r.ignore then - if r.newrow and not r.ignore then - --if r.newrow then - --test = test .. string.format("%2s>%s\n", i, #j) - --print(i, unpack(j)) + local isempty = true + for n, cell in ipairs(r) do + if cell.variant == "normal" then + isempty = false + break + end + end + + --if not ( r.sepline or + --r.sephead )then + if not isempty then local row = [[\\bTR]] for n,c in ipairs(r) do - if not c.parent then + if not (c.parent or + c.variant == "separator") then local celltext = c.stripped if c.span.x or c.span.y then local span_exp = "[" diff --git a/rst_helpers.lua b/rst_helpers.lua index e55112d..caf3ed3 100644 --- a/rst_helpers.lua +++ b/rst_helpers.lua @@ -70,7 +70,7 @@ do p.strip = p.whitespace^0 * C((1 - (p.whitespace * p.last))^1) * p.whitespace^0 * p.last end -function helpers.cell.create(raw, n_row, n_col, continue) +function helpers.cell.create(raw, n_row, n_col, parent, variant) local p = patterns local cell = {} cell.stripped = raw and p.strip:match(raw) or "" @@ -84,7 +84,7 @@ function helpers.cell.create(raw, n_row, n_col, continue) cell.span = {} cell.span.x = 1 cell.span.y = 1 - cell.parent = nil + cell.parent = parent return cell end @@ -124,170 +124,356 @@ local function set_layout (line) return layout end +--function helpers.table.create(raw) + --local self = {} + --self.rows = {} + + --local p = patterns + + --self.resolve_parent = function(row, col) + --print(row, col) + --local cell = self.rows[row][col] + --local par_row, par_col + --if cell.parent then + --par_row, par_col = self.resolve_parent(cell.parent.y, cell.parent.x) + --else + --return par_row, par_col + --end + --end + + --self.__init = function() + --local hc = helpers.cell + --self.layout = set_layout(raw[1]) + --local rowcount = 0 + + -- first get the correct horizontal spans + --local next_is_new_row = true + --for n, line in ipairs(raw) do + -- caching the test results + --local sepline = p.sep_line:match(line) + --local sephead = p.sep_head:match(line) + --local seppart = p.sep_part:match(line) + --local newrow = sepline or sephead or seppart + + --if newrow and n > 1 then + --if sephead then + --self.has_head = true + --end + --rowcount = rowcount + 1 + --end + + --if not (sepline or + --sephead) then + --local row = {} + --row.newrow = (newrow or next_is_new_row) and true or false + --next_is_new_row = false + --local sl = self.layout + --local splitted = {p.cells:match(line, 1, sl)} + --local pos_layout, pos_line = 1, 1 + --local last = nil + --local ignore = {} + --ignore.n, ignore.parent = 0, nil + --while pos_layout <= #sl.slices do + --local splitpos = splitted[pos_line] + --local splitpos = splitted[pos_layout] + --local width_layout = sl.widths[pos_layout] + --local span = 1 + --local this + --if ignore.n > 0 then + --ignore.n = ignore.n - 1 + --this = hc.create(false, n, pos_layout, true) + --row[pos_layout] = this + --this.parent = ignore.parent + --else + --local width_cell = utf.len(splitpos) + --if width_cell > width_layout then + --print(splitpos, width_cell, sl.slices[pos_layout], width_layout) + -- check the horizontal span + --span = span + hc.get_x_span(splitpos, sl, pos_layout) + --end + --pos_line = pos_line + span + --this = hc.create(splitpos, n, pos_layout, false) + --if p.dashesonly:match(splitpos) then + --this.variant = "separator" + --end + --this.span.x = span + --last = this + --row[pos_layout] = this + --ignore.n = span - 1 + --ignore.parent = ignore.n > 0 and { y = rowcount, x = pos_layout } or nil + --end + --pos_layout = pos_layout + 1 + --print(">",this.pos.y,this.pos.x,this.span.y,this.span.x) + --if this.span.y > 1 then + --print(">"..this.content.."<") + --end + --end + --self.rows[#self.rows+1] = row + --print(#self.rows.."<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<") + --for i,j in ipairs(row) do print(i,j.content) end + --print(row.newrow) + --else -- separator + --next_is_new_row = true + + --end + --print(string.format("[t-%2s,%2s]> %s", n, m, cell)) + --end + --print("rc = "..rowcount, "nr = "..#self.rows) + --self.rowcount = rowcount + + --if self.rowcount < #self.rows then -- some cells span vertically + --local has_partsep = function(row) + --for n, cell in ipairs(row) do + --if cell.variant == "separator" then + --return true + --end + --end + --return false + --end + + --local dont_do_next = false + --for nr,row in ipairs(self.rows) do + --local ps = has_partsep(row) + + --row.ignore = ps and true or false + --if ps then + --self.rows[nr+1].newrow = true + --end + --if (not row.newrow or ps) and not dont_do_next then + --print(">>>>>>>>>> NEXT <<<<<<<<<<<<") + --print(row.newrow and has_partsep(row)) + -- continues last row either fully or partially + --for nc, cell in ipairs(row) do + --print(nr, nc, cell.content) + --if cell.content == false then + -- empty cell + --elseif cell.variant ~= "separator" then + --local par_row, par_col + --if cell.parent then + --par_row, par_col = self.resolve_parent(cell.parent.y, cell.parent.x) + --print("old parent: ", par_row, par_col) + --else -- no previous span, setting parent to preceding row + --par_row, par_col = nr -1, nc + --print("new parent: ", par_row, par_col) + --end + + --print (nr, nc, cell.content, cell.parent, par_row, par_col) + --local parent = self.rows[par_row][par_col] + --parent.span.y = parent.span.y + 1 + --parent.content = parent.content .. cell.content + --parent.stripped = parent.stripped .. " " .. cell.stripped + + --if ps then + --local successor = self.rows[nr+1][nc] + --successor.parent = { x = par_col, y = par_row } + --parent.span.y = parent.span.y + 1 + --parent.content = parent.content .. successor.content + --parent.stripped = parent.stripped .. " " .. successor.stripped + --dont_do_next = true + --else + --dont_do_next = false + --end + --print(cell.content, parent.content) + --add_y(cell) + --end + --end + --elseif dont_do_next then + --row.ignore = true + --dont_do_next = false + --end + --end + --end -- vertical span handler + --end -- end __init + + --self.__init() + --return self +--end + + function helpers.table.create(raw) local self = {} self.rows = {} + self.layout = set_layout(raw[1]) local p = patterns - self.resolve_parent = function(row, col) - print(row, col) - local cell = self.rows[row][col] - local par_row, par_col + self.resolve_parent = function(row, col, array) + local array = array or self.rows + local cell = array[row][col] + local par_row, par_col = row, col if cell.parent then par_row, par_col = self.resolve_parent(cell.parent.y, cell.parent.x) - else - return par_row, par_col end + return par_row, par_col end - + self.__init = function() local hc = helpers.cell - self.layout = set_layout(raw[1]) local rowcount = 0 - - -- first get the correct horizontal spans - local next_is_new_row = true - for n, line in ipairs(raw) do - -- caching the test results - local sepline = p.sep_line:match(line) - local sephead = p.sep_head:match(line) - local seppart = p.sep_part:match(line) - local newrow = sepline or sephead or seppart - - if newrow and n > 1 then - if sephead then - self.has_head = true - end - rowcount = rowcount + 1 + local selflayout = self.layout + for nr, row in ipairs(raw) do + self.rows[nr] = {} + local this_row = self.rows[nr] + this_row.sepline = p.sep_line:match(row) + this_row.sephead = p.sep_head:match(row) + this_row.seppart = p.sep_part:match(row) + if this_row.sephead then + self.has_head = true end - if not (sepline or - sephead) then - local row = {} - row.newrow = (newrow or next_is_new_row) and true or false - next_is_new_row = false - local sl = self.layout - local splitted = {p.cells:match(line, 1, sl)} - local pos_layout, pos_line = 1, 1 - local last = nil - local ignore = {} - ignore.n, ignore.parent = 0, nil - while pos_layout <= #sl.slices do - --local splitpos = splitted[pos_line] + --if not this_row.sepline and not this_row.sephead then + --print("new row" , row) + local splitted = { p.cells:match(row, 1, selflayout) } + local pos_layout, pos_row = 1, 1 + local make_empty = {} + make_empty.n, make_empty.parent = 0, nil + + while pos_layout <= #selflayout.widths do local splitpos = splitted[pos_layout] - local width_layout = sl.widths[pos_layout] + local layoutwidth = selflayout.widths[pos_layout] local span = 1 local this - if ignore.n > 0 then - ignore.n = ignore.n - 1 - this = hc.create(false, n, pos_layout, true) - row[pos_layout] = this - this.parent = ignore.parent + + if make_empty.n > 0 then + --print(make_empty.n, make_empty.parent) + make_empty.n = make_empty.n - 1 + this = hc.create("", nr, pos_layout, make_empty.parent) + this.parent = make_empty.parent + p_row, p_col = self.resolve_parent(this.parent.y, this.parent.x) + --print(p_row, p_col) + local thisparent = self.rows[p_row][p_col] + --print(this.parent.y, this.parent.x,p_row,p_col) + --this.variant = "empty" --self.rows[p_row][p_col].variant + --if self.rows[p_row][p_col].variant == "separator" then + if this_row.sepline or this_row.sephead or + self.rows[p_row][p_col].variant == "separator" then + this.variant = "separator" + else + this.variant = "empty1" + end + --this.variant = self.rows[p_row][p_col].variant else - local width_cell = utf.len(splitpos) - if width_cell > width_layout then - --print(splitpos, width_cell, sl.slices[pos_layout], width_layout) - -- check the horizontal span - span = span + hc.get_x_span(splitpos, sl, pos_layout) + local cellwidth = utf.len(splitpos) + if cellwidth > layoutwidth then + span = span + hc.get_x_span(splitpos, selflayout, pos_layout) end - pos_line = pos_line + span - this = hc.create(splitpos, n, pos_layout, false) - if p.dashesonly:match(splitpos) then + pos_row = pos_row + span + this = hc.create(splitpos, nr, pos_layout, nil) + --print("this parent: ",this.parent) + if p.dashesonly:match(splitpos) or + this_row.sepline or this_row.sephead then this.variant = "separator" end this.span.x = span - last = this - row[pos_layout] = this - ignore.n = span - 1 - ignore.parent = ignore.n > 0 and { y = rowcount, x = pos_layout } or nil + make_empty.n = span - 1 + make_empty.parent = span > 1 and { y = nr, x = pos_layout } or nil + --print(this.content, make_empty.parent.y, make_empty.parent.x) end + + this_row[pos_layout] = this pos_layout = pos_layout + 1 - --print(">",this.pos.y,this.pos.x,this.span.y,this.span.x) - --if this.span.y > 1 then - --print(">"..this.content.."<") - --end - end - self.rows[#self.rows+1] = row - --print(#self.rows.."<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<") - --for i,j in ipairs(row) do print(i,j.content) end - --print(row.newrow) - else -- separator - next_is_new_row = true + end -- while + --end -- if + end -- for loop over rows + + --for i, j in ipairs(self.rows) do + --print(i, #j) + --if #j > 0 and j[3].parent then + --print(j[3].content, j[3].span.x, j[3].parent.y, j[3].parent.x, j[3].variant) + --end + --end + local oldrows = self.rows + --local newrows = {} + local newrows = oldrows + for nc, width in ipairs(selflayout.widths) do + -- this is gonna be extremely slow but at least it's readable + local newrow + --print("next columnt <-----------------------------") + local currentrow = 1 + for nr, row in ipairs(newrows) do + --newrows[nr] = newrows[nr] or {} + local cell = row[nc] + io.write(string.format("nc: %s, nr:%2s | %9s | ", nc, nr,cell.variant)) + if row.sepline or row.sephead + or p.dashesonly:match(cell.content) + or cell.variant == "separator" then -- separator; skipping and beginning new row + + --newrows[currentrow] = cell + newrows[nr][nc] = cell + currentrow = currentrow + 1 + newrow = true + io.write(string.format("new >%24s< ", cell.stripped)) + if cell.parent then io.write("parent |") else io.write("no par |") end + else + io.write(string.format("old >%24s< ", cell.stripped)) + if cell.parent then io.write("parent |") else io.write("no par |") end + if newrow then + --newrows[currentrow] = cell + newrows[nr][nc] = cell + currentrow = currentrow + 1 + else -- continuing parent + + local par_row, par_col + local parent + if cell.parent then + --io.write(string.format(" use %s,%2s | ", cell.parent.x, cell.parent.y)) + par_row, par_col = self.resolve_parent(cell.parent.y, cell.parent.x, newrows) + io.write(string.format(" use %s,%2s | ", par_col, par_row)) + else -- Using vertical predecessor. + par_row, par_col = self.resolve_parent(nr-1,nc, newrows) + io.write(string.format(" new %s,%2s | ", par_col, par_row)) + end + parent = newrows[par_row][par_col] - end - --print(string.format("[t-%2s,%2s]> %s", n, m, cell)) - end - --print("rc = "..rowcount, "nr = "..#self.rows) - self.rowcount = rowcount + if newrows[nr].seppart then + io.write("span++") + parent.span.y = parent.span.y + 1 + end - if self.rowcount < #self.rows then -- some cells span vertically - local has_partsep = function(row) - for n, cell in ipairs(row) do - if cell.variant == "separator" then - return true + --print(#newrows, par_row) + --if cell.variant ~= "empty1" then + -- Cells of type empty1 already have their content + -- delegated onto their respective horizontal parent. + parent.content = parent.content .. cell.content + parent.stripped = parent.stripped .. " " .. cell.stripped + cell.variant = "empty2" + --end + cell.parent = { x = par_col, y = par_row } + --this = hc.create("", nr, nc, { x = par_col, y = par_row }, "empty2") + --this.variant = "empty2" + --cell = hc.create("", nr, nc, { x = par_col, y = par_row }, "empty2") + --newrows[nr][nc] = this end + newrow = false end - return false - end - - local dont_do_next = false - for nr,row in ipairs(self.rows) do - local ps = has_partsep(row) + io.write("\n") + newrows[nr][nc] = cell + end -- for loop over rows + end -- for loop over columns + --self.rows = oldrows + self.rows = newrows + end - row.ignore = ps and true or false - if ps then - self.rows[nr+1].newrow = true - end - if (not row.newrow or ps) and not dont_do_next then - --print(">>>>>>>>>> NEXT <<<<<<<<<<<<") - --print(row.newrow and has_partsep(row)) - -- continues last row either fully or partially - for nc, cell in ipairs(row) do - --print(nr, nc, cell.content) - if cell.content == false then - -- empty cell - elseif cell.variant ~= "separator" then - local par_row, par_col - if cell.parent then - par_row, par_col = self.resolve_parent(cell.parent.y, cell.parent.x) - --print("old parent: ", par_row, par_col) - else -- no previous span, setting parent to preceding row - par_row, par_col = nr -1, nc - --print("new parent: ", par_row, par_col) - end + self.__init() - print (nr, nc, cell.content, cell.parent, par_row, par_col) - local parent = self.rows[par_row][par_col] - --parent.span.y = parent.span.y + 1 - parent.content = parent.content .. cell.content - parent.stripped = parent.stripped .. " " .. cell.stripped - if ps then - local successor = self.rows[nr+1][nc] - successor.parent = { x = par_col, y = par_row } - parent.span.y = parent.span.y + 1 - parent.content = parent.content .. successor.content - parent.stripped = parent.stripped .. " " .. successor.stripped - dont_do_next = true - else - dont_do_next = false - end - print(cell.content, parent.content) - --add_y(cell) - end - end - elseif dont_do_next then - --row.ignore = true - dont_do_next = false + self.__draw_debug = function() + for nr, row in ipairs(self.rows) do + for nc, cell in ipairs(row) do + local field = cell.variant:sub(1,7) + if cell.parent then + field = field .. string.format(" %s,%2s",cell.parent.x, cell.parent.y) end + io.write(string.format("%12s | ", field)) + --io.write(string.format("%10s | ",(cell.parent and "true" or "false"))) end - end -- vertical span handler - end -- end __init + io.write("\n") + end + end - self.__init() + self.__draw_debug() return self + end - return helpers -- cgit v1.2.3