summaryrefslogtreecommitdiff
path: root/macros/luatex/generic/luakeys/luakeys.lua
diff options
context:
space:
mode:
Diffstat (limited to 'macros/luatex/generic/luakeys/luakeys.lua')
-rw-r--r--macros/luatex/generic/luakeys/luakeys.lua114
1 files changed, 72 insertions, 42 deletions
diff --git a/macros/luatex/generic/luakeys/luakeys.lua b/macros/luatex/generic/luakeys/luakeys.lua
index e4ecaab7f7..b026413800 100644
--- a/macros/luatex/generic/luakeys/luakeys.lua
+++ b/macros/luatex/generic/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,
+
}