texlive[62904] Master/texmf-dist: luakeys (4apr22)

commits+karl at tug.org commits+karl at tug.org
Mon Apr 4 22:56:44 CEST 2022


Revision: 62904
          http://tug.org/svn/texlive?view=revision&revision=62904
Author:   karl
Date:     2022-04-04 22:56:44 +0200 (Mon, 04 Apr 2022)
Log Message:
-----------
luakeys (4apr22)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/luatex/luakeys/luakeys-doc.pdf
    trunk/Master/texmf-dist/doc/luatex/luakeys/luakeys-doc.tex
    trunk/Master/texmf-dist/tex/luatex/luakeys/luakeys-debug.sty
    trunk/Master/texmf-dist/tex/luatex/luakeys/luakeys.lua
    trunk/Master/texmf-dist/tex/luatex/luakeys/luakeys.sty

Modified: trunk/Master/texmf-dist/doc/luatex/luakeys/luakeys-doc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/luatex/luakeys/luakeys-doc.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luakeys/luakeys-doc.tex	2022-04-04 20:56:29 UTC (rev 62903)
+++ trunk/Master/texmf-dist/doc/luatex/luakeys/luakeys-doc.tex	2022-04-04 20:56:44 UTC (rev 62904)
@@ -30,7 +30,7 @@
   \url{josef at friedrich.rocks}\\%
   \href{https://github.com/Josef-Friedrich/luakeys}{github.com/Josef-Friedrich/luakeys}%
 }
-\date{v0.4 from 2021/12/31}
+\date{v0.5 from 2022/04/04}
 
 \maketitle
 
@@ -526,16 +526,34 @@
 \end{minted}
 
 \noindent
-The function can be called with a options table. This two options are
-supported.
+The function can be called with an options table. This options are
+supported:
 
 \begin{minted}{lua}
 local result = parse('one,two,three', {
   convert_dimensions = false,
-  unpack_single_array_value = false
+  unpack_single_array_value = false,
+  standalone_as_true = false,
+  converter = function(key, value, depth, current_table, root_table)
+    return key, value
+  end,
+  case_insensitive_keys = false,
 })
 \end{minted}
 
+\noindent
+The options can also be set globally using the exported table
+|default_options|:
+
+\begin{minted}{lua}
+luakeys.parse('dim=1cm') -- {dim = 1864679}
+luakeys.default_options.convert_dimensions = false
+-- or:
+-- local defaults = luakeys.default_options
+-- defaults.convert_dimensions = false
+luakeys.parse('dim=1cm') -- {dim = '1cm'}
+\end{minted}
+
 %%
 %
 %%
@@ -695,6 +713,26 @@
 
 \clearpage
 
+\subsection{luakeys.tex}
+
+\inputminted[linenos=true]{latex}{luakeys.tex}
+
+%%
+%
+%%
+
+\clearpage
+
+\subsection{luakeys.tex}
+
+\inputminted[linenos=true]{latex}{luakeys.tex}
+
+%%
+%
+%%
+
+\clearpage
+
 \subsection{luakeys-debug.tex}
 
 \inputminted[linenos=true]{latex}{luakeys-debug.tex}
@@ -726,6 +764,12 @@
 * Parser: Remove support from Lua numbers with exponents (for example '5e+20')
 * Switch the Lua testing framework to busted
 }
+\changes{v0.5}{2022/04/04}{
+* Add possibility to change options globally
+* New option: standalone\_as\_true
+* Add a recursive converter callback / hook to process the parse tree
+* New option: case\_insensitive\_keys
+}
 \pagebreak
 \PrintChanges
 \pagebreak

Modified: trunk/Master/texmf-dist/tex/luatex/luakeys/luakeys-debug.sty
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/luakeys/luakeys-debug.sty	2022-04-04 20:56:29 UTC (rev 62903)
+++ trunk/Master/texmf-dist/tex/luatex/luakeys/luakeys-debug.sty	2022-04-04 20:56:44 UTC (rev 62904)
@@ -17,6 +17,6 @@
 % luakeys-debug.sty and luakeys-debug.tex.
 
 \NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{luakeys-debug}[2021/12/31 v0.4 Debug package for luakeys.]
