summaryrefslogtreecommitdiff
path: root/tex/context/base/tabl-xtb.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/tabl-xtb.lua')
-rw-r--r--tex/context/base/tabl-xtb.lua259
1 files changed, 174 insertions, 85 deletions
diff --git a/tex/context/base/tabl-xtb.lua b/tex/context/base/tabl-xtb.lua
index 04f3eaa50..46f08c6df 100644
--- a/tex/context/base/tabl-xtb.lua
+++ b/tex/context/base/tabl-xtb.lua
@@ -25,7 +25,7 @@ this mechamism will be improved so that it can replace its older cousin.
-- todo: use linked list instead of r/c array
-local tonumber = tonumber
+local tonumber, next = tonumber, next
local commands = commands
local context = context
@@ -110,36 +110,36 @@ local stack, data = { }, nil
function xtables.create(settings)
table.insert(stack,data)
- local rows = { }
- local widths = { }
- local heights = { }
- local depths = { }
- local spans = { }
- local distances = { }
- local autowidths = { }
- local modes = { }
- local fixedrows = { }
- local fixedcolumns = { }
- local frozencolumns = { }
- local options = { }
+ local rows = { }
+ local widths = { }
+ local heights = { }
+ local depths = { }
+ local spans = { }
+ local distances = { }
+ local autowidths = { }
+ local modes = { }
+ local fixedrows = { }
+ local fixedcolumns = { }
+ local frozencolumns = { }
+ local options = { }
data = {
- rows = rows,
- widths = widths,
- heights = heights,
- depths = depths,
- spans = spans,
- distances = distances,
- modes = modes,
- autowidths = autowidths,
- fixedrows = fixedrows,
- fixedcolumns = fixedcolumns,
- frozencolumns = frozencolumns,
- options = options,
- nofrows = 0,
- nofcolumns = 0,
- currentrow = 0,
- currentcolumn = 0,
- settings = settings or { },
+ rows = rows,
+ widths = widths,
+ heights = heights,
+ depths = depths,
+ spans = spans,
+ distances = distances,
+ modes = modes,
+ autowidths = autowidths,
+ fixedrows = fixedrows,
+ fixedcolumns = fixedcolumns,
+ frozencolumns = frozencolumns,
+ options = options,
+ nofrows = 0,
+ nofcolumns = 0,
+ currentrow = 0,
+ currentcolumn = 0,
+ settings = settings or { },
}
local function add_zero(t,k)
t[k] = 0
@@ -155,6 +155,9 @@ function xtables.create(settings)
nx = 0,
ny = 0,
list = false,
+ wd = 0,
+ ht = 0,
+ dp = 0,
}
row[c] = cell
if c > data.nofcolumns then
@@ -210,7 +213,7 @@ function xtables.initialize_reflow_width(option)
end
if option and option ~= "" then
local options = settings_to_hash(option)
- data.options[r][c] = options
+ -- data.options[r][c] = options -- not yet used (commented elsewhere)
if options[v_fixed] then
data.frozencolumns[c] = true
end
@@ -218,8 +221,7 @@ function xtables.initialize_reflow_width(option)
data.currentcolumn = c
end
--- local function rather_fixed(n)
--- for n in node.
+-- todo: we can better set the cell values in one go
function xtables.set_reflow_width()
local r = data.currentrow
@@ -234,19 +236,29 @@ function xtables.set_reflow_width()
--
drc.list = true -- we don't need to keep the content around as we're in trial mode (no: copy_node_list(tb))
--
- local widths, width = data.widths, getfield(tb,"width")
+ local width = getfield(tb,"width")
+ local height = getfield(tb,"height")
+ local depth = getfield(tb,"depth")
+ --
+ local widths = data.widths
+ local heights = data.heights
+ local depths = data.depths
if width > widths[c] then
widths[c] = width
end
- local heights, height = data.heights, getfield(tb,"height")
- if height > heights[r] then
- heights[r] = height
- end
- local depths, depth = data.depths, getfield(tb,"depth")
- if depth > depths[r] then
- depths[r] = depth
+ if drc.ny < 2 then
+ if height > heights[r] then
+ heights[r] = height
+ end
+ if depth > depths[r] then
+ depths[r] = depth
+ end
end
--
+ drc.wd = width
+ drc.ht = height
+ drc.dp = depth
+ --
local dimensionstate = texgetcount("frameddimensionstate")
local fixedcolumns = data.fixedcolumns
local fixedrows = data.fixedrows
@@ -259,25 +271,45 @@ function xtables.set_reflow_width()
elseif dimensionstate == 3 then
fixedrows[r] = height -- width
fixedcolumns[c] = width -- height
- elseif data.options[v_auto] then -- new per 5/5/2014
- data.autowidths[c] = true
- else
- -- no dimensions are set in the cell
- if width <= data.criterium_h and height >= data.criterium_v then
- -- somewhat tricky branch
- if width > fixedcolumns[c] then -- how about a span here?
- -- maybe an image, so let's fix
- fixedcolumns[c] = width
- end
- else
- -- safeguard as it could be text that can be recalculated
- -- and the previous branch could have happened in a previous
- -- row and then forces a wrong one-liner in a multiliner
- if width > fixedcolumns[c] then
- data.autowidths[c] = true -- new per 5/5/2014
- end
+ elseif width <= data.criterium_h and height >= data.criterium_v then
+ -- somewhat tricky branch
+ if width > fixedcolumns[c] then -- how about a span here?
+ -- maybe an image, so let's fix
+ fixedcolumns[c] = width
end
end
+--
+-- -- this fails so not good enough predictor
+--
+-- -- \startxtable
+-- -- \startxrow
+-- -- \startxcell knuth \stopxcell
+-- -- \startxcell \input knuth \stopxcell
+-- -- \stopxrow
+--
+-- else
+-- local o = data.options[r][c]
+-- if o and o[v_auto] then -- new per 5/5/2014 - removed per 15/07/2014
+-- data.autowidths[c] = true
+-- else
+-- -- no dimensions are set in the cell
+-- if width <= data.criterium_h and height >= data.criterium_v then
+-- -- somewhat tricky branch
+-- if width > fixedcolumns[c] then -- how about a span here?
+-- -- maybe an image, so let's fix
+-- fixedcolumns[c] = width
+-- end
+-- else
+-- -- safeguard as it could be text that can be recalculated
+-- -- and the previous branch could have happened in a previous
+-- -- row and then forces a wrong one-liner in a multiliner
+-- if width > fixedcolumns[c] then
+-- data.autowidths[c] = true -- new per 5/5/2014 - removed per 15/07/2014
+-- end
+-- end
+-- end
+-- end
+--
--
drc.dimensionstate = dimensionstate
--
@@ -324,7 +356,6 @@ function xtables.initialize_reflow_height()
end
texsetdimen("d_tabl_x_width",w)
local dimensionstate = drc.dimensionstate or 0
--- print(r,c,w,data.autowidths[c])
if dimensionstate == 1 or dimensionstate == 3 then
-- width was fixed so height is known
texsetcount("c_tabl_x_skip_mode",1)
@@ -347,18 +378,30 @@ function xtables.set_reflow_height()
-- while row[c].span do -- we could adapt drc.nx instead
-- c = c + 1
-- end
- local tb = getbox("b_tabl_x")
+ local tb = getbox("b_tabl_x")
local drc = row[c]
- if data.fixedrows[r] == 0 then -- and drc.dimensionstate < 2
- local heights, height = data.heights, getfield(tb,"height")
- if height > heights[r] then
- heights[r] = height
- end
- local depths, depth = data.depths, getfield(tb,"depth")
- if depth > depths[r] then
- depths[r] = depth
+ --
+ local width = getfield(tb,"width")
+ local height = getfield(tb,"height")
+ local depth = getfield(tb,"depth")
+ --
+ if drc.ny < 2 then
+ if data.fixedrows[r] == 0 then -- and drc.dimensionstate < 2
+ local heights = data.heights
+ local depths = data.depths
+ if height > heights[r] then
+ heights[r] = height
+ end
+ if depth > depths[r] then
+ depths[r] = depth
+ end
end
end
+ --
+ drc.wd = width
+ drc.ht = height
+ drc.dp = depth
+ --
-- c = c + drc.nx - 1
-- data.currentcolumn = c
end
@@ -372,23 +415,35 @@ function xtables.initialize_construct()
c = c + 1
end
data.currentcolumn = c
- local widths = data.widths
+ local widths = data.widths
local heights = data.heights
- local depths = data.depths
- local w = widths[c]
- local h = heights[r]
- local d = depths[r]
+ local depths = data.depths
+ --
local drc = row[c]
+ local wd = drc.wd
+ local ht = drc.ht
+ local dp = drc.dp
+ --
+ local width = widths[c]
+ local height = heights[r]
+ local depth = depths[r]
+ --
for x=1,drc.nx-1 do
- w = w + widths[c+x]
+ width = width + widths[c+x]
end
- for y=1,drc.ny-1 do
- h = h + heights[r+y]
- d = d + depths[r+y]
+ --
+ local total = height + depth
+ local ny = drc.ny
+ if ny > 1 then
+ for y=1,ny-1 do
+ local nxt = r + y
+ total = total + heights[nxt] + depths[nxt]
+ end
end
- texsetdimen("d_tabl_x_width",w)
- texsetdimen("d_tabl_x_height",h + d)
- texsetdimen("d_tabl_x_depth",0)
+ --
+ texsetdimen("d_tabl_x_width",width)
+ texsetdimen("d_tabl_x_height",total)
+ texsetdimen("d_tabl_x_depth",0) -- for now
end
function xtables.set_construct()
@@ -401,8 +456,7 @@ function xtables.set_construct()
-- end
local drc = row[c]
-- this will change as soon as in luatex we can reset a box list without freeing
--- drc.list = copy_node_list(getbox("b_tabl_x"))
-drc.list = takebox("b_tabl_x")
+ drc.list = takebox("b_tabl_x")
-- c = c + drc.nx - 1
-- data.currentcolumn = c
end
@@ -435,6 +489,8 @@ function xtables.reflow_width()
local maxwidth = settings.maxwidth
-- calculate width
local widths = data.widths
+ local heights = data.heights
+ local depths = data.depths
local distances = data.distances
local autowidths = data.autowidths
local fixedcolumns = data.fixedcolumns
@@ -576,10 +632,42 @@ function xtables.reflow_height()
data.currentrow = 0
data.currentcolumn = 0
local settings = data.settings
+ --
+ -- analyze ny
+ --
+ local nofrows = data.nofrows
+ local nofcolumns = data.nofcolumns
+ local widths = data.widths
+ local heights = data.heights
+ local depths = data.depths
+ --
+ for r=1,nofrows do
+ for c=1,nofcolumns do
+ local drc = data.rows[r][c]
+ if drc then
+ local ny = drc.ny
+ if ny > 1 then
+ local height = heights[r]
+ local depth = depths[r]
+ local total = height + depth
+ local htdp = drc.ht + drc.dp
+ for y=1,ny-1 do
+ local nxt = r + y
+ total = total + heights[nxt] + depths[nxt]
+ end
+ local delta = htdp - total
+ if delta > 0 then
+ delta = delta / ny
+ for y=1,ny do
+ heights[y] = heights[y] + delta
+ end
+ end
+ end
+ end
+ end
+ end
+ --
if settings.options[v_height] then
- local heights = data.heights
- local depths = data.depths
- local nofrows = data.nofrows
local totalheight = 0
local totaldepth = 0
for i=1,nofrows do
@@ -597,6 +685,7 @@ function xtables.reflow_height()
end
end
end
+ --
end
local function showspans(data)