ferron

Ferron is a fast and simple static website generator made with Lua.
Log | Files | Refs | Submodules | README | LICENSE

commit 1663d52f26ab4f1b1373b781ba574bf875c8d089
parent 479436a52e11fdb9ecc0c2a4c4182e432b2703b0
Author: Hugo Soucy <hugo@soucy.cc>
Date:   Sat,  2 Feb 2019 08:09:34 -0500

Set metatables for the modules

Diffstat:
Mferron.lua | 64++++++++++++++++++++++++++++++++--------------------------------
Aferron/app.lua | 21+++++++++++++++++++++
Mferron/content.lua | 168++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mferron/feed.lua | 44+++++++++++++++++++++++++-------------------
Mferron/link.lua | 89+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Mferron/list.lua | 158+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Mferron/page.lua | 94++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mferron/plugin.lua | 18+++++++++++-------
Mferron/site.lua | 305++++++++++++++++++++++++++++++++++++++++---------------------------------------
Mferron/static.lua | 25++++++++++++++-----------
Mferron/tag.lua | 87++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Dferron/utilities/exec.lua | 14--------------
Mferron/utilities/file-utils.lua | 162+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Mferron/utilities/table-utils.lua | 131+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Mferron/utilities/template-utils.lua | 12+++++++++---
15 files changed, 730 insertions(+), 662 deletions(-)