+\ProvidesPackage{luakeys-debug}[2022/04/04 v0.5 Debug package for luakeys.]
 
 \input luakeys-debug.tex

Modified: trunk/Master/texmf-dist/tex/luatex/luakeys/luakeys.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/luakeys/luakeys.lua	2022-04-04 20:56:29 UTC (rev 62903)
+++ trunk/Master/texmf-dist/tex/luatex/luakeys/luakeys.lua	2022-04-04 20:56:44 UTC (rev 62904)
@@ -50,9 +50,90 @@
   end
 end
 
---- A table to store parsed key-value results.
-local result_store = {}
+--- Option handling
+-- @section
 
+--- This table stores all allowed option keys.
+local option_keys = {
+  'convert_dimensions',
+  'unpack_single_array_values',
+  'standalone_as_true',
+  'converter',
+  'case_insensitive_keys'
+}
+
+--- The default options.
+local default_options = {
+  convert_dimensions = true,
+  unpack_single_array_values = true,
+  standalone_as_true = false,
+}
+
+local function throw_error(message)
+  if type(tex.error) == 'function' then
+    tex.error(message)
+  else
+    error(message)
+  end
+end
+
+--- Convert a key so that it can be written as a table field without
+--  quotes and square brackets (for example `one 2` becomes `one_2`).
+--  The key can then reference values from a table using dot notation.
+--  (`table["one 2"]` becomes `table.one_2`).
+--
+-- @tparam string key The key to be converted.
+--
+-- @treturn string The converted key.
+local function luafy_key(key)
+  return key:gsub('[^%w]+', '_')
+end
+
+--- Convert all keys in a table to strings containig only alphanumeric
+-- characters and underscores.
+--
+-- @param raw_options Some raw options.
+--
+-- @treturn table Returns always a table. If the input value is not a
+-- an empty table is returned.
+local function luafy_options(raw_options)
+  if type(raw_options) ~= 'table' then
+    raw_options = {}
+  end
+  local options = {}
+  for key, value in pairs(raw_options) do
+    options[luafy_key(key)] = value
+  end
+  return options
+end
+
+--- All option keys can be written with underscores or with spaces as
+-- separators.
+-- For the LaTeX version of the macro
+--  `\luakeysdebug[options]{kv-string}`.
+--
+-- @tparam table options_raw Options in a raw format. The table may be
+-- empty or some keys are not set.
+--
+-- @treturn table
+local function normalize_parse_options (options_raw)
+  options_raw = luafy_options(options_raw)
+  local options = {}
+
+  for _, option_name in ipairs(option_keys) do
+    if options_raw[option_name] ~= nil then
+      options[option_name] = options_raw[option_name]
+    else
+      options[option_name] = default_options[option_name]
+    end
+  end
+
+  return options
+end
+
+--- Parser / Lpeg related
+-- @section
+
 --- Generate the PEG parser using Lpeg.
 --
 -- @treturn userdata The parser.
@@ -244,11 +325,11 @@
 end
 
 --- Unpack a single valued array table like `{ 'one' }` into `one` or
--- `{ 1 }` into `into`.
+-- `{ 1 }` into `1`.
 --
 -- @treturn If the value is a array like table with one non table typed
 -- value in it, the unpacked value, else the unchanged input.
-local function unpack_single_valued_array_table(value)
+local function unpack_single_valued_array_table(value, options)
   if
     type(value) == 'table' and
     get_array_size(value) == 1 and
@@ -255,16 +336,44 @@
     get_table_size(value) == 1 and
     type(value[1]) ~= 'table'
   then
-    return value[1]
+    if type(value[1]) == 'string' and options.standalone_as_true then
+      return value
+    else
+      return value[1]
+    end
   end
   return value
 end
 
