Init
This commit is contained in:
commit
35c8a92b5a
|
@ -0,0 +1,23 @@
|
|||
package = "Dog"
|
||||
version = "1.0-0"
|
||||
source = {
|
||||
url = "ssh://git@git.cuates.net:2274/perro/lua-dog.git",
|
||||
tag = "v1.0.0",
|
||||
}
|
||||
description = {
|
||||
summary = "Lua extensions for lazy dogs",
|
||||
detailed = [[
|
||||
Adds functions to Lua Standard Libraries.
|
||||
]],
|
||||
homepage = "https://git.cuates.net/perro/lua-dog",
|
||||
license = "GPLv3",
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.4, < 5.5"
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
dog = "src/dog.lua"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,297 @@
|
|||
-- Tries popen
|
||||
-- @param ... string: Chunks for popen
|
||||
-- @return boolean, string: Status and output of popen
|
||||
function io.try(...)
|
||||
local cmd = table.concat({...}, " ") .. " 2>&1"
|
||||
local handle = io.popen(cmd)
|
||||
local output = handle:read("*a")
|
||||
local status = (handle:close() ~= nil and true or false)
|
||||
return status, output
|
||||
end
|
||||
|
||||
-- Gets OS short name
|
||||
-- It is just intented to know if it is Linux, macOS or Windows.
|
||||
-- @return string: "linux" or "bsd" or "macos" or "windows"
|
||||
function os.uname()
|
||||
local status, output = io.try("uname")
|
||||
if status then
|
||||
output = output:gsub(" .*", ""):lower()
|
||||
if output ~= "linux" and output:match("bsd") ~= nil then
|
||||
return "bsd"
|
||||
elseif out ~= "linux" then
|
||||
return "macos"
|
||||
end
|
||||
return "linux"
|
||||
end
|
||||
return "windows"
|
||||
end
|
||||
|
||||
-- Checks if OS is windows
|
||||
-- @return boolean: Windows or not
|
||||
function os.iswin()
|
||||
return os.uname() == "windows"
|
||||
end
|
||||
|
||||
-- Checks if OS is Unix
|
||||
-- @return boolean: Unix or not
|
||||
function os.isunix()
|
||||
return os.uname() ~= "windows"
|
||||
end
|
||||
|
||||
-- Gets OS language
|
||||
-- @return string, string, string: Language, locale and encoding
|
||||
function os.lang()
|
||||
local lang = os.getenv("LANG")
|
||||
if lang ~= nil then
|
||||
return lang:match("(%w%w)_?(%w?%w?)%.?(.*)")
|
||||
end
|
||||
return "en", "US", "UTF-8"
|
||||
end
|
||||
|
||||
-- Gets an equivalency table between ASCII and Unicode
|
||||
-- Note: filled on demand.
|
||||
-- @return table: ASCII-Unicode table equivalency
|
||||
function utf8.table()
|
||||
return {
|
||||
["a"] = {"á", "à", "ä"},
|
||||
["e"] = {"é", "è", "ë"},
|
||||
["i"] = {"í", "ì", "ï"},
|
||||
["o"] = {"ó", "ò", "ö"},
|
||||
["u"] = {"ú", "ù", "ü"},
|
||||
["n"] = {"ñ"},
|
||||
}
|
||||
end
|
||||
|
||||
-- Checks if string is empty
|
||||
-- @return boolean: Empty or not
|
||||
function string:isempty()
|
||||
return self == ''
|
||||
end
|
||||
|
||||
-- Changes newlines so everything is in one line
|
||||
-- @return string: String with formatted newlines as literal "\n"
|
||||
function string:linearize()
|
||||
return self:gsub("\n", "\\n")
|
||||
end
|
||||
|
||||
-- Normalizes string
|
||||
-- @return string: Normalized string
|
||||
function string:normalize()
|
||||
self = self:lower()
|
||||
for newchar, chars in pairs(utf8.table()) do
|
||||
for _, oldchar in ipairs(chars) do
|
||||
self = self:gsub(oldchar, newchar)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
-- Adds indent
|
||||
-- @param num number: Indent size, 2 by default
|
||||
-- @param char string: Indent character, space by default
|
||||
-- @return strin: Indented string
|
||||
function string:indent(num, char)
|
||||
num = num or 2
|
||||
char = char or " "
|
||||
char = string.rep(char, num)
|
||||
return char .. self:gsub("\n", "\n" .. char)
|
||||
end
|
||||
|
||||
-- Splits the string
|
||||
-- Note: only support splitting by one character.
|
||||
-- Could be solved by slicing with find.
|
||||
-- @param sep string: String separator, space by default
|
||||
-- @return table: String matches
|
||||
function string:split(sep)
|
||||
sep = sep or "%s+"
|
||||
local parts = {}
|
||||
for part in self:gmatch("([^" .. sep .. "]+)") do
|
||||
table.insert(parts, part)
|
||||
end
|
||||
return parts
|
||||
end
|
||||
|
||||
-- Removes spaces at the beginning of the string
|
||||
-- @return string: Left stripped string
|
||||
function string:lstrip()
|
||||
return self:gsub("^%s+", "")
|
||||
end
|
||||
|
||||
-- Removes spaces at the end of the string
|
||||
-- @return string: Right stripped string
|
||||
function string:rstrip()
|
||||
return self:gsub("%s+$", "")
|
||||
end
|
||||
|
||||
-- Removes spaces at the beginning and at the end of the string
|
||||
-- @return string: Stripped string
|
||||
function string:strip()
|
||||
self = self:lstrip():rstrip()
|
||||
return self
|
||||
end
|
||||
|
||||
-- Alias of strip
|
||||
function string:trim()
|
||||
return self:strip()
|
||||
end
|
||||
|
||||
-- The following are heavily influenced by Python pathlib
|
||||
-- Check: https://docs.python.org/3/library/pathlib.html
|
||||
|
||||
-- Checks if string is a file or a directory
|
||||
-- @return boolean: Exists or not
|
||||
function string:exists()
|
||||
return os.rename(self, self) ~= nil
|
||||
end
|
||||
|
||||
-- Checks if string is a file
|
||||
-- @return boolean: File or not
|
||||
function string:isfile()
|
||||
if self:exists() then
|
||||
return io.open(self, "a+") ~= nil
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Checks if string is a directory
|
||||
-- @return boolean: Directory or not
|
||||
function string:isdir()
|
||||
if self:exists() then
|
||||
return io.open(self, "a+") == nil
|
||||
elseif self == "." or self == ".." then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Reads file content as string
|
||||
-- @return string or nil: File as string or nil
|
||||
function string:readtext()
|
||||
if self:exists() then
|
||||
return io.open(self):read("*a")
|
||||
end
|
||||
end
|
||||
|
||||
-- Read file content as lines
|
||||
-- @return table: Table of file lines or nil
|
||||
function string:readlines()
|
||||
local lines = {}
|
||||
if self:exists() then
|
||||
for line in io.open(self):lines() do
|
||||
table.insert(lines, line)
|
||||
end
|
||||
end
|
||||
return lines
|
||||
end
|
||||
|
||||
-- Gets file without suffix
|
||||
-- @return string: File wihtout suffix
|
||||
function string:stem()
|
||||
return self:gsub("%.%a+$", "")
|
||||
end
|
||||
|
||||
-- Gets file extensions
|
||||
-- @return table: List of file extensions
|
||||
function string:suffixes()
|
||||
local suffixes = {}
|
||||
for suffix in self:gmatch("%.%a+") do
|
||||
table.insert(suffixes, suffix)
|
||||
end
|
||||
return suffixes
|
||||
end
|
||||
|
||||
-- Gets file final extension
|
||||
-- @return string: Final file extension
|
||||
function string:suffix()
|
||||
local suffixes = self:suffixes()
|
||||
if suffixes[#suffixes] then
|
||||
return suffixes[#suffixes]
|
||||
end
|
||||
return ""
|
||||
end
|
||||
|
||||
-- Requires Pandoc
|
||||
-- Check: https://pandoc.org/lua-filters.html#module-pandoc
|
||||
|
||||
if pandoc ~= nil then
|
||||
|
||||
-- Gets file extension namespace
|
||||
-- Check: https://pandoc.org/MANUAL.html#general-options
|
||||
-- If suffix is 'md' or empty, the default is markdown.
|
||||
-- For the rest, the format is the suffix.
|
||||
-- @param file string: File name
|
||||
-- @return string: File extension according to Pandoc format namespaces
|
||||
function pandoc.getext(file)
|
||||
local ext = file:suffix():gsub("^.", "")
|
||||
return ((ext == "md" or ext:isempty()) and "markdown" or ext)
|
||||
end
|
||||
|
||||
-- Pandoc converter
|
||||
-- Converts input file name into output format name.
|
||||
-- If ofile is not nil, writes output file name.
|
||||
-- If iformat is nil, defaults to ifile extension name.
|
||||
-- @param ifile string: Input file name
|
||||
-- @param oformat string: Output format name
|
||||
-- @param ofile string or nil: Output file name
|
||||
-- @param iformat string or nil: Input format name
|
||||
-- @return string: Output file content
|
||||
function pandoc.convert(ifile, oformat, ofile, iformat)
|
||||
iformat = (iformat == nil and pandoc.getext(ifile) or iformat)
|
||||
local doc = pandoc.write(pandoc.read(ifile:readtext(), iformat), oformat)
|
||||
if ofile ~= nil then
|
||||
local eol = (os:isunix() and "\n" or "\r\n")
|
||||
io.open(ofile, "w"):write(doc, eol):close()
|
||||
end
|
||||
return doc
|
||||
end
|
||||
|
||||
-- Stringifies Pandoc content
|
||||
-- Avoids undesired behavios of pandoc.utils.stringify, such as quotes and
|
||||
-- backslashes conversions.
|
||||
-- @param content pandoc.MetaValue: Pandoc content value
|
||||
-- @return string: Pandoc stringified value
|
||||
function pandoc.utils.rawstringify(content)
|
||||
return pandoc.utils.stringify(content:walk {
|
||||
Plain = function(plain)
|
||||
table.insert(plain.content, pandoc.Space())
|
||||
return plain
|
||||
end,
|
||||
Quoted = function(quoted)
|
||||
local q = (quoted.quotetype == SingleQuoted and '"' or "'")
|
||||
return pandoc.Str(q .. pandoc.utils.stringify(quoted.content) .. q)
|
||||
end,
|
||||
RawInline = function(rawinline)
|
||||
return pandoc.Str(rawinline.text:gsub("\\n", "\n"):gsub("\\t", "\t"))
|
||||
end,
|
||||
SoftBreak = function(softbreak)
|
||||
return pandoc.Str("\n")
|
||||
end,
|
||||
Inline = function(inline) return pandoc.utils.stringify(inline) end,
|
||||
})
|
||||
end
|
||||
|
||||
-- Converts pandoc.Meta to table
|
||||
-- Note that stringified numbers, such "1", are converted to numbers because
|
||||
-- Pandoc doesn't make distinctions between strings and numbers.
|
||||
-- Check: https://pandoc.org/lua-filters.html#type-metavalue
|
||||
-- @param meta pandoc.Meta: Pandoc MetaValues collection
|
||||
-- @return table: Pandoc metadata as table
|
||||
function pandoc.metatotable(meta)
|
||||
local newmeta = {}
|
||||
for k, v in pairs(meta) do
|
||||
if pandoc.utils.type(v) == "table" then
|
||||
newmeta[k] = pandoc.metatotable(v)
|
||||
else
|
||||
if type(v) == "boolean" then
|
||||
newmeta[k] = v
|
||||
elseif tonumber(v) then
|
||||
newmeta[k] = tonumber(v)
|
||||
else
|
||||
newmeta[k] = pandoc.utils.rawstringify(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
return newmeta
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue