Lua
Tables
Sorting
Create an iterator
function utils.spairs(t, order)
-- collect the keys
local keys = {}
for k in pairs(t) do keys[#keys + 1] = k end
-- if order function given, sort by it by passing the table and keys a, b,
-- otherwise just sort the keys
if order then
table.sort(keys, function(a, b) return order(t, a, b) end)
else
table.sort(keys)
end
-- return the iterator function
local i = 0
return function()
i = i + 1
if keys![](i) then
return keys![t[keys[i](i])]
end
end
end
Example usage (from {mmx}):
local function make_sorted_entry_iterator(entries)
return utils.spairs(entries, function(es, name_a, name_b)
local entry_a = es![](name_a)
local entry_b = es![](name_b)
if entry_a.date or entry_b.date then
return (entry_a.date or MIN_DATE) > (entry_b.date or MIN_DATE)
else
return name_a < name_b
end
end)
end
utils.lua
local utils = {}
-- file io
function utils.file_exists(path)
local file = io.open(path, "r")
if file ~= nil then
file:close()
return true
else
return false
end
end
function utils.read_file(path)
local file = io.open(path, "rb") -- r read mode and b binary mode
if not file then
error("unable to open file for reading at " .. path)
end
local content = file:read "*a" -- *a or *all reads the whole file
file:close()
return content
end
function utils.write_file(path, content)
local file = io.open(path, "w")
if not file then
error("unable to open file for writing at " .. path)
end
file:write(content)
file:close()
end
function utils.delete_file(path)
assert(os.remove(path))
end
function utils.list_folders(directory)
local pfile = io.popen('cd ' .. directory .. ' && find ' .. directory .. ' -type d')
if not pfile then
error("unable to list folders in directory " .. directory)
end
local folder_names = {}
for folder_name in pfile:lines() do
folder_name = folder_name:sub(#directory + 1)
if not utils.starts_with(folder_name, '.') and #folder_name > 0 then
table.insert(folder_names, folder_name)
end
end
pfile:close()
return folder_names
end
function utils.list_files(directory, extension)
-- resulting command is:
-- find [dir] -type f -name "*.[ext]"
local pfile = io.popen('find -L ' .. directory .. ' -type f -name "*' .. (extension or "") .. '"')
if not pfile then
error("unable to list files in directory " .. directory .. " with extension " .. extension)
end
local file_names = {}
for file_name in pfile:lines() do
file_name = file_name:sub(#directory + 1)
table.insert(file_names, file_name)
end
pfile:close()
return file_names
end
-- strings
function utils.starts_with(str, start)
return str:sub(1, #start) == start
end
function utils.ends_with(str, ending)
return ending == "" or str:sub(-#ending) == ending
end
function utils.lines(str)
if str:sub(-1) ~= "\n" then
str = str .. "\n"
end
return str:gmatch("(.-)\n")
end
function utils.split(input, sep)
if sep == nil then
sep = "%s"
end
local t = {}
for str in string.gmatch(input, "([^" .. sep .. "]+)") do
table.insert(t, str)
end
return t
end
function utils.capitalize(str)
return (str:gsub("^%l", string.upper))
end
function utils.title_case(str)
return utils.capitalize(str:gsub(" %l", string.upper))
end
function utils.slugify(str)
return (str:gsub("[%s%p]", "_")):lower()
end
-- tables
function utils.has_keys(table, keys)
for _, key in pairs(keys) do
if table[key] == nil then
return false
end
end
return true
end
function utils.get_key_case_insensitive(table, key)
return table[key] or table[utils.capitalize(key)] or table[key:lower()] or table[key:upper()] or
table[utils.title_case(key)]
end
function utils.spairs(t, order)
-- collect the keys
local keys = {}
for k in pairs(t) do
keys[#keys + 1] = k
end
-- if order function given, sort by it by passing the table and keys a, b,
-- otherwise just sort the keys
if order then
table.sort(keys, function(a, b)
return order(t, a, b)
end)
else
table.sort(keys)
end
-- return the iterator function
local i = 0
return function()
i = i + 1
if keys[i] then
return keys[i], t[keys[i]]
end
end
end
function utils.dump(o)
if type(o) == 'table' then
local s = '{ '
for k, v in pairs(o) do
if type(k) ~= 'number' then
k = '"' .. k .. '"'
end
s = s .. '[' .. k .. '] = ' .. utils.dump(v) .. ','
end
return s .. '} '
else
return tostring(o)
end
end
-- dates
function utils.today()
local date_table = os.date("*t")
local year, month, day = date_table.year, date_table.month, date_table.day -- date_table.wday to date_table.day
return string.format("%d-%d-%d", year, month, day)
end
function utils.rss_date(date_str)
local handle = io.popen("date -R -d " .. date_str)
if not handle then
error("unable to run command in rss_date")
end
local result = handle:read("*a")
handle:close()
return result
end
return utils
Compiled 2024-04-21