% Kale Ewasiuk (kalekje@gmail.com) % 2023-12-08 % 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-12-08] \RequirePackage{luacode} \RequirePackage{luakeys} \RequirePackage[import]{penlight} \RequirePackage{etoolbox} \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})}% } %%%% \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]} %%% tbls below \NewDocumentCommand{\tblnew}{m}{\luadirect{% initialize a tbl and set blank penlight.tbls[\luastring{#1}] = {} penlight.rec_tbl = \luastring{#1} }} \NewDocumentCommand{\tblfrkv}{m +m O{}}{\luadirect{% penlight.rec_tbl_opts = penlight.luakeys.parse(\luastring{#3}) penlight.tbls[\luastring{#1}] = penlight.luakeys.parse(string.subpar(\luastring{#2}), penlight.rec_tbl_opts) penlight.rec_tbl = \luastring{#1} }} \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) penlight.rec_tbl = \luastring{#1} }} \NewDocumentCommand{\tblfrcsv}{m +m O{}}{\tblfrkv{#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{\tblchg}{ m }{\luadirect{% change recent table penlight.rec_tbl = \luastring{#1} }} \NewDocumentCommand{\tblget}{m}{\luadirect{% get an item penlight.get_tbl_item(\luastring{#1}, true) }} \NewDocumentCommand{\tblset}{m m}{\luadirect{% set item with {value} 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{\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{\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]} % legacy code, delete this \let\kvtblundefcheck\tblkvundefcheck \let\chgtbl\tblchg \let\newtbl\tblnew \let\gettbl\tblget \let\settbl\tblset \let\deftbl\tbldef \let\gdeftbl\tblgdef \let\iftbl\tblif \let\iftblv\tblifv