summaryrefslogtreecommitdiff
path: root/macros/luatex/generic
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2023-07-24 03:04:00 +0000
committerNorbert Preining <norbert@preining.info>2023-07-24 03:04:00 +0000
commit19444d4440a66200b03e05b567996375d0404a46 (patch)
tree450f6790376fe84313c8b2840fe51307bcac2f9e /macros/luatex/generic
parent8e64fc98a1773bc22a0f010f106d56a028e48597 (diff)
CTAN sync 202307240303
Diffstat (limited to 'macros/luatex/generic')
-rw-r--r--macros/luatex/generic/lutabulartools/README.md2
-rw-r--r--macros/luatex/generic/lutabulartools/lutabulartools.lua21
-rw-r--r--macros/luatex/generic/lutabulartools/lutabulartools.pdfbin112601 -> 112269 bytes
-rw-r--r--macros/luatex/generic/lutabulartools/lutabulartools.sty8
-rw-r--r--macros/luatex/generic/lutabulartools/lutabulartools.tex18
-rw-r--r--macros/luatex/generic/penlight/README.md4
-rw-r--r--macros/luatex/generic/penlight/penlight.pdfbin60005 -> 26787 bytes
-rw-r--r--macros/luatex/generic/penlight/penlight.sty127
-rw-r--r--macros/luatex/generic/penlight/penlight.tex225
-rw-r--r--macros/luatex/generic/penlightplus/README.md28
-rw-r--r--macros/luatex/generic/penlightplus/penlightplus.lua (renamed from macros/luatex/generic/penlight/penlightextras.lua)381
-rw-r--r--macros/luatex/generic/penlightplus/penlightplus.pdfbin0 -> 55459 bytes
-rw-r--r--macros/luatex/generic/penlightplus/penlightplus.sty119
-rw-r--r--macros/luatex/generic/penlightplus/penlightplus.tex227
14 files changed, 637 insertions, 523 deletions
diff --git a/macros/luatex/generic/lutabulartools/README.md b/macros/luatex/generic/lutabulartools/README.md
index 51055a89e5..ee3381533b 100644
--- a/macros/luatex/generic/lutabulartools/README.md
+++ b/macros/luatex/generic/lutabulartools/README.md
@@ -7,7 +7,7 @@ macro-enabled spreadsheet named "LaTeX-Tabular-Generator.xlsm" to help make tabl
# License (MIT)
-Copyright (C) 2021-2022 Kale Ewasiuk
+Copyright (C) 2021-2023 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
diff --git a/macros/luatex/generic/lutabulartools/lutabulartools.lua b/macros/luatex/generic/lutabulartools/lutabulartools.lua
index 3ea2151834..92ce236715 100644
--- a/macros/luatex/generic/lutabulartools/lutabulartools.lua
+++ b/macros/luatex/generic/lutabulartools/lutabulartools.lua
@@ -1,6 +1,6 @@
--% Kale Ewasiuk (kalekje@gmail.com)
---% 2023-07-18
---% Copyright (C) 2021-2022 Kale Ewasiuk
+--% 2023-07-22
+--% Copyright (C) 2021-2023 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
@@ -23,15 +23,16 @@
--% OR OTHER DEALINGS IN THE SOFTWARE.
-local pl = _G['penlight'] or _G['pl'] -- penlight for this namespace is pl
-if (__PL_EXTRAS__ == nil) or (__PENLIGHT__ == nil) then
- tex.sprint('\\PackageError{lutabulartools}{penlight package with extras (or extrasglobals) option must be loaded before this package}{}')
- tex.print('\\stop')
-end
-local T = pl.tablex
+
local lutabt = {}
+local pl = penlight
+local T = pl.tablex
+
+lutabt.luakeys = require'luakeys'() -- note: YAMLvars.sty will have checked existence of this already
+
+
lutabt.tablelevel = 0
lutabt.debug = false
@@ -98,7 +99,7 @@ end
function lutabt.set_tabular(sett)
- sett = luakeys.parse(sett)
+ sett = lutabt.luakeys.parse(sett)
local trim = ''
for k, v in pairs(sett) do
if k == 'tbrule' then
@@ -435,7 +436,7 @@ function lutabt.mrX.off()
end
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.mrX.settings = T.update(lutabt.mrX.settings, T.union(lutabt.mrX.resets, lutabt.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)
diff --git a/macros/luatex/generic/lutabulartools/lutabulartools.pdf b/macros/luatex/generic/lutabulartools/lutabulartools.pdf
index 6443b2873a..eab8203760 100644
--- a/macros/luatex/generic/lutabulartools/lutabulartools.pdf
+++ b/macros/luatex/generic/lutabulartools/lutabulartools.pdf
Binary files differ
diff --git a/macros/luatex/generic/lutabulartools/lutabulartools.sty b/macros/luatex/generic/lutabulartools/lutabulartools.sty
index c1e74802c0..ee36589cd5 100644
--- a/macros/luatex/generic/lutabulartools/lutabulartools.sty
+++ b/macros/luatex/generic/lutabulartools/lutabulartools.sty
@@ -1,6 +1,6 @@
% Kale Ewasiuk (kalekje@gmail.com)
-% 2023-07-18
-% Copyright (C) 2021-2022 Kale Ewasiuk
+% 2023-07-22
+% Copyright (C) 2021-2023 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
@@ -23,7 +23,7 @@
% OR OTHER DEALINGS IN THE SOFTWARE.
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{lutabulartools}[2023-07-18]
+\ProvidesPackage{lutabulartools}[2023-07-22]
\RequirePackage{booktabs}
\RequirePackage{multirow}
@@ -34,7 +34,7 @@
\RequirePackage{xcolor}
\RequirePackage{colortbl}
\RequirePackage{luacode}
-\RequirePackage{penlight} % NEEDED, extras option must be used so penlight should be loaded before this...
+\RequirePackage{penlightplus} % NEEDED, extras option must be used so penlight should be loaded before this...
\luadirect{lutabt = require('lutabulartools')}
diff --git a/macros/luatex/generic/lutabulartools/lutabulartools.tex b/macros/luatex/generic/lutabulartools/lutabulartools.tex
index 9be8dbd330..b9a4c96254 100644
--- a/macros/luatex/generic/lutabulartools/lutabulartools.tex
+++ b/macros/luatex/generic/lutabulartools/lutabulartools.tex
@@ -1,6 +1,6 @@
% Kale Ewasiuk (kalekje@gmail.com)
-% 2023-07-18
-% Copyright (C) 2021-2022 Kale Ewasiuk
+% 2023-07-22
+% Copyright (C) 2021-2023 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
@@ -67,7 +67,7 @@
\usepackage{ltxtable}
\usepackage{longtable}
-\usepackage[pl,extras]{penlight}
+\usepackage{penlightplus}
\RequirePackage{lutabulartools}
@@ -100,7 +100,7 @@ so if you have specific settings for these packages, load the \cmd{lutabulartool
{xcolor},
{colortbl},
{luacode},
-{penlight}}.
+{penlightplus}}.
\section{\texttt{\textbackslash settabular}}
@@ -455,6 +455,14 @@ Here's an example with long table. Notice the gray rules reliably appear 3 rows
%\LTXtable{\linewidth}{ltxexample}
-
+\begin{tabular}{c}
+ \\
+ \\
+ \\
+ \\
+ \\
+ \\
+ \\
+\end{tabular}
\end{document}
diff --git a/macros/luatex/generic/penlight/README.md b/macros/luatex/generic/penlight/README.md
index ca66c41b74..a80a51c22e 100644
--- a/macros/luatex/generic/penlight/README.md
+++ b/macros/luatex/generic/penlight/README.md
@@ -1,11 +1,11 @@
# penlight -- Lua libraries for use in LuaLaTeX
-This LuaLaTeX package provides a wrapper to use the [penlight](https://github.com/lunarmodules/Penlight) Lua libraries with LuaLaTeX, with some extra functionality added.
+This LuaLaTeX package provides a wrapper to use the [penlight](https://github.com/lunarmodules/Penlight) Lua libraries with LuaLaTeX.
# License
-Copyright (C) 2021-2022 Kale Ewasiuk
+Copyright (C) 2021-2023 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
diff --git a/macros/luatex/generic/penlight/penlight.pdf b/macros/luatex/generic/penlight/penlight.pdf
index a063e8922a..3932e74389 100644
--- a/macros/luatex/generic/penlight/penlight.pdf
+++ b/macros/luatex/generic/penlight/penlight.pdf
Binary files differ
diff --git a/macros/luatex/generic/penlight/penlight.sty b/macros/luatex/generic/penlight/penlight.sty
index 4f5900e3b8..7a7c94b6a7 100644
--- a/macros/luatex/generic/penlight/penlight.sty
+++ b/macros/luatex/generic/penlight/penlight.sty
@@ -1,6 +1,6 @@
% Kale Ewasiuk (kalekje@gmail.com)
-% 2023-07-18
-% Copyright (C) 2021-2022 Kale Ewasiuk
+% 2023-07-22
+% Copyright (C) 2021-2023 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,124 +22,15 @@
% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
% OR OTHER DEALINGS IN THE SOFTWARE.
-\ProvidesPackage{penlight}[2023-07-18]
+\ProvidesPackage{penlight}[2023-07-22]
-\RequirePackage{luacode}
+\directlua{penlight = require'penlight'}
-\IfFileExists{luakeys.lua}{}{\PackageError{penlight}{This package requires that luakeys be installed}{}}
+\DeclareOption{pl}{\directlua{pl = penlight}}
-
-\DeclareOption{pl}{\luadirect{
- pl = require'penlight'
- __PENLIGHT__ = 'pl'
-}}
-\DeclareOption{penlight}{\luadirect{
- penlight = require'penlight'
- __PENLIGHT__ = 'penlight'
-}}
-
-
-\DeclareOption{stringx}{\luadirect{_G[__PENLIGHT__].stringx.import()}}
-\DeclareOption{format}{\luadirect{_G[__PENLIGHT__].stringx.format_operator()}}
-\DeclareOption{func}{\luadirect{_G[__PENLIGHT__].utils.import(__PENLIGHT__..'.func')}}
-\DeclareOption{extras}{\luadirect{require'penlightextras'}
- \gdef\penlight@loadextras{}
-}
-\DeclareOption{extrasglobals}{\luadirect{
- __PL_GLOBALS__ = true
- require'penlightextras'
- }
- \gdef\penlight@loadextras{}
-}
+\DeclareOption{stringx}{\directlua{penlight.stringx.import()}}
+\DeclareOption{format}{\directlua{penlight.stringx.format_operator()}}
+\DeclareOption{func}{\directlua{penlight.utils.import(penlight.func)}}
+\DeclareOption{import}{\ExecuteOptions{stringx,format,func}}
\ProcessOptions*\relax
-
-\luadirect{
-if __PENLIGHT__ == nil then
- tex.sprint('\\PackageError{penlight}{"penlight" or "pl" option must be passed to penlight as the first option}{}')
-end
-}
-
-\ifdefined\penlight@loadextras
-
-\global\newcommand{\writePDFmetadata}{\luadirect{_G[__PENLIGHT__].tex.writePDFmetadata()}}
-
-\NewDocumentCommand{\writePDFmetadatakv}{ s m }{
-\IfBooleanTF{#1}{% if *, overwrite everything
- \luadirect{
- __PDFmetadata__ = luakeys.parse(\luastring{#2})
- _G[__PENLIGHT__].tex.writePDFmetadata()
- }}{
- \luadirect{
- __PDFmetadata__ = __PDFmetadata__ or {}
- _G[__PENLIGHT__].tablex.update(__PDFmetadata__, luakeys.parse(\luastring{#2}))
- _G[__PENLIGHT__].tex.writePDFmetadata()
- }}
-}
-
-
-\gdef\luastringT#1{\luastring{\unexpanded\expandafter\expandafter\expandafter{#1}}} % expand luastring twice
-\global\let\luastringF\luastring % fully expanded luastring
-
-% allow control over expansion of arguments to a latex function
-\NewDocumentCommand{\MakeluastringCommands}{O{} m }{% #1 the desired commands #2 defaults
- \luadirect{_G[__PENLIGHT__].tex.aliasluastring(\luastring{#2},\luastring{#1})}%
-}
-
-\NewDocumentCommand{\splitToComma}{ O{nn} m m }{%
- \MakeluastringCommands[nn]{#1}%
- \luadirect{_G[__PENLIGHT__].tex.split2comma(\plluastringA{#2},\plluastringB{#3})}%
-}
-
-\NewDocumentCommand{\splitToItems}{ O{NN} m m }{%
- \MakeluastringCommands[nn]{#1}%
- \luadirect{_G[__PENLIGHT__].tex.split2items(\plluastringA{#2},\plluastringB{#3})}%
-}
-
-
-%
-%
-%\NewDocumentCommand{\tblnew}{m}{\luadirect{
-% _G[\luastring{#1}] = {}
-%}}
-%
-%\NewDocumentCommand{\tblfrkv}{m m O{} }{\luadirect{
-% _G[\luastring{#1}] = luakeys.parse(\luastring{#2}, 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]))
-%}}
-%
-%
-%\NewDocumentCommand{\tblupd}{ m m}{\luadirect{
-% _G[__PENLIGHT__].tablex.update(_G[\luastring{#1}], _G[\luastring{#2}])
-%}}
-%
-%\NewDocumentCommand{\tblupdkv}{ m m }{\luadirect{
-% _G[__PENLIGHT__].tablex.update(_G[\luastring{#1}], 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}] = _G[__PENLIGHT__].tablex.update(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,
-% % {tbl}{update}[arg1][arg2]
-% _G[__PENLIGHT__].tablex[\luastring[#1]](_G[\luastring{}], _G[\luastring{}])
-%}}
-
-
-\else\fi \ No newline at end of file
diff --git a/macros/luatex/generic/penlight/penlight.tex b/macros/luatex/generic/penlight/penlight.tex
index edba4933e8..93d7bdbfc3 100644
--- a/macros/luatex/generic/penlight/penlight.tex
+++ b/macros/luatex/generic/penlight/penlight.tex
@@ -1,6 +1,6 @@
% Kale Ewasiuk (kalekje@gmail.com)
-% 2023-07-18
-% Copyright (C) 2021-2022 Kale Ewasiuk
+% 2023-07-22
+% Copyright (C) 2021-2023 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
@@ -53,207 +53,56 @@
\date{\today}
-\RequirePackage[pl,extras]{penlight}
+\RequirePackage{luacode}
+\RequirePackage[pl,import]{penlight}
\title{penlight}
\subtitle{Lua libraries for use in LuaLaTeX}
\begin{document}
-%{\Huge todo add split to text example with ltxexample\\reference the exact version of penlight used in this library. consider no globals by default\\ COVERT existing examples to extras globals, document hyperref}
\maketitle
- Documentation for the Lua library this includes can be found here:\\
- \mbox{\url{https://lunarmodules.github.io/Penlight}}
- \\ This package uses version \cmd{1.13.1}
+ Documentation for Penlight can be found here:\\
+\mbox{\url{https://lunarmodules.github.io/Penlight}}
+\\\\ This package uses version \cmd{1.13.1}
- \subsection*{Required Package Option}
- The first option sent to this package MUST be one of: \\
- \texttt{[penlight]} \ \ \ or \ \ \ \texttt{[pl]}.\\
- All Penlight sub-modules are then available under this global variable by either\\
- \texttt{penlight.XYZ} or \texttt{pl.XYZ}
+\subsection*{Importing Penlight from within LaTeX}
+Loading this package runs the Lua code: \texttt{penlight = require'penlight'}
+Other options for the package are:
+\vspace{1em}
-
- \subsection*{texlua usage}
-If you want to use Penlight (and extras) with the \texttt{texlua} intrepreter (no document made, only for Lua files, useful for testing),
-you can access it by setting \cmd{__SKIP_TEX__ = true} and adding the package to path. For example:
- \begin{verbatim}
-package.path = package.path .. ';'..'path/to/texmf/tex/latex/penlight/?.lua'
-penlight = require'penlight'
--- below is optional
-__SKIP_TEX__ = true --only required if you want to use
- --penlightextras without a LaTeX run
-__PL_GLOBALS__ = true -- optional, include global definitions
-__SKIP_LUAKEYS__ = true -- luakeys is laoded in penlightextras be default, you may skip it with this
-require'penlightextras'
-\end{verbatim}
+\hspace*{-6ex}\begin{tabular}{lp{4.8in}}
+\texttt{pl} & adds the alias \texttt{pl = penlight}\\\\
+\texttt{stringx} & will import additional string functions into the string meta table via\\
+ & \texttt{require('penlight.stringx').import()}\\\\
+\texttt{format} & allows the \% operator for Python-style string formatting via\\
+ & \texttt{require('penlight.stringx').format\_operator()}\\\\
+\texttt{func} & allows placeholder expressions eg. \texttt{\_1+1} to be used via\\
+ & \texttt{penlight.utils.import(penlight.func)}\\\\
+\texttt{import} & does the above three\\
+\end{tabular}
-\pagebreak
+An example usage is: \cmd{\usepackage[pl,import]{penlight}}
-\subsection*{Additional Package Options}
+%https://lunarmodules.github.io/Penlight/libraries/pl.func.html
+%https://lunarmodules.github.io/Penlight/libraries/pl.stringx.html
- \noindent
- \hspace*{-6ex}\begin{tabular}{lp{4.8in}}
- \texttt{stringx} & will import additional string functions into the string meta table.\\
- & this will be ran in pre-amble: \texttt{require('pl.stringx').import()}\\
- \texttt{format} & allows \% operator for Python-style string formating\\
- & this will be ran in pre-amble: \texttt{require('pl.stringx').format\_operator()}\\
- & \mbox{\url{https://lunarmodules.github.io/Penlight/libraries/pl.stringx.html#format_operator}}
- \\
- \texttt{func} & allows placehold expressions eg. \texttt{\_1+1} to be used \\
- & this will be ran in pre-amble: \texttt{penlight.utils.import('pl.func')}\\
- & \url{https://lunarmodules.github.io/Penlight/libraries/pl.func}\\
- \texttt{extras} & does the above three (\cmd{func,stringx,format}); adds some additional functions to \cmd{penlight} module; and adds the \cmd{pl.tex} sub-module.\\
- \texttt{extrasglobals} & does the above \texttt{extras} but makes many of the functions global variables as well.
- \end{tabular}
+\subsection*{Importing Penlight from within Lua}
+Instead of using penlight.sty, you can simply:\\
+\texttt{penlight = require'penlight'} ~~~ from within Lua.
+\newpage
+\section*{}
+This package used to contain \cmd{penlightextras.lua}.
+That functionality now belongs to a standalone package named \cmd{penlightplus}.
+\section*{}
+Disclaimer: I am not the author of the Lua Penlight library.
+Penlight is Copyright \textcopyright 2009-2016 Steve Donovan, David Manura.
+The distribution of Penlight used for this library is:
+\url{https://github.com/lunarmodules/penlight}\\\\
+The author of this library has merged all penlight sub-modules into a single file for this distribution.
-
-\subsection*{Extras}
-Note: this option is considered experimental.
-The following global variables are defined:
-
-\llcmd{__SKIP_TEX__} If using the \cmd{penlight} 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{__SKIP_LUAKEYS__}\\
-\cmd{__PL_NO_HYPERREF__}\\
-\cmd{__PL_EXTRAS__} false, 1 or 2\\
-
-\subsubsection*{penlight additions}
-
-Some functionality is added to penlight/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}\\
-\llcmd{math.mod(n,d)}, \cmd{math.mod2(n)} math modulous\\
-\llcmd{string.}\cmd{totable(s)} string a table of characters\\
-\llcmd{string.}\cmd{delspace(s)} clear spaces from string\\
-\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.\\
-
-\llcmd{pl.utils.}\cmd{filterfiles}\cmd{(dir,filt,rec)} Get files from dir and apply glob-like filters. Set rec to \cmd{true} to include sub directories\\
-
-
-\subsubsection*{A \cmd{pl.tex.} module is added}
-\llcmd{add_bkt}\cmd{_cnt(n), }\cmd{close_bkt_cnt(n), reset_bkt_cnt} functions to keep track of adding curly brackets as strings. \cmd{add} will return \cmd{n} (default 1) \{'s and increment a counter. \cmd{close} will return \cmd{n} \}'s (default will close all brackets) and decrement.\\
-\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{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{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{newcmd}\cmd{(cs, val)} like \cmd{\newcommand}\\
-\llcmd{renewcmd}\cmd{(cs, val)} like \cmd{\renewcommand}\\
-\llcmd{prvcmd}\cmd{(cs, val)} like \cmd{\providecommand}\\
-\llcmd{deccmd}\cmd{(cs, dft, overwrite)} declare a command. If \cmd{dft} (default) is \cmd{nil}, \cmd{cs} is set
-to a package warning saying \cmd{'cs' was declared and used in document, but never set}. If \cmd{overwrite}
-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*{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.\\
-
-
-
-\subsection*{Macro helpers}
-\cmd{\MakeluastringCommands[def]{spec}} will let \cmd{\plluastring(A|B|C..)} be \cmd{\luastring(N|O|T|F)}
-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.
-
-% BELOW IS FOR TROUBLESHOOTING ABOVE
-%\def\NOTexp{\ONEexp}
-%\def\ONEexp{\TWOexp}
-%\def\TWOexp{\TREexp}
-%\def\TREexp{Fully expanded}
-%
-%\NewDocumentCommand{\luastringExpTest}{m m}{
-% \MakeluastringCommands{#1}
-% \luadirect{texio.write_nl('VVVVVVVVVVVVVVVVVVVVVVVVVVVVV')}
-% \luadirect{texio.write_nl(\plluastringA{#2}..' | Not')}
-% \luadirect{texio.write_nl(\plluastringB{#2}..' | Once')}
-% \luadirect{texio.write_nl(\plluastringC{#2}..' | Twice')}
-% \luadirect{texio.write_nl(\plluastringD{#2}..' | Full')}
-% \luadirect{texio.write_nl('VVVVVVVVVVVVVVVVVVVVVVVVVVVVV')}
-%}
-%
-%\luastringExpTest{ n o t f }{\NOTexp}
-
-
-
-
-\subsection*{Split stuff}
-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}-\\
--\splitToComma{ j doe \and s else \and a per \and f guy}{\and}-
-
-\def\authors{j doe \and s else \and a per \and f guy}
-\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.
-
-\begin{LTXexample}
-spliToItems:
-\begin{itemize}
- \splitToItems{kale\and john}{\and}
- \splitToItems{kale -john -someone else}{-}
-\end{itemize}
-\end{LTXexample}
-
-
-
-
-
- \section*{}
- Disclaimer: I am not the author of the Lua Penlight library.
- Penlight is Copyright \textcopyright 2009-2016 Steve Donovan, David Manura.
- The distribution of Penlight used for this library is:
-\url{https://github.com/lunarmodules/penlight}\\
- The author of this library has merged all Lua sub-modules into one file for this package.
-
-% \tblfrkv{tbl_def}{kale=cool,paul=gay,craig=fun}
-% \tblfrkv{tbl}{kale,paul=gay} %[naked_as_value=true]
-%
-% \tblget{tbl}{kale}%
-% \tblget{tbl}{paul}%
-% \tblget{tbl}{craig}%
-%
-% \tblupd{tbl_def}{tbl}%
-%
-% \tblfrkvII{tbl}{kale=cool,paul=gay,craig=fun}{kale=weak,paul=sad}
-% \tblget{tbl}{craig}%
-% \tblget{tbl}{paul}%
-% \tblget{tbl}{kale}%
-%
-% \NewDocumentCommand{\THINg}{ O{} m}{%
-% \tblfrkvII{setti}{color=red,size=small}{#1} % make settings and update based on [arg=]
-% {\color{\tblget{setti}{color}}\tblget{setti}{size} #2}
-% }
-%
-% \THINg[color=blue,size=tiny]{Kale}
-
\end{document} \ No newline at end of file
diff --git a/macros/luatex/generic/penlightplus/README.md b/macros/luatex/generic/penlightplus/README.md
new file mode 100644
index 0000000000..cc80374347
--- /dev/null
+++ b/macros/luatex/generic/penlightplus/README.md
@@ -0,0 +1,28 @@
+# penlightplus
+
+Additions to the Penlight Lua Libraries.
+
+
+# License
+
+Copyright (C) 2021-2023 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
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
+OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/macros/luatex/generic/penlight/penlightextras.lua b/macros/luatex/generic/penlightplus/penlightplus.lua
index 5f5f76aefb..ffdbe89bc5 100644
--- a/macros/luatex/generic/penlight/penlightextras.lua
+++ b/macros/luatex/generic/penlightplus/penlightplus.lua
@@ -1,6 +1,6 @@
--% Kale Ewasiuk (kalekje@gmail.com)
---% 2023-07-18
---% Copyright (C) 2021-2022 Kale Ewasiuk
+--% 2023-07-22
+--% Copyright (C) 2021-2023 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,37 +22,29 @@
--% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
--% OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+
+__PL_PLUS__ = true
__PL_SKIP_TEX__ = __PL_SKIP_TEX__ or false --if declared true before here, it will use regular print functions
-- (for troubleshooting with texlua instead of actual use in lua latex)
-__PL_SKIP_LUAKEYS__ = __PL_SKIP_LUAKEYS__ or false
__PL_GLOBALS__ = __PL_GLOBALS__ or false
-__PL_EXTRAS__ = 1
__PL_NO_HYPERREF__ = __PL_NO_HYPERREF__ or false
--- __PENLIGHT__ = 'penlight' or 'pl'
--- requires penlight
-local pl = _G['penlight'] or _G['pl'] -- penlight for this namespace is pl
-
-if not __PL_SKIP_LUAKEYS__ then
- luakeys = require'luakeys'()
-end
+penlight.luakeys = require'luakeys'()
--- some bonus string operations, % text operator, and functional programming
-pl.stringx.import()
-pl.stringx.format_operator()
-pl.utils.import'pl.func' -- allow placeholder expressions _1 +1 etc.
-pl.COMP = require'pl.comprehension'.new() -- for comprehensions
+penlight.COMP = require'pl.comprehension'.new() -- for comprehensions
-- http://lua-users.org/wiki/SplitJoin -- todo read me!!
-pl.tex = {} -- adding a sub-module for tex related stuff
+penlight.tex = {} -- adding a sub-module for tex related stuff
-local bind = bind or pl.func.bind
+local bind = bind or penlight.func.bind
-function pl.hasval(x) -- if something has value
+function penlight.hasval(x) -- if something has value
if (type(x) == 'function') or (type(x) == 'CFunction') or (type(x) == 'userdata') then
return true
elseif (x == nil) or (x == false) or (x == 0) or (x == '') or (x == {}) then
@@ -71,9 +63,9 @@ end
-- Some simple and helpful LaTeX functions -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- xparse defaults
-pl.tex._xTrue = '\\BooleanTrue '
-pl.tex._xFalse = '\\BooleanFalse '
-pl.tex._xNoValue = '-NoValue-'
+penlight.tex._xTrue = '\\BooleanTrue '
+penlight.tex._xFalse = '\\BooleanFalse '
+penlight.tex._xNoValue = '-NoValue-'
--Generic LuaLaTeX utilities for print commands or environments
@@ -81,97 +73,97 @@ if not __PL_SKIP_TEX__ then
local function check_special_chars(s) -- todo extend to toher special chars?
if type(s) == 'string' then
if string.find(s, '[\n\r\t\0]') then
- pl.tex.pkgwarn('penlight', 'printing string with special (eg. newline) char, possible unexpected behaviour on string: '..s)
+ penlight.tex.pkgwarn('penlight', 'printing string with special (eg. newline) char, possible unexpected behaviour on string: '..s)
end
end
end
-- NOTE: usage is a bit different than default. If number is first arg, you CANT change catcode.
-- We don't need that under normal use, use tex.print or tex.sprint if you need
- function pl.tex.prt(s, ...) -- print something, no new line after
+ function penlight.tex.prt(s, ...) -- print something, no new line after
check_special_chars(s)
if type(s) == 'number' then s = tostring(s) end
tex.sprint(s, ...) --can print lists as well, but will NOT put new line between them or anything printed
end
- function pl.tex.prtn(s, ...) -- print with new line after, can print lists or nums. C-function not in Lua, apparantly
+ function penlight.tex.prtn(s, ...) -- print with new line after, can print lists or nums. C-function not in Lua, apparantly
s = s or ''
check_special_chars(s)
if type(s) == 'number' then s = tostring(s) end
tex.print(s, ...)
end
- pl.tex.wrt = texio.write
- pl.tex.wrtn = texio.write_nl
+ penlight.tex.wrt = texio.write
+ penlight.tex.wrtn = texio.write_nl
else
- pl.tex.prt = io.write
- pl.tex.prtn = print --print with new line
- pl.tex.wrt = io.write
- pl.tex.wrtn = io.write_nl
+ penlight.tex.prt = io.write
+ penlight.tex.prtn = print --print with new line
+ penlight.tex.wrt = io.write
+ penlight.tex.wrtn = io.write_nl
end
-function pl.tex.prtl(str) -- prints a literal/lines string in latex, adds new line between them
+function penlight.tex.prtl(str) -- prints a literal/lines string in latex, adds new line between them
for line in str:gmatch"[^\n]*" do -- gets all characters up to a new line
- pl.tex.prtn(line)
+ penlight.tex.prtn(line)
end
end
-- todo option to specify between character? one for first table, on for recursives?
-function pl.tex.prtt(tab, d1, d2) -- prints a table with new line between each item
+function penlight.tex.prtt(tab, d1, d2) -- prints a table with new line between each item
d1 = d1 or ''
d2 = d2 or '\\leavevmode\\\\'
for _, t in pairs(tab) do --
if type(t) ~= 'table' then
if d1 == '' then
- pl.tex.prtn(t)
+ penlight.tex.prtn(t)
else
- pl.tex.prt(t, d1)
+ penlight.tex.prt(t, d1)
end
else
- pl.tex.prtn(d2)
- pl.tex.prtt(t,d1,d2)
+ penlight.tex.prtn(d2)
+ penlight.tex.prtt(t,d1,d2)
end
end
end
-function pl.tex.help_wrt(s1, s2) -- helpful printing, makes it easy to debug, s1 is object, s2 is note
+function penlight.tex.help_wrt(s1, s2) -- helpful printing, makes it easy to debug, s1 is object, s2 is note
local wrt2 = wrt or texio.write_nl or print
s2 = s2 or ''
wrt2('\nvvvvv '..s2..'\n')
if type(s1) == 'table' then
- wrt2(pl.pretty.write(s1))
+ wrt2(penlight.pretty.write(s1))
else
wrt2(tostring(s1))
end
wrt2('\n^^^^^\n')
end
-pl.help_wrt = pl.tex.help_wrt
+penlight.help_wrt = penlight.tex.help_wrt
-function pl.tex.prt_array2d(t)
+function penlight.tex.prt_array2d(t)
for _, r in ipairs(t) do
local s = ''
for _, v in ipairs(r) do
s = s.. tostring(v)..', '
end
- pl.tex.prt(s)
- pl.tex.prt('\n')
+ penlight.tex.prt(s)
+ penlight.tex.prt('\n')
end
end
-- -- -- -- --
-function pl.tex.pkgwarn(pkg, msg1, msg2)
+function penlight.tex.pkgwarn(pkg, msg1, msg2)
pkg = pkg or ''
msg1 = msg1 or ''
msg2 = msg2 or ''
tex.sprint('\\PackageWarning{'..pkg..'}{'..msg1..'}{'..msg2..'}')
end
-function pl.tex.pkgerror(pkg, msg1, msg2, stop)
+function penlight.tex.pkgerror(pkg, msg1, msg2, stop)
pkg = pkg or ''
msg1 = msg1 or ''
msg2 = msg2 or ''
- stop = pl.hasval(stop)
+ stop = penlight.hasval(stop)
tex.sprint('\\PackageError{'..pkg..'}{'..msg1..'}{'..msg2..'}')
if stop then tex.sprint('\\stop') end -- stop on the spot (say that 10 times)
end
@@ -179,18 +171,18 @@ end
--definition helpers -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-function pl.tex.defmacro(cs, val) -- , will not work if val contains undefined tokens (so pre-define them if using..)
+function penlight.tex.defmacro(cs, val) -- , 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')
end
-function pl.tex.defcmd(cs, val) -- fixes above issue, but only chars allowed in cs (and no @)
+function penlight.tex.defcmd(cs, val) -- fixes above issue, but only chars allowed in cs (and no @)
val = val or ''
tex.sprint('\\gdef\\'..cs..'{'..val..'}')
end
-function pl.tex.defcmdAT(cs, val) -- allows @ in cs,
+function penlight.tex.defcmdAT(cs, val) -- allows @ in cs,
--however should only be used in preamble. I avoid \makeatother because I've ran into issues with cls and sty files using it.
val = val or ''
tex.sprint('\\makeatletter\\gdef\\'..cs..'{'..val..'}')
@@ -198,34 +190,34 @@ end
-function pl.tex.prvcmd(cs, val) -- provide command via lua
+function penlight.tex.prvcmd(cs, val) -- provide command via lua
if token.is_defined(cs) then
-- do nothing if token is defined already --pkgwarn('penlight', 'Definition '..cs..' is being overwritten')
else
- pl.tex.defcmd(cs, val)
+ penlight.tex.defcmd(cs, val)
end
end
-function pl.tex.newcmd(cs, val) -- provide command via lua
+function penlight.tex.newcmd(cs, val) -- provide command via lua
if token.is_defined(cs) then
- pl.tex.pkgerror('penlight: newcmd',cs..' already defined')
+ penlight.tex.pkgerror('penlight: newcmd',cs..' already defined')
else
- pl.tex.defcmd(cs, val)
+ penlight.tex.defcmd(cs, val)
end
end
-function pl.tex.renewcmd(cs, val) -- provide command via lua
+function penlight.tex.renewcmd(cs, val) -- provide command via lua
if token.is_defined(cs) then
- pl.tex.defcmd(cs, val)
+ penlight.tex.defcmd(cs, val)
else
- pl.tex.pkgerror('penlight: renewcmd',cs..' not defined')
+ penlight.tex.pkgerror('penlight: renewcmd',cs..' not defined')
end
end
-function pl.tex.deccmd(cs, def, overwrite) -- declare a definition, placeholder throws an error if it used but not set!
- overwrite = pl.hasval(overwrite)
+function penlight.tex.deccmd(cs, def, overwrite) -- declare a definition, placeholder throws an error if it used but not set!
+ overwrite = penlight.hasval(overwrite)
local decfun
- if overwrite then decfun = pl.tex.defcmd else decfun = pl.tex.newcmd end
+ if overwrite then decfun = penlight.tex.defcmd else decfun = penlight.tex.newcmd end
if def == nil then
decfun(cs, pkgerror('penlight', cs..' was declared and used in document, but never set'))
else
@@ -257,26 +249,26 @@ end
-- when nesting commands, this makes it helpful to not worry about brackets
-pl.tex._NumBkts = 0
+penlight.tex._NumBkts = 0
--prt(opencmd('textbf')..opencmd('texttt')..'bold typwriter'..close_bkt_cnt())
-function pl.tex.opencmd(cmd)
+function penlight.tex.opencmd(cmd)
return '\\'..cmd..add_bkt_cnt()
end
-function pl.tex.reset_bkt_cnt(n)
+function penlight.tex.reset_bkt_cnt(n)
n = n or 0
_NumBkts = n
end
-function pl.tex.add_bkt_cnt(n)
+function penlight.tex.add_bkt_cnt(n)
-- add open bracket n times, returns brackets
n = n or 1
_NumBkts = _NumBkts + n
return ('{'):rep(n)
end
-function pl.tex.close_bkt_cnt(n)
+function penlight.tex.close_bkt_cnt(n)
n = n or _NumBkts
local s = ('}'):rep(n)
_NumBkts = _NumBkts - n
@@ -285,12 +277,12 @@ end
-function pl.tex.aliasluastring(s, d)
+function penlight.tex.aliasluastring(s, d)
s = s:delspace():upper():tolist()
d = d:delspace():upper():tolist()
- for i, S in pl.seq.enum(d:slice_assign(1,#s,s)) do
+ for i, S in penlight.seq.enum(d:slice_assign(1,#s,s)) do
if (S == 'E') or (S == 'F') then S = '' end -- E or F is fully expanded
- pl.tex.prtn('\\let\\plluastring'..pl.Char(i)..'\\luastring'..S)
+ penlight.tex.prtn('\\let\\plluastring'..penlight.Char(i)..'\\luastring'..S)
end
end
@@ -298,7 +290,7 @@ end
-function pl.tex.get_ref_info(l)
+function penlight.tex.get_ref_info(l)
local n = 5
if __PL_NO_HYPERREF__ then
local n = 2
@@ -306,19 +298,19 @@ function pl.tex.get_ref_info(l)
local r = token.get_macro('r@'..l)
local t = {}
if r == nil then
- t = pl.tablex.new(n, 0) -- make all 0s
+ t = penlight.tablex.new(n, 0) -- make all 0s
r = '-not found-'
else
t = {r:match(("(%b{})"):rep(n))}
- t = pl.tablex.map(string.trimfl, t)
+ t = penlight.tablex.map(string.trimfl, t)
end
t[#t+1] = r -- add the og return of label
- --pl.help_wrt(t, 'ref info')
+ --penlight.help_wrt(t, 'ref info')
return t
end
-- todo add regex pattern for cref info
---function pl.tex.get_ref_info_all_cref(l)
+--function penlight.tex.get_ref_info_all_cref(l)
-- local r = token.get_macro('r@'..l..'@cref')
-- if r == nil then
-- return r, 0, 0
@@ -364,11 +356,11 @@ local number = P{"number",
-function pl.char(num)
+function penlight.char(num)
return string.char(string.byte("a")+num-1)
end
-function pl.Char(num)
+function penlight.Char(num)
return string.char(string.byte("A")+num-1)
end
@@ -434,7 +426,7 @@ function str_mt.__index.totable(str)
end
function str_mt.__index.tolist(str)
- return pl.List(str)
+ return penlight.List(str)
end
@@ -454,7 +446,7 @@ end
-- -- -- -- function stuff
-function pl.clone_function(fn)
+function penlight.clone_function(fn)
local dumped = string.dump(fn)
local cloned = loadstring(dumped)
local i = 1
@@ -474,15 +466,15 @@ end
-- -- -- -- -- -- -- -- -- -- -- -- functions below extend the operator module
-function pl.operator.strgt(a,b) return tostring(a) > tostring(b) end
-function pl.operator.strlt(a,b) return tostring(a) < tostring(b) end
+function penlight.operator.strgt(a,b) return tostring(a) > tostring(b) end
+function penlight.operator.strlt(a,b) return tostring(a) < tostring(b) end
-- -- -- -- functions below are helpers for arrays and 2d
local function compare_elements(a, b, op, ele)
- op = op or pl.oper.gt
+ op = op or penlight.oper.gt
ele = ele or 1
return op(a[ele], b[ele])
end
@@ -499,32 +491,32 @@ end
-- table stuff below
-function pl.tablex.map_slice(func, T, j1, j2)
+function penlight.tablex.map_slice(func, T, j1, j2)
if type(j1) == 'string' then
- return pl.array2d.map_slice(func, {T}, ','..j1)[1]
+ return penlight.array2d.map_slice(func, {T}, ','..j1)[1]
else
- return pl.array2d.map_slice(func, {T}, 1, j1, 1, j2)[1]
+ return penlight.array2d.map_slice(func, {T}, 1, j1, 1, j2)[1]
end
end
-pl.array2d.map_slice1 = pl.tablex.map_slice
+penlight.array2d.map_slice1 = penlight.tablex.map_slice
-- todo option for multiple filters with AND logic, like the filter files??
-function pl.tablex.filterstr(t, exp, case)
+function penlight.tablex.filterstr(t, exp, case)
-- case = case sensitive
- case = pl.hasval(case)
+ case = penlight.hasval(case)
-- apply lua patterns to a table to filter iter
-- str or table of str's can be passed, OR logic is used if table is passed
if case then
- return pl.tablex.filter(t, bind(string.containsany,_1,exp))
+ return penlight.tablex.filter(t, bind(string.containsany,_1,exp))
else
- return pl.tablex.filter(t, bind(string.containsanycase,_1,exp))
+ return penlight.tablex.filter(t, bind(string.containsanycase,_1,exp))
end
end
-function pl.utils.filterfiles(...)
+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
@@ -547,11 +539,11 @@ function pl.utils.filterfiles(...)
end
local files
- if r then files = pl.dir.getallfiles(dir)
- else files = pl.dir.getfiles(dir)
+ if r then files = penlight.dir.getallfiles(dir)
+ else files = penlight.dir.getfiles(dir)
end
for i=nstart,args.n do
- files = pl.tablex.filter(files, pl.func.compose(bind(string.containsanycase,_1, args[i]), pl.path.basename))
+ files = penlight.tablex.filter(files, penlight.func.compose(bind(string.containsanycase,_1, args[i]), penlight.path.basename))
end
return files
end
@@ -562,54 +554,54 @@ end
-- -- -- -- -- -- -- -- functions below extend the array2d module
-function pl.array2d.map_slice(func, M, i1, j1, i2, j2) -- map a function to a slice of a Matrix
- func = pl.utils.function_arg(1, func)
- for i,j in pl.array2d.iter(M, true, i1, j1, i2, j2) do
+function penlight.array2d.map_slice(func, M, i1, j1, i2, j2) -- map a function to a slice of a Matrix
+ func = penlight.utils.function_arg(1, func)
+ for i,j in penlight.array2d.iter(M, true, i1, j1, i2, j2) do
M[i][j] = func(M[i][j])
end
return M
end
-pl.array2d.map_slice2 = pl.array2d.map_slice
+penlight.array2d.map_slice2 = penlight.array2d.map_slice
-function pl.array2d.map_cols(func, M, j1, j2) -- map function to columns of matrix
+function penlight.array2d.map_cols(func, M, j1, j2) -- map function to columns of matrix
if type(j1) == 'string' then
- return pl.array2d.map_slice(func, M, ','..j1)
+ return penlight.array2d.map_slice(func, M, ','..j1)
else
j2 = j2 or -1
- return pl.array2d.map_slice(func, M, 1, j1, -1, j2)
+ return penlight.array2d.map_slice(func, M, 1, j1, -1, j2)
end
end
-pl.array2d.map_columns = pl.array2d.map_cols
+penlight.array2d.map_columns = penlight.array2d.map_cols
-function pl.array2d.map_rows(func, M, i1, i2) -- map function to rows of matrix
+function penlight.array2d.map_rows(func, M, i1, i2) -- map function to rows of matrix
if type(i1) == 'string' then
- return pl.array2d.map_slice(func, M, i1)
+ return penlight.array2d.map_slice(func, M, i1)
else
i2 = i2 or -1
- return pl.array2d.map_slice(func, M, i1, 1, i2, -1)
+ return penlight.array2d.map_slice(func, M, i1, 1, i2, -1)
end
end
-- -- -- -- -- -- -- --
-function pl.array2d.sortOP(M, op, ele) -- sort a 2d array based on operator criteria, ele is column, ie sort on which element
+function penlight.array2d.sortOP(M, op, ele) -- sort a 2d array based on operator criteria, ele is column, ie sort on which element
M_new = {}
- for row in pl.seq.sort(M, comp_2ele_func(op, ele)) do
+ for row in penlight.seq.sort(M, comp_2ele_func(op, ele)) do
M_new[#M_new+1] = row
end
return M_new
end
-function pl.array2d.like(M1, v)
+function penlight.array2d.like(M1, v)
v = v or 0
- r, c = pl.array2d.size(M1)
- return pl.array2d.new(r,c,v)
+ r, c = penlight.array2d.size(M1)
+ return penlight.array2d.new(r,c,v)
end
-function pl.array2d.from_table(t) -- turns a labelled table to a 2d, label-free array
+function penlight.array2d.from_table(t) -- turns a labelled table to a 2d, label-free array
t_new = {}
for k, v in pairs(t) do
if type(v) == 'table' then
@@ -625,10 +617,10 @@ function pl.array2d.from_table(t) -- turns a labelled table to a 2d, label-free
return t_new
end
-function pl.array2d.toTeX(M, EL) --puts & between columns, can choose to end line with \\ if EL is true (end-line)
+function penlight.array2d.toTeX(M, EL) --puts & between columns, can choose to end line with \\ if EL is true (end-line)
EL = EL or false
if EL then EL = '\\\\' else EL = '' end
- return pl.array2d.reduce2(_1..EL.._2, _1..'&'.._2, M)..EL
+ return penlight.array2d.reduce2(_1..EL.._2, _1..'&'.._2, M)..EL
end
@@ -649,7 +641,7 @@ local function parse_numpy1d(i1, i2, iS)
return i1, i2
end
-function pl.array2d.parse_numpy2d_str(s)
+function penlight.array2d.parse_numpy2d_str(s)
s = s:gsub('%s+', '')
_, _, i1, iS, i2, j1, jS, j2 = string.find(s, "(%-?%d*)(:?)(%-?%d*),?(%-?%d*)(:?)(%-?%d*)")
i1, i2 = parse_numpy1d(i1, i2, iS)
@@ -658,12 +650,12 @@ function pl.array2d.parse_numpy2d_str(s)
end
-local _parse_range = pl.clone_function(pl.array2d.parse_range)
+local _parse_range = penlight.clone_function(penlight.array2d.parse_range)
-function pl.array2d.parse_range(s) -- edit parse range to do numpy string if no letter passed
- pl.utils.assert_arg(1,s,'string')
+function penlight.array2d.parse_range(s) -- edit parse range to do numpy string if no letter passed
+ penlight.utils.assert_arg(1,s,'string')
if not s:find'%a' then
- return pl.array2d.parse_numpy2d_str(s)
+ return penlight.array2d.parse_numpy2d_str(s)
end
return _parse_range(s)
end
@@ -674,68 +666,68 @@ end
-- https://tex.stackexchange.com/questions/38150/in-lualatex-how-do-i-pass-the-content-of-an-environment-to-lua-verbatim
-pl.tex.recordedbuf = ""
-function pl.tex.readbuf(buf)
+penlight.tex.recordedbuf = ""
+function penlight.tex.readbuf(buf)
i,j = string.find(buf, '\\end{%w+}')
if i==nil then -- if not ending an environment
- pl.tex.recordedbuf = pl.tex.recordedbuf .. buf .. "\n"
+ penlight.tex.recordedbuf = penlight.tex.recordedbuf .. buf .. "\n"
return ""
else
return nil
end
end
-function pl.tex.startrecording()
- pl.tex.recordedbuf = ""
- luatexbase.add_to_callback('process_input_buffer', pl.tex.readbuf, 'readbuf')
+function penlight.tex.startrecording()
+ penlight.tex.recordedbuf = ""
+ luatexbase.add_to_callback('process_input_buffer', penlight.tex.readbuf, 'readbuf')
end
-function pl.tex.stoprecording()
+function penlight.tex.stoprecording()
luatexbase.remove_from_callback('process_input_buffer', 'readbuf')
- pl.tex.recordedbuf = pl.tex.recordedbuf:gsub("\\end{%w+}\n","")
+ penlight.tex.recordedbuf = penlight.tex.recordedbuf:gsub("\\end{%w+}\n","")
end
__PDFmetadata__ = {}
-pl.tex.add_xspace_intext = true
+penlight.tex.add_xspace_intext = true
-function pl.tex.updatePDFtable(k, v, o) -- key val overwrite
+function penlight.tex.updatePDFtable(k, v, o) -- key val overwrite
k = k:upfirst()
- if pl.hasval(o) or (__PDFmetadata__[k] == nil) then
+ if penlight.hasval(o) or (__PDFmetadata__[k] == nil) then
__PDFmetadata__[k] = v
end
end
-pl.tex.writePDFmetadata = function(t) -- write PDF metadata to xmpdata file
+penlight.tex.writePDFmetadata = function(t) -- write PDF metadata to xmpdata file
t = t or __PDFmetadata__
local str = ''
for k, v in pairs(t) do
k = k:upfirst()
str = str..'\\'..k..'{'..v..'}'..'\n'
end
- pl.utils.writefile(tex.jobname..'.xmpdata', str)
+ penlight.utils.writefile(tex.jobname..'.xmpdata', str)
end
-function pl.tex.clear_cmds_str(s)
+function penlight.tex.clear_cmds_str(s)
return s:gsub('%s+', ' '):gsub('\\\\',' '):gsub('\\%a+',''):gsub('{',' '):gsub('}',' '):gsub('%s+',' '):strip()
end
-function pl.tex.makePDFvarstr(s)
+function penlight.tex.makePDFvarstr(s)
s = s:gsub('%s*\\sep%s+','\0'):gsub('%s*\\and%s+','\0') -- turn \and into \sep
- s = pl.tex.clear_cmds_str(s)
+ s = penlight.tex.clear_cmds_str(s)
s = s:gsub('\0','\\sep ')
- --pl.tex.help_wrt(s,'PDF var string')
+ --penlight.tex.help_wrt(s,'PDF var string')
return s
end
-function pl.tex.makeInTextstr(s)
+function penlight.tex.makeInTextstr(s)
local s, c_and = s:gsub('%s*\\and%s+','\0')
- s = pl.tex.clear_cmds_str(s)
- if pl.tex.add_xspace_intext then
+ s = penlight.tex.clear_cmds_str(s)
+ if penlight.tex.add_xspace_intext then
s = s..'\\xspace'
end
if c_and == 1 then
@@ -744,13 +736,13 @@ function pl.tex.makeInTextstr(s)
s = s:gsub('\0',', ', c_and - 1)
s = s:gsub('\0',', and ')
end
- --pl.tex.help_wrt(s,'in text var string')
+ --penlight.tex.help_wrt(s,'in text var string')
return s
end
--todo decide on above or below
-function pl.tex.list2comma(t)
+function penlight.tex.list2comma(t)
local s = ''
if #t == 1 then
s = t[1]
@@ -762,28 +754,27 @@ function pl.tex.list2comma(t)
return s
end
-function pl.tex.split2comma(s, d)
- local t = pl.List(s:split(d)):map(string.strip)
- pl.tex.prt(pl.tex.list2comma(t))
+function penlight.tex.split2comma(s, d)
+ local t = penlight.List(s:split(d)):map(string.strip)
+ penlight.tex.prt(penlight.tex.list2comma(t))
end
-function pl.tex.split2items(s, d)
- local t = pl.List(s:split(d)):map(string.strip)
+function penlight.tex.split2items(s, d)
+ local t = penlight.List(s:split(d)):map(string.strip)
for n, v in ipairs(t) do
- pl.tex.prtn('\\item '..v)
+ penlight.tex.prtn('\\item '..v)
end
end
-if pl.hasval(__PL_GLOBALS__) then
- __PL_EXTRAS__ = 2
+if penlight.hasval(__PL_GLOBALS__) then
-- iterators
- kpairs = pl.utils.kpairs
- npairs = pl.utils.npairs
+ kpairs = penlight.utils.kpairs
+ npairs = penlight.utils.npairs
--enum = utils.enum
- for k,v in pairs(pl.tablex) do -- extend the table table to contain tablex functions
+ for k,v in pairs(penlight.tablex) do -- extend the table table to contain tablex functions
if k == 'sort' then
table.sortk = v
elseif k == 'move' then
@@ -795,27 +786,27 @@ if pl.hasval(__PL_GLOBALS__) then
table.join = table.concat -- alias
-- todo should tablex have all table functions
- pl.tablex.concat = table.concat
- pl.tablex.insert = table.insert
- pl.tablex.maxn = table.maxn
- pl.tablex.remove = table.remove
- pl.tablex.sort = table.sort
+ penlight.tablex.concat = table.concat
+ penlight.tablex.insert = table.insert
+ penlight.tablex.maxn = table.maxn
+ penlight.tablex.remove = table.remove
+ penlight.tablex.sort = table.sort
- hasval = pl.hasval
- COMP = pl.COMP
+ hasval = penlight.hasval
+ COMP = penlight.COMP
-- shortcuts
--- http://stevedonovan.github.io/Penlight/api/libraries/pl.utils.html
- pl.writefile = pl.utils.writefile
- pl.readfile = pl.utils.readfile
- pl.readlines = pl.utils.readfile
- pl.filterfiles = pl.utils.filterfiles
+-- http://stevedonovan.github.io/Penlight/api/libraries/penlight.utils.html
+ penlight.writefile = penlight.utils.writefile
+ penlight.readfile = penlight.utils.readfile
+ penlight.readlines = penlight.utils.readfile
+ penlight.filterfiles = penlight.utils.filterfiles
- pl.a2 = pl.array2d
- pl.tbl = pl.tablex
+ penlight.a2 = penlight.array2d
+ penlight.tbl = penlight.tablex
- for k,v in pairs(pl.tex) do -- make tex functions global
+ for k,v in pairs(penlight.tex) do -- make tex functions global
_G[k] = v
end
@@ -825,42 +816,42 @@ end
- --_xTrue = pl.tex._xTrue
- --_xFalse = pl.tex._xFalse
- --_xNoValue = pl.tex._xNoValue
+ --_xTrue = penlight.tex._xTrue
+ --_xFalse = penlight.tex._xFalse
+ --_xNoValue = penlight.tex._xNoValue
--
- --prt = pl.tex.prt
- --prtn = pl.tex.prtn
- --wrt = pl.tex.wrt
- --wrtn = pl.tex.wrtn
+ --prt = penlight.tex.prt
+ --prtn = penlight.tex.prtn
+ --wrt = penlight.tex.wrt
+ --wrtn = penlight.tex.wrtn
--
- --prtl = pl.tex.prtl
- --prtt = pl.tex.prtt
+ --prtl = penlight.tex.prtl
+ --prtt = penlight.tex.prtt
--
- --help_wrt = pl.tex.help_wrt
- --prt_array2d = pl.tex.prt_array2d
+ --help_wrt = penlight.tex.help_wrt
+ --prt_array2d = penlight.tex.prt_array2d
--
- --pkgwarn = pl.tex.pkgwarn
- --pkgerror = pl.tex.pkgerror
+ --pkgwarn = penlight.tex.pkgwarn
+ --pkgerror = penlight.tex.pkgerror
--
- --defcmd = pl.tex.defcmd
- --prvcmd = pl.tex.prvcmd
- --newcmd = pl.tex.newcmd
- --renewcmd = pl.tex.renewcmd
- --deccmd = pl.tex.deccmd
+ --defcmd = penlight.tex.defcmd
+ --prvcmd = penlight.tex.prvcmd
+ --newcmd = penlight.tex.newcmd
+ --renewcmd = penlight.tex.renewcmd
+ --deccmd = penlight.tex.deccmd
--
- --_NumBkts = pl.tex._NumBkts
- --opencmd = pl.tex.opencmd
- --reset_bkt_cnt = pl.tex.reset_bkt_cnt
- --add_bkt_cnt = pl.tex.add_bkt_cnt
- --close_bkt_cnt = pl.tex.close_bkt_cnt
+ --_NumBkts = penlight.tex._NumBkts
+ --opencmd = penlight.tex.opencmd
+ --reset_bkt_cnt = penlight.tex.reset_bkt_cnt
+ --add_bkt_cnt = penlight.tex.add_bkt_cnt
+ --close_bkt_cnt = penlight.tex.close_bkt_cnt
-- graveyard
-- luakeys parses individual keys as ipairs, this changes the list to a pure map
---function pl.luakeystomap(t)
+--function penlight.luakeystomap(t)
-- local t_new = {}
-- for k, v in pairs(t) do
-- if type(k) == 'number' then
@@ -874,7 +865,7 @@ end
--if luakeys then -- if luakeys is already loaded
-- function luakeys.parseN(s, ...)
-- local t = luakeys.parse(s,...)
--- t = pl.luakeystomap(t)
+-- t = penlight.luakeystomap(t)
-- return t
-- end
--end
@@ -893,13 +884,13 @@ end
-- -- -- -- functions below extend the array2d module
---function pl.array2d.map_slice1(func, L, i1, i2) -- map a function to a slice of an array, can use PlcExpr
+--function penlight.array2d.map_slice1(func, L, i1, i2) -- map a function to a slice of an array, can use PlcExpr
-- i2 = i2 or i1
-- local len = #L
-- i1 = check_index(i1, len)
-- i2 = check_index(i2, len)
-- func = check_func(func)
--- for i in pl.seq.range(i1,i2) do
+-- for i in penlight.seq.range(i1,i2) do
-- L[i] = func(L[i])
-- end
-- return L
@@ -907,8 +898,8 @@ end
-- used this below when iter was not working..
--i1, j1, i2, j2 = check_slice(M, i1, j1, i2, j2)
- --for i in pl.seq.range(i1,i2) do
- -- for j in pl.seq.range(j1,j2) do
+ --for i in penlight.seq.range(i1,i2) do
+ -- for j in penlight.seq.range(j1,j2) do
--end
-- penlight may have fixed this
--local function check_index(ij, rc) -- converts array index to positive value if negative
@@ -926,7 +917,7 @@ end
-- end
--end
--local function check_slice(M, i1, j1, i2, j2) -- ensure a slice is valid; i.e. all positive numbers
--- r, c = pl.array2d.size(M)
+-- r, c = penlight.array2d.size(M)
-- i1 = check_index(i1 or 1, r)
-- i2 = check_index(i2 or r, r)
-- j1 = check_index(j1 or 1, c)
diff --git a/macros/luatex/generic/penlightplus/penlightplus.pdf b/macros/luatex/generic/penlightplus/penlightplus.pdf
new file mode 100644
index 0000000000..89b8236d66
--- /dev/null
+++ b/macros/luatex/generic/penlightplus/penlightplus.pdf
Binary files differ
diff --git a/macros/luatex/generic/penlightplus/penlightplus.sty b/macros/luatex/generic/penlightplus/penlightplus.sty
new file mode 100644
index 0000000000..0d49ff90d0
--- /dev/null
+++ b/macros/luatex/generic/penlightplus/penlightplus.sty
@@ -0,0 +1,119 @@
+% Kale Ewasiuk (kalekje@gmail.com)
+% 2023-07-22
+% Copyright (C) 2021-2023 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
+% in the Software without restriction, including without limitation the rights
+% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+% copies of the Software, and to permit persons to whom the Software is
+% furnished to do so, subject to the following conditions:
+%
+% The above copyright notice and this permission notice shall be included in
+% all copies or substantial portions of the Software.
+%
+% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+% ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+% TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+% PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+% SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+% ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+% ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
+% OR OTHER DEALINGS IN THE SOFTWARE.
+
+\ProvidesPackage{penlightplus}[2023-07-22]
+
+\RequirePackage{luacode}
+\RequirePackage{luakeys}
+\RequirePackage[import]{penlight}
+
+\DeclareOption{globals}{\luadirect{__PL_GLOBALS__ = true}}
+\DeclareOption{pl}{\directlua{pl = penlight}}
+\ProcessOptions*\relax
+
+\luadirect{require'penlightplus'}
+
+
+
+
+\global\newcommand{\writePDFmetadata}{\luadirect{penlight.tex.writePDFmetadata()}}
+
+\NewDocumentCommand{\writePDFmetadatakv}{ s m }{
+\IfBooleanTF{#1}{% if *, overwrite everything
+ \luadirect{
+ __PDFmetadata__ = penlight.luakeys.parse(\luastring{#2})
+ penlight.tex.writePDFmetadata()
+ }}{
+ \luadirect{
+ __PDFmetadata__ = __PDFmetadata__ or {}
+ penlight.tablex.update(__PDFmetadata__, penlight.luakeys.parse(\luastring{#2}))
+ penlight.tex.writePDFmetadata()
+ }}
+}
+
+
+\gdef\luastringT#1{\luastring{\unexpanded\expandafter\expandafter\expandafter{#1}}} % expand luastring twice
+\global\let\luastringF\luastring % fully expanded luastring
+
+% allow control over expansion of arguments to a latex function
+\NewDocumentCommand{\MakeluastringCommands}{O{} m }{% #1 the desired commands #2 defaults
+ \luadirect{penlight.tex.aliasluastring(\luastring{#2},\luastring{#1})}%
+}
+
+\NewDocumentCommand{\splitToComma}{ O{nn} m m }{%
+ \MakeluastringCommands[nn]{#1}%
+ \luadirect{penlight.tex.split2comma(\plluastringA{#2},\plluastringB{#3})}%
+}
+
+\NewDocumentCommand{\splitToItems}{ O{NN} m m }{%
+ \MakeluastringCommands[nn]{#1}%
+ \luadirect{penlight.tex.split2items(\plluastringA{#2},\plluastringB{#3})}%
+}
+
+
+%
+%
+%\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]))
+%}}
+%
+%
+%\NewDocumentCommand{\tblupd}{ m m}{\luadirect{
+% penlight.tablex.update(_G[\luastring{#1}], _G[\luastring{#2}])
+%}}
+%
+%\NewDocumentCommand{\tblupdkv}{ m m }{\luadirect{
+% penlight.tablex.update(_G[\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,
+% % {tbl}{update}[arg1][arg2]
+% penlight.tablex[\luastring[#1]](_G[\luastring{}], _G[\luastring{}])
+%}}
+
+
diff --git a/macros/luatex/generic/penlightplus/penlightplus.tex b/macros/luatex/generic/penlightplus/penlightplus.tex
new file mode 100644
index 0000000000..50f87fa38b
--- /dev/null
+++ b/macros/luatex/generic/penlightplus/penlightplus.tex
@@ -0,0 +1,227 @@
+% Kale Ewasiuk (kalekje@gmail.com)
+% 2023-07-22
+% Copyright (C) 2021-2023 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
+% in the Software without restriction, including without limitation the rights
+% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+% copies of the Software, and to permit persons to whom the Software is
+% furnished to do so, subject to the following conditions:
+%
+% The above copyright notice and this permission notice shall be included in
+% all copies or substantial portions of the Software.
+%
+% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+% ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+% TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+% PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+% SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+% ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+% ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
+% OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+\documentclass[11pt,parskip=half]{scrartcl}
+\setlength{\parindent}{0ex}
+\newcommand{\llcmd}[1]{\leavevmode\llap{\texttt{\detokenize{#1}}}}
+\newcommand{\cmd}[1]{\texttt{\detokenize{#1}}}
+\newcommand{\qcmd}[1]{``\cmd{#1}''}
+\usepackage{url}
+\usepackage{xcolor}
+\usepackage{showexpl}
+\lstset{explpreset={justification=\raggedright,pos=r,wide=true}}
+\setlength\ResultBoxRule{0mm}
+\lstset{
+ language=[LaTeX]TeX,
+ basicstyle=\ttfamily\small,
+ commentstyle=\ttfamily\small\color{gray},
+ frame=none,
+ numbers=left,
+ numberstyle=\ttfamily\small\color{gray},
+ prebreak=\raisebox{0ex}[0ex][0ex]{\color{gray}\ensuremath{\hookleftarrow}},
+ extendedchars=true,
+ breaklines=true,
+ tabsize=4,
+}
+\addtokomafont{title}{\raggedright}
+\addtokomafont{author}{\raggedright}
+\addtokomafont{date}{\raggedright}
+\author{Kale Ewasiuk (\url{kalekje@gmail.com})}
+\usepackage[yyyymmdd]{datetime}\renewcommand{\dateseparator}{--}
+\date{\today}
+
+
+\RequirePackage{penlightplus}
+
+\title{penlightplus}
+\subtitle{Additions to the Penlight Lua Libraries}
+
+\begin{document}
+%
+
+\maketitle
+
+This package first loads the \cmd{[import]penlight} package.\\
+The \texttt{pl} option may be passed to this package to create an alias for \cmd{penlight}.\\
+\texttt{globals} option may be used to make several of the functions global (as discussed below).
+
+\subsection*{texlua usage}
+If you want to use penlightplus.lua with the \texttt{texlua} interpreter
+(no document is made, but useful for testing your Lua code),
+you can access it by setting \cmd{__SKIP_TEX__ = true} before loading. For example:
+ \begin{verbatim}
+package.path = package.path .. ';'..'path/to/texmf/tex/latex/penlightplus/?.lua'
+package.path = package.path .. ';'..'path/to/texmf/tex/latex/penlight/?.lua'
+penlight = require'penlight'
+
+__SKIP_TEX__ = true --only required if you want to use
+ --penlightplus without a LaTeX run
+__PL_GLOBALS__ = true -- optional, include global definitions
+require'penlightplus'
+\end{verbatim}
+
+
+
+
+
+
+\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}\\
+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_NO_HYPERREF__} a flag used to change the behaviour of a function, depending on if you don't use the hyperref package\\
+
+\subsubsection*{penlight additions}
+
+Some functionality is added to penlight/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}\\
+\llcmd{math.mod(n,d)}, \cmd{math.mod2(n)} math modulous\\
+\llcmd{string.}\cmd{totable(s)} string a table of characters\\
+\llcmd{string.}\cmd{delspace(s)} clear spaces from string\\
+\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.\\
+
+\llcmd{pl.utils.}\cmd{filterfiles}\cmd{(dir,filt,rec)} Get files from dir and apply glob-like filters. Set rec to \cmd{true} to include sub directories\\
+
+
+\subsubsection*{A \cmd{pl.tex.} module is added}
+\llcmd{add_bkt}\cmd{_cnt(n), }\cmd{close_bkt_cnt(n), reset_bkt_cnt} functions to keep track of adding curly brackets as strings. \cmd{add} will return \cmd{n} (default 1) \{'s and increment a counter. \cmd{close} will return \cmd{n} \}'s (default will close all brackets) and decrement.\\
+\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{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{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{newcmd}\cmd{(cs, val)} like \cmd{\newcommand}\\
+\llcmd{renewcmd}\cmd{(cs, val)} like \cmd{\renewcommand}\\
+\llcmd{prvcmd}\cmd{(cs, val)} like \cmd{\providecommand}\\
+\llcmd{deccmd}\cmd{(cs, dft, overwrite)} declare a command. If \cmd{dft} (default) is \cmd{nil}, \cmd{cs} is set
+to a package warning saying \cmd{'cs' was declared and used in document, but never set}. If \cmd{overwrite}
+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*{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.\\
+
+
+
+\subsection*{Macro helpers}
+\cmd{\MakeluastringCommands[def]{spec}} will let \cmd{\plluastring(A|B|C..)} be \cmd{\luastring(N|O|T|F)}
+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.
+
+% BELOW IS FOR TROUBLESHOOTING ABOVE
+%\def\NOTexp{\ONEexp}
+%\def\ONEexp{\TWOexp}
+%\def\TWOexp{\TREexp}
+%\def\TREexp{Fully expanded}
+%
+%\NewDocumentCommand{\luastringExpTest}{m m}{
+% \MakeluastringCommands{#1}
+% \luadirect{texio.write_nl('VVVVVVVVVVVVVVVVVVVVVVVVVVVVV')}
+% \luadirect{texio.write_nl(\plluastringA{#2}..' | Not')}
+% \luadirect{texio.write_nl(\plluastringB{#2}..' | Once')}
+% \luadirect{texio.write_nl(\plluastringC{#2}..' | Twice')}
+% \luadirect{texio.write_nl(\plluastringD{#2}..' | Full')}
+% \luadirect{texio.write_nl('VVVVVVVVVVVVVVVVVVVVVVVVVVVVV')}
+%}
+%
+%\luastringExpTest{ n o t f }{\NOTexp}
+
+
+
+
+\subsection*{Split stuff}
+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}-\\
+-\splitToComma{ j doe \and s else \and a per \and f guy}{\and}-
+
+\def\authors{j doe \and s else \and a per \and f guy}
+\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.
+
+\begin{LTXexample}
+spliToItems:
+\begin{itemize}
+ \splitToItems{kale\and john}{\and}
+ \splitToItems{kale -john -someone else}{-}
+\end{itemize}
+\end{LTXexample}
+
+
+
+
+
+
+% \tblfrkv{tbl_def}{kale=cool,paul=gay,craig=fun}
+% \tblfrkv{tbl}{kale,paul=gay} %[naked_as_value=true]
+%
+% \tblget{tbl}{kale}%
+% \tblget{tbl}{paul}%
+% \tblget{tbl}{craig}%
+%
+% \tblupd{tbl_def}{tbl}%
+%
+% \tblfrkvII{tbl}{kale=cool,paul=gay,craig=fun}{kale=weak,paul=sad}
+% \tblget{tbl}{craig}%
+% \tblget{tbl}{paul}%
+% \tblget{tbl}{kale}%
+%
+% \NewDocumentCommand{\THINg}{ O{} m}{%
+% \tblfrkvII{setti}{color=red,size=small}{#1} % make settings and update based on [arg=]
+% {\color{\tblget{setti}{color}}\tblget{setti}{size} #2}
+% }
+%
+% \THINg[color=blue,size=tiny]{Kale}
+
+\end{document} \ No newline at end of file