diff options
-rw-r--r-- | Master/texmf-dist/doc/luatex/luakeys/luakeys-debug.tex | 35 | ||||
-rw-r--r-- | Master/texmf-dist/doc/luatex/luakeys/luakeys.pdf | bin | 140586 -> 153582 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/luatex/luakeys/luakeys.tex | 121 | ||||
-rw-r--r-- | Master/texmf-dist/tex/luatex/luakeys/luakeys-debug.sty | 21 | ||||
-rw-r--r-- | Master/texmf-dist/tex/luatex/luakeys/luakeys.lua | 114 |
5 files changed, 220 insertions, 71 deletions
diff --git a/Master/texmf-dist/doc/luatex/luakeys/luakeys-debug.tex b/Master/texmf-dist/doc/luatex/luakeys/luakeys-debug.tex index 499b1305f67..b63e67e0502 100644 --- a/Master/texmf-dist/doc/luatex/luakeys/luakeys-debug.tex +++ b/Master/texmf-dist/doc/luatex/luakeys/luakeys-debug.tex @@ -20,14 +20,43 @@ luakeys = require('luakeys') } -\def\luakeysdebug#1{ +% https://tex.stackexchange.com/a/418401/42311 +\catcode`\@=11 +\long\def\LuaKeysIfNextChar#1#2#3{% + \let\@tmpa=#1% + \def\@tmpb{#2}% + \def\@tmpc{#3}% + \futurelet\@future\LuaKeysIfNextChar@i% +}% +\def\LuaKeysIfNextChar@i{% + \ifx\@tmpa\@future% + \expandafter\@tmpb + \else + \expandafter\@tmpc + \fi +}% +\def\luakeysdebug@parse@options#1{ + \directlua{ + luakeys.save('debug_options', luakeys.parse('#1')) + } +}% +\def\luakeysdebug@output#1{ { \tt \parindent=0pt \directlua{ - local result = luakeys.parse('#1') + local result = luakeys.parse('\luaescapestring{\unexpanded{#1}}', luakeys.get('debug_options')) tex.print(luakeys.stringify(result, true)) luakeys.print(result) } } -} +}% +\def\luakeysdebug@oarg[#1]#2{% + \luakeysdebug@parse@options{#1}% + \luakeysdebug@output{#2}% +}% +\def\luakeysdebug@marg#1{% + \luakeysdebug@output{#1}% +}% +\def\luakeysdebug{\LuaKeysIfNextChar[{\luakeysdebug@oarg}{\luakeysdebug@marg}}% +\catcode`\@=12 diff --git a/Master/texmf-dist/doc/luatex/luakeys/luakeys.pdf b/Master/texmf-dist/doc/luatex/luakeys/luakeys.pdf Binary files differindex ceaebbee048..c65765d5b9f 100644 --- a/Master/texmf-dist/doc/luatex/luakeys/luakeys.pdf +++ b/Master/texmf-dist/doc/luatex/luakeys/luakeys.pdf diff --git a/Master/texmf-dist/doc/luatex/luakeys/luakeys.tex b/Master/texmf-dist/doc/luatex/luakeys/luakeys.tex index 75ffbc8c70d..fc465f46aec 100644 --- a/Master/texmf-dist/doc/luatex/luakeys/luakeys.tex +++ b/Master/texmf-dist/doc/luatex/luakeys/luakeys.tex @@ -28,9 +28,9 @@ \author{% Josef Friedrich\\% \url{josef@friedrich.rocks}\\% - \href{https://github.com/Josef-Friedrich/nodetree}{github.com/Josef-Friedrich/luakeys}% + \href{https://github.com/Josef-Friedrich/luakeys}{github.com/Josef-Friedrich/luakeys}% } -\date{v0.1 from 2021/01/18} +\date{v0.2 from 2021/09/19} \maketitle @@ -105,6 +105,27 @@ This package would not be possible without the article \clearpage +\section{Usage} + +\begin{minted}{latex} +\documentclass{article} +\directlua{ + luakeys = require('luakeys') +} + +\newcommand{\helloworld}[2][]{ + \directlua{ + local keys = luakeys.parse('\luaescapestring{\unexpanded{#1}}') + luakeys.print(keys) + local marg = '#2' + tex.print(keys.greeting .. ', ' .. marg .. keys.punctuation) + } +} +\begin{document} +\helloworld[greeting=hello,punctuation=!]{world} +\end{document} +\end{minted} + \section{Syntax of the recognized key-value format} %% @@ -123,7 +144,7 @@ lists (\texttt{level1=\{level2=\{key=value,value\}\}}). % %% -\subsection{An (incomplete) attempt to put the syntax into the (Extended) Backus-Naur form} +\subsection{An (incomplete) attempt to put the syntax into the Extended Backus-Naur Form} \begin{grammar} <list> ::= <list-item> | <list-item> <list> @@ -137,6 +158,25 @@ lists (\texttt{level1=\{level2=\{key=value,value\}\}}). \alt <number> \alt <string-quoted> \alt <string-unquoted> + +<sign> ::= `-' | `+' + +<integer> ::= `0' | `1' | `2' | `3' | `4' | `5' | `6' | `7' | `8' | `9' + +<unit> ::= `bp' | `BP' + \alt `cc' | `CC' + \alt `cm' | `CM' + \alt `dd' | `DD' + \alt `em' | `EM' + \alt `ex' | `EX' + \alt `in' | `IN' + \alt `mm' | `MM' + \alt `nc' | `NC' + \alt `nd' | `ND' + \alt `pc' | `PC' + \alt `pt' | `PT' + \alt `sp' | `SP' + \end{grammar} ... to be continued @@ -226,7 +266,8 @@ local result = parse('dim=1cm', { }) \end{minted} -If you want to convert a scale point into a unit string you can used the module +\noindent +If you want to convert a scale point into a unit string you can use the module \href{https://raw.githubusercontent.com/latex3/lualibs/master/lualibs-util-dim.lua}{lualibs-util-dim.lua}. \begin{minted}{latex} @@ -317,6 +358,46 @@ marks must be used. \end{minted} \end{multicols} +\subsubsection{Standalone values} + +Standalone values are values without a key. They are converted into an +array. In Lua an array is a table with numeric indexes (The first index +is 1). + +\begin{multicols}{2} +\begin{minted}{latex} +\luakeysdebug{one,two,three} +\end{minted} +\columnbreak +\begin{minted}{lua} +{ 'one', 'two', 'three' } +\end{minted} + +\noindent +is equivalent to + +\begin{minted}{lua} +{ + [1] = 'one', + [2] = 'two', + [3] = 'three', +} +\end{minted} +\end{multicols} + +\noindent +All recognized data types can be used as standalone values. + +\begin{multicols}{2} +\begin{minted}{latex} +\luakeysdebug{one,2,3cm} +\end{minted} +\columnbreak +\begin{minted}{lua} +{ 'one', 2, 5594039 } +\end{minted} +\end{multicols} + %----------------------------------------------------------------------- % %----------------------------------------------------------------------- @@ -325,7 +406,7 @@ marks must be used. \section{Exported functions of the Lua module \texttt{luakeys.lua}} -To learn more about the individual functions (local functions), pleasecommand +To learn more about the individual functions (local functions), please read the \href{https://josef-friedrich.github.io/luakeys/}{source code documentation}, which was created with \href{http://stevedonovan.github.io/ldoc/}{LDoc}. The Lua module exports @@ -336,6 +417,8 @@ local luakeys = require('luakeys') local parse = luakeys.parse local render = luakeys.render --local print = luakeys.print -- That would overwrite the built-in Lua function +local save = luakeys.save +local get = luakeys.get \end{minted} %% @@ -443,6 +526,26 @@ The output should look like this: } \end{minted} +%% +% +%% + +\subsection{\texttt{save(identifier, result): void}} + +The function \lua{save(identifier, result)} saves a result (a +table from a previous run of \lua{parse}) under an identifier. +Therefore, it is not necessary to pollute the global namespace to +store results for the later usage. + +%% +% +%% + +\subsection{\texttt{get(identifier): table}} + +The function \lua{get(identifier)} retrieves a saved result from the +result store. + %----------------------------------------------------------------------- % %----------------------------------------------------------------------- @@ -535,8 +638,12 @@ An example of how to use the command in \LaTeX: \inputminted[linenos=true]{latex}{luakeys-debug.sty} -\changes{v0.1}{2020/01/17}{Inital release} - +\changes{v0.1}{2021/01/18}{Inital release} +\changes{v0.2}{2021/09/19}{ +* Allow all recognized data types as keys +* Allow TeX macros in the values +* New public Lua functions: save(identifier, result), get(identifier) +} \pagebreak \PrintChanges \pagebreak diff --git a/Master/texmf-dist/tex/luatex/luakeys/luakeys-debug.sty b/Master/texmf-dist/tex/luatex/luakeys/luakeys-debug.sty index 77dfa0063eb..a96d2d51c60 100644 --- a/Master/texmf-dist/tex/luatex/luakeys/luakeys-debug.sty +++ b/Master/texmf-dist/tex/luatex/luakeys/luakeys-debug.sty @@ -17,23 +17,6 @@ % and luakeys-debug.tex. \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{luakeys-debug}[2021/01/18 Debug package for luakeys.] +\ProvidesPackage{luakeys-debug}[2021/09/19 Debug package for luakeys.] -%\input luakeys-debug.tex - -\directlua{ - luakeys = require('luakeys') -} - -\newcommand{\luakeysdebug}[2][]{ - { - \tt - \parindent=0pt - \directlua{ - local options_raw = luakeys.parse('#1') - local result = luakeys.parse('#2', options_raw) - tex.print(luakeys.stringify(result, true)) - luakeys.print(result) - } - } -} +\input luakeys-debug.tex diff --git a/Master/texmf-dist/tex/luatex/luakeys/luakeys.lua b/Master/texmf-dist/tex/luatex/luakeys/luakeys.lua index e4ecaab7f70..b0264138003 100644 --- a/Master/texmf-dist/tex/luatex/luakeys/luakeys.lua +++ b/Master/texmf-dist/tex/luatex/luakeys/luakeys.lua @@ -41,16 +41,19 @@ if not tex then end end +--- A table to store parsed key-value results. +local result_store = {} + --- Generate the PEG parser using Lpeg. -- --- @treturn userdata The parser +-- @treturn userdata The parser. local function generate_parser(options) -- Optional whitespace - local white_space = lpeg.S(' \t\n\r')^0 + local white_space = lpeg.S(' \t\n\r') --- Match literal string surrounded by whitespace local ws = function(match) - return white_space * lpeg.P(match) * white_space + return white_space^0 * lpeg.P(match) * white_space^0 end local boolean_true = @@ -87,17 +90,24 @@ local function generate_parser(options) local sign = lpeg.S('-+') local integer = lpeg.R('09')^1 local tex_number = (integer^1 * (lpeg.P('.') * integer^1)^0) + (lpeg.P('.') * integer^1) - local unit - -- https://raw.githubusercontent.com/latex3/lualibs/master/lualibs-util-dim.lua - for _, dimension_extension in ipairs({'bp', 'cc', 'cm', 'dd', 'em', 'ex', 'in', 'mm', 'nc', 'nd', 'pc', 'pt', 'sp'}) do - if unit then - unit = unit + lpeg.P(dimension_extension) - else - unit = lpeg.P(dimension_extension) - end - end - local dimension = (sign^0 * tex_number * unit) + -- https://raw.githubusercontent.com/latex3/lualibs/master/lualibs-util-dim.lua + local unit = + lpeg.P('bp') + lpeg.P('BP') + + lpeg.P('cc') + lpeg.P('CC') + + lpeg.P('cm') + lpeg.P('CM') + + lpeg.P('dd') + lpeg.P('DD') + + lpeg.P('em') + lpeg.P('EM') + + lpeg.P('ex') + lpeg.P('EX') + + lpeg.P('in') + lpeg.P('IN') + + lpeg.P('mm') + lpeg.P('MM') + + lpeg.P('nc') + lpeg.P('NC') + + lpeg.P('nd') + lpeg.P('ND') + + lpeg.P('pc') + lpeg.P('PC') + + lpeg.P('pt') + lpeg.P('PT') + + lpeg.P('sp') + lpeg.P('SP') + + local dimension = (sign^0 * white_space^0 * tex_number * white_space^0 * unit) if options.convert_dimensions then return dimension / tex.sp @@ -106,7 +116,7 @@ local function generate_parser(options) end end - --- Add values to a table in a two modes: + --- Add values to a table in two modes: -- -- # Key value pair -- @@ -150,15 +160,7 @@ local function generate_parser(options) ) * ws(',')^-1, key_value_pair = - (lpeg.V('key') * ws('=')) * (lpeg.V('list_container') + lpeg.V('value')), - - -- ./ for tikz style keys - key_word = lpeg.R('az', 'AZ', '09', './'), - - key = white_space * lpeg.C( - lpeg.V('key_word')^1 * - (lpeg.P(' ')^1 * lpeg.V('key_word')^1)^0 - ) * white_space, + (lpeg.V('value') * ws('=')) * (lpeg.V('list_container') + lpeg.V('value')), value = lpeg.V('boolean') + @@ -174,25 +176,25 @@ local function generate_parser(options) dimension = build_dimension_pattern(), string_quoted = - white_space * lpeg.P('"') * + white_space^0 * lpeg.P('"') * lpeg.C((lpeg.P('\\"') + 1 - lpeg.P('"'))^0) * - lpeg.P('"') * white_space, + lpeg.P('"') * white_space^0, string_unquoted = - white_space * - lpeg.C((1 - lpeg.S('{},='))^1) * - white_space, + white_space^0 * + lpeg.C( + lpeg.V('word_unquoted')^1 * + (lpeg.S(' \t')^1 * lpeg.V('word_unquoted')^1)^0) * + white_space^0, + + word_unquoted = (1 - white_space - lpeg.S('{},='))^1; number = - white_space * (number / tonumber) * white_space, + white_space^0 * (number / tonumber) * white_space^0, }) end -local function trim(input_string) - return input_string:gsub('^%s*(.-)%s*$', '%1') -end - --- Get the size of an array like table `{ 'one', 'two', 'three' }` = 3. -- -- @tparam table value A table or any input. @@ -238,16 +240,19 @@ local function unpack_single_valued_array_table(value) return value end ---- This normalization tasks are performed on the raw input table --- coming directly from the PEG parser: +--- This normalization tasks are performed on the raw input table coming +-- directly from the PEG parser: -- -- 1. Trim all strings: ` text \n` into `text` --- 2. Unpack all single valued array like tables: `{ 'text' }` --- into `text` +-- 2. Unpack all single valued array like tables: `{ 'text' }` into +-- `text` -- -- @tparam table raw The raw input table coming directly from the PEG -- parser -- +-- @tparam table options Some options. A table with the key +-- `unpack_single_array_values` +-- -- @treturn table A normalized table ready for the outside world. local function normalize(raw, options) local function normalize_recursive(raw, result, options) @@ -257,8 +262,6 @@ local function normalize(raw, options) end if type(value) == 'table' then result[key] = normalize_recursive(value, {}, options) - elseif type(value) == 'string' then - result[key] = trim(value) else result[key] = value end @@ -288,8 +291,8 @@ local function stringify(input, for_tex) if for_tex then line_break = '\\par' - start_bracket = '\\{' - end_bracket = '\\}' + start_bracket = '$\\{$' + end_bracket = '$\\}$' indent = '\\ \\ ' else line_break = '\n' @@ -306,6 +309,10 @@ local function stringify(input, for_tex) table.insert(output, string.rep(indent, depth) .. text) end + if type(input) ~= 'table' then + return tostring(input) + end + for key, value in pairs(input) do if (key and type(key) == 'number' or type(key) == 'string') then key = string.format('[\'%s\']', key); @@ -423,7 +430,7 @@ return { if kv_string == nil then return {} end - options = normalize_parse_options() + options = normalize_parse_options(options) local parser = generate_parser(options) return normalize(parser:match(kv_string), options) @@ -480,4 +487,27 @@ return { print(stringify(tbl, false)) end, + --- The function `save(identifier, result): void` saves a result (a + -- table from a previous run of `parse`) under an identifier. + -- Therefore, it is not necessary to pollute the global namespace to + -- store results for the later usage. + -- + -- @tparam string identifier The identifier under which the result is + -- saved. + -- + -- @tparam table result A result to be stored and that was created by + -- the key-value parser. + save = function(identifier, result) + result_store[identifier] = result + end, + + --- The function `get(identifier): table` retrieves a saved result + -- from the result store. + -- + -- @tparam string identifier The identifier under which the result was + -- saved. + get = function(identifier) + return result_store[identifier] + end, + } |