diff options
author | Norbert Preining <norbert@preining.info> | 2020-08-15 03:01:13 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2020-08-15 03:01:13 +0000 |
commit | 1dfccec61618ca50bcd43f066778f9f3900924ec (patch) | |
tree | 003d84c37eaa6bc142b0507c45023c93cb2d8bb2 /macros/luatex/latex/luaprogtable/luaprogtable-utility.lua | |
parent | 02ead80143e7082dee86522ac65a59443428bd7b (diff) |
CTAN sync 202008150301
Diffstat (limited to 'macros/luatex/latex/luaprogtable/luaprogtable-utility.lua')
-rw-r--r-- | macros/luatex/latex/luaprogtable/luaprogtable-utility.lua | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/macros/luatex/latex/luaprogtable/luaprogtable-utility.lua b/macros/luatex/latex/luaprogtable/luaprogtable-utility.lua new file mode 100644 index 0000000000..4ac10f5fd5 --- /dev/null +++ b/macros/luatex/latex/luaprogtable/luaprogtable-utility.lua @@ -0,0 +1,109 @@ +inspect = require "inspect.lua" + +function raise_error(...) + local arg = {...} + local description = "a luaprogtable package exception occured:\n" .. table.concat(arg, ", ") + tex.error(description) + error(description) +end + +local _spacer = lpeg.S(" \t\f\v\n\r") +local _non_spacer = 1 - _spacer +local _stripper = _spacer^0 * lpeg.C((_spacer^0 * _non_spacer^1)^0) + + +function _lpt_strip(s) + return s and lpeg.match(_stripper,s) or "" +end + +function _lpt_split(s, sep) + sep = lpeg.P(sep) + local elem = lpeg.C((1 - sep)^0) + local p = lpeg.Ct(elem * (sep * elem)^0) -- make a table capture + return lpeg.match(p, s) +end + + +function _lpt_tonumber(s) + local n = tonumber(s) + if n == nil then + raise_error(string.format("'{%s}' is not a valid number expression", s)) + end + return n +end + + +function _lpt_parse_index_expr(expr) + local expr = _lpt_strip(expr) + local parts = _lpt_split(expr, ",") + local ret = {} + + for i=1,#parts do + local subexpr = _lpt_strip(parts[i]) + + if subexpr:len() == 0 then + raise_error(string.format("empty field in index expression '%s'", expr)) + end + + local colon_pos = subexpr:find(":") + local str_l = "" + local str_r = "" + + if colon_pos == nil then + str_l = subexpr + str_r = subexpr + else + local subsubexpr = _lpt_split(subexpr, ":") + str_l = _lpt_strip(subsubexpr[1]) + str_r = _lpt_strip(subsubexpr[2]) + if str_l:len() == 0 then + str_l = "1" + end + if str_r:len() == 0 then + str_r = "-1" + end + end + + local n_l = _lpt_tonumber(str_l) + local n_r = _lpt_tonumber(str_r) + + table.insert(ret, {n_l, n_r}) + end + + return ret +end + +function _lpt_parse_shape(shape_expr) + local shape_expr = _lpt_strip(shape_expr) + local parts = _lpt_split(shape_expr, ",") + if #parts ~= 2 then + raise_error(string.format("invalid shape: '%s'", shape_expr)) + end + local shape1 = _lpt_tonumber(parts[1]) + local shape2 = _lpt_tonumber(parts[2]) + if shape1 < 1 or shape2 < 1 then + raise_error(string.format("invalid shape: '%s'", shape_expr)) + end + return {shape1, shape2} +end + +function table.slice(tbl, first, last, step) + local sliced = {} + + for i = first or 1, last or #tbl, step or 1 do + sliced[#sliced+1] = tbl[i] + end + + return sliced +end + +function table.find(tbl, item, index) + for i=index or 1, #tbl do + local tbl_item = tbl[i] + if tbl_item == item then + return i + end + end + return nil +end + |