---- This normalization tasks are performed on the raw input table coming
---  directly from the PEG parser:
+local function visit_parse_tree(parse_tree, callback_func)
+  if type(parse_tree) ~= 'table' then
+    throw_error('Parse tree has to be a table')
+  end
+  local function visit_parse_tree_recursive(root_table, current_table, result, depth, callback_func)
+    for key, value in pairs(current_table) do
+      if type(value) == 'table' then
+        value = visit_parse_tree_recursive(root_table, value, {}, depth + 1, callback_func)
+      end
+
+      key, value = callback_func(key, value, depth, current_table, root_table)
+
+      if key ~= nil and value ~= nil then
+        result[key] = value
+      end
+    end
+    if next(result) ~= nil then
+      return result
+    end
+  end
+
+  return visit_parse_tree_recursive(parse_tree, parse_tree, {}, 1, callback_func)
+end
+
+--- Normalize the result tables of the LPeg 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
+-- * Unpack all single valued array like tables: `{ 'text' }` into
 --    `text`
 --
 -- @tparam table raw The raw input table coming directly from the PEG
@@ -278,7 +387,7 @@
   local function normalize_recursive(raw, result, options)
     for key, value in pairs(raw) do
       if options.unpack_single_array_values then
-        value = unpack_single_valued_array_table(value)
+        value = unpack_single_valued_array_table(value, options)
       end
       if type(value) == 'table' then
         result[key] = normalize_recursive(value, {}, options)
@@ -288,9 +397,134 @@
     end
     return result
   end
-  return normalize_recursive(raw, {}, options)
+  raw = normalize_recursive(raw, {}, options)
+
+  if options.standalone_as_true then
+    raw = visit_parse_tree(raw, function (key, value)
+      if type(key) == 'number' and type(value) == 'string' then
+        return value, true
+      end
+      return key, value
+    end)
+  end
+
+  if options.case_insensitive_keys then
+    raw = visit_parse_tree(raw, function (key, value)
+      if type(key) == 'string' then
+        return key:lower(), value
+      end
+      return key, value
+    end)
+  end
+
+  return raw
 end
 
+--- Parse a LaTeX/TeX style key-value string into a Lua table. With
+-- this function you should be able to parse key-value strings like
+-- this example:
+--
+--     show,
+--     hide,
+--     key with spaces = String without quotes,
+--     string="String with double quotes: ,{}=",
+--     dimension = 1cm,
+--     number = -1.2,
+--     list = {one,two,three},
+--     key value list = {one=one,two=two,three=three},
+--     nested key = {
+--       nested key 2= {
+--         key = value,
+--       },
+--     },
+--
+-- The string above results in this Lua table:
+--
+--     {
+--       'show',
+--       'hide',
+--       ['key with spaces'] = 'String without quotes',
+--       string = 'String with double quotes: ,{}=',
+--       dimension = 1864679,
+--       number = -1.2,
+--       list = {'one', 'two', 'three'},
+--       key value list = {
+--         one = 'one',
+--         three = 'three',
+--         two = 'two'
+--       },
+--       ['nested key'] = {
+--         ['nested key 2'] = {
+--           key = 'value'
+--         }
+--       },
+--     }
+--
+-- @tparam string kv_string A string in the TeX/LaTeX style key-value
+--   format as described above.
+--
+-- @tparam table options A table containing
+-- settings: `convert_dimensions`, `unpack_single_array_values`, `standalone_as_true`, `converter`
+--
+-- @treturn table A hopefully properly parsed table you can do
+-- something useful with.
+local function parse (kv_string, options)
+  if kv_string == nil then
+    return {}
+  end
+  options = normalize_parse_options(options)
+
+  local parser = generate_parser(options)
+  local parse_tree = parser:match(kv_string)
+
+  if options.converter ~= nil and type(options.converter) == 'function' then
+    parse_tree = visit_parse_tree(parse_tree, options.converter)
+  end
+  return normalize(parse_tree, options)
+end
+
+--- Convert back to strings
+-- @section
+
+--- The function `render(tbl)` reverses the function
+--  `parse(kv_string)`. It takes a Lua table and converts this table
+--  into a key-value string. The resulting string usually has a
+--  different order as the input table. In Lua only tables with
+--  1-based consecutive integer keys (a.k.a. array tables) can be
+--  parsed in order.
+--
+-- @tparam table tbl A table to be converted into a key-value string.
+--
+-- @treturn string A key-value string that can be passed to a TeX
+-- macro.
+local function render (tbl)
+  local function render_inner(tbl)
+    local output = {}
+    local function add(text)
+      table.insert(output, text)
+    end
+    for key, value in pairs(tbl) do
+      if (key and type(key) == 'string') then
+        if (type(value) == 'table') then
+          if (next(value)) then
+            add(key .. '={')
+            add(render_inner(value))
+            add('},')
+          else
+            add(key .. '={},')
+          end
+        else
+          add(key .. '=' .. tostring(value) .. ',')
+        end
+      else
+        add(tostring(value) .. ',')
+      end
+    end
+    return table.concat(output)
+  end
+  return render_inner(tbl)
+end
+
 --- The function `stringify(tbl, for_tex)` converts a Lua table into a
 --   printable string. Stringify a table means to convert the table into
 --   a string. This function is used to realize the `print` function.
