From d215ba492183a22167b7cdf9900899ab51f7dda6 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 28 Nov 2022 03:03:54 +0000 Subject: CTAN sync 202211280303 --- .../generic/lutabulartools/lutabulartools.lua | 186 ++++++++++++++++----- .../generic/lutabulartools/lutabulartools.pdf | Bin 110213 -> 114054 bytes .../generic/lutabulartools/lutabulartools.sty | 62 ++++--- .../generic/lutabulartools/lutabulartools.tex | 85 ++++++---- 4 files changed, 242 insertions(+), 91 deletions(-) (limited to 'macros/luatex') diff --git a/macros/luatex/generic/lutabulartools/lutabulartools.lua b/macros/luatex/generic/lutabulartools/lutabulartools.lua index 24c8d5598e..23ef965482 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-10-22 +--% 2022-11-27 --% Copyright (C) 2021-2022 Kale Ewasiuk --% --% Permission is hereby granted, free of charge, to any person obtaining a copy @@ -28,11 +28,61 @@ if (__PL_EXTRAS__ == nil) or (__PENLIGHT__ == nil) then tex.sprint('\\PackageError{yamlvars}{penlight package with extras (or extrasglobals) option must be loaded before this package}{}') tex.print('\\stop') end +local T = pl.tablex local ltt = {} +ltt.tablelevel = 0 ltt.debug = false + +ltt.auto_topbot = false + +ltt.auto_crules = {} -- {{span,trim}, } appearance is like this, 'range|trim', -- auto_rules created by MC +ltt.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 + + +ltt.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 + l = 'l', + c = 'c', + r = 'r', + p = 'l', + P = 'c', + X = 'l', + Y = 'c', + Z = 'l', + N = 'c', + L = 'l', + R = 'r', + C = 'c', +} + +-- allow user to place their own replacements in for a table, say if they define a column that expands to multiple +ltt.col_replaces = { +--x = 'lll' +} + +ltt.SI_cols = {'S', 'N', 'Q', 'L', 'R'} + + + +----- +----- utility funcs +----- + + function ltt.debugtalk(s, ss) ss = ss or '' if ltt.debug then @@ -40,12 +90,32 @@ function ltt.debugtalk(s, ss) end end -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 + +function ltt.set_tabular(sett) + sett = luakeys.parse(sett) + local trim = '' + for k, v in pairs(sett) do + if k == 'tbrule' then + ltt.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..'}') + end + end +end +----- +----- tabular utility funcs +----- + +function ltt.reset_rows() + if ltt.tablelevel == 1 then + ltt.row_num = 0 + end +end + function ltt.set_col_num() -- register current column info (column number and specification) local nest @@ -96,7 +166,12 @@ end -- this case should be considered in this code. -- for example: \multirow{2}{=} -function ltt.MagicCell(s0,spec,mcspec,pre,content) + +----- +----- magic cell and helpers +----- + +function ltt.MagicCell(s0,spec,mcspec,pre,content,trim) -- ltt.set_col_num() -- register current column number and column spec @@ -144,9 +219,14 @@ function ltt.MagicCell(s0,spec,mcspec,pre,content) --help_wrt(STR..' <<< magic cell string') ltt.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) end + function ltt.parse_MagicCell_spec(spec) local mrowsym = '*' -- * = natural width, = will match p{2cm} for example local skipmakecell = false @@ -199,45 +279,76 @@ function ltt.get_HColSpec(h, mcspec, c) -- take horizontal alignment end +----- +----- autorules (with \MC() or auto top bot +----- -ltt.col_ver_repl = { -m = 'm', -M = 'm', -b = 'b', -} +function ltt.add_auto_midrules(rows) + ltt.auto_midrules = rows:split(',') +end + +function ltt.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 + -- {{span 1-2, trim}, ..} + end +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') + 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!') + tex.print('\\midrule ') + end + end + end + end + ltt.auto_crules = {} +end -ltt.col_hor_repl = { -- horizontal cell alignment that multicolumn should use if () or [hori] not passed to func - l = 'l', - c = 'c', - r = 'r', - p = 'l', - P = 'c', - X = 'l', - Y = 'c', - Z = 'l', - N = 'c', - L = 'l', - R = 'r', - C = 'c', -} --- allow user to place their own replacements in for a table, say if they define a column that expands to multiple -ltt.col_replaces = { ---x = 'lll' -} -ltt.SI_cols = {'S', 'N', 'Q', 'L', 'R'} ---ltt.SI_cols = {'S'} ---ltt.SI_cols = {'N'} + +function ltt.process_auto_topbot_rule(rule) + if ltt.tablelevel == 1 then + if ltt.auto_topbot then + tex.print('\\'..rule..'rule ') + end + end +end + ----- ---- midrule stuff +----- midrule and midruleX stuff ----- + +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) if string.find(s, '+') then s = s:gsub('+', '') @@ -282,15 +393,6 @@ function ltt.makecmidrules(s, r, c, cmd) end -local T = pl.tablex - -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.mrX.set_midruleX(new_sett, def) def = def or '' diff --git a/macros/luatex/generic/lutabulartools/lutabulartools.pdf b/macros/luatex/generic/lutabulartools/lutabulartools.pdf index 5d6e7f62d0..c915ba6291 100644 Binary files a/macros/luatex/generic/lutabulartools/lutabulartools.pdf and b/macros/luatex/generic/lutabulartools/lutabulartools.pdf differ diff --git a/macros/luatex/generic/lutabulartools/lutabulartools.sty b/macros/luatex/generic/lutabulartools/lutabulartools.sty index f1dea60c5a..1d2522b099 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-10-22 +% 2022-11-27 % 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-10-22] +\ProvidesPackage{lutabulartools}[2022-11-27] \RequirePackage{booktabs} \RequirePackage{multirow} @@ -40,13 +40,8 @@ \newcommand{\lttdebugON}{\luadirect{lutabt.debug = true}} \newcommand{\lttdebugOFF}{\luadirect{lutabt.debug = true}} -\newcolumntype{\ltt@ltrim}{@{}} -\newcolumntype{\ltt@rtrim}{@{}} -\DeclareOption{notrim}{ - \newcolumntype{\ltt@ltrim}{} - \newcolumntype{\ltt@rtrim}{} -} - +\newcolumntype{\lttltrim}{} +\newcolumntype{\lttrtrim}{} %%% midrule every X rows @@ -143,40 +138,67 @@ +\NewDocumentCommand{\midrulesat}{m}{\luadirect{lutabt.add_auto_midrules(\luastring{#1})}} + + + + +\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 \RenewExpandableDocumentCommand{\tabular}{ O{l} m }{% \luadirect{lutabt.set_col_spec(\luastringN{#2})}% - \oldtabular[#1]{\ltt@ltrim#2\ltt@rtrim}% + \oldtabular[#1]{\lttltrim#2\lttrtrim}\ltt@inctablelevel\ltt@resetrownum\ltt@autotoprule% } +\def\endtabular{\ltt@autobotrule\ltt@dectablelevel\oldendtabular} + + + \expandafter\let\expandafter\oldtabulars\csname tabular*\endcsname \expandafter\let\expandafter\endoldtabulars\csname endtabular*\endcsname \RenewDocumentEnvironment{tabular*}{ m O{l} m }{% \luadirect{lutabt.set_col_spec(\luastringN{#3})}% - \begin{oldtabulars}{#1}[#2]{\ltt@ltrim#3\ltt@rtrim}% + \begin{oldtabulars}{#1}[#2]{\lttltrim#3\lttrtrim}\ltt@inctablelevel\ltt@resetrownum\ltt@autotoprule% }{% - \end{oldtabulars}% + \ltt@autobotrule\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}% \luadirect{lutabt.set_col_spec(\luastringN{#2})}% - \oldlongtable[#1]{\ltt@ltrim#2\ltt@rtrim}% + \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\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{} D(){} D<>{} m }{% +\NewExpandableDocumentCommand{\MC}{ s O{} O{} D<>{} D(){x} m }{% % Magic cell *wraps with {} but automatically checks for SI column, - % [column spec] (mult-column spec override) {cell content} + % [column spec] [mult-column spec override] (add rule) {cell content} \luadirect{lutabt.MagicCell( \luastring{#1}, \luastring{#2}, \luastringN{#3}, \luastringN{#4}, - \luastringN{#5} + \luastringN{#6}, + \luastring{#5} )}} @@ -219,12 +241,12 @@ % \setcounter{RowNumCnt}{1}% % \luadirect{lutabt.NumTabColsMX = 0}% fall back if calc doesnt work for some reason %\DeclareOption{notrimx}{ -% \global\newcolumntype{\ltt@ltrim}{!{\stepcounter{RowNumCnt}}} -%% \global\newcolumntype{\ltt@rtrim}{!{\luadirect{lutabt.get_TabColNum()}}} +% \global\newcolumntype{\lttltrim}{!{\stepcounter{RowNumCnt}}} +%% \global\newcolumntype{\lttrtrim}{!{\luadirect{lutabt.get_TabColNum()}}} %} %\DeclareOption{trimx}{ -% \newcolumntype{\ltt@ltrim}{@{\stepcounter{RowNumCnt}}} -%% \newcolumntype{\ltt@rtrim}{@{\luadirect{lutabt.get_TabColNum()}}} +% \newcolumntype{\lttltrim}{@{\stepcounter{RowNumCnt}}} +%% \newcolumntype{\lttrtrim}{@{\luadirect{lutabt.get_TabColNum()}}} %} diff --git a/macros/luatex/generic/lutabulartools/lutabulartools.tex b/macros/luatex/generic/lutabulartools/lutabulartools.tex index 97802fce07..7af9cbc4a6 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-10-22 +% 2022-11-27 % Copyright (C) 2021-2022 Kale Ewasiuk % % Permission is hereby granted, free of charge, to any person obtaining a copy @@ -101,22 +101,21 @@ The following packages are loaded if not already, so if you have specific settin {xcolor}, {colortbl}, {luacode}, -{penlight}, -} +{penlight} +}. -\section{Options} -The author likes tables with left and right-most columns flush to the end. -Since the \cmd{tabular} env is redefined in this, the author took the liberty to -automatically pad the \cmd{tabular} cell spec with \cmd{@{}} on each end. -If you don't want this, you can pass \cmd{notrim} to the package. Or, -you can manually fix it in a \cmd{tabular} with \cmd{!{}} like so: +\section{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} -\begin{tabular}{!{}c!{}}\toprule -Xyz\\\bottomrule \end{tabular} +\settabular{nopad,tbrule} % or +\settabular{nopad=false,tbrule=false} \end{LTXexample} -\subsection{Debugging} +\section{Debugging} You can toggle log output debugging with \cmd{\lttdebugON} and \cmd{\lttdebugOFF}. The messages will be printed in a format like so: \begin{verbatim} @@ -132,7 +131,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 multicolumn col) \{contents\} } +\texttt{\textbackslash MC * [cell spec] [override multicol] (add cmidrule) \{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. @@ -166,16 +165,20 @@ 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). -\llcmd{(override}% +\llcmd{[override mc]}% You may want to adjust the column specification of a multicolumn cell,\\ -\llcmd{multicolumn)}for example, using -\texttt{(@\{\}c@\{\})} to remove padding between the 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{}% 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} 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, @@ -195,24 +198,50 @@ S is included by default. \let\nl\\ +Change the settings for the rest of the doc. + + +\begin{LTXexample} +\settabular{nopad,tbrule} +\end{LTXexample} + +\settabular{nopad,tbrule} + + \subsubsection{A good use for headers} + \begin{LTXexample} -\begin{tabular}{ l l l }\toprule +\begin{tabular}{ l l l } \MC[+m]<\itshape>{A Decent Example}\\\midrule - & \MC[2m]{Heading} \\\cmidrule{2-} -\MC[b,-2]{Multi\\Line} & A & B \\\midrule + & \MC[2m](r){Heading} \\ +\MC[b,-2]{Multi\\Line} & A & B \\\midrule + end & & \\ \end{tabular} \end{LTXexample} + + \subsubsection{A small example} +\begin{LTXexample} +\midrulesat{1,2,3} +\begin{tabular}{ l l l } +a \\ +b \\ +c \\ +d \\ +\end{tabular} +\end{LTXexample} + +\subsubsection{A small example} \begin{LTXexample} \begin{tabular}{ l l l }\midrule - A & \MC[mc2,2]{Lttrs} \\ - B & \\ - 1 & A & B \\ + \MC(){A} & \MC[mc2,2]{Lttrs} \\ + \MC(r){B} & \\ \cmidrule{2-3} + \MC(r){1} & \MC(r){A} & \MC(r){B} \\ % todo must fix + \\ \end{tabular} \end{LTXexample} @@ -221,7 +250,7 @@ S is included by default. Notice that the top-aligned p-column doesn't play particularly well with the middle aligned \cmd{\MC} \begin{LTXexample} -\begin{tabular}{ p{1cm} l }\toprule +\begin{tabular}{ p{1cm} l } hello\newline world & \MC[mr]{11\\2} \\ \end{tabular} @@ -232,9 +261,9 @@ doesn't play particularly well with the middle aligned \cmd{\MC} \begin{LTXexample} \begin{tabular}{|c|c|c|} \hline 1 & 2 & 3\\\hline -4 & \MC[2,2cm](@{}c@{}|)% +4 & \MC[2,2cm][@{}c@{}|]% <\ttfamily>{5}\\\cline{1-1} - & \MC[2](r|){} \\\hline%hacky fix + & \MC[2][r|]{} \\\hline%hacky fix 6 & 7 & 8\\\hline \end{tabular} \end{LTXexample} @@ -258,7 +287,7 @@ doesn't play particularly well with the middle aligned \cmd{\MC} \begin{tabular}{| c | c | c | c | c | c |}\toprule \MC[2,2cm]<\ttfamily>{2,2cm} & \MC[2r]<\ttfamily>{2r} & 5 & \MC[,2b]<\ttfamily>{,2b}\\ & & 3 & 4 & 5 & \\\midrule - 1 & 2 & \MC[2l](@{}l)<\ttfamily>{2l (\@\{\}l)} & 5 & 6666\\\cmidrule{3-4} + 1 & 2 & \MC[2l][@{}l]<\ttfamily>{2l (\@\{\}l)} & 5 & 6666\\\cmidrule{3-4} 1 & \MC[+r]<\ttfamily>{+r} \\ \\ 1 & 2 & 3 & 4 & 5 & \MC[,-2]<\ttfamily>{,\\-2}\\ @@ -369,8 +398,7 @@ Note that \cmd{\resetmidruleX} resets the row counter to 0, and is in effect, a \begin{LTXexample} \setmidruleX{step=3,rule=gmidrule} \begin{tabular}{rclc@{\midruleX}} - % ^^^ inject midrule -\toprule + % ^^^ inject midruleX Num & . & . & . \\ \midrule\resetmidruleX % reset so header dont count @@ -388,7 +416,6 @@ Num & . & . & . \\ \resetmidruleX % resest % so no bottom gray rule 12 & & & \\ -\bottomrule \end{tabular} \end{LTXexample} -- cgit v1.2.3