From 86df9231241afb195794206c6c7204255a9f3d8c Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Fri, 1 Mar 2024 21:45:51 +0000 Subject: penlightplus (1mar24) git-svn-id: svn://tug.org/texlive/trunk@70312 c570f23f-e606-0410-a88d-b1316a301751 --- .../doc/luatex/penlightplus/penlightplus.pdf | Bin 66585 -> 80983 bytes .../doc/luatex/penlightplus/penlightplus.tex | 164 +++++++++++++++------ .../tex/luatex/penlightplus/penlightplus.lua | 120 +++++++++++---- .../tex/luatex/penlightplus/penlightplus.sty | 80 +++++----- 4 files changed, 264 insertions(+), 100 deletions(-) (limited to 'Master') diff --git a/Master/texmf-dist/doc/luatex/penlightplus/penlightplus.pdf b/Master/texmf-dist/doc/luatex/penlightplus/penlightplus.pdf index 17d95268ebe..8f4fcb97172 100644 Binary files a/Master/texmf-dist/doc/luatex/penlightplus/penlightplus.pdf and b/Master/texmf-dist/doc/luatex/penlightplus/penlightplus.pdf differ diff --git a/Master/texmf-dist/doc/luatex/penlightplus/penlightplus.tex b/Master/texmf-dist/doc/luatex/penlightplus/penlightplus.tex index 988a51bb2a8..53488619bf5 100644 --- a/Master/texmf-dist/doc/luatex/penlightplus/penlightplus.tex +++ b/Master/texmf-dist/doc/luatex/penlightplus/penlightplus.tex @@ -1,6 +1,6 @@ % Kale Ewasiuk (kalekje@gmail.com) -% 2023-12-08 -% Copyright (C) 2021-2023 Kale Ewasiuk +% 2024-02-29 +% Copyright (C) 2021-2024 Kale Ewasiuk % % Permission is hereby granted, free of charge, to any person obtaining a copy % of this software and associated documentation files (the "Software"), to deal @@ -35,11 +35,11 @@ \setlength\ResultBoxRule{0mm} \lstset{ language=[LaTeX]TeX, - basicstyle=\ttfamily\small, - commentstyle=\ttfamily\small\color{gray}, + basicstyle=\ttfamily\footnotesize, + commentstyle=\ttfamily\footnotesize\color{gray}, frame=none, numbers=left, - numberstyle=\ttfamily\small\color{gray}, + numberstyle=\ttfamily\footnotesize\color{gray}, prebreak=\raisebox{0ex}[0ex][0ex]{\color{gray}\ensuremath{\hookleftarrow}}, extendedchars=true, breaklines=true, @@ -53,7 +53,7 @@ \date{\today} -\RequirePackage{penlightplus} +\RequirePackage[pl,globals]{penlightplus} \title{penlightplus} \subtitle{Additions to the Penlight Lua Libraries} @@ -97,14 +97,28 @@ The gloals flags below are taken care of in the package options:\\ \cmd{__PL_NO_HYPERREF__} a flag used to change the behaviour of a function, depending on if you don't use the hyperref package\\ \cmd{__PDFmetadata__} a table used to store PDF meta-data + +\subsubsection*{global extras} +If the package option \cmd{globals} is used, many additional globals are set for easier scripting. +\cmd{pl.hasval}, \cmd{pl.COMP}, \cmd{pl.utils.kpairs}, \cmd{pl.utils.npairs} become globals. +\cmd{pl.tablex} is aliased as \cmd{pl.tbx and tbx} (which also includes all native Lua table functions), and +\cmd{pl.array2d} is aliased as \cmd{pl.a2d and a2d}. + +If you want global \cmd{pl.tex} funcs and vars, call \cmd{pl.make_tex_global()}\\ + + \subsubsection*{penlight additions} Some functionality is added to penlight and Lua. \llcmd{pl.hasval(x)} Python-like boolean testing\\ \llcmd{COMP'xyz'()} Python-like comprehensions:\\\url{https://lunarmodules.github.io/Penlight/libraries/pl.comprehension.html}\\ + +\cmd{clone_function(f)} returns a cloned function\\ +\cmd{operator.strgt(a,b)} compares strings a greater than b (useful for sorting)\\ +\cmd{operator.strlt(a,b)} compares strings a less than b (useful for sorting)\\ + \llcmd{math.mod(n,d)}, \cmd{math.mod2(n)} math modulous\\ -\\ \llcmd{string.}\cmd{upfirst(s)} uppercase first letter\\ \llcmd{string.}\cmd{delspace(s)} delete all spaces\\ @@ -123,6 +137,16 @@ Some functionality is added to penlight and Lua. a few improvements. \cmd{t} can be an array (reference items like \cmd{\$1} in the string), and \cmd{fmt} can be a table of formats (keys correspond to those in \cmd{t}), or a string that is processed by luakeys.\\ +\llcmd{string.}\cmd{parsekv(s, opts)} parse a string using \cmd{penlight.luakeys}. A string or table can be used for opts. + +\llcmd{tablex.}\cmd{fmt(t, f)} format a table with table or key-value string f\\ +\llcmd{tablex.}\cmd{strinds(t)} convert integer indexes to string indices (1 -> '1')\\ +\llcmd{tablex.}\cmd{filterstr(t,e,case)} keep only values in table t that contain expression e, case insensitive by default.\\ +\llcmd{tablex.}\cmd{mapslice(f,t,i1,i2)} map a function to elements between i1 and i2\\ +\llcmd{tablex.}\cmd{listcontains(t,v)} checks if a value is in a array-style list \\ + + + \llcmd{pl.}\cmd{char(n)} return letter corresponding to 1=a, 2=b, etc.\\ \llcmd{pl.}\cmd{Char(n)} return letter corresponding to 1=A, 2=B, etc.\\ @@ -156,17 +180,13 @@ to a package warning saying \cmd{'cs' was declared and used in document, but nev is true, it will overwrite an existing command (using \cmd{defcmd}), otherwise, it will throw error like \cmd{newcmd}.\\ \llcmd{get_ref_info(l)}accesses the \cmd{\r@label} and returns a table\\ +\subsubsection*{Recording latex input} +\cmd{penlight.tex.startrecording()} start recording input buffer without printing to latex\\ +\cmd{penlight.tex.stoprecording()} stop recording input buffer\\ +\cmd{penlight.tex.readbuf()} internal-use function that interprets the buffer. This will ignore an environment ending (eg. \cmd{end{envir}})\\\\ +\cmd{penlight.tex.recordedbuf} the string variable where the recorded buffer is stored\\ -\subsubsection*{global extras} -If the package option \cmd{globals} is used, many additional globals are set for easier scripting. -\cmd{pl.hasval}, \cmd{pl.COMP}, \cmd{pl.utils.kpairs}, \cmd{pl.utils.npairs} become globals. -\cmd{pl.tablex} is aliased as \cmd{pl.tbx and tbx} (which also includes all native Lua table functions), and -\cmd{pl.array2d} is aliased as \cmd{pl.a2d and a2d}. - -If you want global \cmd{pl.tex} funcs and vars, call \cmd{pl.make_tex_global()} -\\ - \subsection*{Macro helpers} @@ -224,17 +244,27 @@ no, once, twice, or full expansion. For example, we can control the expansion of \cmd{\tblchg{t}} changes the 'recent' table\\ \cmd{\tblfrkv{t}{key-val string}[luakeys opts]} new table from key-vals using \cmd{luakeys} \\ \cmd{\tblfrkvN{t}{key-val string}[luakeys opts]} does not expand key-val string \cmd{luakeys} \\ - \cmd{\tblfrcsv} a shorthand \cmd{\tblfrkv{t}{csv}[naked_as_value=true,opts]}, a good way to convert a comma-separated list to an array\\ +\cmd{\tblfrkvCD{t}{key-val string}[luakeys opts]} define tbl from key-val, +check if any were not defined as defaults (see below), and then push all to definitions\\ +\cmd{\tblkvundefcheck} will throw an error if you use define a table from key-values +and use a key that was not specified in the luakeys parse options via \cmd{opts.defaults} or \cmd{opts.defs}. + \cmd{\tblfrcsv{t}{csv}} a shorthand \cmd{\tblfrkv{t}{csv}[naked_as_value=true,opts]}, a good way to convert a comma-separated list to an array\\ + \cmd{\tblfrcsvN{t}{csv}} same as above, but the csv is not expanded. \cmd{\tblset{i}{v}} sets a value of the table/index \cmd{i} to \cmd{v}\\ -\cmd{\tblget{i}} gets the value and \cmd{tex.sprint()}'s it\\ +\cmd{\tblget{i}} gets the value and \cmd{tex.sprint()}s it\\ +\cmd{\tbladd{i}{v}} add a new value to a table using index method\\ +\cmd{\tbladdN{i}{v}} above, but don't expand the value argument\\ +\cmd{\tblcon{t}{csv}} concatenate an array-style csv\\ +\cmd{\tblapp{t}{v}} append a value (integer-wise) to a table\\ \cmd{\tbldef{i}{d}} pushes the value to macro \cmd{d}\\ -\cmd{\tbldefall{t}{d}} define all item in table \cmd{t} (use recent if blank) with format \cmd{d}, if \cmd{d} is blank, commands are defined as \cmd{tbl} \\ -\cmd{\tblgdef{i}{d}} pushes the value to a global\\ +\cmd{\tbldefall{t}{d}} define all item in table \cmd{t} (use recent if blank) with format \cmd{d} where d is your prefix. If d is blank, keys will be defined as \cmd{\dtbl} +\cmd{\tblgdef{i}{d}} pushes the defined value to a global\\ \cmd{\tbldefxy{i}{d}} splits the value of item by spaces creates two definitions \cmd{\dx} and \cmd{\dy}. Useful for pasing tikz coordinates like \cmd{xy=0 5}\\ +For definiting tables, if \cmd{d} is blank, commands are defined as \cmd{dtbl}\\ \cmd{\iftbl{i}{tr}[fa]} runs code \cmd{ta} if the item is true else \cmd{fr}\\ \cmd{\iftblv{i}{tr}[fa]} runs code \cmd{ta} if the item is truthy else \cmd{fr}\\ -\cmd{\tblkvundefcheck} will throw an error if you use define a table from key-values -and use a key that was not specified in the luakeys parse options via \cmd{opts.defaults} or \cmd{opts.defs}. + +\cmd{\tblprt{t}} print the table in console There are 3 ways to use the index (placeholder \cmd{{i}} above). \cmd{t.key} where \cmd{t} is the table name and \cmd{key} is a string key, @@ -248,6 +278,7 @@ or simply use \cmd{ind} without the table name, where the assumed table is the l \tblset{a}{tRuE!!} \tblget{a}\\ \tblget{my.x}\\ +\tblget{.x}\\ \tblif{n}{tr}[fa]\\ \tblifv{n}{TR}[FA]\\ \tblif{my.y}{Tr}[Fa]\\ @@ -263,14 +294,21 @@ or simply use \cmd{ind} without the table name, where the assumed table is the l \tblset{my.a}{12 36} \tbldefxy{my.a}{coord} (\coordx,\coordy) +\tbldefxy{my.a}{} (\dtblmyax,\dtblmyay) +\tbldefxy{a}{} (\dtblmyax,\dtblmyay) \tblfrcsv{me}{a,b,"c,see",d,e} \tblget{me/1},\tblget{2}\\ \tblget{3}\\ -\tblset{me/4}{D}\tblget{me/4}\\ +\tblset{me/4}{D}\tblget{me/4}\tblget{/4}\\ \tblset{5}{E}\tblget{5}\\ \tblget{-2},\tblget{me/-1}\\ +\tblget{/-3}\\ %% \tblget{k} % would throw error + +\tblfrkvCD{M}{a=A,b=B,d=D}[defaults={a,b,c,d}] +\dtblMa \dtblMb \dtblMc \dtblMd + \end{LTXexample} @@ -287,6 +325,38 @@ Note: for this versions: all latex tbl commands are now prefixed with \cmd{tbl}, Old-style commands eg. \cmd{gettbl} will be kept as aliases for a few more releases then removed. +\subsubsection*{A practical tbl example} + +\begin{LTXexample} +\begin{luacode*} + function prt_pyth() + t = pl.tbls.pyth + if not t.a then + pl.tex.pkgerror('must pass a= to \\pyth') + elseif not t.b then + t.b = (tonumber(t.c)^2 - + tonumber(t.a)^2)^0.5 + elseif not t.c then + t.c = (tonumber(t.a)^2 + + tonumber(t.b)^2)^0.5 + end + local t = pl.tbx.fmt(t,'.'..t.d..'f') -- format table according to d decimals + s = 'Right-angle sides a=$a and b=$b form a hypotenuse of c=$c' + pl.tex.prt(s:fmt(t)) + end +\end{luacode*} +\NewDocumentCommand{\pyth}{m}{% + \tblfrkv{pyth}{#1}[defaults={a=false,b=false,c=false,d=0,e=extras}] + \luadirect{prt_pyth()}% +} + +\pyth{a=3,c=5}\\ +\pyth{a=3.2,b=4.2,d=2}\\ +C: \tblget{c} + +\end{LTXexample} + + \subsection*{Splitting strings} Splitting text (or a cmd) into oxford comma format via: \cmd{\splittocomma[expansion level]{text}{text to split on}}: @@ -314,9 +384,20 @@ You can do a similar string split but to \cmd{\item} instead of commas with \cmd +\subsubsection*{PDF meta data (for pdfx package)} +\cmd{\writePDFmetadatakv*{m}} Take a key-value string (eg. \cmd{title=whatever, author=me}) and writes to the \cmd{jobname.xmpdata} file, to be used by pdfx. \cmd{*} will first clear the data\\ +\cmd{\writePDFmetadata} runs the lua function \cmd{penlight.tex.writePDFmetadata()}, +which pushes the lua variable \cmd{__PDFmetadata__} (a table) to the xmpdata file. + + +%\pyth{} % erro +%\begin{luacode*} +% pl.tex.wrth(('a,b,c=3'):parsekv('!naked_as_value'), 'dumy') +%\end{luacode*} + % \tblfrkv{tbl_def}{kale=cool,paul=gay,craig=fun} % \tblfrkv{tbl}{kale,paul=gay} %[naked_as_value=true] % @@ -338,24 +419,25 @@ You can do a similar string split but to \cmd{\item} instead of commas with \cmd % % \THINg[color=blue,size=tiny]{Kale} % -%\begin{luacode*} -%penlight.wrth(('$1'):fmt(5.5,'.8f','XYZ')) -%function prttol() -% penlight.tbls.tol[3] = penlight.tbls.tol[3] or 3 -% penlight.tbls.tol[4] = penlight.tbls.tol[1]*(1.0-penlight.tbls.tol[3]/100.0) + 0.0 -% penlight.tbls.tol[5] = penlight.tbls.tol[1]*(1.0+penlight.tbls.tol[3]/100.0) + 0.0 -% penlight.tbls.tol['k'] = 'fuckboi' -% penlight.wrth(('$k $1\\$2 (\\pmpct{$3} tolerance, $4\\ndash$5\\$2)'):fmt(penlight.tbls.tol, '4=.1f, 5=.1f'), 'XYZ') -%end -%\end{luacode*} -%\NewDocumentCommand{\prttol}{ m }{% {50.0,kV,3} % 50\us (\pmpct{20} tolerance, 40=--60\us) -%\tblfrcsv{tol}{#1}\luadirect{prttol()}} -% -%\prttol{50,kV,3.21} -% -%\begin{luacode*} -%--pl.wrth(('2.23'):gnum()) -%\end{luacode*} +\begin{luacode*} +function prttol() + local dec = penlight.tbls.tol[4] or 1 + penlight.wrth(dec,'??') + penlight.tbls.tol[3] = penlight.tbls.tol[3] or 3 + penlight.tbls.tol[4] = penlight.tbls.tol[1]*(1.0-penlight.tbls.tol[3]/100.0) + 0.0 + penlight.tbls.tol[5] = penlight.tbls.tol[1]*(1.0+penlight.tbls.tol[3]/100.0) + 0.0 + --penlight.tbls.tol['k'] = 'fuckboi' + --ttt = pl.tbx.fmt(penlight.tbls.tol, '.3f') + penlight.wrth(('$1\\$2 (\\pmpct{$3} tolerance, $4\\ndash$5\\$2)'):fmt(penlight.tbls.tol, '4=.'..dec..'f, 5=.'..dec..'f'), 'XYZ') +end +\end{luacode*} +\NewDocumentCommand{\prttol}{ m }{\tblfrcsv{tol}{#1}\luadirect{prttol()}}% {50.0,kV,3,P} % 50\us (\pmpct{20} tolerance, 40=--60\us), P is optional and precision of the range (number of decimals) + +\prttol{50,kV,3} + +\begin{luacode*} + pl.wrth(pl.filterfiles('.',true,'.*%.tex'), 'FF') +\end{luacode*} \end{document} \ No newline at end of file diff --git a/Master/texmf-dist/tex/luatex/penlightplus/penlightplus.lua b/Master/texmf-dist/tex/luatex/penlightplus/penlightplus.lua index 6aa1331fdd5..a831c6721d8 100644 --- a/Master/texmf-dist/tex/luatex/penlightplus/penlightplus.lua +++ b/Master/texmf-dist/tex/luatex/penlightplus/penlightplus.lua @@ -1,6 +1,6 @@ --% Kale Ewasiuk (kalekje@gmail.com) ---% 2023-12-08 ---% Copyright (C) 2021-2023 Kale Ewasiuk +--% 2024-02-29 +--% Copyright (C) 2021-2024 Kale Ewasiuk --% --% Permission is hereby granted, free of charge, to any person obtaining a copy --% of this software and associated documentation files (the "Software"), to deal @@ -143,8 +143,9 @@ function penlight.tex.wrth(s1, s2) -- helpful printing, makes it easy to debug, end wrt2('\n^^^^^\n') end +penlight.wrth = penlight.tex.wrth +penlight.tex.help_wrt = penlight.tex.wrth penlight.help_wrt = penlight.tex.wrth -penlight.wrth = penlight.help_wrt function penlight.tex.prt_array2d(t) for _, r in ipairs(t) do @@ -456,22 +457,18 @@ function str_mt.__index.subpar(s, r) end -function str_mt.__index.fmt(s, t, fmt) -- format a $1 string with an array or table and formats - -- formats can be a luakeys string, or a table - fmt = fmt or {} - if type(fmt) == 'string' then - fmt = penlight.tablex.strinds(penlight.luakeys.parse(fmt, {naked_as_value=true})) - end +function str_mt.__index.fmt(s, t, fmt) -- format a $1 and $k string with an array or table and formats + -- formats can be a luakeys string, or a table and are applied to table before string is formatted if type(t) ~= 'table' then t = {t} end t = penlight.tablex.strinds(t) - for k, f in pairs(fmt) do -- apply formats - t[k] = string.format('%'..f, t[tostring(k)]) - end + t = penlight.tablex.fmt(t, fmt, true) return s % t end - - +function str_mt.__index.parsekv(s, t) -- parsekv string + if type(t) ~= 'table' then t = penlight.luakeys.parse(t) end + return penlight.luakeys.parse(s, t) +end -- -- -- -- function stuff @@ -532,6 +529,37 @@ function penlight.tablex.strinds(t) -- convert indices that are numbers to strin end +function penlight.tablex.listcontains(t, v) + return penlight.tablex.find(t, v) ~= nil +end + + +-- format contents of a table +function penlight.tablex.fmt(t, fmt, strinds) + if fmt == nil then + return t + end + strinds = strinds or false -- if your fmt table should use string indexes + if type(fmt) == 'string' then + if not fmt:find('=') then -- if no = assume format all same + for k, v in pairs(t) do -- apply same format to all + if tonumber(v) ~= nil then -- only apply to numeric values + t[k] = string.format("%"..fmt, v) + end + end + return t + else + fmt = fmt:parsekv('naked_as_value') -- make fmt a table from keyval str + end + end + if strinds then fmt = penlight.tablex.strinds(fmt) end -- convert int inds to str inds + for k, f in pairs(fmt) do -- apply formatting to table + t[k] = string.format("%"..f, tostring(t[k])) + end + return t +end + + function penlight.tablex.map_slice(func, T, j1, j2) if type(j1) == 'string' then return penlight.array2d.map_slice(func, {T}, ','..j1)[1] @@ -556,24 +584,25 @@ function penlight.tablex.filterstr(t, exp, case) end end - +--todo add doc function penlight.utils.filterfiles(...) -- f1 is a series of filtering patterns, or condition -- f2 is a series of filtering patters, or condition -- (f1_a or f2_...) and (f2 .. ) must match local args = table.pack(...) - -- todo -- check where boolean is for recursive or not, set starting argument + -- dir, recursive[bool], filt1, filt2 etc... + -- OR recursive[bool], filt1, filt2, etc.. + -- OR filt1, filt2, filt3, etc.. -- this could allow one to omit dir - -- todo if no boolean at all, assume dir = '.' and r = false - -- if boolean given, assume dir = '.' + -- if boolean given ar arg 1, assume dir = '.' local nstart = 3 - local r = args[2] - local dir = args[1] + local r = args[2] -- recursive + local dir = args[1] -- start dir if type(args[1]) == 'boolean' then dir = '.' r = args[1] nstart = 2 - elseif type(args[2]) ~= 'boolean' then + elseif type(args[2]) ~= 'boolean' then -- if boolean given ar arg 1, assume dir = '.' dir = '.' r = false nstart = 1 @@ -591,7 +620,6 @@ end - -- -- -- -- -- -- -- -- functions below extend the array2d module @@ -808,6 +836,18 @@ function penlight.tex.split2items(s, d) end +function penlight.toggle_luaexpr(expr) + if expr then + tex.sprint('\\toggletrue{luaexpr}') + else + tex.sprint('\\togglefalse{luaexpr}') + end +end + + + + + penlight.tbls = {} penlight.rec_tbl = '' @@ -820,6 +860,11 @@ function penlight.get_tbl_name(s) return s end +function penlight.get_tbl(s) + s = penlight.get_tbl_name(s) + return penlight.tbls[s] +end + function penlight.get_tbl_index(s) local tbl = '' local key = '' @@ -830,6 +875,7 @@ function penlight.get_tbl_index(s) elseif s:find('/') then local tt = s:split('/') tbl = tt[1] + if tbl == '' then tbl = penlight.rec_tbl end key = tonumber(tonumber(tt[2])) if key < 0 then key = #penlight.tbls[tbl]+1+key end else @@ -837,6 +883,7 @@ function penlight.get_tbl_index(s) key = tonumber(s) or s if type(key) == 'number' and key < 0 then key = #penlight.tbls[tbl]+1+key end end + if tbl == '' then tbl = penlight.rec_tbl end if penlight.tbls[tbl] == nil or penlight.tbls[tbl][key] == nil then penlight.tex.pkgerror('penlightplus', 'Invalid index of tbl using: "'..s..'"') end @@ -881,10 +928,26 @@ function penlight.check_recent_tbl_undefault() end end +function penlight.def_tbl(ind, def, g) + local _tbl, _key = penlight.get_tbl_index(ind) + if def == '' then def = 'dtbl'.._tbl.._key end + token.set_macro(def, tostring(penlight.tbls[_tbl][_key]), g) +end + +function penlight.def_tbl_all(ind, def) + local _tbl = penlight.get_tbl_name(ind) + if def == '' then def = 'dtbl'.._tbl end + for k, v in pairs(penlight.tbls[_tbl]) do + token.set_macro(def..k, tostring(v)) + end +end + -- TODO TODO TODO get error working xy def, and referene which table for key-vals penlight.tbl_xysep = '%s+' -- spaces separate x-y coordinates -function penlight.def_tbl_coords(str, def) - -- todo could definitely make this flexible for a table... +function penlight.def_tbl_coords(ind, def) + local tbl, key = penlight.get_tbl_index(ind) + local str = penlight.tbls[tbl][key] + if def == '' then def = 'dtbl'..tbl..key end local x, y = str:strip():splitv(penlight.tbl_xysep) if (not penlight.hasval(x)) or (not penlight.hasval(y)) then penlight.tex.pkgerror('penlightplus', 'def_tbl_coords function could not parse coordiantes given as "'..str..'" ensure two numbers separated by space are given!', '', true) @@ -894,7 +957,14 @@ function penlight.def_tbl_coords(str, def) end --- + + + + + + + +-- global setting type stuff function penlight.make_tex_global() for k,v in pairs(penlight.tex) do -- make tex functions global diff --git a/Master/texmf-dist/tex/luatex/penlightplus/penlightplus.sty b/Master/texmf-dist/tex/luatex/penlightplus/penlightplus.sty index f5ffc0f1767..ee7ff3ad11f 100644 --- a/Master/texmf-dist/tex/luatex/penlightplus/penlightplus.sty +++ b/Master/texmf-dist/tex/luatex/penlightplus/penlightplus.sty @@ -1,6 +1,6 @@ % Kale Ewasiuk (kalekje@gmail.com) -% 2023-12-08 -% Copyright (C) 2021-2023 Kale Ewasiuk +% 2024-02-29 +% Copyright (C) 2021-2024 Kale Ewasiuk % % Permission is hereby granted, free of charge, to any person obtaining a copy % of this software and associated documentation files (the "Software"), to deal @@ -22,7 +22,7 @@ % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE % OR OTHER DEALINGS IN THE SOFTWARE. -\ProvidesPackage{penlightplus}[2023-12-08] +\ProvidesPackage{penlightplus}[2024-02-29] \RequirePackage{luacode} \RequirePackage{luakeys} @@ -84,22 +84,16 @@ \newtoggle{luaexpr}\togglefalse{luaexpr} \begin{luacode*} - function toggle_luaexpr(expr) - if expr then - tex.sprint('\\toggletrue{luaexpr}') - else - tex.sprint('\\togglefalse{luaexpr}') - end - end + \end{luacode*} -\NewDocumentCommand{\ifluax}{m m O{}}{% - \luadirect{toggle_luaexpr(#1)}% +\NewDocumentCommand{\ifluax}{m m O{}}{% if lua expression is true do {m} if not [o] + \luadirect{penlight.toggle_luaexpr(#1)}% \iftoggle{luaexpr}{#2}{#3}% \togglefalse{luaexpr}% safety set to false } -\NewDocumentCommand{\ifluaxv}{m m O{}}{\ifluax{penlight.hasval(#1)}{#2}[#3]} +\NewDocumentCommand{\ifluaxv}{m m O{}}{\ifluax{penlight.hasval(#1)}{#2}[#3]}% if lua expression is truthy do {m} else [o] @@ -116,6 +110,10 @@ penlight.rec_tbl = \luastring{#1} }} +\NewDocumentCommand{\tblfrkvCD}{m +m O{}}{\tblfrkv{#1}{#2}[#3]\tblkvundefcheck\tbldefall{}{}} +%% tbl from key-vals, then check defaults, then define all keys using default format +\NewDocumentCommand{\tblfrkvNCD}{m +m O{}}{\tblfrkvN{#1}{#2}[#3]\tblkvundefcheck\tbldefall{}{}} + \NewDocumentCommand{\tblfrkvN}{m +m O{}}{\luadirect{% penlight.rec_tbl_opts = penlight.luakeys.parse(\luastring{#3}) penlight.tbls[\luastring{#1}] = penlight.luakeys.parse(string.subpar(\luastringN{#2}), penlight.rec_tbl_opts) @@ -124,9 +122,38 @@ \NewDocumentCommand{\tblfrcsv}{m +m O{}}{\tblfrkv{#1}{#2}[naked_as_value=true,#3]} +\NewDocumentCommand{\tblfrcsvN}{m +m O{}}{\tblfrkvN{#1}{#2}[naked_as_value=true,#3]} + \NewDocumentCommand{\tblkvundefcheck}{}{\luadirect{penlight.check_recent_tbl_undefault()}}% check defaults list and throw error if foreign keys were used + + +\NewDocumentCommand{\tblapp}{m m}{\luadirect{% append to a table (ie using integer index) with a value (second arg) # todo option for string or number + __tbl__ = penlight.get_tbl_name(\luastring{#1}) + table.insert(penlight.tbls[__tbl__], \luastring{#2}) +}} + +\NewDocumentCommand{\tblcon}{m m}{\luadirect{% concatenate to a table (ie using integer index) with a list of comma separated values (second arg) # + __tbl__ = penlight.get_tbl_name(\luastring{#1}) + for k, v in ipairs(penlight.luakeys.parse(string.subpar(\luastring{#2}), {naked_as_value=true})) do + table.insert(penlight.tbls[__tbl__], v) + end +}} + +\NewDocumentCommand{\tbladd}{m m m}{\luadirect{% add a kv pair to a table + __tbl__ = penlight.get_tbl_name(\luastring{#1}) + penlight.tbls[__tbl__][\luastring{#2}] = \luastring{#3} +}} + +\NewDocumentCommand{\tbladdN}{m m m}{\luadirect{% add a kv pair to a table + __tbl__ = penlight.get_tbl_name(\luastring{#1}) + penlight.tbls[__tbl__][\luastring{#2}] = \luastringN{#3} +}} + + + + \NewDocumentCommand{\tblchg}{ m }{\luadirect{% change recent table penlight.rec_tbl = \luastring{#1} }} @@ -140,36 +167,21 @@ penlight.set_tbl_item(\luastring{#1}, \luastring{#2}) }} -% todo if no definition is provided, assume -\NewDocumentCommand{\tbldef}{ m m }{\luadirect{% define a {table key}{def} - local _tbl, _key = penlight.get_tbl_index(\luastring{#1}) - local _tbl_def_ = \luastring{#2} - if _tbl_def_ == '' then _tbl_def_ = 'dtbl'.._tbl.._key end - token.set_macro(_tbl_def_, tostring(penlight.tbls[_tbl][_key])) -}} -\NewDocumentCommand{\tbldefall}{ m m }{\luadirect{% define all {table} keys to {table} \table - % todo maybe change tbldef {def} to [def] and make same as table name - local _tbl = penlight.get_tbl_name(\luastring{#1}) - local _tbl_def_ = \luastring{#2} - if _tbl_def_ == '' then _tbl_def_ = 'dtbl'.._tbl end - for k, v in pairs(penlight.tbls[_tbl]) do - token.set_macro(_tbl_def_..k, tostring(v)) - end -}} +\NewDocumentCommand{\tbldef}{ m m }{\luadirect{penlight.def_tbl(\luastring{#1}, \luastring{#2})}} +% define a table, use * to make global definition +\NewDocumentCommand{\tblgdef}{ m m }{\luadirect{penlight.def_tbl(\luastring{#1}, \luastring{#2}, 'global')}} -\NewDocumentCommand{\tblgdef}{ m m }{\luadirect{% define a table, use * to make global definition - token.set_macro(\luastring{#2}, tostring(penlight.get_tbl_item(\luastring{#1})), 'global') -}} - -\NewDocumentCommand{\tbldefxy}{ m m }{\luadirect{penlight.def_tbl_coords(penlight.get_tbl_item(\luastring{#1}), \luastring{#2})}}% define #2x and #2y from a space delimited x-y pair +\NewDocumentCommand{\tbldefall}{ m m }{\luadirect{penlight.def_tbl_all(\luastring{#1}, \luastring{#2})}} +\NewDocumentCommand{\tbldefxy}{ m m }{\luadirect{penlight.def_tbl_coords(\luastring{#1}, \luastring{#2})}}% define #2x and #2y from a space delimited x-y pair \NewDocumentCommand{\tblif}{m m O{}}{\ifluax{penlight.get_tbl_item(\luastring{#1})}{#2}[#3]} \NewDocumentCommand{\tblifv}{m m O{}}{\ifluaxv{penlight.get_tbl_item(\luastring{#1})}{#2}[#3]} +\NewDocumentCommand{\tblprt}{m}{\luadirect{penlight.wrth(penlight.get_tbl(\luastring{#1}),'penlightplus table: '..\luastring{#1})}} % legacy code, delete this \let\kvtblundefcheck\tblkvundefcheck -- cgit v1.2.3