diff options
Diffstat (limited to 'macros/luatex')
-rw-r--r-- | macros/luatex/generic/lutabulartools/lutabulartools.lua | 336 | ||||
-rw-r--r-- | macros/luatex/generic/lutabulartools/lutabulartools.pdf | bin | 114054 -> 116020 bytes | |||
-rw-r--r-- | macros/luatex/generic/lutabulartools/lutabulartools.sty | 63 | ||||
-rw-r--r-- | macros/luatex/generic/lutabulartools/lutabulartools.tex | 204 |
4 files changed, 335 insertions, 268 deletions
diff --git a/macros/luatex/generic/lutabulartools/lutabulartools.lua b/macros/luatex/generic/lutabulartools/lutabulartools.lua index 23ef965482..719f89873e 100644 --- a/macros/luatex/generic/lutabulartools/lutabulartools.lua +++ b/macros/luatex/generic/lutabulartools/lutabulartools.lua @@ -1,5 +1,5 @@ --% Kale Ewasiuk (kalekje@gmail.com) ---% 2022-11-27 +--% 2022-11-29 --% Copyright (C) 2021-2022 Kale Ewasiuk --% --% Permission is hereby granted, free of charge, to any person obtaining a copy @@ -30,31 +30,33 @@ if (__PL_EXTRAS__ == nil) or (__PENLIGHT__ == nil) then end local T = pl.tablex -local ltt = {} +local lutabt = {} -ltt.tablelevel = 0 +lutabt.tablelevel = 0 -ltt.debug = false +lutabt.debug = false -ltt.auto_topbot = false +lutabt.auto_topbot = false +lutabt.auto_topbot_old = false -ltt.auto_crules = {} -- {{span,trim}, } appearance is like this, 'range|trim', -- auto_rules created by MC -ltt.auto_midrules = {} +lutabt.auto_crules = {} -- {{span,trim}, } appearance is like this, 'range|trim', -- auto_rules created by MC +lutabt.auto_midrules = {} -ltt.col_spec1 = {} -- column spec if one column wide (since makcell nests a tabular, preserve col_spec below) -ltt.col_spec = {} -- tab column spec if above 1 -ltt.col = '' -- current column spec, single char, only applies to tabular with more than 1 column -ltt.col_num = 1 -- current column number -ltt.row_num = 0 -- current row number +lutabt.col_spec1 = {} -- column spec if one column wide (since makcell nests a tabular, preserve col_spec below) +lutabt.col_spec = {} -- tab column spec if above 1 +lutabt.col = '' -- current column spec, single char, only applies to tabular with more than 1 column +lutabt.col_num = 1 -- current column number +lutabt.row_num = 0 -- current row number +lutabt.actlvl = 1 -- 'active' level on which to apply midrules, normally 1 -ltt.col_ver_repl = { +lutabt.col_ver_repl = { m = 'm', M = 'm', b = 'b', } -ltt.col_hor_repl = { -- horizontal cell alignment that multicolumn should use if () or [hori] not passed to func +lutabt.col_hor_repl = { -- horizontal cell alignment that multicolumn should use if () or [hori] not passed to func l = 'l', c = 'c', r = 'r', @@ -70,11 +72,11 @@ ltt.col_hor_repl = { -- horizontal cell alignment that multicolumn should use if } -- allow user to place their own replacements in for a table, say if they define a column that expands to multiple -ltt.col_replaces = { +lutabt.col_replaces = { --x = 'lll' } -ltt.SI_cols = {'S', 'N', 'Q', 'L', 'R'} +lutabt.SI_cols = {'S', 'N', 'Q', 'L', 'R'} @@ -83,24 +85,33 @@ ltt.SI_cols = {'S', 'N', 'Q', 'L', 'R'} ----- -function ltt.debugtalk(s, ss) +function lutabt.debugtalk(s, ss) ss = ss or '' - if ltt.debug then + if lutabt.debug then pl.tex.help_wrt(s, ss..' (lutabulartools)') end end +function __lutabt__debugprtall() + --pl.help_wrt(pl.tablex.filter({ lutabt }, function(v) return type(v) ~= 'function' end), '(lutabulartools state)') + pl.help_wrt(lutabt, '(lutabulartools state)') +end + -function ltt.set_tabular(sett) +function lutabt.set_tabular(sett) sett = luakeys.parse(sett) local trim = '' for k, v in pairs(sett) do if k == 'tbrule' then - ltt.auto_topbot = v + lutabt.auto_topbot = v elseif k == 'nopad' then if pl.hasval(v) then trim = '@{}' end -- set to trim tex.print('\\newcolumntype{\\lttltrim}{'..trim..'}') tex.print('\\newcolumntype{\\lttrtrim}{'..trim..'}') + elseif k =='rowsep' then + tex.print('\\gdef\\arraystretch{'..v..'}') + elseif k =='colsep' then + tex.print('\\global\\setlength{\\tabcolsep}{'..(v*6)..'pt'..'}') end end end @@ -110,13 +121,13 @@ end ----- tabular utility funcs ----- -function ltt.reset_rows() - if ltt.tablelevel == 1 then - ltt.row_num = 0 +function lutabt.reset_rows() + if lutabt.isactlevel() then + lutabt.row_num = 0 end end -function ltt.set_col_num() +function lutabt.set_col_num() -- register current column info (column number and specification) local nest for i = tex.nest.ptr, 1, -1 do @@ -131,16 +142,16 @@ function ltt.set_col_num() for _, sub in node.traverse_id(node.id'unset', nest.head) do col = col + sub + 1 end - ltt.col_num = col + lutabt.col_num = col else - ltt.col_num = 1 + lutabt.col_num = 1 end - ltt.col = ltt.col_spec[ltt.col_num] - ltt.debugtalk('col_num='..ltt.col_num..'; col_spec='..ltt.col,'set_col_num') + lutabt.col = lutabt.col_spec[lutabt.col_num] + lutabt.debugtalk('col_num='..lutabt.col_num..'; col_spec='..lutabt.col,'set_col_num') end -function ltt.set_col_spec(zz) +function lutabt.set_col_spec(zz) -- contents of string 'zz' -- register the table column specification zz = zz:gsub ( "%*%s-{(%d-)}%s-(%b{})" , -- expand expressions such as "*{5}{l}" to "lllll" @@ -148,15 +159,15 @@ function ltt.set_col_spec(zz) zz = zz:gsub ( "%b{}" , "" ) -- omit all stuff in curly braces and square zz = zz:gsub ( "%b[]" , "" ) zz = zz:gsub ( "[@!|><%s%*\']" , "" ) -- some more characters to ignore - zz = zz:gsub('%a', ltt.col_replaces) -- sub extra column + zz = zz:gsub('%a', lutabt.col_replaces) -- sub extra column _col_spec = zz:totable() -- requires pl extras --help_wrt(_col_spec, 'helpme') if #_col_spec > 1 then - ltt.col_spec = _col_spec + lutabt.col_spec = _col_spec else - ltt.col_spec1 = _col_spec + lutabt.col_spec1 = _col_spec end - ltt.debugtalk(ltt.col_spec,'set_col_spec') + lutabt.debugtalk(lutabt.col_spec,'set_col_spec') end @@ -171,23 +182,26 @@ end ----- magic cell and helpers ----- -function ltt.MagicCell(s0,spec,mcspec,pre,content,trim) +function lutabt.MagicCell(s0,spec,mcspec,pre,content,trim) + -- todo delete trim!!! -- - ltt.set_col_num() -- register current column number and column spec + lutabt.set_col_num() -- register current column number and column spec local STR = '' pl.tex.reset_bkt_cnt() - local v, h, r, c, mrowsym, skipmakecell = ltt.parse_MagicCell_spec(spec) -- get v/h align, number rows/columns + local spec, iscmidrule, trim = lutabt.check_MC_cmidrule(spec) -- check for cmidrule and clean spec + + local v, h, r, c, mrowsym, skipmakecell = lutabt.parse_MagicCell_spec(spec) -- get v/h align, number rows/columns local mcspec = mcspec or '' - h, mcspec, c = ltt.get_HColSpec(h, mcspec, c) -- infer horizontal alignment, num columns + h, mcspec, c = lutabt.get_HColSpec(h, mcspec, c) -- infer horizontal alignment, num columns - ltt.debugtalk(pl.List{v, h, r, c, mcspec}:join'; ','v, h, r, c, mcspec') + lutabt.debugtalk(pl.List{v, h, r, c, mcspec}:join'; ','v, h, r, c, mcspec') --help_wrt(_CurTabColAbv,'current column') - if s0 == pl.tex._xTrue or (pl.List(ltt.SI_cols):contains(ltt.col) -- special columns for SI + if s0 == pl.tex._xTrue or (pl.List(lutabt.SI_cols):contains(lutabt.col) -- special columns for SI and c == '') then -- multicolumn cannot have {} around it STR = STR .. '{' -- multirow and makcell must have {} around it S column is used pl.tex.add_bkt_cnt() @@ -217,17 +231,30 @@ function ltt.MagicCell(s0,spec,mcspec,pre,content,trim) STR = STR..content..pl.tex.close_bkt_cnt() --Troubleshooting --help_wrt(STR..' <<< magic cell string') - ltt.debugtalk(STR,'MagicCell') + lutabt.debugtalk(STR,'MagicCell') tex.sprint(STR)--tex print the STR - local en - if c == '' then en = ltt.col_num else en = ltt.col_num + c -1 end - ltt.add_auto_crule(ltt.col_num, en, trim) + if iscmidrule then + local en + if c == '' then en = lutabt.col_num else en = lutabt.col_num + c -1 end + lutabt.add_auto_crule(lutabt.col_num, en, trim) + end end +function lutabt.check_MC_cmidrule(spec) + local iscmidrule = false + local trim = '' + local st, en = spec:find('_') + if st ~= nil then + trim = spec:sub(st+1, #spec) + spec = spec:sub(1,st-1) + iscmidrule = true + end + return spec, iscmidrule, trim +end -function ltt.parse_MagicCell_spec(spec) +function lutabt.parse_MagicCell_spec(spec) local mrowsym = '*' -- * = natural width, = will match p{2cm} for example local skipmakecell = false if string.find(spec, '=') then @@ -238,7 +265,7 @@ function ltt.parse_MagicCell_spec(spec) spec = spec:lower():gsub('%s','') -- take lower case and remove space local vh, rc = spec:gextract('%a') -- extract characters - local v = vh:gfirst({'t', 'm', 'b'}) or ltt.col_ver_repl[ltt.col] or 't' + local v = vh:gfirst({'t', 'm', 'b'}) or lutabt.col_ver_repl[lutabt.col] or 't' local h = vh:gfirst({'l', 'c', 'r'}) or '' v = v:gsub('m', 'c') @@ -252,27 +279,27 @@ function ltt.parse_MagicCell_spec(spec) end -function ltt.get_HColSpec(h, mcspec, c) -- take horizontal alignment +function lutabt.get_HColSpec(h, mcspec, c) -- take horizontal alignment -- c is num columns, h is horizontal alginment, --Assumes _TabColNum was calculated previosly if c == '+' then -- fill row to end - c = tostring(#ltt.col_spec - ltt.col_num + 1) + c = tostring(#lutabt.col_spec - lutabt.col_num + 1) end if h == '' then -- if horizontal not provided, use declared column - h = ltt.col_hor_repl[ltt.col] or 'l' + h = lutabt.col_hor_repl[lutabt.col] or 'l' end if c ~= '' then -- only make new mcspec if column nums > 0 if mcspec == '' then -- and if no mcspec was passed mcspec = h - if ltt.col_num == 1 then -- if first column, auto detect padding + if lutabt.col_num == 1 then -- if first column, auto detect padding mcspec = '@{}'..mcspec end - if (ltt.col_num + tonumber(c) - 1) == #ltt.col_spec then -- if end on last column + if (lutabt.col_num + tonumber(c) - 1) == #lutabt.col_spec then -- if end on last column mcspec = mcspec..'@{}' end else -- if mcspec if given, extract the alignment - ltt.set_col_spec(mcspec) - h = ltt.col_spec1[1] -- get 1 character column spec from mcspec and override h + lutabt.set_col_spec(mcspec) + h = lutabt.col_spec1[1] -- get 1 character column spec from mcspec and override h end end return h, mcspec, c @@ -280,52 +307,54 @@ end ----- ------ autorules (with \MC() or auto top bot +----- autorules (with \MC() or auto top bot or midrule X, performed after \\ ----- -function ltt.add_auto_midrules(rows) - ltt.auto_midrules = rows:split(',') +function lutabt.add_auto_midrules(rows) + lutabt.auto_midrules = rows:split(',') end -function ltt.add_auto_crule(st,en,trim) +function lutabt.add_auto_crule(st,en,trim) if trim ~= 'x' then - ltt.auto_crules[#ltt.auto_crules + 1] = {math.floor(st)..'-'..math.floor(en), trim} -- append here + lutabt.auto_crules[#lutabt.auto_crules + 1] = {math.floor(st)..'-'..math.floor(en), trim} -- append here -- {{span 1-2, trim}, ..} end end +function lutabt.isactlevel() + lutabt.tablelevel = tonumber(lutabt.tablelevel) + lutabt.actlvl = tonumber(lutabt.actlvl) + return lutabt.actlvl == lutabt.tablelevel +end -function ltt.process_auto_rules() - if ltt.tablelevel == 1 then - ltt.row_num = ltt.row_num + 1 - end - if ltt.auto_crules ~= {} then - if ltt.tablelevel == 1 then - for _, v in ipairs(ltt.auto_crules) do - --pl.help_wrt(ltt.auto_crules, 'fuck') - ltt.make1cmidrule('', v[2], v[1], 'cmidrule') + +function lutabt.process_auto_rules() + if lutabt.isactlevel() then + lutabt.row_num = lutabt.row_num + 1 + if lutabt.auto_crules ~= {} then + for _, v in ipairs(lutabt.auto_crules) do + lutabt.make1cmidrule('', v[2], v[1], 'cmidrule') end - for i, v in ipairs(ltt.auto_midrules) do - --pl.help_wrt(ltt.auto_midrules, 'fuck') - --pl.help_wrt(v, 'fuck') - pl.help_wrt(ltt.row_num, 'fuck') - if tonumber(v) == ltt.row_num then - _ = table.remove(ltt.auto_midrules,i) - --pl.help_wrt(v, 'removed!') + for i, v in ipairs(lutabt.auto_midrules) do + if tonumber(v) == lutabt.row_num then + _ = table.remove(lutabt.auto_midrules,i) tex.print('\\midrule ') end end end + if lutabt.mrX.settings.on then + lutabt.mrX.midruleX() + end end - ltt.auto_crules = {} + lutabt.auto_crules = {} end -function ltt.process_auto_topbot_rule(rule) - if ltt.tablelevel == 1 then - if ltt.auto_topbot then +function lutabt.process_auto_topbot_rule(rule) + if lutabt.isactlevel() then + if lutabt.auto_topbot then tex.print('\\'..rule..'rule ') end end @@ -337,31 +366,24 @@ end ----- ------ midrule and midruleX stuff +----- extra midrule ----- -ltt.mrX = {} -ltt.mrX.defaults = {step=5, rule='midrule', reset=false, resetnum=0, cntr=0} -ltt.mrX.settings = T.copy(ltt.mrX.defaults) -ltt.mrX.cntr = 0 -ltt.mrX.pgcntr = 0 - - -function ltt.get_midrule_col(s) +function lutabt.get_midrule_col(s) if string.find(s, '+') then s = s:gsub('+', '') if (s == '') or (s == '0') then s = 1 end - s = tostring(#ltt.col_spec - tonumber(s) + 1) -- use number of tabular columns above 0, + s = tostring(#lutabt.col_spec - tonumber(s) + 1) -- use number of tabular columns above 0, end return s end -function ltt.make1cmidrule(s, r, c, cmd) -- s=square r=round c=curly +function lutabt.make1cmidrule(s, r, c, cmd) -- s=square r=round c=curly cmd = '\\'..cmd if s ~= '' then cmd = cmd..'['..s..']' @@ -376,61 +398,86 @@ function ltt.make1cmidrule(s, r, c, cmd) -- s=square r=round c=curly if t[2] == nil then t[2] = t[1] end - c = ltt.get_midrule_col(t[1])..'-'..ltt.get_midrule_col(t[2]) + c = lutabt.get_midrule_col(t[1])..'-'..lutabt.get_midrule_col(t[2]) cmd = cmd..'{'..c..'}' - ltt.debugtalk(cmd,'make1cmidrule') + lutabt.debugtalk(cmd,'make1cmidrule') tex.print(cmd) end -function ltt.makecmidrules(s, r, c, cmd) +function lutabt.makecmidrules(s, r, c, cmd) for k, c1 in pairs(string.split(c, ',')) do r1, c2 = c1:gextract('%a') if r1 == '' then -- if nothing passed in with the column r1 = r -- set to the global value passed in round brackets end - ltt.make1cmidrule(s, r1:strip(), c2:strip(), cmd) + lutabt.make1cmidrule(s, r1:strip(), c2:strip(), cmd) end end +----- +----- midruleX +----- + +lutabt.mrX = {} +lutabt.mrX.resets = {long=false, longhead=0, cntr=0, head=nil, longx=false, on=true} -- settings that reset when \setmidruleX used +lutabt.mrX.resets['head*'] = nil +lutabt.mrX.settings = T.update(T.copy(lutabt.mrX.resets), {pgcntr=0, step=5, rule='midrule'}) -- current settings, not overwritten with each call + + +function lutabt.mrX.reset_midruleX(n) + lutabt.mrX.settings.cntr = tonumber(n) +end + +function lutabt.mrX.off() + if lutabt.isactlevel() then + lutabt.mrX.settings.on = false + end +end -function ltt.mrX.set_midruleX(new_sett, def) - def = def or '' - local curr_sett = {} - if def == pl.tex._xTrue then -- default flag, if true, reset all non-used keys to default - curr_sett = ltt.mrX.defaults +function lutabt.mrX.set_midruleX(new_sett, def) + lutabt.mrX.settings = T.update(lutabt.mrX.settings, T.union(lutabt.mrX.resets, luakeys.parse(new_sett))) + lutabt.debugtalk(lutabt.mrX.settings, 'new midruleX settings') + if lutabt.mrX.settings.head ~= nil then + lutabt.mrX.settings.cntr = -1*tonumber(lutabt.mrX.settings.head) + elseif lutabt.mrX.settings['head*'] ~= nil then + lutabt.mrX.settings.cntr = -1*tonumber(lutabt.mrX.settings['head*']) + lutabt.auto_midrules[#lutabt.auto_midrules + 1] = lutabt.mrX.settings['head*'] + lutabt.mrX.settings['head*'] = nil -- for some reason need to do this to clear head* + end + if lutabt.mrX.settings.longx then -- longtable X messes with the tablelevel settings, hack to fix, use longx keyword + lutabt.actlvl = 3 + lutabt.mrX.settings.long = true else - curr_sett = ltt.mrX.settings + lutabt.actlvl = 1 end - new_sett = luakeys.parse(new_sett) - ltt.mrX.settings = T.union(curr_sett, new_sett) - ltt.debugtalk(ltt.mrX.settings, 'new midruleX settings') - ltt.mrX.cntr = curr_sett.cntr end -function ltt.mrX.midruleX(n) + +function lutabt.mrX.midruleX(n) n = n or '' -- todo placeholder for noalign ? - local s = ltt.mrX.settings + lutabt.debugtalk(lutabt.mrX.settings, 'midruleX here') + local s = lutabt.mrX.settings local rule = s.rule - if pl.hasval(s.reset) and ltt.mrX.add_label_and_check_page_change() then ltt.mrX.cntr = s.resetnum end - ltt.mrX.cntr = ltt.mrX.cntr + 1 - if ltt.mrX.cntr == s.step then + if pl.hasval(s.long) and lutabt.mrX.add_label_and_check_page_change() then lutabt.mrX.settings.cntr = -1*s.longhead end -- reset to number on page change + lutabt.mrX.settings.cntr = lutabt.mrX.settings.cntr + 1 + if lutabt.mrX.settings.cntr == s.step then if not rule:startswith('\\') then rule = '\\'..rule end -- todo consider allowing \gmidrule syntax, possible issue with expansion - ltt.debugtalk(rule, 'apply midruleX') + lutabt.debugtalk(rule, 'apply midruleX') tex.sprint(rule) - ltt.mrX.cntr = 0 + lutabt.mrX.settings.cntr = 0 end end -function ltt.mrX.add_label_and_check_page_change() - ltt.mrX.pgcntr = ltt.mrX.pgcntr + 1 - tex.print('\\noalign{\\label{ltt@tabular@row@'..ltt.mrX.pgcntr..'}}') - local rcurr = pl.tex.get_ref_info('ltt@tabular@row@'..ltt.mrX.pgcntr) - local rprev = pl.tex.get_ref_info('ltt@tabular@row@'..ltt.mrX.pgcntr-1) - --local rcurrc, _, _ = pl.tex.get_ref_info_all_cref('ltt@tabular@row@'..ltt.mrX.pgcntr) - ltt.debugtalk('curr: '..rcurr[2]..' prev: '..rprev[2]..' row: '..ltt.mrX.pgcntr, 'check midruleX page change') - ltt.debugtalk(rcurr, 'miduleX current reference info for row: '..ltt.mrX.pgcntr) - --ltt.debugtalk(rcurrc, 'miduleX current cleveref cref info') +function lutabt.mrX.add_label_and_check_page_change() + lutabt.mrX.settings.pgcntr = lutabt.mrX.settings.pgcntr + 1 + tex.print('\\noalign{\\label{ltt@tabular@row@'..lutabt.mrX.settings.pgcntr..'}}') + local rcurr = pl.tex.get_ref_info('ltt@tabular@row@'..lutabt.mrX.settings.pgcntr) + local rprev = pl.tex.get_ref_info('ltt@tabular@row@'..lutabt.mrX.settings.pgcntr-1) + --local rcurrc, _, _ = pl.tex.get_ref_info_all_cref('ltt@tabular@row@'..lutabt.mrX.settings.pgcntr) + lutabt.debugtalk('curr: '..rcurr[2]..' prev: '..rprev[2]..' row: '..lutabt.mrX.settings.pgcntr, 'check midruleX page change') + lutabt.debugtalk(rcurr, 'miduleX current reference info for row: '..lutabt.mrX.settings.pgcntr) + --lutabt.debugtalk(rcurrc, 'miduleX current cleveref cref info') if rcurr[2] ~= rprev[2] then -- pg no is second element return true end @@ -438,18 +485,28 @@ function ltt.mrX.add_label_and_check_page_change() end +return lutabt -- lutabulartools + + + +--http://ctan.mirror.rafal.ca/macros/latex/contrib/multirow/multirow.pdf +--http://ctan.mirror.colo-serv.net/macros/latex/contrib/makecell/makecell.pdf +-- https://tex.stackexchange.com/questions/331716/newline-in-multirow-environment + + + -- ---ltt.tabular_row_pages_cntr = 0 ---function ltt.reset_midruleX_on_newpage(n) +--lutabt.tabular_row_pages_cntr = 0 +--function lutabt.reset_midruleX_on_newpage(n) -- local n = n or 0 --- ltt.tabular_row_pages_cntr = ltt.tabular_row_pages_cntr + 1 --- tex.print('\\noalign{\\label{tabular@row@'..ltt.tabular_row_pages_cntr..'}}') --- if ltt.get_ref_page('tabular@row@'..ltt.tabular_row_pages_cntr) - --- ltt.get_ref_page('tabular@row@'..(ltt.tabular_row_pages_cntr-1)) == 1 then +-- lutabt.tabular_row_pages_cntr = lutabt.tabular_row_pages_cntr + 1 +-- tex.print('\\noalign{\\label{tabular@row@'..lutabt.tabular_row_pages_cntr..'}}') +-- if lutabt.get_ref_page('tabular@row@'..lutabt.tabular_row_pages_cntr) - +-- lutabt.get_ref_page('tabular@row@'..(lutabt.tabular_row_pages_cntr-1)) == 1 then -- tex.print('\\setcounter{midruleX}{'..n..'}') -- end --end @@ -457,14 +514,29 @@ end --help_wrt('TEST COL ') --for _, s in ipairs{ 'll', '*{6}{s}', 'l*{6}{l}', 'lll', 'll[]', 'll[]*{6}{l}', '*{6}{l}', 'y*{6}{sq}x', } do --- ltt. set_col_spec(s) --- help_wrt(ltt.col_spec,s) +-- lutabt. set_col_spec(s) +-- help_wrt(lutabt.col_spec,s) --end -return ltt -- lutabulartools - - ---http://ctan.mirror.rafal.ca/macros/latex/contrib/multirow/multirow.pdf ---http://ctan.mirror.colo-serv.net/macros/latex/contrib/makecell/makecell.pdf --- https://tex.stackexchange.com/questions/331716/newline-in-multirow-environment +-- todo move mrX mechanim to avoid @{} +--function lutabt.mrX.set_midruleX(new_sett, def) +-- def = def or '' +-- local curr_sett = {} +-- if def == pl.tex._xTrue then -- default flag, if true, reset all non-used keys to default +-- curr_sett = lutabt.mrX.defaults +-- else +-- curr_sett = lutabt.mrX.settings +-- end +-- new_sett = luakeys.parse(new_sett) +-- lutabt.mrX.settings = T.union(curr_sett, new_sett) +-- +-- lutabt.debugtalk(lutabt.mrX.settings, 'new midruleX settings') +-- lutabt.mrX.settings.cntr = tonumber(curr_sett.cntr) -- todo this needs to be a settings var +-- if new_sett.cntr ~= nil then -- todo fix the counter +-- lutabt.mrX.settings.cntr = tonumber(new_sett.cntr) +-- end +-- if new_sett.head ~= nil then -- todo fix the counter +-- lutabt.mrX.settings.cntr = -1*tonumber(new_sett.head) +-- end +--end diff --git a/macros/luatex/generic/lutabulartools/lutabulartools.pdf b/macros/luatex/generic/lutabulartools/lutabulartools.pdf Binary files differindex c915ba6291..74c3446796 100644 --- a/macros/luatex/generic/lutabulartools/lutabulartools.pdf +++ b/macros/luatex/generic/lutabulartools/lutabulartools.pdf diff --git a/macros/luatex/generic/lutabulartools/lutabulartools.sty b/macros/luatex/generic/lutabulartools/lutabulartools.sty index 1d2522b099..4ca3752578 100644 --- a/macros/luatex/generic/lutabulartools/lutabulartools.sty +++ b/macros/luatex/generic/lutabulartools/lutabulartools.sty @@ -1,5 +1,5 @@ % Kale Ewasiuk (kalekje@gmail.com) -% 2022-11-27 +% 2022-11-29 % Copyright (C) 2021-2022 Kale Ewasiuk % % Permission is hereby granted, free of charge, to any person obtaining a copy @@ -23,7 +23,7 @@ % OR OTHER DEALINGS IN THE SOFTWARE. \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{lutabulartools}[2022-11-27] +\ProvidesPackage{lutabulartools}[2022-11-29] \RequirePackage{booktabs} \RequirePackage{multirow} @@ -39,6 +39,7 @@ \newcommand{\lttdebugON}{\luadirect{lutabt.debug = true}} \newcommand{\lttdebugOFF}{\luadirect{lutabt.debug = true}} +\newcommand{\lttdebugprt}{\luadirect{__lutabt__debugprtall()}} \newcolumntype{\lttltrim}{} \newcolumntype{\lttrtrim}{} @@ -46,15 +47,38 @@ %%% midrule every X rows -\def\midruleX{\aftergroup\aftergroup\aftergroup\midruleX@aux} -\def\midruleX@aux{\luadirect{lutabt.mrX.midruleX('')}} % todo argument for vadjust or noalign?? -\NewDocumentCommand{\setmidruleX}{s O{N} m}{% +% NO LONGER NEEDED %%% this was used for @{\midruleX} in colspec, but I made a better way +%\def\midruleX{\aftergroup\aftergroup\aftergroup\midruleX@aux} +%\def\midruleX@aux{\luadirect{lutabt.mrX.midruleX('')}} % +%%% + +\NewDocumentCommand{\midruleX}{s O{N} m}{% \MakeluastringCommands[N]{#2}% \luadirect{lutabt.mrX.set_midruleX(\plluastringA{#3}, \luastring{#1})}% } -\NewDocumentCommand{\midruleXreset}{O{0}}{\luadirect{lutabt.mrX.cntr = tonumber(\luastring{#1})}} -\NewCommandCopy\resetmidruleX\midruleXreset +\NewDocumentCommand{\resetmidruleX}{O{0}}{\luadirect{lutabt.mrX.reset_midruleX(\luastring{#1})}} + + +\NewDocumentCommand{\settabular}{s m}{\luadirect{lutabt.set_tabular(\luastring{#2})}} % + +\def\ltt@resetrownum{\luadirect{lutabt.reset_rows()}} +\def\ltt@resetrownumhard{\luadirect{lutabt.row_num = 0}} +\def\ltt@autotoprule{\luadirect{lutabt.process_auto_topbot_rule('top')}} +\def\ltt@autobotrule{\luadirect{lutabt.process_auto_topbot_rule('bottom')}} +\def\ltt@storeautotbandfalse{\luadirect{ + lutabt.auto_topbot_old = lutabt.auto_topbot + lutabt.auto_topbot = false}} +\def\ltt@restoreautotb{\luadirect{lutabt.auto_topbot = lutabt.auto_topbot_old}} +\def\ltt@inctablelevel{\luadirect{lutabt.tablelevel = lutabt.tablelevel + 1}} +\def\ltt@dectablelevel{\luadirect{lutabt.tablelevel = lutabt.tablelevel - 1}} +\def\ltt@midruleXoff{\luadirect{lutabt.mrX.off()}} +\def\ltt@actlevelreset{\luadirect{lutabt.actlvl = 1}} + +\apptocmd{\@arraycr}{\luadirect{lutabt.process_auto_rules()}}{}{} + + +\NewDocumentCommand{\midrulesat}{m}{\luadirect{lutabt.add_auto_midrules(\luastring{#1})}} %%%% @@ -138,16 +162,11 @@ -\NewDocumentCommand{\midrulesat}{m}{\luadirect{lutabt.add_auto_midrules(\luastring{#1})}} +\apptocmd{\LTXtable}{\ltt@actlevelreset\ltt@resetrownumhard\luadirect{lutabt.tablelevel=0}}{}{} -\NewDocumentCommand{\settabular}{s m}{\luadirect{lutabt.set_tabular(\luastring{#2})}} % make kv interface for auto - -\def\ltt@resetrownum{\luadirect{lutabt.reset_rows()}} -\def\ltt@autotoprule{\luadirect{lutabt.process_auto_topbot_rule('top')}} -\def\ltt@autobotrule{\luadirect{lutabt.process_auto_topbot_rule('bottom')}} \let\oldtabular\tabular \let\oldendtabular\endtabular @@ -155,9 +174,7 @@ \luadirect{lutabt.set_col_spec(\luastringN{#2})}% \oldtabular[#1]{\lttltrim#2\lttrtrim}\ltt@inctablelevel\ltt@resetrownum\ltt@autotoprule% } -\def\endtabular{\ltt@autobotrule\ltt@dectablelevel\oldendtabular} - - +\def\endtabular{\ltt@autobotrule\ltt@midruleXoff\ltt@dectablelevel\oldendtabular} \expandafter\let\expandafter\oldtabulars\csname tabular*\endcsname @@ -166,27 +183,21 @@ \luadirect{lutabt.set_col_spec(\luastringN{#3})}% \begin{oldtabulars}{#1}[#2]{\lttltrim#3\lttrtrim}\ltt@inctablelevel\ltt@resetrownum\ltt@autotoprule% }{% - \ltt@autobotrule\ltt@dectablelevel\end{oldtabulars}% + \ltt@autobotrule\ltt@midruleXoff\ltt@dectablelevel\end{oldtabulars}% } %%% NOTE tabularx uses tabular*, NO NEED TO CHANGE TABULARX! + \let\oldlongtable\longtable \RenewExpandableDocumentCommand{\longtable}{ O{l} m }{% - \luadirect{lutabt.auto_topbot_old = lutabt.auto_topbot - lutabt.auto_topbot = false}% + \ltt@storeautotbandfalse% \luadirect{lutabt.set_col_spec(\luastringN{#2})}% \oldlongtable[#1]{\lttltrim#2\lttrtrim}\ltt@inctablelevel\ltt@resetrownum% } \let\oldendlongtable\endlongtable -\def\endlongtable{\luadirect{lutabt.auto_topbot = lutabt.auto_topbot_old} - \ltt@dectablelevel\oldendlongtable}% restore status of auto topbot rule - -\apptocmd{\@arraycr}{\luadirect{lutabt.process_auto_rules()}}{}{} +\def\endlongtable{\ltt@restoreautotb\ltt@midruleXoff\ltt@dectablelevel\oldendlongtable}% restore status of auto topbot rule -\def\ltt@inctablelevel{\luadirect{lutabt.tablelevel = lutabt.tablelevel + 1}} -\def\ltt@dectablelevel{\luadirect{lutabt.tablelevel = lutabt.tablelevel - 1}} - %s0,spec,mcspec,pre,content % Magic Cell \NewExpandableDocumentCommand{\MC}{ s O{} O{} D<>{} D(){x} m }{% diff --git a/macros/luatex/generic/lutabulartools/lutabulartools.tex b/macros/luatex/generic/lutabulartools/lutabulartools.tex index 7af9cbc4a6..25acf21e25 100644 --- a/macros/luatex/generic/lutabulartools/lutabulartools.tex +++ b/macros/luatex/generic/lutabulartools/lutabulartools.tex @@ -1,5 +1,5 @@ % Kale Ewasiuk (kalekje@gmail.com) -% 2022-11-27 +% 2022-11-29 % Copyright (C) 2021-2022 Kale Ewasiuk % % Permission is hereby granted, free of charge, to any person obtaining a copy @@ -86,12 +86,13 @@ % todo: can improve naming... set col spec to a table instead of a string - \maketitle -lutabulartools is a package that contains a few useful Lua\LaTeX-based macros to help with tables. -This package redefines the {\ttfamily tabular} and {\ttfamily tabular*} environments. -The following packages are loaded if not already, so if you have specific settings for these packages, load this package after: +\cmd{lutabulartools} is a package that contains a few useful Lua\LaTeX-based macros to help with tables. +A global \cmd{lua} variable \cmd{lutabt} is created. +This package redefines the {\ttfamily tabular} and {\ttfamily tabular*} environments as well as \cmd{\@arraycr} to add functionarlity. +The following packages are loaded by this one, +so if you have specific settings for these packages, load the \cmd{lutabulartools} package after: \texttt{ {booktabs}, {multirow}, @@ -101,19 +102,21 @@ The following packages are loaded if not already, so if you have specific settin {xcolor}, {colortbl}, {luacode}, -{penlight} -}. +{penlight}}. -\section{settabular} +\section{\texttt{\textbackslash settabular}} A key-val interface in the \cmd{\settabular{}} command is used to set some tabular settings. \cmd{nopad} automatically adds \cmd{@{}} on each end of the column spec.\\ -\cmd{tbrule} automatically adds \cmd{\toprule} as the first thing in the environment, and \cmd{\bottomrule} as the last. -Note that automatic rule adding is disabled in \cmd{longtable}. -\begin{LTXexample} -\settabular{nopad,tbrule} % or -\settabular{nopad=false,tbrule=false} -\end{LTXexample} +\cmd{tbrule} automatically adds \cmd{\toprule} as the first thing in the \cmd{tabular(*|x)} environment, and \cmd{\bottomrule} as the last. +Note that this automatic top/bottom rule adding is disabled in \cmd{longtable}. +\cmd{row/colsep} tweaks the row spacing with \cmd{arraystretch} +or adjusts the \cmd{tabcolsep} length (an integer must be used, the result is multiplied by 6pt). For example: +\begin{verbatim} +\settabular{nopad,tbrule,rowsep=2,colsep=2} % or +\settabular{nopad=false,tbrule=false} % to set the switches to off +\end{verbatim} + \section{Debugging} You can toggle log output debugging with \cmd{\lttdebugON} and \cmd{\lttdebugOFF}. @@ -124,6 +127,9 @@ msg2 ^^^^^ \end{verbatim} +\cmd{\lttdebugprt} can be used pretty-print the \cmd{lutabt} module and its attributes---useful for checking the +``state'' of the package. + \section{\texttt{\textbackslash MC} -- Magic Cell} \texttt{\textbackslash MC} (magic cell) combines the facilities of \cmd{\multirow} and \cmd{\multicolumn} from the \texttt{multirow} package, and \cmd{\makcell} from the titular package. @@ -131,7 +137,7 @@ With the help of LuaLaTeX, it takes an easy-to-use cell specification and employ \cmd{\MC} will not work properly if your table is only 1 column wide (you probably don't need \cmd{MC} in that case anyway...). Here is the usage: -\texttt{\textbackslash MC * [cell spec] [override multicol] <cell format> (add cmidrule) \{contents\} } +\texttt{\textbackslash MC * [cell spec] [override multicol] <cell format> \{contents\} } \llcmd{*}This will wrap the entire command in \{\}. This is necessary for \texttt{siunitx} single-column width columns. However, the \cmd{\MC} command attempts to detect this automatically. @@ -162,24 +168,19 @@ Examples:\\ \cmd{\MC[+,2]}, if placed in the first column, occupies the entire row and is two rows tall.\\ \cmd{\MC[+,2]}, if placed in the second column, occupies the second column to the end of the table and is two rows tall.\\ In any of these examples, you can place the alignment letters anywhere. -So, \cmd{\MC[l1,2b]} and \cmd{\MC[1,2 lb]} are both left-bottom aligned (spaces are ignored). - +So, \cmd{\MC[l1,2b]} and \cmd{\MC[1,2 lb]} are both left-bottom aligned (spaces are ignored).\\ +Put an \cmd{_} as the last thing to add a \cmd{cmidrule} under, followed by a trim spec (the thing that goes in \cmd{()}) +\cmd{\MC[+c_l]} will add a \cmd{cmidrule} underneath the cell (which fills until the end of the table), with the left side trimmed. \llcmd{[override mc]}% You may want to adjust the column specification of a multicolumn cell,\\ \texttt{[@\{\}c@\{\}]} for example to remove padding between the cell. -\llcmd{(cmidrule)} will add a cmidrule at end of row. \cmd{()} to add without trim or \cmd{(lr)} to trim. - \llcmd{<cell format>}% You can place formatting like \cmd{\bfseries} here. -\subsection{midrulesat} -If you'd rather specify the location of midrules outside the table, use \cmd{\midrulesat{1,2,3}}: a midrule will be -placed on rows 1, 2, and 3, for the next table only. - -\subsection{Defaults}\label{s.def} +\subsection{\texttt{\textbackslash MC} Defaults}\label{s.def} The \cmd{tabular[*]} environment is re-defined to use Lua pattern matching to parse the column specification of the table. This is done to determine how many columns there are, and what the current column type is, even if specifications like \cmd{r@{.}l*{3}{r}} are used. @@ -189,18 +190,20 @@ You can also specify default horizontal and vertical alignments (ie if alignment for an arbitrary column by \cmd{\setMChordef{?}{l|r|c}} and\\ \cmd{\setMChordef{?}{t|m|b}}, where \cmd{?} is the column. To add a column that should be surrounded by brackets for \cmd{siunitx} purposes, do so with \cmd{\addMCsicol{?}}. -S is included by default. +\cmd{S} is included by default. + +\section{\texttt{\textbackslash midrulesat}} +If you'd rather specify the location of midrules outside the table, use \cmd{\midrulesat{1,2,3}}: a midrule will be +placed on rows 1, 2, and 3, for the next table only. -\subsection{Examples} +\section{Examples} \let\nl\\ - Change the settings for the rest of the doc. - \begin{LTXexample} \settabular{nopad,tbrule} \end{LTXexample} @@ -214,14 +217,12 @@ Change the settings for the rest of the doc. \begin{tabular}{ l l l } \MC[+m]<\itshape>{A Decent Example}\\\midrule - & \MC[2m](r){Heading} \\ + & \MC[2m_]{Heading} \\ \MC[b,-2]{Multi\\Line} & A & B \\\midrule end & & \\ \end{tabular} \end{LTXexample} - - \subsubsection{A small example} \begin{LTXexample} \midrulesat{1,2,3} @@ -238,9 +239,9 @@ d \\ \begin{LTXexample} \begin{tabular}{ l l l }\midrule - \MC(){A} & \MC[mc2,2]{Lttrs} \\ - \MC(r){B} & \\ \cmidrule{2-3} - \MC(r){1} & \MC(r){A} & \MC(r){B} \\ % todo must fix + \MC[_]{A} & \MC[mc2,2]{Lttrs} \\ + \MC[_r]{B} & \\ \cmidrule{2-3} + \MC[_r]{1} & \MC[_r]{A} & \MC[_r]{B} \\ \\ \end{tabular} \end{LTXexample} @@ -296,35 +297,6 @@ doesn't play particularly well with the middle aligned \cmd{\MC} - - -%%% https://tex.stackexchange.com/questions/287346/width-of-column-after-multicolumn-header - -%\textbackslash MC[<spec>]{<contents} - - -%\subsubsection{And another one} -% -%\begin{LTXexample} -%\setMChordef{l}{r} -%\setMCverdef{l}{b} -%% change deflt alignment ^ -%\newcolumntype{e}{ll} -%\setMCrepl{e}{ll} -%% e -> l l ^ -%\begin{tabular}{l l l e}\toprule -%aaaaa & bbb & ccc & eee & fff\\ -%\MC{aaaaa}\\ -%\MC{a}\\\midrule -%\MC{a\\bbbbb} & x\\\midrule -%\makecell[br]{a\\b} & x\\\midrule -%\MC[+]{--- ---}\\ -%\end{tabular} -%\end{LTXexample} -%% WHY ISNT THIS RIGHT? - - - \newpage @@ -347,65 +319,58 @@ Here's an example: \begin{LTXexample} \begin{tabular}{c c c c c c} - 1 & 2 & 3 & 4 & 5 & 6\\ + a & 2 & 3 & 4 & 5 & 6\\ \cmidrule{+1} % rule on last column - 1 & 2 & 3 & 4 & 5 & 6\\ + b & 2 & 3 & 4 & 5 & 6\\ \cmidrules{1,3-+3,+} % rule on first col, third to third last col, and last col - 1 & 2 & 3 & 4 & 5 & 6\\ + c & 2 & 3 & 4 & 5 & 6\\ \cmidrules{1,3-+3rl,+} % same as above, but trim middle - 1 & 2 & 3 & 4 & 5 & 6\\ + d & 2 & 3 & 4 & 5 & 6\\ \cmidrules(l){1,r3-+3,+1}% trim left for all, but only trim right for middle rule - 1 & 2 & 3 & 4 & 5 & 6\\ + e & 2 & 3 & 4 & 5 & 6\\ \gcmidrule{+1} % rule on last column - 1 & 2 & 3 & 4 & 5 & 6\\ + f & 2 & 3 & 4 & 5 & 6\\ \gcmidrules{1,3-+3,+} % rule on first col, third to third last col, and last col - 1 & 2 & 3 & 4 & 5 & 6\\ + g & 2 & 3 & 4 & 5 & 6\\ \gcmidrules{1,3-+3rl,+} % same as above, but trim middle - 1 & 2 & 3 & 4 & 5 & 6\\ + h & 2 & 3 & 4 & 5 & 6\\ \gcmidrules(l){1,r3-+3,+1}% trim left for all, but only trim right for middle rule \end{tabular} \end{LTXexample} -\subsection{Midrule every X\textsuperscript{th} row} +\section{\texttt{\textbackslash midruleX} - Midrule every X\textsuperscript{th} row} -\llcmd{\midruleX}% With this command, you can place a rule -every X rows. -To use, place \cmd{@{\midruleX}} at the end of the tabular column spec, eg. \cmd{\begin{tabular}{ll@{\midruleX}}..}. +every X rows for the next table made (place command outside of table). You can configure the step size and what kind of midrule you prefer with the following key-val syntax, with default values below:\\ -\cmd{\setmidruleX{step=5,rule=midrule,reset=false,resetnum=0,cntr=0}}\\ +\cmd{\midruleX{step=5,rule=midrule,cntr=0,head=0,long=false,longhead=0}}\\ \cmd{step} is the number of rows (X) before applying the rule set by \cmd{rule}. \\ -Concering \cmd{longtable}s: If \cmd{reset} is set to \cmd{true}, +Concering \cmd{longtable}s: If \cmd{long} is set to \cmd{true} (or the key is present), \cmd{\midruleX} will also add a unique \cmd{\label{}} on each row, and if the row starts on a newpage, -resets the row counter to \cmd{resetnum}, to ensure you have the same X number of rows after the header of each page of a \cmd{longtable}.\\ -The starred version of first reverts the settings to default, then loads your inputted settings, which the non-starred -version only overwrites the settings specified. \cmd{\setmidruleX*{}} will restore to default. -Use optional parameter \cmd{\setmidruleX*[o|n|f]{}} +resets the row counter to -1*\cmd{longhead}, to ensure you have the same X number of rows after the header of each page of a \cmd{longtable}.\\ +Use optional parameter \cmd{\midruleX*[o|n|f]{}} to control expansion of the key-val settings (\cmd{[n]} for not expanded is default). -Before you want counting to begin, you should -apply \cmd{\resetmidruleX} to avoid header rows being counted. -Use \cmd{\noalign{\resetmiduleX}} if you need place a rule on the same line the reset takes place, or in a cell before \cmd{\\}. -Note that \cmd{\resetmidruleX} resets the row counter to 0, and is in effect, a short-cut for \cmd{\setmidruleX{}} or \cmd{\setmidruleX{cntr=0}} +Before you want counting to begin, or anywhere in the table, you could +apply \cmd{\resetmidruleX[cntr]} (\cmd{cnter} is incremented each row) to avoid header +rows being counted and set the row \cmd{cntr} to an arbitrary value. +If you want to skip the first \cmd{x} rows with \cmd{\midruleX}, set \cmd{head=x} (which is equivalent to \cmd{cntr=-x}). +If you want to add a \cmd{midrule} under row \cmd{x}, use \cmd{head*=x} instead. +Note: Use \cmd{\noalign{\resetmiduleX}} if you need place a rule on the same line the reset takes place (ie. in a cell before \cmd{\\}). -% -%\begin{tabular}{l@{\luadirect{tex.print('\\midrule')}}} -% Hello \\ -%\end{tabular} -% +\subsection{\texttt{\textbackslash midruleX} examples} + \begin{LTXexample} -\setmidruleX{step=3,rule=gmidrule} -\begin{tabular}{rclc@{\midruleX}} +\midruleX{step=3,rule=gmidrule,head*=1} +\begin{tabular}{rclc} % ^^^ inject midruleX Num & . & . & . \\ -\midrule\resetmidruleX -% reset so header dont count 1 & & & \\ 2 & & & \\ 3 & & & \\ -4 & & & \\ +4 & \MC[2,2]{Hi\\world} \\ 5 & & & \\ 6 & & & \\ 7 & & & \\ @@ -419,21 +384,17 @@ Num & . & . & . \\ \end{tabular} \end{LTXexample} -%} - -% - \pagebreak Here's an example with long table. Notice the gray rules reliably appear 3 rows after each header. \begin{verbatim} -\setmidruleX{reset=true,resetnum=0,rule="\gcmidrules{1r,2-}"} +\midruleX{long=true,step=3,rule="\gcmidrules{1r,2-}"} \def\tblhead{\toprule No & Name & Place & other\\\midrule} \def\tblcontinued{\MC[+l]{Continued...}\\} -\def\tblcontinues\MC[+r]{...Continues}\\} -\begin{longtable}{rclc@{\midruleX}} +\def\tblcontinues{\MC[+r]{...Continues}\\} +\begin{longtable}{rclc} \tblhead\endfirsthead - \tblcontinued\head\endhead % all the lines above this will be repeated on every page + \tblcontinued\tblhead\endhead % all the lines above this will be repeated on every page \tblcontinues\endfoot \bottomrule End.\endlastfoot \resetmidruleX @@ -448,29 +409,29 @@ Here's an example with long table. Notice the gray rules reliably appear 3 rows 9 & & & \\ 10 & & & \\ 11 & & & \\ -12 & & & \\ +12 & \MC[2,-2](){Hi\\world} \\ 13 & & & \\ 14 & & & \\ 15 & & & \\\newpage -16 & & & \\ +16 & \MC[2,2]{Hi\\world} \\ 17 & & & \\ 18 & & & \\\resetmidruleX 19 & & & \\ \end{longtable} \end{verbatim} -\setmidruleX{reset=true,resetnum=0,rule="\gcmidrules{1r,2-}"} +\midruleX{long=true,rule="\gcmidrules{1r,2-}"} \def\tblhead{\toprule No & Name & Place & other\\\midrule} \def\tblcontinued{\MC[+l]{Continued...}\\} \def\tblcontinues{\MC[+r]{...Continues}\\} -\begin{longtable}{rclc@{\midruleX}} +\begin{longtable}{rclc} \tblhead\endfirsthead \tblcontinued\tblhead\endhead % all the lines above this will be repeated on every page \tblcontinues\endfoot \bottomrule End.\endlastfoot \resetmidruleX 1 & & & \\ -2 & & & \\ +2 & \MC[_]{hi} & & \\ 3 & & & \\ 4 & & & \\ 5 & & & \\ @@ -480,18 +441,41 @@ Here's an example with long table. Notice the gray rules reliably appear 3 rows 9 & & & \\ 10 & & & \\ 11 & & & \\ -12 & & & \\ +12 & \MC[2,-2_]{Hi\\world} \\ 13 & & & \\ 14 & & & \\ 15 & & & \\\newpage -16 & & & \\ +16 & \MC[2,-2_]{Hi\\world} \\ 17 & & & \\ 18 & & & \\\resetmidruleX 19 & & & \\ \end{longtable} +%\begin{tabular}{ll} +% a \\ +% b \\ +% v \\ +% d \\ +% r \\ +%\end{tabular} + +Long table X example \LTXtable{\linewidth}{ltxexample} +%\luadirect{pl.help_wrt(lutabt.actlvl, 'actlevel')} +%\luadirect{pl.help_wrt(lutabt.row_num, 'row')} +%\lttdebugprt + +%\settabular{tbrule} % glitch with LTX +%\midrulesat{1,2,3} +%\begin{tabular}{ll} +% a \\ +% b \\ +% c \\ +% d \\ +% e \\ +%\end{tabular} + \end{document} |