diff --git a/ferron.lua b/ferron.lua @@ -13,7 +13,7 @@ local list = require "ferron.list" local link = require "ferron.link" local static = require "ferron.static" local plugin = require "ferron.plugin" -local exec = require "ferron.utilities.exec" +local app = require "ferron.app" -- App's Globals -- Init the main namespace @@ -22,57 +22,57 @@ Ferron = {} Ferron.devmode = (arg[1] == "--dev" and true or false) -- Chosen site to build must be global Ferron.site = { - location = lfs.currentdir() .. "/" .. config.sites, - config = nil, - path = nil, - pagestable = {}, - navigation = {}, + location = lfs.currentdir() .. "/" .. config.sites, + config = nil, + path = nil, + pagestable = {}, + navigation = {}, } Ferron.init = { - site.setsite, - site.sitereset, - site.setnavigation, + site.setsite, + site.sitereset, + site.setnavigation, } Ferron.build = { - page.init, - list.init, - link.makeshorts, - link.makerewritemap, - static.init, + page.init, + list.init, + link.makeshorts, + link.makerewritemap, + static.init, } if arg[1] == "--set" and arg[2] == "content" then - return content.setcontent(site.setsite()) + return content.setcontent(site.setsite()) end if arg[1] == "--make" and arg[2] == "site" then - return site.startsite() + return site.startsite() end if arg[1] == "--run" and type(arg[2]) == "string" and arg[2] ~= "" then - return plugin.run(site.setsite(), arg[2]) + return plugin.run(site.setsite(), arg[2]) end -return exec(Ferron.init, Ferron.build) +return app.exec(Ferron.init, Ferron.build) --[[ - @TODO API + @TODO API - - App - -- Execution - -- Installing + - App + -- Execution + -- Installing - - Site - -- Information - -- Listing - -- Selection - -- Creation - -- Reseting - -- Building + - Site + -- Information + -- Listing + -- Selection + -- Creation + -- Reseting + -- Building - - Content (markdown) - -- Creation - -- Listing + - Content (markdown) + -- Creation + -- Listing ]]-- diff --git a/ferron/app.lua b/ferron/app.lua @@ -0,0 +1,21 @@ +-- app.lua +local app = {} +local appmeta = { + __call = function(self, key, vars) + print(key) + end +} + +function app.exec(...) + for argkey, argval in pairs({...}) do + if type(argval) == "table" then + for funckey, funcval in ipairs(argval) do + if type(funcval) == "function" then + funcval() + end + end + end + end +end + +return setmetatable(app, appmeta) diff --git a/ferron/content.lua b/ferron/content.lua @@ -1,6 +1,10 @@ ---[[ - -]]-- +-- content.lua +local content = {} +local contentmeta = { + __call = function(self, key, vars) + print(key) + end +} -- Required Packages local fileutils = require "ferron.utilities.file-utils" @@ -8,102 +12,98 @@ local slugify = require "ferron.utilities.lua-slugify.slugify" local tableutils = require "ferron.utilities.table-utils" local templateutils = require "ferron.utilities.template-utils" - --- Module Declaration -local content = {} - function content.getarchetypes(dir) - local archetypes = {} - local archetypesdir = (dir ~= nil and dir or Ferron.site.archetypes) - - if fileutils.isDirectory(archetypesdir) then - for archetype, attr in fileutils.getdirtree(archetypesdir) do - if attr.mode ~= "directory" - and archetype:match("^.+(%..+)$") == ".json" - then - archetypes[#archetypes+1] = archetype:match("^.+/(.+)$"):match("(.+)%..*") - end - end - - return archetypes + local archetypes = {} + local archetypesdir = (dir ~= nil and dir or Ferron.site.archetypes) + + if fileutils.isDirectory(archetypesdir) then + for archetype, attr in fileutils.getdirtree(archetypesdir) do + if attr.mode ~= "directory" + and archetype:match("^.+(%..+)$") == ".json" + then + archetypes[#archetypes+1] = archetype:match("^.+/(.+)$"):match("(.+)%..*") + end end + + return archetypes + end end function content.setcontent() - local archetypes = content.getarchetypes(Ferron.site.archetypes) - local whicharchetype = nil - local whichtitle = nil + local archetypes = content.getarchetypes(Ferron.site.archetypes) + local whicharchetype = nil + local whichtitle = nil - repeat - io.write("Which archetypes do you need to complete your request? \n") + repeat + io.write("Which archetypes do you need to complete your request? \n") - for k, v in ipairs(archetypes) do - io.write(k .. ") " .. v .. "\n") - end + for k, v in ipairs(archetypes) do + io.write(k .. ") " .. v .. "\n") + end - io.write("Please enter the number... \n") - io.flush() + io.write("Please enter the number... \n") + io.flush() - whicharchetype=io.read() - until (tableutils.haskey(archetypes, tonumber(whicharchetype))) == true + whicharchetype=io.read() + until (tableutils.haskey(archetypes, tonumber(whicharchetype))) == true - repeat - io.write("Please write the title of your new content... \n") - io.flush() + repeat + io.write("Please write the title of your new content... \n") + io.flush() - whichtitle=io.read() - until (type(tostring(whichtitle))) == "string" + whichtitle=io.read() + until (type(tostring(whichtitle))) == "string" - return content.makecontent(archetypes[tonumber(whicharchetype)], tostring(whichtitle)) + return content.makecontent(archetypes[tonumber(whicharchetype)], tostring(whichtitle)) end function content.makecontent(contenttype, contenttitle) - local archetypetype = (contenttype ~= nil and contenttype or arg[1]) - local title = (contenttitle ~= nil and contenttitle or arg[2]) - - if tableutils.hasvalue(content.getarchetypes(), archetypetype) and type(title) == "string" then - local archetype = {} - local contentpath = Ferron.site.content .. "/" .. archetypetype .. "/" .. os.date("%Y") .."/"..os.date("%m") .. "/" - local archetypepath = Ferron.site.archetypes .. "/" - - archetype.title = title - archetype.filename = slugify(archetype.title) - archetype.date = os.date("%Y-%m-%d") - archetype.datetime = os.date("%H:%M:%S") - archetype.template = archetypetype - - if not fileutils.isDirectory(contentpath) then - fileutils.mkdir(contentpath) - end - - -- Build the markdown file - fileutils.pushfilecontent( - contentpath .. archetype.filename .. ".md", - templateutils.rendermustache( - fileutils.pullfilecontent(archetypepath .. archetypetype .. ".md" ), - Ferron.site.templates .. "/partials", - archetype - ) - ) - - -- Build the JSON file - fileutils.pushfilecontent( - contentpath .. archetype.filename .. ".json", - templateutils.rendermustache( - fileutils.pullfilecontent(archetypepath .. archetypetype .. ".json"), - Ferron.site.templates .. "/partials", - archetype - ) - ) - - if fileutils.isFile(contentpath .. archetype.filename .. ".md") - and fileutils.isFile(contentpath .. archetype.filename .. ".json") - then - print("¤¤ The files `" .. contentpath .. "{" .. archetype.filename .. ".md," .. archetype.filename .. ".json}` have been created. ¤¤") - else - print("! Error, something went wrong !") - end + local archetypetype = (contenttype ~= nil and contenttype or arg[1]) + local title = (contenttitle ~= nil and contenttitle or arg[2]) + + if tableutils.hasvalue(content.getarchetypes(), archetypetype) and type(title) == "string" then + local archetype = {} + local contentpath = Ferron.site.content .. "/" .. archetypetype .. "/" .. os.date("%Y") .."/"..os.date("%m") .. "/" + local archetypepath = Ferron.site.archetypes .. "/" + + archetype.title = title + archetype.filename = slugify(archetype.title) + archetype.date = os.date("%Y-%m-%d") + archetype.datetime = os.date("%H:%M:%S") + archetype.template = archetypetype + + if not fileutils.isDirectory(contentpath) then + fileutils.mkdir(contentpath) + end + + -- Build the markdown file + fileutils.pushfilecontent( + contentpath .. archetype.filename .. ".md", + templateutils.rendermustache( + fileutils.pullfilecontent(archetypepath .. archetypetype .. ".md" ), + Ferron.site.templates .. "/partials", + archetype + ) + ) + + -- Build the JSON file + fileutils.pushfilecontent( + contentpath .. archetype.filename .. ".json", + templateutils.rendermustache( + fileutils.pullfilecontent(archetypepath .. archetypetype .. ".json"), + Ferron.site.templates .. "/partials", + archetype + ) + ) + + if fileutils.isFile(contentpath .. archetype.filename .. ".md") + and fileutils.isFile(contentpath .. archetype.filename .. ".json") + then + print("¤¤ The files `" .. contentpath .. "{" .. archetype.filename .. ".md," .. archetype.filename .. ".json}` have been created. ¤¤") + else + print("! Error, something went wrong !") end + end end -return content +return setmetatable(content, contentmeta) diff --git a/ferron/feed.lua b/ferron/feed.lua @@ -1,29 +1,35 @@ --- +-- feed.lua +local feed = {} +local feedmeta = { + __call = function(self, key, vars) + print(key) + end +} + local fileutils = require "ferron.utilities.file-utils" local tableutils = require "ferron.utilities.table-utils" local templateutils = require "ferron.utilities.template-utils" -local feed = {} function feed.makefeed(entries, destination) - local feedtypes = Ferron.site.config.feedtypes - local feedpartials = fileutils.isDirectory(Ferron.site.templates .. "/partials") + local feedtypes = Ferron.site.config.feedtypes + local feedpartials = fileutils.isDirectory(Ferron.site.templates .. "/partials") - for k, v in pairs(feedtypes) do - local feedtemplate = Ferron.site.templates .. "/feed/" .. k .. ".mustache" + for k, v in pairs(feedtypes) do + local feedtemplate = Ferron.site.templates .. "/feed/" .. k .. ".mustache" - if fileutils.isFile(feedtemplate) then - fileutils.pushfilecontent( - destination .. "/" .. v.name .. v.extension, - templateutils.rendermustache( - fileutils.pullfilecontent(feedtemplate), - feedpartials, - entries - ) - ) - else - print("*** Warning! The `" .. feedtemplate .. "` template is missing!") - end + if fileutils.isFile(feedtemplate) then + fileutils.pushfilecontent( + destination .. "/" .. v.name .. v.extension, + templateutils.rendermustache( + fileutils.pullfilecontent(feedtemplate), + feedpartials, + entries + ) + ) + else + print("*** Warning! The `" .. feedtemplate .. "` template is missing!") end + end end -return feed +return setmetatable(feed, feedmeta) diff --git a/ferron/link.lua b/ferron/link.lua @@ -1,69 +1,76 @@ +-- link.lua +local link = {} +local linkmeta = { + __call = function(self, key, vars) + print(key) + end +} + -- @TODO Make sure to always keep the alphanumerical order local json = require "dkjson" local fileutils = require "ferron.utilities.file-utils" local tableutils = require "ferron.utilities.table-utils" local templateutils = require "ferron.utilities.template-utils" -local link = {} function link.makeshorts() - local links = {} - local links_keyorder = {} - local links_db = Ferron.site.data .. "/shortlinks.json" + local links = {} + local links_keyorder = {} + local links_db = Ferron.site.data .. "/shortlinks.json" - -- If `links_db` dosen't exists create it - if fileutils.isFile(links_db) == false then - local counter = 0 + -- If `links_db` dosen't exists create it + if fileutils.isFile(links_db) == false then + local counter = 0 - fileutils.pushfilecontent(links_db, "") + fileutils.pushfilecontent(links_db, "") - for k, v in tableutils.sortdescendingpairs(Ferron.site.pagestable) do - if v.rellink ~= "" then - counter = counter + 1 + for k, v in tableutils.sortdescendingpairs(Ferron.site.pagestable) do + if v.rellink ~= "" then + counter = counter + 1 - table.insert(links_keyorder, v.rellink) + table.insert(links_keyorder, v.rellink) - links[v.rellink] = fileutils.shorturlencode(counter) + links[v.rellink] = fileutils.shorturlencode(counter) - fileutils.pushfilecontent(links_db, json.encode(links, {indent = true, keyorder = links_keyorder})) - end - end - else - links = json.decode(fileutils.pullfilecontent(links_db)) + fileutils.pushfilecontent(links_db, json.encode(links, {indent = true, keyorder = links_keyorder})) + end + end + else + links = json.decode(fileutils.pullfilecontent(links_db)) - for k, v in tableutils.sortdescendingpairs(Ferron.site.pagestable) do - if v.rellink ~= "" and links[v.rellink] == nil then - table.insert(links_keyorder, v.rellink) + for k, v in tableutils.sortdescendingpairs(Ferron.site.pagestable) do + if v.rellink ~= "" and links[v.rellink] == nil then + table.insert(links_keyorder, v.rellink) - links[v.rellink] = fileutils.shorturlencode(tableutils.length(links) + 1) + links[v.rellink] = fileutils.shorturlencode(tableutils.length(links) + 1) - fileutils.pushfilecontent(links_db, json.encode(links, {indent = true, keyorder = links_keyorder})) - end - end + fileutils.pushfilecontent(links_db, json.encode(links, {indent = true, keyorder = links_keyorder})) + end end + end end function link.makerewritemap() - local links_db = Ferron.site.data .. "/shortlinks.json" - local links_map = Ferron.site.html .. "/shortlinksmap.txt" + local links_db = Ferron.site.data .. "/shortlinks.json" + local links_map = Ferron.site.html .. "/shortlinksmap.txt" - if fileutils.isFile(links_db) then - links = json.decode(fileutils.pullfilecontent(links_db)) + if fileutils.isFile(links_db) then + links = json.decode(fileutils.pullfilecontent(links_db)) - if links then - -- Create an empty map file - fileutils.pushfilecontent(links_map, "") + if links then + -- Create an empty map file + fileutils.pushfilecontent(links_map, "") - -- Open it - map, map_err = io.open(links_map, "a") + -- Open it + map, map_err = io.open(links_map, "a") - for k, v in pairs(links) do - map:write(v .. " " .. k, "\n") - end + for k, v in pairs(links) do + map:write(v .. " " .. k, "\n") + end - -- Close it when it's done - map:close() - end + -- Close it when it's done + map:close() end + end end -return link +return setmetatable(link, linkmeta) diff --git a/ferron/list.lua b/ferron/list.lua @@ -1,4 +1,11 @@ --- +-- list.lua +local list = {} +local listmeta = { + __call = function(self, key, vars) + print(key) + end +} + local json = require "dkjson" local markdown = require "discount" local fileutils = require "ferron.utilities.file-utils" @@ -6,100 +13,99 @@ local tableutils = require "ferron.utilities.table-utils" local templateutils = require "ferron.utilities.template-utils" local feed = require "ferron.feed" local static = require "ferron.static" -local list = {} local function sortentries(entries_tb, list_mt) - local list_length = list_mt.length ~= nil and list_mt.length or nil - local entries_count = list_length ~= nil and 0 or nil - - if entries_count ~= nil then - for k, v in tableutils.sortdescendingpairs(entries_tb) do - if entries_count < list_length then - table.insert(list_mt["entries"], v) - - entries_count = entries_count + 1 - end - end - else - for k, v in tableutils.sortdescendingpairs(entries_tb) do - table.insert(list_mt["entries"], v) - end + local list_length = list_mt.length ~= nil and list_mt.length or nil + local entries_count = list_length ~= nil and 0 or nil + + if entries_count ~= nil then + for k, v in tableutils.sortdescendingpairs(entries_tb) do + if entries_count < list_length then + table.insert(list_mt["entries"], v) + + entries_count = entries_count + 1 + end + end + else + for k, v in tableutils.sortdescendingpairs(entries_tb) do + table.insert(list_mt["entries"], v) end + end - return list_mt["entries"] + return list_mt["entries"] end local function setentries(directory, list_mt) - local entries_tb = {} + local entries_tb = {} - tableutils.each( - function(entry) - local entry_metadatas = fileutils.getpageconf(entry) - local entry_key = entry_metadatas.date .. "|" .. entry_metadatas.datetime .. "|" .. fileutils.getrelpath(fileutils.removeextension(entry)) + tableutils.each( + function(entry) + local entry_metadatas = fileutils.getpageconf(entry) + local entry_key = entry_metadatas.date .. "|" .. entry_metadatas.datetime .. "|" .. fileutils.getrelpath(fileutils.removeextension(entry)) - entries_tb[entry_key] = Ferron.site.pagestable[entry_key] - end, - tableutils.filter(fileutils.isNotIndex, tableutils.settable(fileutils.getdirtree(directory))) - ) + entries_tb[entry_key] = Ferron.site.pagestable[entry_key] + end, + tableutils.filter(fileutils.isNotIndex, tableutils.settable(fileutils.getdirtree(directory))) + ) - sortentries(entries_tb, list_mt) + sortentries(entries_tb, list_mt) - return list_mt["entries"] + return list_mt["entries"] end function list.render(listsource) - local list = listsource - local list_htmlpath = fileutils.sethtmlpath(fileutils.getrelpath(fileutils.getdirname(list))) - local list_conf = fileutils.getpageconf(list) - local list_conf_mt = setmetatable({}, { __index = list_conf }) - - print("§ Make a list page for the `" .. fileutils.getrelpath(fileutils.getdirname(list)) .. "` subdirectory ...") - - -- Convert the markdown file to HTML - list_conf_mt.content = markdown(fileutils.pullfilecontent(list)) - -- Set a dynamic permalink - list_conf_mt.permalink = Ferron.site.config.baseurl .. fileutils.getdirname(fileutils.getrelpath(fileutils.removeextension(list))) - -- Import site configuration in the metatable - list_conf_mt["site"] = Ferron.site.config - -- Import site navigation in the metatable - list_conf_mt["navigation"] = Ferron.site.navigation - -- Set a table for the list of entries - list_conf_mt["entries"] = {} - - -- Set and get entries of the list - setentries(fileutils.getdirname(list), list_conf_mt) - - if not fileutils.isDirectory(list_htmlpath) then - fileutils.mkdir(list_htmlpath) - end - - -- Create syndication feeds for each list - if list_conf.feed ~= false then - feed.makefeed(list_conf_mt, list_htmlpath) - end - - -- Move static files in the public HTML folder - -- static.dispatch(list) - - print("==========") - - -- Build and push the HTML page - fileutils.pushfilecontent( - list_htmlpath .. "/" .. fileutils.getplainname(list) .. ".html", - templateutils.rendertemplate( - templateutils.selecttemplate(false, list_conf.template), - list_conf_mt, - Ferron.site.templates .. "/partials" - ) + local list = listsource + local list_htmlpath = fileutils.sethtmlpath(fileutils.getrelpath(fileutils.getdirname(list))) + local list_conf = fileutils.getpageconf(list) + local list_conf_mt = setmetatable({}, { __index = list_conf }) + + print("§ Make a list page for the `" .. fileutils.getrelpath(fileutils.getdirname(list)) .. "` subdirectory ...") + + -- Convert the markdown file to HTML + list_conf_mt.content = markdown(fileutils.pullfilecontent(list)) + -- Set a dynamic permalink + list_conf_mt.permalink = Ferron.site.config.baseurl .. fileutils.getdirname(fileutils.getrelpath(fileutils.removeextension(list))) + -- Import site configuration in the metatable + list_conf_mt["site"] = Ferron.site.config + -- Import site navigation in the metatable + list_conf_mt["navigation"] = Ferron.site.navigation + -- Set a table for the list of entries + list_conf_mt["entries"] = {} + + -- Set and get entries of the list + setentries(fileutils.getdirname(list), list_conf_mt) + + if not fileutils.isDirectory(list_htmlpath) then + fileutils.mkdir(list_htmlpath) + end + + -- Create syndication feeds for each list + if list_conf.feed ~= false then + feed.makefeed(list_conf_mt, list_htmlpath) + end + + -- Move static files in the public HTML folder + -- static.dispatch(list) + + print("==========") + + -- Build and push the HTML page + fileutils.pushfilecontent( + list_htmlpath .. "/" .. fileutils.getplainname(list) .. ".html", + templateutils.rendertemplate( + templateutils.selecttemplate(false, list_conf.template), + list_conf_mt, + Ferron.site.templates .. "/partials" ) + ) end function list.init() - local contentpath = assert(fileutils.isDirectory(Ferron.site.content)) + local contentpath = assert(fileutils.isDirectory(Ferron.site.content)) - tableutils.each(list.render, tableutils.filter(fileutils.isIndex, tableutils.settable(fileutils.getdirtree(contentpath)))) + tableutils.each(list.render, tableutils.filter(fileutils.isIndex, tableutils.settable(fileutils.getdirtree(contentpath)))) - return + return end -return list +return setmetatable(list, listmeta) diff --git a/ferron/page.lua b/ferron/page.lua @@ -1,62 +1,68 @@ --- +-- page.lua +local page = {} +local pagemeta = { + __call = function(self, key, vars) + print(key) + end +} + local json = require "dkjson" local markdown = require "discount" local fileutils = require "ferron.utilities.file-utils" local tableutils = require "ferron.utilities.table-utils" local templateutils = require "ferron.utilities.template-utils" -local page = {} function page.render(pagesource) - local page = pagesource - local page_htmlpath = fileutils.sethtmlpath(fileutils.getrelpath(fileutils.getdirname(page))) - local page_conf = fileutils.getpageconf(page) - local page_conf_mt = setmetatable({}, { __index = page_conf }) - local page_key = page_conf.date .. "|" .. page_conf.datetime .. "|" .. fileutils.getrelpath(fileutils.removeextension(page)) - - -- Set some dynamic configuration properties - page_conf_mt.content = markdown(fileutils.pullfilecontent(page)) - page_conf_mt.updated = os.date("%Y-%m-%dT%H:%M:%S", lfs.attributes(page).modification) - page_conf_mt.permalink = Ferron.site.config.baseurl .. (fileutils.getplainname(page) ~= "index" and fileutils.getrelpath(fileutils.removeextension(page)) .. ".html" or "") - page_conf_mt.rellink = (fileutils.getplainname(page) ~= "index" and fileutils.getrelpath(fileutils.removeextension(page)) .. ".html" or "") - page_conf_mt["site"] = Ferron.site.config - page_conf_mt["navigation"] = Ferron.site.navigation - - if page_conf.id == nil then - page_conf_mt.id = "tag:" .. Ferron.site.config.domainname .. "," .. page_conf.date .. ":" .. string.sub(page_conf.date, 0, 4) .. "/" .. string.sub(page_conf.date, 6, 7) .. "/" .. fileutils.getplainname(page) - end - - Ferron.site.pagestable[page_key] = page_conf_mt - - -- If the ancestors of the page dosen't exists make it - if not fileutils.isDirectory(page_htmlpath) then - fileutils.mkdir(page_htmlpath) - end - - -- Build and push the HTML page - fileutils.pushfilecontent( - page_htmlpath .. "/" .. fileutils.getplainname(page) .. ".html", - templateutils.rendertemplate( - templateutils.selecttemplate(false, page_conf.template), - page_conf_mt, - assert(fileutils.isDirectory(Ferron.site.templates)) .. "/partials" - ) + local page = pagesource + local page_htmlpath = fileutils.sethtmlpath(fileutils.getrelpath(fileutils.getdirname(page))) + local page_conf = fileutils.getpageconf(page) + local page_conf_mt = setmetatable({}, { __index = page_conf }) + local page_key = page_conf.date .. "|" .. page_conf.datetime .. "|" .. fileutils.getrelpath(fileutils.removeextension(page)) + + -- Set some dynamic configuration properties + page_conf_mt.content = markdown(fileutils.pullfilecontent(page)) + page_conf_mt.updated = os.date("%Y-%m-%dT%H:%M:%S", lfs.attributes(page).modification) + page_conf_mt.permalink = Ferron.site.config.baseurl .. (fileutils.getplainname(page) ~= "index" and fileutils.getrelpath(fileutils.removeextension(page)) .. ".html" or "") + page_conf_mt.rellink = (fileutils.getplainname(page) ~= "index" and fileutils.getrelpath(fileutils.removeextension(page)) .. ".html" or "") + page_conf_mt["site"] = Ferron.site.config + page_conf_mt["navigation"] = Ferron.site.navigation + + if page_conf.id == nil then + page_conf_mt.id = "tag:" .. Ferron.site.config.domainname .. "," .. page_conf.date .. ":" .. string.sub(page_conf.date, 0, 4) .. "/" .. string.sub(page_conf.date, 6, 7) .. "/" .. fileutils.getplainname(page) + end + + Ferron.site.pagestable[page_key] = page_conf_mt + + -- If the ancestors of the page dosen't exists make it + if not fileutils.isDirectory(page_htmlpath) then + fileutils.mkdir(page_htmlpath) + end + + -- Build and push the HTML page + fileutils.pushfilecontent( + page_htmlpath .. "/" .. fileutils.getplainname(page) .. ".html", + templateutils.rendertemplate( + templateutils.selecttemplate(false, page_conf.template), + page_conf_mt, + assert(fileutils.isDirectory(Ferron.site.templates)) .. "/partials" ) + ) - print(page_conf.date .. " - " .. page_conf.title) + print(page_conf.date .. " - " .. page_conf.title) - return true + return true end function page.init() - local contentpath = assert(fileutils.isDirectory(Ferron.site.content)) + local contentpath = assert(fileutils.isDirectory(Ferron.site.content)) - tableutils.each(page.render, tableutils.filter(fileutils.isNotIndex, tableutils.settable(fileutils.getdirtree(contentpath)))) + tableutils.each(page.render, tableutils.filter(fileutils.isNotIndex, tableutils.settable(fileutils.getdirtree(contentpath)))) - print("==========") - print("§ " .. tableutils.length(Ferron.site.pagestable) .. " HTML pages have been created.") - print("==========") + print("==========") + print("§ " .. tableutils.length(Ferron.site.pagestable) .. " HTML pages have been created.") + print("==========") - return --print(inspect(Ferron.site.pagestable)) + return --print(inspect(Ferron.site.pagestable)) end -return page +return setmetatable(page, pagemeta) diff --git a/ferron/plugin.lua b/ferron/plugin.lua @@ -1,13 +1,17 @@ ---[[ - Plugin Module -]]-- -local fileutils = require "ferron.utilities.file-utils" +-- plugin.lua local plugin = {} +local pluginmeta = { + __call = function(self, key, vars) + print(key) + end +} + +local fileutils = require "ferron.utilities.file-utils" function plugin.run(site, plugname) - local plugin = require(Ferron.site.config.sites .. fileutils.getbasename(Ferron.site.path) .. Ferron.site.config.paths.plugins .. "/" .. plugname) + local plugin = require(Ferron.site.config.sites .. fileutils.getbasename(Ferron.site.path) .. Ferron.site.config.paths.plugins .. "/" .. plugname) - return plugin.init(site) + return plugin.init(site) end -return plugin +return setmetatable(plugin, pluginmeta) diff --git a/ferron/site.lua b/ferron/site.lua @@ -1,185 +1,192 @@ +-- site.lua +local site = {} +local sitemeta = { + __call = function(self, key, vars) + print(key) + end +} + local lfs = require "lfs" local config = require "ferron.config" local tableutils = require "ferron.utilities.table-utils" local fileutils = require "ferron.utilities.file-utils" -local site = {} function site.getsitelist(siteslocation) - local location = siteslocation or Ferron.site.location - -- Create a simple array with the directory name of the sites - local siteslist = tableutils.map( - function(site, i) - if fileutils.isDirectory(location .. site) - and site ~= "." - and site ~= ".." - then - return site - end - end, - - tableutils.settable(lfs.dir(location)) - ) - - return siteslist + local location = siteslocation or Ferron.site.location + -- Create a simple array with the directory name of the sites + local siteslist = tableutils.map( + function(site, i) + if fileutils.isDirectory(location .. site) + and site ~= "." + and site ~= ".." + then + return site + end + end, + + tableutils.settable(lfs.dir(location)) + ) + + return siteslist end function site.getsiteconfig(sitename) - package.path = package.path .. ";sites/".. sitename .."/?.lua" + package.path = package.path .. ";sites/".. sitename .."/?.lua" - local siteconfig = require "config" + local siteconfig = require "config" - return siteconfig + return siteconfig end function site.setsite(sitename) - local siteslist = site.getsitelist() - local whichsite - - if #siteslist > 1 and not sitename then - repeat - io.write("For which website do you want to proceed? \n") - - for k, v in ipairs(siteslist) do - io.write(k .. ") " .. v .. "\n") - end - - io.write("Please enter the number... \n") - io.flush() - - whichsite=io.read() - until (tableutils.haskey(siteslist, tonumber(whichsite))) == true - elseif not sitename then - whichsite = 1 - end - - -- Assign values to Ferron.site.path and Ferron.site.config - Ferron.site.path = Ferron.site.location .. (sitename or siteslist[tonumber(whichsite)]) - Ferron.site.config = tableutils.extend({}, config, (site.getsiteconfig(sitename or siteslist[tonumber(whichsite)]))) - - -- Have different values if devmode is at true or not - Ferron.site.config.baseurl = (Ferron.devmode == true and Ferron.site.config.urldev or Ferron.site.config.url) - - -- Create absolute path properties for the chosen site's folders - Ferron.site.archetypes = Ferron.site.path .. Ferron.site.config.paths.archetypes - Ferron.site.content = Ferron.site.path .. Ferron.site.config.paths.content - Ferron.site.data = Ferron.site.path .. Ferron.site.config.paths.data - Ferron.site.html = Ferron.site.path .. Ferron.site.config.paths.html - Ferron.site.plugins = Ferron.site.path .. Ferron.site.config.paths.plugins - Ferron.site.static = Ferron.site.path .. Ferron.site.config.paths.static - Ferron.site.templates = Ferron.site.path .. Ferron.site.config.paths.templates - - return true + local siteslist = site.getsitelist() + local whichsite + + if #siteslist > 1 and not sitename then + repeat + io.write("For which website do you want to proceed? \n") + + for k, v in ipairs(siteslist) do + io.write(k .. ") " .. v .. "\n") + end + + io.write("Please enter the number... \n") + io.flush() + + whichsite=io.read() + until (tableutils.haskey(siteslist, tonumber(whichsite))) == true + elseif not sitename then + whichsite = 1 + end + + -- Assign values to Ferron.site.path and Ferron.site.config + Ferron.site.path = Ferron.site.location .. (sitename or siteslist[tonumber(whichsite)]) + Ferron.site.config = tableutils.extend({}, config, (site.getsiteconfig(sitename or siteslist[tonumber(whichsite)]))) + + -- Have different values if devmode is at true or not + Ferron.site.config.baseurl = (Ferron.devmode == true and Ferron.site.config.urldev or Ferron.site.config.url) + + -- Create absolute path properties for the chosen site's folders + Ferron.site.archetypes = Ferron.site.path .. Ferron.site.config.paths.archetypes + Ferron.site.content = Ferron.site.path .. Ferron.site.config.paths.content + Ferron.site.data = Ferron.site.path .. Ferron.site.config.paths.data + Ferron.site.html = Ferron.site.path .. Ferron.site.config.paths.html + Ferron.site.plugins = Ferron.site.path .. Ferron.site.config.paths.plugins + Ferron.site.static = Ferron.site.path .. Ferron.site.config.paths.static + Ferron.site.templates = Ferron.site.path .. Ferron.site.config.paths.templates + + return true end function site.setnavigation(contentlocation) - local location = assert(fileutils.isDirectory(contentlocation or Ferron.site.content)) - local navigation = tableutils.map( - function(f, i) - local meta = fileutils.getpageconf(f) - - if meta.navigation then - local label = meta.navigation.label and meta.navigation.label or meta.title - local location = Ferron.site.config.baseurl .. fileutils.removeextension(fileutils.getrelpath(f)) .. ".html" - local attributes = meta.navigation.attributes - local order = meta.navigation.order - - if fileutils.getbasename(location) == "index.html" then - location = fileutils.getdirname(location) - end - - return {label = label, location = location, attributes = attributes, order = order} - end - end, - -- The data table - tableutils.filter(fileutils.isMarkdown, tableutils.settable(fileutils.getdirtree(location))) - ) - - -- It's a dumb way to sort but it works for now. - -- Maybe it should be coroutines. - local function sortnavigation(tbl) - local _tbl = {} - - -- First, add those who get an navigation.order property sets - for idx, val in ipairs(tbl) do - if val.order then - _tbl[val.order] = val - end + local location = assert(fileutils.isDirectory(contentlocation or Ferron.site.content)) + local navigation = tableutils.map( + function(f, i) + local meta = fileutils.getpageconf(f) + + if meta.navigation then + local label = meta.navigation.label and meta.navigation.label or meta.title + local location = Ferron.site.config.baseurl .. fileutils.removeextension(fileutils.getrelpath(f)) .. ".html" + local attributes = meta.navigation.attributes + local order = meta.navigation.order + + if fileutils.getbasename(location) == "index.html" then + location = fileutils.getdirname(location) end - --- Then add the rest - for idx, val in ipairs(tbl) do - if not val.order then - _tbl[#_tbl+1] = val - end - end + return {label = label, location = location, attributes = attributes, order = order} + end + end, + -- The data table + tableutils.filter(fileutils.isMarkdown, tableutils.settable(fileutils.getdirtree(location))) + ) + + -- It's a dumb way to sort but it works for now. + -- Maybe it should be coroutines. + local function sortnavigation(tbl) + local _tbl = {} + + -- First, add those who get an navigation.order property sets + for idx, val in ipairs(tbl) do + if val.order then + _tbl[val.order] = val + end + end - return _tbl + --- Then add the rest + for idx, val in ipairs(tbl) do + if not val.order then + _tbl[#_tbl+1] = val + end end - return tableutils.extend(Ferron.site.navigation, sortnavigation(navigation)) + return _tbl + end + + return tableutils.extend(Ferron.site.navigation, sortnavigation(navigation)) end function site.startsite(samplelocation) - local newsite = { - domain = nil, - name = nil, - location = nil, - config = nil, - sample = Ferron.site.location .. "ferron-ssg.tld", - } - local location = samplelocation or newsite.sample - - io.write("How do you want names your new website? \n") - io.write("Please enter that name below... \n") - io.flush() - - newsite.name = io.read() - newsite.location = Ferron.site.location .. newsite.name - - fileutils.mkdir(newsite.location) - - os.execute("cp -Rp " .. location .. "/*" .. " " .. newsite.location) - - if fileutils.isDirectory(newsite.location) then - return print("Your new website is ready to be cutomize here '" .. newsite.location .. "'!") - else - return print("!! Error, something went wrong !") - end + local newsite = { + domain = nil, + name = nil, + location = nil, + config = nil, + sample = Ferron.site.location .. "ferron-ssg.tld", + } + local location = samplelocation or newsite.sample + + io.write("How do you want names your new website? \n") + io.write("Please enter that name below... \n") + io.flush() + + newsite.name = io.read() + newsite.location = Ferron.site.location .. newsite.name + + fileutils.mkdir(newsite.location) + + os.execute("cp -Rp " .. location .. "/*" .. " " .. newsite.location) + + if fileutils.isDirectory(newsite.location) then + return print("Your new website is ready to be cutomize here '" .. newsite.location .. "'!") + else + return print("!! Error, something went wrong !") + end end -- Reset the `public_html/` folder of the selected site function site.sitereset(htmllocation) - local location = htmllocation or Ferron.site.html - local function removefiles(dir) - local ok, errormsg - -- remove files from directory - for file in lfs.dir(dir) do - if file == "." or file == ".." or file == ".gitignore" then -- skip system files - -- do nothing - else - local thefile = dir.."/"..file - - if lfs.attributes(thefile, "mode") == "directory" then - removefiles(thefile) - else - ok, errormsg = os.remove(thefile) - - if not ok then - print("Error removing file: "..file..":"..errormsg) - end - end - end + local location = htmllocation or Ferron.site.html + local function removefiles(dir) + local ok, errormsg + -- remove files from directory + for file in lfs.dir(dir) do + if file == "." or file == ".." or file == ".gitignore" then -- skip system files + -- do nothing + else + local thefile = dir.."/"..file + + if lfs.attributes(thefile, "mode") == "directory" then + removefiles(thefile) + else + ok, errormsg = os.remove(thefile) + + if not ok then + print("Error removing file: "..file..":"..errormsg) + end end + end + end - -- remove directory - ok, errormsg = os.remove(dir) + -- remove directory + ok, errormsg = os.remove(dir) - if not ok then - print("Can't removing directory: "..dir..":"..errormsg) - end + if not ok then + print("Can't removing directory: "..dir..":"..errormsg) end + end - removefiles(location) + removefiles(location) end -return site +return setmetatable(site, sitemeta) diff --git a/ferron/static.lua b/ferron/static.lua @@ -1,27 +1,30 @@ ---[[ - Static Module -]]-- +-- static.lua +local static = {} +local staticmeta = { + __call = function(self, key, vars) + print(key) + end +} -- Required Packages local fileutils = require "ferron.utilities.file-utils" local tableutils = require "ferron.utilities.table-utils" -local static = {} local function dispatchnontextual(file) - return os.execute("cp -p " .. file .. " " .. Ferron.site.html) + return os.execute("cp -p " .. file .. " " .. Ferron.site.html) end local function movestaticfolder() - return os.execute("cp -Rp " .. Ferron.site.static .. "/*" .. " " .. Ferron.site.html) + return os.execute("cp -Rp " .. Ferron.site.static .. "/*" .. " " .. Ferron.site.html) end function static.init() - local contentpath = assert(fileutils.isDirectory(Ferron.site.content)) + local contentpath = assert(fileutils.isDirectory(Ferron.site.content)) - print("¤¤ Your site is ready at `" .. Ferron.site.html .. "` ¤¤") + print("¤¤ Your site is ready at `" .. Ferron.site.html .. "` ¤¤") - return movestaticfolder(), - tableutils.each(dispatchnontextual, tableutils.filter(fileutils.isNonTextual, tableutils.settable(fileutils.getdirtree(contentpath)))) + return movestaticfolder(), + tableutils.each(dispatchnontextual, tableutils.filter(fileutils.isNonTextual, tableutils.settable(fileutils.getdirtree(contentpath)))) end -return static +return setmetatable(static, staticmeta) diff --git a/ferron/tag.lua b/ferron/tag.lua @@ -1,62 +1,67 @@ --- +-- tag.lua +local tag = {} +local tagmeta = { + __call = function(self, key, vars) + print(key) + end +} + local json = require "dkjson" local fileutils = require "ferron.utilities.file-utils" local tableutils = require "ferron.utilities.table-utils" local templateutils = require "ferron.utilities.template-utils" -local tag = {} - local function maketagstable() - local tagstable = {} - local pages = Ferron.site.pagestable - - for k, page in pairs(pages) do - if page.keywords ~= nil then - for i, keyword in ipairs(page.keywords) do - if tableutils.hasvalue(tagstable, keyword) == false then - tagstable[keyword] = {} - end - end + local tagstable = {} + local pages = Ferron.site.pagestable + + for k, page in pairs(pages) do + if page.keywords ~= nil then + for i, keyword in ipairs(page.keywords) do + if tableutils.hasvalue(tagstable, keyword) == false then + tagstable[keyword] = {} end + end end + end - for k, page in pairs(pages) do - if page.keywords ~= nil then - for i, keyword in ipairs(page.keywords) do - if tagstable[keyword] ~= nil then - table.insert(tagstable[keyword], page.rellink) - end - end + for k, page in pairs(pages) do + if page.keywords ~= nil then + for i, keyword in ipairs(page.keywords) do + if tagstable[keyword] ~= nil then + table.insert(tagstable[keyword], page.rellink) end + end end + end - return tagstable + return tagstable end function tag.maketagpage() - local tagstable = maketagstable() - - for tag, urls in pairs(tagstable) do - local tag_tb = { - tagname = tag, - tagurls = urls - } + local tagstable = maketagstable() - if fileutils.isDirectory(Ferron.site.html .. "/tag") == false then - fileutils.mkdir(Ferron.site.html .. "/tag") - end + for tag, urls in pairs(tagstable) do + local tag_tb = { + tagname = tag, + tagurls = urls + } - -- Build the HTML file - fileutils.pushfilecontent( - Ferron.site.html .. "/tag/" .. tag .. ".html", - templateutils.rendermustache( - fileutils.pullfilecontent(Ferron.site.templates .. "/tag.mustache"), - Ferron.site.templates .. "/partials", - tag_tb - ) - ) + if fileutils.isDirectory(Ferron.site.html .. "/tag") == false then + fileutils.mkdir(Ferron.site.html .. "/tag") end + -- Build the HTML file + fileutils.pushfilecontent( + Ferron.site.html .. "/tag/" .. tag .. ".html", + templateutils.rendermustache( + fileutils.pullfilecontent(Ferron.site.templates .. "/tag.mustache"), + Ferron.site.templates .. "/partials", + tag_tb + ) + ) + end + end -return tag +return setmetatable(tag) diff --git a/ferron/utilities/exec.lua b/ferron/utilities/exec.lua @@ -1,14 +0,0 @@ --- -local exec = function(...) - for argkey, argval in pairs({...}) do - if type(argval) == "table" then - for funckey, funcval in ipairs(argval) do - if type(funcval) == "function" then - funcval() - end - end - end - end -end - -return exec diff --git a/ferron/utilities/file-utils.lua b/ferron/utilities/file-utils.lua @@ -1,113 +1,119 @@ --- +-- fileutils.lua +local fileutils = {} +local fileutilsmeta = { + __call = function(self, key, vars) + print(key) + end +} + local json = require "dkjson" local lfs = require "lfs" local mimetypes = require "mimetypes" local config = require "ferron.config" local tableutils = require "ferron.utilities.table-utils" -local fileutils = {} function fileutils.getbasename(filepath) - return string.gsub(filepath, "(.*/)(.*)", "%2") + return string.gsub(filepath, "(.*/)(.*)", "%2") end function fileutils.isFile(filepath) - if lfs.attributes(filepath) == nil then - return false - elseif lfs.attributes(filepath).mode == "file" then - return filepath - end - + if lfs.attributes(filepath) == nil then return false + elseif lfs.attributes(filepath).mode == "file" then + return filepath + end + + return false end function fileutils.isDirectory(filepath) - if lfs.attributes(filepath) == nil then - return false - elseif lfs.attributes(filepath).mode == "directory" then - return filepath - end - + if lfs.attributes(filepath) == nil then return false + elseif lfs.attributes(filepath).mode == "directory" then + return filepath + end + + return false end function fileutils.isMarkdown(filepath) - if fileutils.isFile(filepath) - and (mimetypes.guess(filepath) == "text/x-markdown" - or fileutils.getextension(filepath) == ".md") then - return filepath - end + if fileutils.isFile(filepath) + and (mimetypes.guess(filepath) == "text/x-markdown" + or fileutils.getextension(filepath) == ".md") then + return filepath + end - return + return end function fileutils.isIndex(filepath) - if fileutils.isMarkdown(filepath) == false then - return false - elseif fileutils.getbasename(filepath) == "index.md" then - return filepath - end - + if fileutils.isMarkdown(filepath) == false then return false + elseif fileutils.getbasename(filepath) == "index.md" then + return filepath + end + + return false end function fileutils.isNotIndex(filepath) - if fileutils.isMarkdown(filepath) == false then - return false - elseif fileutils.isMarkdown(filepath) and not fileutils.isIndex(filepath) then - return filepath - end - + if fileutils.isMarkdown(filepath) == false then return false + elseif fileutils.isMarkdown(filepath) and not fileutils.isIndex(filepath) then + return filepath + end + + return false end function fileutils.isNonTextual(file) - local mimestable = config.mimetypes + local mimestable = config.mimetypes - return (tableutils.hasvalue(mimestable, mimetypes.guess(file)) and true or false) + return (tableutils.hasvalue(mimestable, mimetypes.guess(file)) and true or false) end -- getdirtree function fileutils.getdirtree(dir) - assert(dir and dir ~= "", "directory parameter is missing or empty") + assert(dir and dir ~= "", "directory parameter is missing or empty") - if string.sub(dir, -1) == "/" then - dir = string.sub(dir, 1, -2) - end + if string.sub(dir, -1) == "/" then + dir = string.sub(dir, 1, -2) + end - local function yieldtree(dir) - for entry in lfs.dir(dir) do - if entry ~= "." and entry ~= ".." then - entry = dir.."/"..entry + local function yieldtree(dir) + for entry in lfs.dir(dir) do + if entry ~= "." and entry ~= ".." then + entry = dir.."/"..entry - local attr = lfs.attributes(entry) + local attr = lfs.attributes(entry) - coroutine.yield(entry,attr) + coroutine.yield(entry,attr) - if attr.mode == "directory" then - yieldtree(entry) - end - end + if attr.mode == "directory" then + yieldtree(entry) end + end end + end - return coroutine.wrap(function() yieldtree(dir) end) + return coroutine.wrap(function() yieldtree(dir) end) end -- mkdir function fileutils.mkdir(path) - local sep, pStr = package.config:sub(1, 1), "" + local sep, pStr = package.config:sub(1, 1), "" - for dir in path:gmatch("[^" .. sep .. "]+") do - pStr = pStr .. sep .. dir + for dir in path:gmatch("[^" .. sep .. "]+") do + pStr = pStr .. sep .. dir - lfs.mkdir(pStr) - end + lfs.mkdir(pStr) + end end -- pullfilecontent function fileutils.pullfilecontent(pathtofile) - local file = assert(io.open(pathtofile, "r")) + local file = assert(io.open(pathtofile, "r")) local content = file:read "*a" file:close() @@ -117,55 +123,55 @@ end -- pushfilecontent function fileutils.pushfilecontent(pathtofile, data) - local file = io.open(pathtofile, "w+") + local file = io.open(pathtofile, "w+") - file:write(data) + file:write(data) file:close() - return assert(fileutils.isFile(pathtofile)) + return assert(fileutils.isFile(pathtofile)) end function fileutils.getrelpath(file) - return file:sub((Ferron.site.path .. Ferron.site.config.paths.content):len() + 1) + return file:sub((Ferron.site.path .. Ferron.site.config.paths.content):len() + 1) end function fileutils.sethtmlpath(folder) - return Ferron.site.path .. Ferron.site.config.paths.html .. folder + return Ferron.site.path .. Ferron.site.config.paths.html .. folder end function fileutils.removeextension(file) - return file:match("(.+)%..*") + return file:match("(.+)%..*") end function fileutils.getextension(file) - return file:match("^.+(%..+)$") + return file:match("^.+(%..+)$") end function fileutils.getplainname(file) - return fileutils.removeextension(file):match("^.+/(.+)$") + return fileutils.removeextension(file):match("^.+/(.+)$") end function fileutils.getdirname(file) - return file:match("(.*/)") + return file:match("(.*/)") end function fileutils.getpageconf(pagepath) - local pageconf = nil - local conflua = fileutils.isFile(fileutils.removeextension(pagepath) .. ".lua") - local confjson = fileutils.isFile(fileutils.removeextension(pagepath) .. ".json") - - if conflua then - package.path = package.path .. ";" .. fileutils.getdirname(conflua) .. "/?.lua" - pageconf = require(fileutils.getplainname(conflua)) - elseif confjson then - pageconf = json.decode(fileutils.pullfilecontent(confjson)) - end + local pageconf = nil + local conflua = fileutils.isFile(fileutils.removeextension(pagepath) .. ".lua") + local confjson = fileutils.isFile(fileutils.removeextension(pagepath) .. ".json") + + if conflua then + package.path = package.path .. ";" .. fileutils.getdirname(conflua) .. "/?.lua" + pageconf = require(fileutils.getplainname(conflua)) + elseif confjson then + pageconf = json.decode(fileutils.pullfilecontent(confjson)) + end - return pageconf + return pageconf end function fileutils.shorturlencode(num) - local alphabet = "23456789bcdfghjkmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ-_" + local alphabet = "23456789bcdfghjkmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ-_" local base = alphabet:len() local str = "" @@ -178,4 +184,4 @@ function fileutils.shorturlencode(num) end -- Export `fileutils` module -return fileutils +return setmetatable(fileutils, fileutilsmeta) diff --git a/ferron/utilities/table-utils.lua b/ferron/utilities/table-utils.lua @@ -1,118 +1,123 @@ --- +-- tableutils.lua local tableutils = {} +local tableutilsmeta = { + __call = function(self, key, vars) + print(key) + end +} -- sortdescendingpairs function tableutils.sortdescendingpairs(tbl) - local keys = {} - local i = 0 - - for k in pairs(tbl) do table.insert(keys, k) end - - table.sort(keys, function(a,b) - if tonumber(a) and tonumber(b) then - return a > b - else - return tostring(a)>tostring(b) - end - end) - - return function() - if i < #keys then - i = i + 1 - return keys[i], tbl[keys[i]] - end + local keys = {} + local i = 0 + + for k in pairs(tbl) do table.insert(keys, k) end + + table.sort(keys, function(a,b) + if tonumber(a) and tonumber(b) then + return a > b + else + return tostring(a)>tostring(b) + end + end) + + return function() + if i < #keys then + i = i + 1 + return keys[i], tbl[keys[i]] end + end end -- hasvalue function tableutils.hasvalue(tbl, val) - for index, value in ipairs(tbl) do - if value == val then - return true - end + for index, value in ipairs(tbl) do + if value == val then + return true end + end - return false + return false end -- haskey function tableutils.haskey(tbl, key) - for k, v in ipairs(tbl) do - if k == key then - return true - end + for k, v in ipairs(tbl) do + if k == key then + return true end + end - return false + return false end -- length function tableutils.length(tbl) - local count = 0 + local count = 0 - for _ in pairs(tbl) do - count = count + 1 - end + for _ in pairs(tbl) do + count = count + 1 + end - return count + return count end -- extend function tableutils.extend(list, ...) - local lists = {...} + local lists = {...} - for i, source in ipairs(lists) do - for k, v in pairs(source) do - list[k] = source[k] - end + for i, source in ipairs(lists) do + for k, v in pairs(source) do + list[k] = source[k] end + end - return list + return list end function tableutils.settable(...) - local _tbl = {} + local _tbl = {} - for x in ... do _tbl[#_tbl + 1] = x end + for x in ... do _tbl[#_tbl + 1] = x end - return _tbl + return _tbl end -- each(function, table) -- ex.: tableutils.each(double, {1,2,3}) -> {2,4,6} function tableutils.each(func, tbl) - for i, v in pairs(tbl) do - func(v, i) - end + for i, v in pairs(tbl) do + func(v, i) + end - return + return end -- map(function, table) -- ex.: tableutils.map(double, {1,2,3}) -> {2,4,6} function tableutils.map(func, tbl) - local _tbl = {} + local _tbl = {} - for i, v in pairs(tbl) do - _tbl[#_tbl+1] = func(v, i) - end + for i, v in pairs(tbl) do + _tbl[#_tbl+1] = func(v, i) + end - return _tbl + return _tbl end -- filter(function, table) - -- ex.: tableutils.filter(is_even, {1,2,3,4}) -> {2,4} - function tableutils.filter(func, tbl) - local _tbl= {} +-- ex.: tableutils.filter(is_even, {1,2,3,4}) -> {2,4} +function tableutils.filter(func, tbl) + local _tbl= {} - for i,v in pairs(tbl) do - if func(v) then - _tbl[i] = v - end - end + for i,v in pairs(tbl) do + if func(v) then + _tbl[i] = v + end + end - return _tbl - end + return _tbl +end -return tableutils +return setmetatable(tableutils, tableutilsmeta) diff --git a/ferron/utilities/template-utils.lua b/ferron/utilities/template-utils.lua @@ -1,9 +1,15 @@ --- +-- templateutils.lua +local templateutils = {} +local templateutilsmeta = { + __call = function(self, key, vars) + print(key) + end +} + local lustache = require "lustache" local etlua = require "etlua" local fileutils = require "ferron.utilities.file-utils" -local templateutils = {} -- set template function templateutils.selecttemplate(index, templatename) @@ -59,4 +65,4 @@ function templateutils.rendertemplate(template, data, partials) return render end -return templateutils +return setmetatable(templateutils, templateutilsmeta)