From 64e26532c685fd24d6983508c6239e3c268b810b Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Tue, 29 Aug 2023 03:00:56 +0000 Subject: CTAN sync 202308290300 --- .../luatex/generic/penlightplus/penlightplus.lua | 57 +++++++++- .../luatex/generic/penlightplus/penlightplus.pdf | Bin 55459 -> 62224 bytes .../luatex/generic/penlightplus/penlightplus.sty | 117 ++++++++++++++++----- .../luatex/generic/penlightplus/penlightplus.tex | 91 ++++++++++++---- 4 files changed, 213 insertions(+), 52 deletions(-) (limited to 'macros/luatex/generic') diff --git a/macros/luatex/generic/penlightplus/penlightplus.lua b/macros/luatex/generic/penlightplus/penlightplus.lua index ffdbe89bc5..96eb565fb6 100644 --- a/macros/luatex/generic/penlightplus/penlightplus.lua +++ b/macros/luatex/generic/penlightplus/penlightplus.lua @@ -1,5 +1,5 @@ --% Kale Ewasiuk (kalekje@gmail.com) ---% 2023-07-22 +--% 2023-08-27 --% Copyright (C) 2021-2023 Kale Ewasiuk --% --% Permission is hereby granted, free of charge, to any person obtaining a copy @@ -67,6 +67,10 @@ penlight.tex._xTrue = '\\BooleanTrue ' penlight.tex._xFalse = '\\BooleanFalse ' penlight.tex._xNoValue = '-NoValue-' +penlight.tex.xTrue = '\\BooleanTrue ' +penlight.tex.xFalse = '\\BooleanFalse ' +penlight.tex.xNoValue = '-NoValue-' + --Generic LuaLaTeX utilities for print commands or environments if not __PL_SKIP_TEX__ then @@ -138,6 +142,8 @@ function penlight.tex.help_wrt(s1, s2) -- helpful printing, makes it easy to deb wrt2('\n^^^^^\n') end penlight.help_wrt = penlight.tex.help_wrt +penlight.wrth = penlight.help_wrt +penlight.tex.wrth = penlight.help_wrt function penlight.tex.prt_array2d(t) for _, r in ipairs(t) do @@ -171,9 +177,10 @@ end --definition helpers -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -function penlight.tex.defmacro(cs, val) -- , will not work if val contains undefined tokens (so pre-define them if using..) +function penlight.tex.defmacro(cs, val, g) -- , will not work if val contains undefined tokens (so pre-define them if using..) val = val or '' -- however this works for arbitrary command names (\@hello-123 etc allowed) - token.set_macro(cs, val, 'global') + g = g or 'global' + token.set_macro(cs, val, g) end @@ -767,6 +774,47 @@ function penlight.tex.split2items(s, d) end +penlight.tbls = {} + +function penlight.get_tbl_item(s, p) -- get item with string, p means print value + p = p or false + local itm = 'tbl: INVALID INDEX WITH: "'..s..'"' + if s:find('%.') then + local tt = s:split('.') + itm = penlight.tbls[tt[1]][tt[2]] + elseif s:find('/') then + local tt = s:split('/') + itm = penlight.tbls[tt[1]][tonumber(tonumber(tt[2]))] + else + if s:isdigit() then + itm = penlight.tbls._recent[tonumber(s)] + else + itm = penlight.tbls._recent[s] + end + end + if p then + tex.sprint(tostring(itm)) + end + return itm +end + + +function penlight.set_tbl_item(s, v) + if s:find('%.') then + local tt = s:split('.') + penlight.tbls[tt[1]][tt[2]] = v + elseif s:find('/') then + local tt = s:split('/') + penlight.tbls[tt[1]][tonumber(tonumber(tt[2]))] = v + else + if s:isdigit() then + penlight.tbls._recent[tonumber(s)] = v + else + penlight.tbls._recent[s] = v + end + end + end + if penlight.hasval(__PL_GLOBALS__) then -- iterators @@ -803,8 +851,9 @@ if penlight.hasval(__PL_GLOBALS__) then penlight.filterfiles = penlight.utils.filterfiles penlight.a2 = penlight.array2d + A2d = penlight.array2d penlight.tbl = penlight.tablex - + TX = penlight.tablex for k,v in pairs(penlight.tex) do -- make tex functions global _G[k] = v diff --git a/macros/luatex/generic/penlightplus/penlightplus.pdf b/macros/luatex/generic/penlightplus/penlightplus.pdf index 89b8236d66..32135ebb6e 100644 Binary files a/macros/luatex/generic/penlightplus/penlightplus.pdf and b/macros/luatex/generic/penlightplus/penlightplus.pdf differ diff --git a/macros/luatex/generic/penlightplus/penlightplus.sty b/macros/luatex/generic/penlightplus/penlightplus.sty index 0d49ff90d0..3f95ae4d9e 100644 --- a/macros/luatex/generic/penlightplus/penlightplus.sty +++ b/macros/luatex/generic/penlightplus/penlightplus.sty @@ -1,5 +1,5 @@ % Kale Ewasiuk (kalekje@gmail.com) -% 2023-07-22 +% 2023-08-27 % Copyright (C) 2021-2023 Kale Ewasiuk % % Permission is hereby granted, free of charge, to any person obtaining a copy @@ -22,11 +22,12 @@ % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE % OR OTHER DEALINGS IN THE SOFTWARE. -\ProvidesPackage{penlightplus}[2023-07-22] +\ProvidesPackage{penlightplus}[2023-08-27] \RequirePackage{luacode} \RequirePackage{luakeys} \RequirePackage[import]{penlight} +\RequirePackage{etoolbox} \DeclareOption{globals}{\luadirect{__PL_GLOBALS__ = true}} \DeclareOption{pl}{\directlua{pl = penlight}} @@ -72,43 +73,92 @@ } -% -% -%\NewDocumentCommand{\tblnew}{m}{\luadirect{ -% _G[\luastring{#1}] = {} -%}} -% -%\NewDocumentCommand{\tblfrkv}{m m O{} }{\luadirect{ -% _G[\luastring{#1}] = penlight.luakeys.parse(\luastring{#2}, penlight.luakeys.parse(\luastring{#3})) -%}} -% -%\NewDocumentCommand{\tblset}{m m m}{\luadirect{ -% _G[\luastring{#1}][\luastring{#2}] = \luastring{#3} -%}} -% -%\NewDocumentCommand{\tblget}{m m}{\luadirect{ -% tex.sprint(tostring(_G[\luastring{#1}][\luastring{#2}])) -%}} -% -%\NewDocumentCommand{\tblidx}{m m}{\luadirect{ -% tex.sprint(tostring(_G[\luastring{#1}][#2])) -%}} -% -% + + + + + + +%%%% + +\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)}% + \iftoggle{luaexpr}{#2}{#3}% + \togglefalse{luaexpr}% safety set to false +} + +\NewDocumentCommand{\ifluaxv}{m m O{}}{\ifluax{penlight.hasval(#1)}{#2}[#3]} + + +% testing ifluax +% {-->\ifluax{1 == 2}{\LARGE TRUE}[\tiny FALSE]<--test\\ +% -->\ifluax{abc == nil}{\LARGE TRUE}[\tiny FALSE]<--test} + + +%%% + +\NewDocumentCommand{\newtbl}{m}{\luadirect{ + penlight.tbls[\luastring{#1}] = {} + penlight.tbls._recent = penlight.tbls[\luastring{#1}] +}} + +\NewDocumentCommand{\tblfrkv}{m m O{}}{ \luadirect{ + penlight.tbls[\luastring{#1}] = penlight.luakeys.parse(\luastring{#2}, penlight.luakeys.parse(\luastring{#3})) + penlight.tbls._recent = penlight.tbls[\luastring{#1}] +}} + +\NewDocumentCommand{\chgtbl}{ m }{ \luadirect{ + penlight.tbls._recent = penlight.tbls[\luastring{#1}] +}} + +\NewDocumentCommand{\gettbl}{m}{\luadirect{ + penlight.get_tbl_item(\luastring{#1}, true) +}} + +\NewDocumentCommand{\settbl}{m m}{\luadirect{ + penlight.set_tbl_item(\luastring{#1}, \luastring{#2}) +}} + +\NewDocumentCommand{\deftbl}{ m m }{\luadirect{% define a table, use * to make definition + token.set_macro(\luastring{#2}, tostring(penlight.get_tbl_item(\luastring{#1}))) +}} + +\NewDocumentCommand{\gdeftbl}{ 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{\iftbl}{m m O{}}{\ifluax{penlight.get_tbl_item(\luastring{#1})}{#2}[#3]} + +\NewDocumentCommand{\iftblv}{m m O{}}{\ifluaxv{penlight.get_tbl_item(\luastring{#1})}{#2}[#3]} + + + %\NewDocumentCommand{\tblupd}{ m m}{\luadirect{ -% penlight.tablex.update(_G[\luastring{#1}], _G[\luastring{#2}]) +% penlight.tablex.update(penlight.tbls[\luastring{#1}], penlight.tbls[\luastring{#2}]) %}} % %\NewDocumentCommand{\tblupdkv}{ m m }{\luadirect{ -% penlight.tablex.update(_G[\luastring{#1}], penlight.luakeys.parse(\luastring{#2})) +% penlight.tablex.update(penlight.tbls[\luastring{#1}], penlight.luakeys.parse(\luastring{#2})) %}} + % %% todo need a get table function. If blank is passed, the last table referenced is used. %\NewDocumentCommand{\tblfrkvII}{ m m m }{\luadirect{ % _G[\luastring{#1}] = penlight.tablex.update(penlight.luakeys.parse(\luastring{#2}), luakeys.parse(\luastring{#3})) %}} - %\NewDocumentCommand{\tbldo}{m m O{} }{\luadirect{ % % tex.sprint(tostring(_G[\luastring{#1}][#2])) % % todo allow one to use pl tablex function here, @@ -117,3 +167,14 @@ %}} + + +%%%%%%%%5 + +%\begin{luacode*} +% function set_dim(name, len) +% tex.sprint('\\global\\let\\'..name..'\\relax') -- reset length +% tex.sprint('\\global\\newlength{\\'..name..'}') -- make new len +% tex.setglue(name, tex.sp(len)) +% end +%\end{luacode*} diff --git a/macros/luatex/generic/penlightplus/penlightplus.tex b/macros/luatex/generic/penlightplus/penlightplus.tex index 50f87fa38b..fec72b8dfd 100644 --- a/macros/luatex/generic/penlightplus/penlightplus.tex +++ b/macros/luatex/generic/penlightplus/penlightplus.tex @@ -1,5 +1,5 @@ % Kale Ewasiuk (kalekje@gmail.com) -% 2023-07-22 +% 2023-08-27 % Copyright (C) 2021-2023 Kale Ewasiuk % % Permission is hereby granted, free of charge, to any person obtaining a copy @@ -85,20 +85,17 @@ require'penlightplus' +The following global Lua variables are defined: - -\subsection*{} - -The following global variables are defined: - -\llcmd{__SKIP_TEX__} If using the \cmd{penlightplus} package with \cmd{texlua} (good for troubleshooting), set this global before loading \cmd{penlight}\\ +\cmd{__SKIP_TEX__} If using the \cmd{penlightplus} package with \cmd{texlua} (good for troubleshooting), set this global before loading \cmd{penlight}\\ The gloals flags below are taken care of in the package options:\\ -\llcmd{__PL_}\cmd{GLOBALS__} If using package with \cmd{texlua} and you don't want to set some globals (described in next sections), set this global before to \cmd{true} loading \cmd{penlight}\\ +\cmd{__PL_GLOBALS__} If using package with \cmd{texlua} and you don't want to set some globals (described in next sections), set this global before to \cmd{true} loading \cmd{penlight}\\ \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*{penlight additions} -Some functionality is added to penlight/lua. +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}\\ @@ -116,18 +113,19 @@ Some functionality is added to penlight/lua. \llcmd{_NumBkts} internal integer for tracking the number of brackets\\ \llcmd{opencmd(cs)} prints \cmd{\cs}\{ and adds to the bracket counters.\\ \\ -\llcmd{_xNoValue,}\cmd{_xTrue,_xFalse}: \cmd{xparse} equivalents for commands\\ +\llcmd{xNoValue,}\cmd{xTrue,xFalse}: \cmd{xparse} equivalents for commands\\ \\ \llcmd{prt(x),prtn(x)} print without or with a newline at end. Tries to help with special characters or numbers printing.\\ \llcmd{prtl(l),prtt(t)} print a literal string, or table\\ \llcmd{wrt(x), wrtn(x)} write to log\\ -\llcmd{help_wrt}\cmd{(s1, s2)} pretty-print something to console. S2 is a flag to help you find.\\ +\llcmd{help_wrt}\cmd{(s1, s2)} pretty-print something to console. S2 is a flag to help you find., alias is \cmd{wrth}\\ \llcmd{prt_array2d(tt)} pretty print a 2d array\\ \\ \llcmd{pkgwarn}\cmd{(pkg, msg1, msg2)} throw a package warning\\ \llcmd{pkgerror}\cmd{(pkg, msg1, msg2, stop)} throw a package error. If stop is true, immediately ceases compile.\\ \\ -\llcmd{defcmd}\cmd{(cs, val)} like \cmd{\gdef}\\ +\llcmd{defcmd}\cmd{(cs, val)} like \cmd{\gdef}, but note that no special chars allowed in \cmd{cs}(eg. \cmd{@})\\ +\llcmd{defmacro}\cmd{(cs, val)} like \cmd{\gdef}, allows special characters, but any tokens in val must be pre-defined (this uses \cmd{token.set_macro} internally)\\ \llcmd{newcmd}\cmd{(cs, val)} like \cmd{\newcommand}\\ \llcmd{renewcmd}\cmd{(cs, val)} like \cmd{\renewcommand}\\ \llcmd{prvcmd}\cmd{(cs, val)} like \cmd{\providecommand}\\ @@ -139,9 +137,11 @@ is true, it will overwrite an existing command (using \cmd{defcmd}), otherwise, \subsubsection*{global extras} -If \cmd{extrasglobals} is used and NOT \cmd{extras}, many additional globals are set for shortcuts\\ -All \cmd{pl.tex} modules are made global.\\ -\cmd{pl.hasval}, \cmd{pl.COMP}, \cmd{pl.utils.kpairs}, \cmd{pl.utils.npairs} become globals with the function name.\\ +If the package option \cmd{globals} is used, many additional globals are set for easier scripting. +All \cmd{pl.tex} functions, and variables, \cmd{pl.hasval}, \cmd{pl.COMP}, \cmd{pl.utils.kpairs}, \cmd{pl.utils.npairs} become globals. +\cmd{pl.tablex} is aliased as \cmd{TX} (which also includes all native Lua table functions), and +\cmd{pl.array2d} is aliased as \cmd{A2d}. +\\ @@ -150,7 +150,14 @@ All \cmd{pl.tex} modules are made global.\\ based on the letters that \cmd{spec} is set to (or \cmd{def} if nothing is provided) This is useful if you want to write a command with flexibility on argument expansion. The user can specify \cmd{n}, \cmd{o}, \cmd{t}, and \cmd{f} (case insensitve) if they want -no, once, twice, or full expansion. +no, once, twice, or full expansion. For example, we can control the expansion of args 2 and 3 with arg 1: + +\begin{verbatim} + \NewDocumentCommand{\splitToComma}{ O{nn} m m }{% + \MakeluastringCommands[nn]{#1}% + \luadirect{penlight.tex.split2comma(\plluastringA{#2},\plluastringB{#3})}% +} +\end{verbatim} % BELOW IS FOR TROUBLESHOOTING ABOVE %\def\NOTexp{\ONEexp} @@ -171,14 +178,57 @@ no, once, twice, or full expansion. %\luastringExpTest{ n o t f }{\NOTexp} +\subsection*{Lua boolean expressions for LaTeX conditionals} + +\cmd{\ifluax{}{}[]} and\\ \cmd{\ifluax{}{}[]} for truthy (uses \cmd{penlight.hasval}) + +\begin{LTXexample} +\ifluax{3^3 == 27}{3*3*3 is 27}[WRONG]\\ +\ifluax{abc123 == nil}{Var is nil}[WRONG]\\ +\ifluax{not true}{tRuE}[fAlSe]\\ +\ifluax{''}{TRUE}[FALSE]\\ +\ifluaxv{''}{true}[false]\\ +\end{LTXexample} + +\subsection*{Creating and using Lua tables in LaTeX} +\cmd{penlightplus} provides a Lua-table interface. Tables are stored in the +\cmd{penlight.tbls} table. + + +\cmd{\newtbl{t}} declares a new table with name \cmd{t}\\ +\cmd{\chgtbl{t}} changes the 'recent' table\\ +\cmd{\tblfrkv{t}{key-val string}[luakeys opts]} new table from key-vals, used \cmd{luakeys} \\ +\cmd{\settbl{i}{v}} sets a value of the table/index \cmd{i} to \cmd{v}\\ +\cmd{\gettbl{i}} gets the value and \cmd{tex.sprint()}'s it\\ +\cmd{\deftbl{i}{d}} pushes the value to a \cmd{cs} named \cmd{d}\\ +\cmd{\gdeftbl{i}{d}} pushes the value to a global\\ +\cmd{\iftbl{i}{t}[f]} runs code \cmd{t} if the item is true else \cmd{f}\\ +\cmd{\iftblv{i}{t}[f]} runs code \cmd{t} if the item is truthy else \cmd{f}\\ + +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, +\cmd{t/int} where \cmd{int} is a numeric indexer (ie uses \cmd{t[int]}), +or simply \cmd{ind} without the table name, where the assumed table is the last one that was created or changed to, (pure-numbers are not treated as strings in this case). + +\begin{LTXexample} +\tblfrkv{my}{a,b,c,first=john,last=smith}[defaults={x=0,1=one,n=false,y=yes}, naked_as_value=true] + +\settbl{my/4}{d}\gettbl{my/4}\\ +\settbl{5}{e}\gettbl{5}\\ +\gettbl{my.x}\\ +\iftbl{n}{t}[f]\\ +\iftblv{n}{t}[f]\\ +\iftbl{my.y}{t}[f]\\ +\iftblv{y}{t}[f]\\ +\end{LTXexample} -\subsection*{Split stuff} + +\subsection*{Splitting strings} Splitting text (or a cmd) into oxford comma format via: \cmd{\splitToComma[expansion level]{text}{text to split on}}: \begin{LTXexample} - -\splitToComma{ j doe }{\and}-\\ -\splitToComma{ j doe \and s else }{\and}-\\ -\splitToComma{ j doe \and s else \and a per }{\and}-\\ @@ -188,13 +238,14 @@ Splitting text (or a cmd) into oxford comma format via: \splitToComma[o]{\authors}{\and} \end{LTXexample} -The expansion level is up to two characters, \cmd{n|o|t|f}, to control teh expasion of each argument. +The expansion level is up to two characters, \cmd{n|o|t|f}, to control the expansion of each argument. +You can do a similar string split but to \cmd{\item} instead of commas with \cmd{\splitToItems} \begin{LTXexample} -spliToItems: \begin{itemize} \splitToItems{kale\and john}{\and} \splitToItems{kale -john -someone else}{-} + \splitToItems{1,2,3,4}{,} \end{itemize} \end{LTXexample} -- cgit v1.2.3