summaryrefslogtreecommitdiff
path: root/macros/luatex/latex/luaprogtable/luaprogtable-utility.lua
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2020-08-15 03:01:13 +0000
committerNorbert Preining <norbert@preining.info>2020-08-15 03:01:13 +0000
commit1dfccec61618ca50bcd43f066778f9f3900924ec (patch)
tree003d84c37eaa6bc142b0507c45023c93cb2d8bb2 /macros/luatex/latex/luaprogtable/luaprogtable-utility.lua
parent02ead80143e7082dee86522ac65a59443428bd7b (diff)
CTAN sync 202008150301
Diffstat (limited to 'macros/luatex/latex/luaprogtable/luaprogtable-utility.lua')
-rw-r--r--macros/luatex/latex/luaprogtable/luaprogtable-utility.lua109
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
+