Compare commits

..

No commits in common. "no-masters" and "v1.0.0" have entirely different histories.

3 changed files with 102 additions and 126 deletions

View File

@ -1,30 +1,11 @@
# Lua Dog
Adds functions to Lua Standard Libraries and Pandoc Library.
Adds functions to Lua Standard Libraries.
## Install
luarocks install lua-dog
## Usage
You can use Lua Dog in 2 ways.
The laziest way is:
local dog = require("dog")
dog.import()
-- Lua Dog 'dog.os.uname()' function was imported as 'os.uname()'
os.uname()
This will import all Lua Dog functions to the Lua Standard Libraries and Pandoc Library.
If you prefer not to import, the way is:
require "dog"
-- Lua Dog 'dog.os.uname()' function was NOT imported as 'os.uname()'
dog.os.uname()
## Functions
Check `src`.

View File

@ -1,13 +1,12 @@
package = "lua-dog"
version = "1.1.0-1"
version = "1.0-0"
source = {
url = "https://gitlab.com/perritotuerto/codigo/lua-dog/-/archive/v" ..
version .. "/lua-dog-v" .. version .. ".tar.gz",
url = "https://gitlab.com/perritotuerto/codigo/lua-dog/-/archive/v1.0.0/lua-dog-v1.0.0.tar.gz",
}
description = {
summary = "Lua extensions for lazy dogs",
detailed = [[
Extends Lua Standard Libraries and Pandoc Library.
Adds functions to Lua Standard Libraries.
]],
homepage = "https://gitlab.com/perritotuerto/codigo/lua-dog/",
license = "GPLv3",

View File

@ -1,39 +1,8 @@
-- Variable for storing all the functions
local dog = {}
-- Functions are divided according to the standard library to extend
dog.io = {}
dog.os = {}
dog.string = {}
dog.utf8 = {}
-- Imports dog functions to _G
-- Allows using the other functions without a prefix, i.e.:
-- dog.os.uname() => os.uname()
function dog.import()
local msg = "[WARNING] [DOG] "
msg = msg .. "Ignoring import: '@1' already exists; use '@2' instead"
for libkey, dogfns in pairs(dog) do
local lib = _G[libkey]
if type(dogfns) == "table" then
for fnkey, fn in pairs(dogfns) do
if not lib[fnkey] then
lib[fnkey] = fn
else
local name = libkey .. "." .. fnkey .. "()"
msg = msg:gsub("@1", name):gsub("@2", "dog." .. name)
print(msg)
end
end
end
end
end
-- Tries popen
-- @param ... string: Chunks for popen
-- @return boolean, string: Status and output of popen
function dog.io.try(...)
local cmd = table.concat({ ... }, " ") .. " 2>&1"
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)
@ -43,13 +12,13 @@ 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 dog.os.uname()
local status, output = dog.io.try("uname")
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 output ~= "linux" then
elseif out ~= "linux" then
return "macos"
end
return "linux"
@ -59,60 +28,84 @@ end
-- Checks if OS is windows
-- @return boolean: Windows or not
function dog.os.iswin() return dog.os.uname() == "windows" end
function os.iswin()
return os.uname() == "windows"
end
-- Checks if OS is Unix
-- @return boolean: Unix or not
function dog.os.isunix() return dog.os.uname() ~= "windows" end
function os.isunix()
return os.uname() ~= "windows"
end
-- Gets OS language
-- @return string, string, string: Language, locale and encoding
function dog.os.lang()
function os.lang()
local lang = os.getenv("LANG")
if lang ~= nil then return lang:match("(%w%w)_?(%w?%w?)%.?(.*)") end
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 dog.string.isempty(str) return str == "" end
function string:isempty()
return self == ''
end
-- Changes newlines so everything is in one line
-- @return string: String with formatted newlines as literal "\n"
function dog.string.linearize(str) return str:gsub("\n", "\\n") end
function string:linearize()
return self:gsub("\n", "\\n")
end
-- Normalizes string
-- @return string: Normalized string
function dog.string.normalize(str)
str = str:lower()
for newchar, chars in pairs(dog.utf8.table()) do
function string:normalize()
self = self:lower()
for newchar, chars in pairs(utf8.table()) do
for _, oldchar in ipairs(chars) do
str = str:gsub(oldchar, newchar)
self = self:gsub(oldchar, newchar)
end
end
return str
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 dog.string.indent(str, num, char)
function string:indent(num, char)
num = num or 2
char = char or " "
char = string.rep(char, num)
return char .. str:gsub("\n", "\n" .. char)
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.
-- Could be solved by slicing with find.
-- @param sep string: String separator, space by default
-- @return table: String matches
function dog.string.split(str, sep)
function string:split(sep)
sep = sep or "%s+"
local parts = {}
for part in str:gmatch("([^" .. sep .. "]+)") do
for part in self:gmatch("([^" .. sep .. "]+)") do
table.insert(parts, part)
end
return parts
@ -120,42 +113,52 @@ end
-- Removes spaces at the beginning of the string
-- @return string: Left stripped string
function dog.string.lstrip(str) return str:gsub("^%s+", "") end
function string:lstrip()
return self:gsub("^%s+", "")
end
-- Removes spaces at the end of the string
-- @return string: Right stripped string
function dog.string.rstrip(str) return str:gsub("%s+$", "") end
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 dog.string.strip(str)
str = dog.string.lstrip(str)
return dog.string.rstrip(str)
function string:strip()
self = self:lstrip():rstrip()
return self
end
-- Alias of strip
function dog.string.trim(str) return dog.string.strip(str) end
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 dog.string.exists(str) return os.rename(str, str) ~= nil end
function string:exists()
return os.rename(self, self) ~= nil
end
-- Checks if string is a file
-- @return boolean: File or not
function dog.string.isfile(str)
if dog.string.exists(str) then return io.open(str, "a+") ~= nil end
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 dog.string.isdir(str)
if dog.string.exists(str) then
return io.open(str, "a+") == nil
elseif str == "." or str == ".." then
function string:isdir()
if self:exists() then
return io.open(self, "a+") == nil
elseif self == "." or self == ".." then
return true
end
return false
@ -163,16 +166,18 @@ end
-- Reads file content as string
-- @return string or nil: File as string or nil
function dog.string.readtext(str)
if dog.string.exists(str) then return io.open(str):read("*a") end
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 dog.string.readlines(str)
function string:readlines()
local lines = {}
if dog.string.exists(str) then
for line in io.open(str):lines() do
if self:exists() then
for line in io.open(self):lines() do
table.insert(lines, line)
end
end
@ -181,13 +186,15 @@ end
-- Gets file without suffix
-- @return string: File wihtout suffix
function dog.string.stem(str) return str:gsub("%.%a+$", "") end
function string:stem()
return self:gsub("%.%a+$", "")
end
-- Gets file extensions
-- @return table: List of file extensions
function dog.string.suffixes(str)
function string:suffixes()
local suffixes = {}
for suffix in str:gmatch("%.%a+") do
for suffix in self:gmatch("%.%a+") do
table.insert(suffixes, suffix)
end
return suffixes
@ -195,30 +202,19 @@ end
-- Gets file final extension
-- @return string: Final file extension
function dog.string.suffix(str)
local suffixes = str:suffixes()
if suffixes[#suffixes] then return suffixes[#suffixes] end
function string:suffix()
local suffixes = self:suffixes()
if suffixes[#suffixes] then
return suffixes[#suffixes]
end
return ""
end
-- Gets an equivalency table between ASCII and Unicode
-- Note: filled on demand.
-- @return table: ASCII-Unicode table equivalency
function dog.utf8.table()
return {
["a"] = { "á", "à", "ä" },
["e"] = { "é", "è", "ë" },
["i"] = { "í", "ì", "ï" },
["o"] = { "ó", "ò", "ö" },
["u"] = { "ú", "ù", "ü" },
["n"] = { "ñ" },
}
end
-- Extends Pandoc Library
-- 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.
@ -226,8 +222,8 @@ if pandoc ~= nil then
-- @param file string: File name
-- @return string: File extension according to Pandoc format namespaces
function pandoc.getext(file)
local ext = dog.string.suffix(file):gsub("^.", "")
return ((ext == "md" or dog.string.isempty(ext)) and "markdown" or ext)
local ext = file:suffix():gsub("^.", "")
return ((ext == "md" or ext:isempty()) and "markdown" or ext)
end
-- Pandoc converter
@ -241,10 +237,9 @@ if pandoc ~= nil then
-- @return string: Output file content
function pandoc.convert(ifile, oformat, ofile, iformat)
iformat = (iformat == nil and pandoc.getext(ifile) or iformat)
local itext = pandoc.read(dog.string.readtext(ifile), iformat)
local doc = pandoc.write(itext, oformat)
local doc = pandoc.write(pandoc.read(ifile:readtext(), iformat), oformat)
if ofile ~= nil then
local eol = (dog.os:isunix() and "\n" or "\r\n")
local eol = (os:isunix() and "\n" or "\r\n")
io.open(ofile, "w"):write(doc, eol):close()
end
return doc
@ -253,10 +248,10 @@ if pandoc ~= nil then
-- Stringifies Pandoc content
-- Avoids undesired behavios of pandoc.utils.stringify, such as quotes and
-- backslashes conversions.
-- @param content pandoc.MetaValue: Pandoc content value
-- @param content pandoc.MetaValue: Pandoc content value
-- @return string: Pandoc stringified value
function pandoc.utils.rawstringify(content)
return pandoc.utils.stringify(content:walk({
return pandoc.utils.stringify(content:walk {
Plain = function(plain)
table.insert(plain.content, pandoc.Space())
return plain
@ -268,9 +263,11 @@ if pandoc ~= nil then
RawInline = function(rawinline)
return pandoc.Str(rawinline.text:gsub("\\n", "\n"):gsub("\\t", "\t"))
end,
SoftBreak = function(_) return pandoc.Str("\n") end,
SoftBreak = function(softbreak)
return pandoc.Str("\n")
end,
Inline = function(inline) return pandoc.utils.stringify(inline) end,
}))
})
end
-- Converts pandoc.Meta to table
@ -296,6 +293,5 @@ if pandoc ~= nil then
end
return newmeta
end
end
return dog
end