@@ -371,171 +605,84 @@
   return start_bracket .. line_break .. stringify_inner(input, 1) .. line_break .. end_bracket
 end
 
---- For the LaTeX version of the macro
---  `\luakeysdebug[options]{kv-string}`.
+--- The function `pretty_print(tbl)` pretty prints a Lua table to standard
+--   output (stdout). It is a utility function that can be used to
+--   debug and inspect the resulting Lua table of the function
+--   `parse`. You have to compile your TeX document in a console to
+--   see the terminal output.
 --
--- @tparam table options_raw Options in a raw format. The table may be
--- empty or some keys are not set.
---
--- @treturn table
-local function normalize_parse_options (options_raw)
-  if options_raw == nil then
-    options_raw = {}
-  end
-  local options = {}
+-- @tparam table tbl A table to be printed to standard output for
+-- debugging purposes.
+local function pretty_print(tbl)
+  print(stringify(tbl, false))
+end
 
-  if options_raw['unpack single array values'] ~= nil then
-    options['unpack_single_array_values'] = options_raw['unpack single array values']
-  end
+--- Store results
+-- @section
 
-  if options_raw['convert dimensions'] ~= nil then
-    options['convert_dimensions'] = options_raw['convert dimensions']
-  end
+--- A table to store parsed key-value results.
+local result_store = {}
 
-  if options.convert_dimensions == nil then
-    options.convert_dimensions = true
-  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.
+local function save(identifier, result)
+  result_store[identifier] = result
+end
 
-  if options.unpack_single_array_values == nil then
-    options.unpack_single_array_values = true
-  end
-
-  return options
+--- The function `get(identifier): table` retrieves a saved result
+--  from the result store.
+--
+-- @tparam string identifier The identifier under which the result was
+--   saved.
+local function get(identifier)
+  -- if result_store[identifier] == nil then
+  --   throw_error('No stored result was found for the identifier \'' .. identifier .. '\'')
+  -- end
+  return result_store[identifier]
 end
 
