From 13748bb6611bee0fb4e20bb703a26d778791bd21 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Thu, 17 Nov 2022 21:02:07 +0000 Subject: luakeys (17nov22) git-svn-id: svn://tug.org/texlive/trunk@65041 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/luatex/luakeys/README.md | 18 +++ .../texmf-dist/doc/luatex/luakeys/luakeys-doc.pdf | Bin 276812 -> 283942 bytes .../texmf-dist/doc/luatex/luakeys/luakeys-doc.tex | 130 ++++++++++++++++++++- .../tex/luatex/luakeys/luakeys-debug.sty | 2 +- Master/texmf-dist/tex/luatex/luakeys/luakeys.lua | 118 ++++++++++--------- Master/texmf-dist/tex/luatex/luakeys/luakeys.sty | 2 +- 6 files changed, 209 insertions(+), 61 deletions(-) (limited to 'Master') diff --git a/Master/texmf-dist/doc/luatex/luakeys/README.md b/Master/texmf-dist/doc/luatex/luakeys/README.md index 2bff44088bc..bd30edb0667 100644 --- a/Master/texmf-dist/doc/luatex/luakeys/README.md +++ b/Master/texmf-dist/doc/luatex/luakeys/README.md @@ -78,6 +78,9 @@ local defs = { ```lua local opts = { + -- Configure the delimiter that assigns a value to a key. + assignment_operator = '=', + -- Automatically convert dimensions into scaled points (1cm -> 1864679). convert_dimensions = false, @@ -97,6 +100,12 @@ local opts = { -- lower, snake, upper format_keys = { 'snake' }, + -- Configure the delimiter that marks the beginning of a group. + group_begin = '{', + + -- Configure the delimiter that marks the end of a group. + group_end = '}', + -- Listed in the order of execution hooks = { kv_string = function(kv_string) @@ -131,6 +140,9 @@ local opts = { end, }, + -- Configure the delimiter that separates list items from each other. + list_separator = ',', + -- If true, naked keys are converted to values: -- { one = true, two = true, three = true } -> { 'one', 'two', 'three' } naked_as_value = false, @@ -138,6 +150,12 @@ local opts = { -- Throw no error if there are unknown keys. no_error = false, + -- Configure the delimiter that marks the beginning of a string. + quotation_begin = '"', + + -- Configure the delimiter that marks the end of a string. + quotation_end = '"', + -- { key = { 'value' } } -> { key = 'value' } unpack = false, } diff --git a/Master/texmf-dist/doc/luatex/luakeys/luakeys-doc.pdf b/Master/texmf-dist/doc/luatex/luakeys/luakeys-doc.pdf index ee0f3411f6e..04e307a84d0 100644 Binary files a/Master/texmf-dist/doc/luatex/luakeys/luakeys-doc.pdf and b/Master/texmf-dist/doc/luatex/luakeys/luakeys-doc.pdf differ diff --git a/Master/texmf-dist/doc/luatex/luakeys/luakeys-doc.tex b/Master/texmf-dist/doc/luatex/luakeys/luakeys-doc.tex index dd6fcc0973c..f7d2940f664 100644 --- a/Master/texmf-dist/doc/luatex/luakeys/luakeys-doc.tex +++ b/Master/texmf-dist/doc/luatex/luakeys/luakeys-doc.tex @@ -58,7 +58,7 @@ The default value of the option “\texttt{#1}” is: \href{https://github.com/Josef-Friedrich/luakeys} {github.com/Josef-Friedrich/luakeys}% } -\date{0.7.0 from 2022/07/06} +\date{0.8.0 from 2022/11/17} \maketitle @@ -357,7 +357,7 @@ The \lua{parse} function can be called with an options table. This options are supported: \catcode`_=12 \directlua{luakeys.print_names('opts')} -\InputLua[firstline=5,lastline=69]{opts/all-opts.lua} +\InputLua[firstline=5,lastline=86]{opts/all-opts.lua} \noindent The options can also be set globally using the exported table @@ -371,6 +371,32 @@ The options can also be set globally using the exported table % %% +\subsubsection{Option “\texttt{assignment_operator}”} +\label{option:assignment-operator} +\label{options-delimiter} + +The option \lua{assignment_operator} configures the delimiter that +assigns a value to a key. The default value of this option is +\texttt{"="}. + +The code example below demonstrates all six delimiter related options. + +\InputLua[firstline=4,lastline=13]{opts/delimiters.lua} + +\begin{tabular}{ll} +\textbf{Delimiter options} & \textbf{Section} \\ +assignment_operator & \ref{option:assignment-operator}\\ +group_begin & \ref{option:group-begin}\\ +group_end & \ref{option:group-end}\\ +list_separator & \ref{option:list-separator}\\ +quotation_begin & \ref{option:quotation-begin}\\ +quotation_end & \ref{option:quotation-end}\\ +\end{tabular} + +%% +% +%% + \subsubsection{Option “\texttt{convert_dimensions}”} % Wenn Sie die Option \lua{convert_dimensions} auf \lua{true} setzen, @@ -515,26 +541,76 @@ we can write ... \subsubsection{Option “\texttt{format_keys}”} +% Mit Hilfe der Option \lua{format_keys} können die Schlüssel formatiert +% werden. +With the help of the option \lua{format_keys} the keys can be formatted. +% Die Werte dieser Option müssen in einer Tabelle angegeben werden. +The values of this option must be specified in a table. + \begin{description} -\item[lower] \strut +\item[lower] + +% Um alle Schlüssel in \emph{Kleinbuchstaben} umzuwandeln, geben sie in +% der Optionentabelle \lua{lower} an. +To convert all keys to \emph{lowercase}, specify \lua{lower} in the +options table. \InputLua[firstline=4,lastline=5]{opts/format-keys.lua} -\item[snake] \strut +\item[snake] + +% Um alle Schlüssel in \emph{snake case} (Die Wörter sind durch +% Unterstriche getrennt) umzuwandeln, geben sie in der Optionentabelle +% \lua{snake} an. +To make all keys \emph{snake case} (The words are separated by +underscores), specify \lua{snake} in the options +table. \InputLua[firstline=11,lastline=12]{opts/format-keys.lua} -\item[upper] \strut +\item[upper] + +% Um alle Schlüssel in \emph{Grossbuchstaben} umzuwandeln, geben sie in der +% Optionentabelle \lua{upper} an. +To convert all keys to \emph{uppercase}, specify \lua{upper} in the +options table. \InputLua[firstline=18,lastline=19]{opts/format-keys.lua} \end{description} +% Sie können auch mehrere Formatierungsarten kombinieren. +You can also combine several types of formatting. + +\InputLua[firstline=25,lastline=26]{opts/format-keys.lua} + \DefaultOptDescription{format_keys} %% % %% +\subsubsection{Option “\texttt{group_begin}”} +\label{option:group-begin} + +The option \lua{group_begin} configures the delimiter that marks the +beginning of a group. The default value of this option is \texttt{"\{"}. +A code example can be found in section \ref{options-delimiter}. + +%% +% +%% + +\subsubsection{Option “\texttt{group_end}”} +\label{option:group-end} + +The option \lua{group_end} configures the delimiter that marks the end +of a group. The default value of this option is \texttt{"\}"}. A code +example can be found in section \ref{options-delimiter}. + +%% +% +%% + \subsubsection{Option “\texttt{hooks}”} % Die folgenden Hooks bzw. Callback-Funktionen ermöglichen es in den @@ -623,6 +699,18 @@ as a parameter. % %% +\subsubsection{Option “\texttt{list_separator}”} +\label{option:list-separator} + +The option \lua{list_separator} configures the delimiter that separates +list items from each other. The default value of this option is +\texttt{","}. A code example can be found in section +\ref{options-delimiter}. + +%% +% +%% + \subsubsection{Option “\texttt{naked_as_value}”} % Mit Hilfe der Option \lua{naked_as_value} werden nackte Schlüssel @@ -665,13 +753,37 @@ If we set the option \lua{no_error} to \lua{true}: % %% +\subsubsection{Option “\texttt{quotation_begin}”} +\label{option:quotation-begin} + +The option \lua{quotation_begin} configures the delimiter that marks the +beginning of a string. The default value of this option is +\texttt{'"'} (double quotes). A code example can be found in section +\ref{options-delimiter}. + +%% +% +%% + +\subsubsection{Option “\texttt{quotation_end}”} +\label{option:quotation-end} + +The option \lua{quotation_end} configures the delimiter that marks the +end of a string. The default value of this option is \texttt{'"'} +(double quotes). A code example can be found in section +\ref{options-delimiter}. + +%% +% +%% + \subsubsection{Option “\texttt{unpack}”} % Mit Hilfe der Option \lua{unpack} werden alle Tabellen, die nur aus % einem einzigen nackten Schlüssel bzw. einen einzigen alleinstehenden % Wert bestehen, aufgelöst. With the help of the option \lua{unpack}, all tables that consist of -only one a single naked key or a single standalone value are unpacked. +only a single naked key or a single standalone value are unpacked. \InputLua[firstline=4,lastline=5]{opts/unpack.lua} @@ -1816,6 +1928,12 @@ An example of how to use the command in \LaTeX: that means scan for tokens that are enclosed in square brackets * extend and improve documentation } +\changes{0.8.0}{2022/11/17}{ +* Add 6 new options to change the delimiters: “assignment_operator”, + “group_begin”, “group_end”, “list_separator”, “quotation_begin”, + “quotation_end”. +* Extend the documentation about the option “format_keys”. +} \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 1a26a664504..5f8cc808f52 100644 --- a/Master/texmf-dist/tex/luatex/luakeys/luakeys-debug.sty +++ b/Master/texmf-dist/tex/luatex/luakeys/luakeys-debug.sty @@ -17,6 +17,6 @@ % luakeys-debug.sty and luakeys-debug.tex. \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{luakeys-debug}[2022/07/06 0.7.0 Debug package for luakeys.] +\ProvidesPackage{luakeys-debug}[2022/11/17 0.8.0 Debug package for luakeys.] \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 3221fc3efdb..8b065289de8 100644 --- a/Master/texmf-dist/tex/luatex/luakeys/luakeys.lua +++ b/Master/texmf-dist/tex/luatex/luakeys/luakeys.lua @@ -172,15 +172,21 @@ local utils = { local namespace = { opts = { + assignment_operator = '=', convert_dimensions = false, debug = false, default = true, defaults = false, defs = false, format_keys = false, + group_begin = '{', + group_end = '}', hooks = {}, + list_separator = ',', naked_as_value = false, no_error = false, + quotation_begin = '"', + quotation_end = '"', unpack = true, }, @@ -224,6 +230,38 @@ local function throw_error(message) end end +--- Normalize the parse options. +--- +---@param opts? table # Options in a raw format. The table may be empty or some keys are not set. +--- +---@return table +local function normalize_opts(opts) + if type(opts) ~= 'table' then + opts = {} + end + for key, _ in pairs(opts) do + if namespace.opts[key] == nil then + throw_error('Unknown parse option: ' .. tostring(key) .. '!') + end + end + local old_opts = opts + opts = {} + for name, _ in pairs(namespace.opts) do + if old_opts[name] ~= nil then + opts[name] = old_opts[name] + else + opts[name] = default_options[name] + end + end + + for hook in pairs(opts.hooks) do + if namespace.hooks[hook] == nil then + throw_error('Unknown hook: ' .. tostring(hook) .. '!') + end + end + return opts +end + local l3_code_cctab = 10 --- Convert back to strings @@ -375,13 +413,12 @@ end --- * [TUGboat article: Parsing complex data formats in LuaTEX with LPEG](https://tug.or-g/TUGboat/tb40-2/tb125menke-Patterndf) --- ---@param initial_rule string # The name of the first rule of the grammar table passed to the `lpeg.P(attern)` function (e. g. `list`, `number`). ----@param convert_dimensions? boolean # Whether the dimensions should be converted to scaled points (by default `false`). +---@param opts? table # Whether the dimensions should be converted to scaled points (by default `false`). --- ---@return userdata # The parser. -local function generate_parser(initial_rule, - convert_dimensions) - if convert_dimensions == nil then - convert_dimensions = false +local function generate_parser(initial_rule, opts) + if type(opts) ~= 'table' then + opts = normalize_opts(opts) end local Variable = lpeg.V @@ -413,7 +450,7 @@ local function generate_parser(initial_rule, input = input:gsub('%s+', '') -- Convert the unit string into lowercase. input = input:lower() - if convert_dimensions then + if opts.convert_dimensions then return tex.sp(input) else return input @@ -458,7 +495,7 @@ local function generate_parser(initial_rule, -- '{' list '}' list_container = - ws('{') * Variable('list') * ws('}'), + ws(opts.group_begin) * Variable('list') * ws(opts.group_end), -- ( list_container / key_value_pair / value ) ','? list_item = @@ -466,11 +503,11 @@ local function generate_parser(initial_rule, Variable('list_container') + Variable('key_value_pair') + Variable('value') - ) * ws(',')^-1, + ) * ws(opts.list_separator)^-1, -- key '=' (list_container / value) key_value_pair = - (Variable('key') * ws('=')) * (Variable('list_container') + Variable('value')), + (Variable('key') * ws(opts.assignment_operator)) * (Variable('list_container') + Variable('value')), -- number / string_quoted / string_unquoted key = @@ -555,9 +592,9 @@ local function generate_parser(initial_rule, -- '"' ('\"' / !'"')* '"' string_quoted = - white_space^0 * Pattern('"') * - CaptureSimple((Pattern('\\"') + 1 - Pattern('"'))^0) * - Pattern('"') * white_space^0, + white_space^0 * Pattern(opts.quotation_begin) * + CaptureSimple((Pattern('\\' .. opts.quotation_end) + 1 - Pattern(opts.quotation_end))^0) * + Pattern(opts.quotation_end) * white_space^0, string_unquoted = white_space^0 * @@ -566,7 +603,11 @@ local function generate_parser(initial_rule, (Set(' \t')^1 * Variable('word_unquoted')^1)^0) * white_space^0, - word_unquoted = (1 - white_space - Set('{},='))^1 + word_unquoted = (1 - white_space - Set( + opts.group_begin .. + opts.group_end .. + opts.assignment_operator .. + opts.list_separator))^1 }) -- LuaFormatter on end @@ -614,7 +655,7 @@ local is = { if type(value) == 'boolean' then return true end - local parser = generate_parser('boolean_only', false) + local parser = generate_parser('boolean_only') local result = parser:match(tostring(value)) return result ~= nil end, @@ -623,7 +664,7 @@ local is = { if value == nil then return false end - local parser = generate_parser('dimension_only', false) + local parser = generate_parser('dimension_only') local result = parser:match(tostring(value)) return result ~= nil end, @@ -643,7 +684,7 @@ local is = { if type(value) == 'number' then return true end - local parser = generate_parser('number_only', false) + local parser = generate_parser('number_only') local result = parser:match(tostring(value)) return result ~= nil end, @@ -778,7 +819,10 @@ local function apply_definitions(defs, -- integer elseif def.data_type == 'integer' then if is.number(value) then - converted = math.floor(tonumber(value)) + local n = tonumber(value) + if type(n) == 'number' and n ~= nil then + converted = math.floor(n) + end end -- number elseif def.data_type == 'number' then @@ -1038,7 +1082,7 @@ end --- Parse a LaTeX/TeX style key-value string into a Lua table. --- ---@param kv_string string # A string in the TeX/LaTeX style key-value format as described above. ----@param opts table # A table containing the settings: +---@param opts? table # A table containing the settings: --- `convert_dimensions`, `unpack`, `naked_as_value`, `converter`, --- `debug`, `preprocess`, `postprocess`. -- @@ -1047,48 +1091,16 @@ end ---@return table raw # The unprocessed, raw result of the LPeg parser. local function parse(kv_string, opts) if kv_string == nil then - return {} + return {}, {}, {} end - --- Normalize the parse options. - --- - ---@param opts table # Options in a raw format. The table may be empty or some keys are not set. - --- - ---@return table - local function normalize_opts(opts) - if type(opts) ~= 'table' then - opts = {} - end - for key, _ in pairs(opts) do - if namespace.opts[key] == nil then - throw_error('Unknown parse option: ' .. tostring(key) .. '!') - end - end - local old_opts = opts - opts = {} - for name, _ in pairs(namespace.opts) do - if old_opts[name] ~= nil then - opts[name] = old_opts[name] - else - opts[name] = default_options[name] - end - end - - for hook in pairs(opts.hooks) do - if namespace.hooks[hook] == nil then - throw_error('Unknown hook: ' .. tostring(hook) .. '!') - end - end - return opts - end opts = normalize_opts(opts) if type(opts.hooks.kv_string) == 'function' then kv_string = opts.hooks.kv_string(kv_string) end - local result = generate_parser('list', opts.convert_dimensions):match( - kv_string) + local result = generate_parser('list', opts):match(kv_string) local raw = clone_table(result) local function apply_hook(name) @@ -1218,7 +1230,7 @@ local result_store = {} -- @section local export = { - version = { 0, 7, 0 }, + version = { 0, 8, 0 }, namespace = namespace, diff --git a/Master/texmf-dist/tex/luatex/luakeys/luakeys.sty b/Master/texmf-dist/tex/luatex/luakeys/luakeys.sty index d0917f1d9d5..68c3892ee43 100644 --- a/Master/texmf-dist/tex/luatex/luakeys/luakeys.sty +++ b/Master/texmf-dist/tex/luatex/luakeys/luakeys.sty @@ -17,5 +17,5 @@ % luakeys-debug.sty and luakeys-debug.tex. \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{luakeys}[2022/07/06 0.7.0 Parsing key-value options using Lua.] +\ProvidesPackage{luakeys}[2022/11/17 0.8.0 Parsing key-value options using Lua.] \directlua{luakeys = require('luakeys')} -- cgit v1.2.3