-return {
+--- Exports
+-- @section
+
+local export = {
+  --- @see default_options
+  default_options = default_options,
+
+  --- @see stringify
   stringify = stringify,
 
-  --- Parse a LaTeX/TeX style key-value string into a Lua table. With
-  -- this function you should be able to parse key-value strings like
-  -- this example:
-  --
-  --     show,
-  --     hide,
-  --     key with spaces = String without quotes,
-  --     string="String with double quotes: ,{}=",
-  --     dimension = 1cm,
-  --     number = -1.2,
-  --     list = {one,two,three},
-  --     key value list = {one=one,two=two,three=three},
-  --     nested key = {
-  --       nested key 2= {
-  --         key = value,
-  --       },
-  --     },
-  --
-  -- The string above results in this Lua table:
-  --
-  --     {
-  --       'show',
-  --       'hide',
-  --       ['key with spaces'] = 'String without quotes',
-  --       string = 'String with double quotes: ,{}=',
-  --       dimension = 1864679,
-  --       number = -1.2,
-  --       list = {'one', 'two', 'three'},
-  --       key value list = {
-  --         one = 'one',
-  --         three = 'three',
-  --         two = 'two'
-  --       },
-  --       ['nested key'] = {
-  --         ['nested key 2'] = {
-  --           key = 'value'
-  --         }
-  --       },
-  --     }
-  --
-  -- @tparam string kv_string A string in the TeX/LaTeX style key-value
-  --   format as described above.
-  --
-  -- @tparam table options A table containing
-  -- settings: `convert_dimensions` `unpack_single_array_values`
-  --
-  -- @treturn table A hopefully properly parsed table you can do
-  -- something useful with.
-  parse = function (kv_string, options)
-    if kv_string == nil then
-      return {}
-    end
-    options = normalize_parse_options(options)
+  --- @see parse
+  parse = parse,
 
-    local parser = generate_parser(options)
-    return normalize(parser:match(kv_string), options)
-  end,
+  --- @see render
+  render = render,
 
-  --- The function `render(tbl)` reverses the function
-  --  `parse(kv_string)`. It takes a Lua table and converts this table
-  --  into a key-value string. The resulting string usually has a
-  --  different order as the input table. In Lua only tables with
-  --  1-based consecutive integer keys (a.k.a. array tables) can be
-  --  parsed in order.
-  --
-  -- @tparam table tbl A table to be converted into a key-value string.
-  --
-  -- @treturn string A key-value string that can be passed to a TeX
-  -- macro.
-  render = function (tbl)
-    local function render_inner(tbl)
-      local output = {}
-      local function add(text)
-        table.insert(output, text)
-      end
-      for key, value in pairs(tbl) do
-        if (key and type(key) == 'string') then
-          if (type(value) == 'table') then
-            if (next(value)) then
-              add(key .. '={')
-              add(render_inner(value))
-              add('},')
-            else
-              add(key .. '={},')
-            end
-          else
-            add(key .. '=' .. tostring(value) .. ',')
-          end
-        else
-          add(tostring(value) .. ',')
-        end
-      end
-      return table.concat(output)
-    end
-    return render_inner(tbl)
-  end,
+  --- @see pretty_print
+  print = pretty_print,
 
-  --- The function `print(tbl)` pretty prints a Lua table to standard
-  --   output (stdout). It is a utility function that can be used to
-  --   debug and inspect the resulting Lua table of the function
-  --   `parse`. You have to compile your TeX document in a console to
-  --   see the terminal output.
-  --
-  -- @tparam table tbl A table to be printed to standard output for
-  -- debugging purposes.
-  print = function(tbl)
-    print(stringify(tbl, false))
-  end,
+  --- @see save
+  save = save,
 
-  --- 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,
+  --- @see get
+  get = get,
+}
 
-  --- 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,
+-- http://olivinelabs.com/busted/#private
+if _TEST then
+  export.luafy_key = luafy_key
+  export.luafy_options = luafy_options
+  export.normalize = normalize
+  export.normalize_parse_options = normalize_parse_options
+  export.unpack_single_valued_array_table = unpack_single_valued_array_table
+  export.visit_parse_tree = visit_parse_tree
+end
 
-}
+return export

Modified: trunk/Master/texmf-dist/tex/luatex/luakeys/luakeys.sty
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/luakeys/luakeys.sty	2022-04-04 20:56:29 UTC (rev 62903)
+++ trunk/Master/texmf-dist/tex/luatex/luakeys/luakeys.sty	2022-04-04 20:56:44 UTC (rev 62904)
@@ -17,5 +17,5 @@
 % luakeys-debug.sty and luakeys-debug.tex.
 
 \NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{luakeys}[2021/12/31 v0.4 Parsing key-value options using Lua.]
+\ProvidesPackage{luakeys}[2022/04/04 v0.5 Parsing key-value options using Lua.]
 \directlua{luakeys = require('luakeys')}



More information about the tex-live-commits mailing list.