ferron

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

commit 79d33a27143dcaf6e685d8dae8241a595d1c755d
parent 2801f504e58237f231a43a8d0771cf9c8b911dd5
Author: Hugo Soucy <hugo@soucy.cc>
Date:   Wed, 31 Jan 2018 21:35:10 -0500

Rename functions repository to ferron.

Diffstat:
Mferron.lua | 20++++++++++----------
Aferron/create-archetype-content.lua | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aferron/dispatch-nontextuals.lua | 35+++++++++++++++++++++++++++++++++++
Rfunctions/exec.lua -> ferron/exec.lua | 0
Rfunctions/ferron-utils.lua -> ferron/ferron-utils.lua | 0
Aferron/file-utils.lua | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aferron/get-archetypes.lua | 21+++++++++++++++++++++
Aferron/get-sites.lua | 28++++++++++++++++++++++++++++
Aferron/make-atom-feed.lua | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Aferron/make-lists-of-pages.lua | 124+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aferron/make-pages.lua | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rfunctions/move-to-publichtml.lua -> ferron/move-to-publichtml.lua | 0
Aferron/set-site.lua | 28++++++++++++++++++++++++++++
Rfunctions/table-utils.lua -> ferron/table-utils.lua | 0
Aferron/template-utils.lua | 20++++++++++++++++++++
Dfunctions/create-archetype-content.lua | 55-------------------------------------------------------
Dfunctions/dispatch-nontextuals.lua | 35-----------------------------------
Dfunctions/file-utils.lua | 76----------------------------------------------------------------------------
Dfunctions/get-archetypes.lua | 21---------------------
Dfunctions/get-sites.lua | 28----------------------------
Dfunctions/make-atom-feed.lua | 53-----------------------------------------------------
Dfunctions/make-lists-of-pages.lua | 124-------------------------------------------------------------------------------
Dfunctions/make-pages.lua | 89-------------------------------------------------------------------------------
Dfunctions/set-site.lua | 28----------------------------
Dfunctions/template-utils.lua | 20--------------------
25 files changed, 559 insertions(+), 539 deletions(-)

diff --git a/ferron.lua b/ferron.lua @@ -9,15 +9,15 @@ local Ferron = Ferron -- Ferron submodules local config = require("config") -local getsites = require("functions.get-sites") -local getarchetypes = require("functions.get-archetypes") -local setsite = require("functions.set-site") -local createarchetypecontent = require("functions.create-archetype-content") -local makepages = require("functions.make-pages") -local makelistsofpages = require("functions.make-lists-of-pages") -local makeatomfeed = require("functions.make-atom-feed") -local movetopublichtml = require("functions.move-to-publichtml") -local exec = require("functions.exec") +local getsites = require("ferron.get-sites") +local getarchetypes = require("ferron.get-archetypes") +local setsite = require("ferron.set-site") +local createarchetypecontent = require("ferron.create-archetype-content") +local makepages = require("ferron.make-pages") +local makelistsofpages = require("ferron.make-lists-of-pages") +local makeatomfeed = require("ferron.make-atom-feed") +local movetopublichtml = require("ferron.move-to-publichtml") +local exec = require("ferron.exec") inspect = require("inspect") @@ -38,7 +38,7 @@ Ferron.initfunctions = { Ferron.buildfunctions = { makepages, makelistsofpages, - makeatomfeed, + makeatomfeed, movetopublichtml } diff --git a/ferron/create-archetype-content.lua b/ferron/create-archetype-content.lua @@ -0,0 +1,55 @@ +-- +local path = require("path") +local fileutils = require("ferron.file-utils") +local tableutils = require("ferron.table-utils") +local templateutils = require("ferron.template-utils") + +local function createarchetypecontent() + if tableutils.hasvalue(Ferron.archetypes, arg[1]) and type(arg[2]) == "string" then + local archetype = {} + local contentpath = Ferron.site.path .. Ferron.site.config.SITE.PATHS.CONTENT .. "/" .. arg[1] .. "/" .. os.date("%Y") .."/"..os.date("%m") .. "/" + local archetypepath = Ferron.site.path .. Ferron.site.config.SITE.PATHS.ARCHETYPES .. "/" + + archetype.title = arg[2] + archetype.filename = string.lower(archetype.title:gsub('%p','-'):gsub('%s','-')) + archetype.date = os.date("%Y-%m-%d") + archetype.datetime = os.date("%H:%M:%S") + archetype.template = arg[1] + + if path.isdir(contentpath) == false then + fileutils.mkdir(contentpath) + end + + -- Build the markdown file + fileutils.pushfilecontent( + contentpath .. archetype.filename .. ".md", + templateutils.setmustache( + fileutils.pullfilecontent(archetypepath .. arg[1] .. ".md" ), + Ferron.site.path .. Ferron.site.config.SITE.PATHS.TEMPLATES .. "/partials", + archetype + ) + ) + + -- Build the JSON file + fileutils.pushfilecontent( + contentpath .. archetype.filename .. ".json", + templateutils.setmustache( + fileutils.pullfilecontent(archetypepath .. arg[1] .. ".json"), + Ferron.site.path .. Ferron.site.config.SITE.PATHS.TEMPLATES .. "/partials", + archetype + ) + ) + + if path.isfile(contentpath .. archetype.filename .. ".md") + and path.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 + + os.exit() + end +end + +return createarchetypecontent diff --git a/ferron/dispatch-nontextuals.lua b/ferron/dispatch-nontextuals.lua @@ -0,0 +1,35 @@ +-- +local lfs = require("lfs") +local mimetypes = require('mimetypes') +local path = require("path") +local ferronutils = require("ferron.ferron-utils") +local tableutils = require("ferron.table-utils") + +local function dispatchnontextuals(file) + local mimestable = Ferron.site.config.SITE.MIMETYPES + local prefetchedtable = Ferron.site.config.SITE.PREFETCHLIST + + path.each( + path.dirname(file) .. "/*", "f", + function(f) + if tableutils.hasvalue(mimestable, mimetypes.guess(f)) then + local listindex_dirname = path.dirname(file) + local img = f + local img_name = img:match("^.+/(.+)$") + local img_relpath = ferronutils.getrelpath(img) + local htmlfolder = Ferron.site.path .. Ferron.site.config.SITE.PATHS.HTML + + -- Then symlinks from those non-textuals for list index pages + lfs.link("." .. img:sub((listindex_dirname):len() + 1), listindex_dirname .. "/" .. img_name, true) + + -- Copy all non-textual contents (jpg, pdf, png, svg, etc.) to `public_html/` + path.copy(img, htmlfolder .. img_relpath) + + prefetchedtable[#prefetchedtable + 1] = img_relpath + end + end, + {recurse = true} + ) +end + +return dispatchnontextuals diff --git a/functions/exec.lua b/ferron/exec.lua diff --git a/functions/ferron-utils.lua b/ferron/ferron-utils.lua diff --git a/ferron/file-utils.lua b/ferron/file-utils.lua @@ -0,0 +1,96 @@ +-- +local lfs = require("lfs") +local fileutils = {} + +-- loadlocalconfig +function fileutils.loadlocalconfig(file) + local env = {} + local chunk, err = loadfile(file, 'bt', env) + + if not err then + chunk() + end + + return env, err +end + +-- getdirtree +function fileutils.getdirtree(dir) + assert(dir and dir ~= "", "directory parameter is missing or empty") + + 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 attr = lfs.attributes(entry) + + coroutine.yield(entry,attr) + + if attr.mode == "directory" then + yieldtree(entry) + end + end + end + end + + return coroutine.wrap(function() yieldtree(dir) end) +end + +-- mkdir +function fileutils.mkdir(path) + local sep, pStr = package.config:sub(1, 1), "" + + for dir in path:gmatch("[^" .. sep .. "]+") do + pStr = pStr .. sep .. dir + + lfs.mkdir(pStr) + end +end + +-- pullfilecontent +function fileutils.pullfilecontent(pathtofile) + local file = assert(io.open(pathtofile, "r")) + local content = file:read "*a" + + file:close() + + return content +end + +-- pushfilecontent +function fileutils.pushfilecontent(pathtofile, data) + local file = io.open(pathtofile, "w+") + + file:write(data) + file:close() +end + +function fileutils.getrelpath(file) + return file:sub((Ferron.site.path .. Ferron.site.config.SITE.PATHS.CONTENT):len() + 1) +end + +function fileutils.sethtmlpath(folder) + return Ferron.site.path .. Ferron.site.config.SITE.PATHS.HTML .. folder +end + +function fileutils.shorturlencode(num) + local alphabet = "23456789bcdfghjkmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ-_" + local base = alphabet:len() + local str = "" + + while num > 0 do + str = string.sub(alphabet, num % base, num % base) .. str + num = math.floor(num / base) + end + + return str +end + + +-- Export `fileutils` module +return fileutils diff --git a/ferron/get-archetypes.lua b/ferron/get-archetypes.lua @@ -0,0 +1,21 @@ +-- +local path = require("path") +local fileutils = require("ferron.file-utils") + +local function getarchetypes() + local archetypesdir = Ferron.site.path .. Ferron.site.config.SITE.PATHS.ARCHETYPES + + if path.isdir(archetypesdir) then + for archetype, attr in fileutils.getdirtree(archetypesdir) do + if attr.mode ~= "directory" + and archetype:match("^.+(%..+)$") == ".json" + then + Ferron.archetypes[#Ferron.archetypes+1] = archetype:match("^.+/(.+)$"):match("(.+)%..*") + end + end + + return Ferron.archetypes + end +end + +return getarchetypes diff --git a/ferron/get-sites.lua b/ferron/get-sites.lua @@ -0,0 +1,28 @@ +-- +local path = require("path") +local fileutils = require("ferron.file-utils") + +local function getsites() + -- Create a table with the content of `Ferron.config.paths.sites` + for site in path.each(Ferron.config.paths.sites .. "/*", "f", {delay = true; reverse = true;}) do + if path.isdir(site) then + -- Load site configuration + local siteconfig, siteconfig_err = fileutils.loadlocalconfig(site .. "/site.config.lua") + + -- Create a table with the basic infos of the site + Ferron.sites[site:match("^.+/(.+)$")] = { + path = site, + config = siteconfig, + pagestable = {} + } + + -- Create a simple array with the name of the sites + Ferron.sitesarray[#Ferron.sitesarray+1] = site:match("^.+/(.+)$") + + end + end + + return Ferron.sites, Ferron.sitesarray +end + +return getsites diff --git a/ferron/make-atom-feed.lua b/ferron/make-atom-feed.lua @@ -0,0 +1,53 @@ +-- +local path = require("path") +local fileutils = require("ferron.file-utils") +local tableutils = require("ferron.table-utils") +local templateutils = require("ferron.template-utils") + +local function makeatomfeed() + local feed = {} + local feedtemplate = path.isfile(Ferron.site.path .. Ferron.site.config.SITE.PATHS.TEMPLATES .. "/feed.mustache") + local feedrsstemplate = path.isfile(Ferron.site.path .. Ferron.site.config.SITE.PATHS.TEMPLATES .. "/rss2.mustache") + local feedpartials = path.isdir(Ferron.site.path .. Ferron.site.config.SITE.PATHS.TEMPLATES .. "/partials") + local feedfile = Ferron.site.path .. Ferron.site.config.SITE.PATHS.HTML .. "/feed.atom.xml" + local feedrssfile = Ferron.site.path .. Ferron.site.config.SITE.PATHS.HTML .. "/feed.rss.xml" + + print("§ Make an ATOM feed with all the pages of the site ...") + + feed["SITE"] = Ferron.site.config.SITE + feed["entries"] = {} + + for k, v in tableutils.sortdescendingpairs(Ferron.site.pagestable) do + table.insert(feed["entries"], v) + end + + feed["lastupdate"] = feed["entries"][1].updated + + -- Build the Atom XML file + fileutils.pushfilecontent( + feedfile, + templateutils.setmustache( + fileutils.pullfilecontent(feedtemplate), + feedpartials, + feed + ) + ) + + -- Build the RSS 2 XML file + fileutils.pushfilecontent( + feedrssfile, + templateutils.setmustache( + fileutils.pullfilecontent(feedrsstemplate), + feedpartials, + feed + ) + ) + + if path.isfile(feedfile) == false then + print(" !! /feed.atom.xml - error!") + end + + print("==========") +end + +return makeatomfeed diff --git a/ferron/make-lists-of-pages.lua b/ferron/make-lists-of-pages.lua @@ -0,0 +1,124 @@ +-- +local json = require("dkjson") +local markdown = require("markdown") +local path = require("path") +local ferronutils = require("ferron.ferron-utils") +local fileutils = require("ferron.file-utils") +local tableutils = require("ferron.table-utils") +local templateutils = require("ferron.template-utils") +local dispatchnontextuals = require("ferron.dispatch-nontextuals") + +local function makelistsofpages() + local contentpath = Ferron.site.path .. Ferron.site.config.SITE.PATHS.CONTENT + + path.each( + contentpath .. "/*.md", + function(listindex) + if path.basename(listindex) == "index.md" and listindex ~= contentpath .. "/index.md" then + local listindex = listindex + local listindex_noextension = listindex:match("(.+)%..*") + local listindex_plainname = listindex_noextension:match("^.+/(.+)$") + local listindex_dir = path.dirname(listindex) + local listindex_relpath = ferronutils.getrelpath(listindex_noextension) + local listindex_htmlpath = ferronutils.sethtmlpath(ferronutils.getrelpath(path.dirname(listindex))) + local listindex_section = path.dirname(listindex):match("^.+/(.+)$") + local listindex_metadatas = json.decode(fileutils.pullfilecontent(listindex_noextension .. ".json")) + local listindex_metadatas_mt = setmetatable({}, { __index = listindex_metadatas }) + local listindex_length = listindex_metadatas_mt.length ~= nil and listindex_metadatas_mt.length or nil + local pagecounter = listindex_length ~= nil and 0 or nil + + print("§ Make an index page for the `" .. ferronutils.getrelpath(listindex_dir) .. "` section ...") + + -- Convert the markdown file to HTML + listindex_metadatas_mt.content = markdown(fileutils.pullfilecontent(listindex)) + -- Set a dynamic permalink + listindex_metadatas_mt.permalink = Ferron.site.config.SITE.BASEURL .. path.dirname(listindex_relpath) + -- Import site configuration in the metatable + listindex_metadatas_mt["SITE"] = Ferron.site.config.SITE + -- Set a table for the list of entries + listindex_metadatas_mt["entries"] = {} + + local function setlistindexentries() + local listindex_tmp_tab = {} + + path.each( + listindex_dir .. "/*.md", + function(md) + if path.basename(md) ~= "index.md" or md == contentpath .. "/index.md" then + local md_noextension = md:match("(.+)%..*") + local md_relpath = ferronutils.getrelpath(md_noextension) + local md_section = md_relpath:match("/(%a-)/") + local md_metadatas = json.decode(fileutils.pullfilecontent(md_noextension .. ".json")) + local md_key = md_metadatas.date .. "|" .. md_metadatas.datetime .. "|" .. (md_section ~= nil and md_section or "root") .. "|" .. md_relpath + + listindex_tmp_tab[md_key] = Ferron.site.pagestable[md_key] + end + end, + { + delay = true; -- use snapshot of directory + recurse = true; -- include subdirs + reverse = false; -- subdirs at first + } + ) + + local function sortentries() + if pagecounter ~= nil then + for k, v in tableutils.sortdescendingpairs(listindex_tmp_tab) do + if pagecounter < listindex_length then + table.insert(listindex_metadatas_mt["entries"], v) + + pagecounter = pagecounter + 1 + end + end + else + for k, v in tableutils.sortdescendingpairs(listindex_tmp_tab) do + table.insert(listindex_metadatas_mt["entries"], v) + end + end + end + + sortentries() + + return listindex_metadatas_mt["entries"] + end + + setlistindexentries() + + if path.isdir(listindex_htmlpath) == false then + fileutils.mkdir(listindex_htmlpath) + end + + dispatchnontextuals(listindex) + + -- Build the HTML file + fileutils.pushfilecontent( + listindex_htmlpath .. "/" .. listindex_plainname .. ".html", + templateutils.setmustache( + fileutils.pullfilecontent(Ferron.site.path .. Ferron.site.config.SITE.PATHS.TEMPLATES .. "/" .. listindex_metadatas.template .. ".mustache"), + Ferron.site.path .. Ferron.site.config.SITE.PATHS.TEMPLATES .. "/partials", + listindex_metadatas_mt + ) + ) + + if path.isfile(listindex_htmlpath .. "/" .. listindex_plainname .. ".html") == false then + print(" !! " .. listindex_relpath .. ".html - error!") + end + + print("==========") + + -- Update the JSON file data + listindex_metadatas["entries"] = nil + listindex_metadatas["SITE"] = nil + + fileutils.pushfilecontent(listindex_noextension .. ".json", json.encode(listindex_metadatas, {indent = true, keyorder = {"bridgy","cite","citeurl","content","date","datetime","description","id","keywords","permalink","section","template","title","updated"}})) + end + end, + { + delay = true; -- use snapshot of directory + recurse = true; -- include subdirs + reverse = false; -- subdirs at first + } + ) +end + +return makelistsofpages diff --git a/ferron/make-pages.lua b/ferron/make-pages.lua @@ -0,0 +1,89 @@ +-- +local json = require("dkjson") +local markdown = require("markdown") +local path = require("path") +local ferronutils = require("ferron.ferron-utils") +local fileutils = require("ferron.file-utils") +local tableutils = require("ferron.table-utils") +local templateutils = require("ferron.template-utils") + +local function makepages() + local contentpath = Ferron.site.path .. Ferron.site.config.SITE.PATHS.CONTENT + local datapath = Ferron.site.path .. Ferron.site.config.SITE.PATHS.DATA + local pagesrelpath = {} + local shortlinks = {} + + -- Loop in the content directory + print("- Looking for markdown in " .. contentpath .. " ...") + print(" ¬ Then make the HTML pages of the site ...") + + path.each( + contentpath .. "/*.md", + function(md) + if path.basename(md) ~= "index.md" or md == contentpath .. "/index.md" then + local md = md + local md_noextension = md:match("(.+)%..*") + local md_plainname = md_noextension:match("^.+/(.+)$") + local md_relpath = ferronutils.getrelpath(md_noextension) + local md_htmlpath = ferronutils.sethtmlpath(ferronutils.getrelpath(path.dirname(md))) + local md_section = md_relpath:match("/(%a-)/") + local md_metadatas = json.decode(fileutils.pullfilecontent(md_noextension .. ".json")) + local md_metadatas_mt = setmetatable({}, { __index = md_metadatas }) + local md_key = md_metadatas.date .. "|" .. md_metadatas.datetime .. "|" .. (md_section ~= nil and md_section or "root") .. "|" .. md_relpath + + md_metadatas.updated = os.date("%Y-%m-%dT%H:%M:%S", path.mtime(md)) + md_metadatas.id = "tag:" .. Ferron.site.config.SITE.DOMAINNAME .. "," .. md_metadatas.date .. ":" .. string.sub(md_metadatas.date, 0, 4) .. "/" .. string.sub(md_metadatas.date, 6, 7) .. "/" .. md_plainname + + -- Convert the markdown file to HTML + -- And put it in a metatable + md_metadatas_mt.content = markdown(fileutils.pullfilecontent(md)) + + md_metadatas_mt.permalink = Ferron.site.config.SITE.BASEURL .. (md_plainname ~= "index" and md_relpath .. ".html" or "") + md_metadatas_mt.section = md_section + md_metadatas_mt["SITE"] = Ferron.site.config.SITE + + Ferron.site.pagestable[md_key] = md_metadatas_mt + + if path.isdir(md_htmlpath) == false then + fileutils.mkdir(md_htmlpath) + end + + -- Build the HTML file + fileutils.pushfilecontent( + md_htmlpath .. "/" .. md_plainname .. ".html", + templateutils.setmustache( + fileutils.pullfilecontent(Ferron.site.path .. Ferron.site.config.SITE.PATHS.TEMPLATES .. "/" .. md_metadatas.template .. ".mustache"), + Ferron.site.path .. Ferron.site.config.SITE.PATHS.TEMPLATES .. "/partials", + md_metadatas_mt + ) + ) + + if path.isfile(md_htmlpath .. "/" .. md_plainname .. ".html") == false then + print(" !! " .. md_relpath .. ".html - error!") + end + + --pagesrelpath[#pagesrelpath +1] = md_relpath + + -- Update the JSON file data + fileutils.pushfilecontent(md_noextension .. ".json", json.encode(md_metadatas, {indent = true, keyorder = {"bridgy","cite","citeurl","content","date","datetime","description","id","keywords","permalink","section","template","title","updated"}})) + end + end, + { + delay = true; -- use snapshot of directory + recurse = true; -- include subdirs + reverse = true; -- subdirs at first + } + ) + + -- for k, v in pairs(pagesrelpath) do + -- shortlinks[v] = ferronutils.shorturlencode(k) + -- end + + -- print(inspect(shortlinks)) + + fileutils.pushfilecontent(datapath .. "/shortlinks.json", json.encode(shortlinks, {indent = true})) + + print("==========") +end + +return makepages diff --git a/functions/move-to-publichtml.lua b/ferron/move-to-publichtml.lua diff --git a/ferron/set-site.lua b/ferron/set-site.lua @@ -0,0 +1,28 @@ +-- +local tableutils = require("ferron.table-utils") + +local function setsite() + -- Site chooser: Which site do you want to build? + local answer + + repeat + io.write("Welcome to Ferron! Which site do you want to build? \n") + + for k, v in ipairs(Ferron.sitesarray) do + io.write(k .. ") " .. v .. "\n") + end + + io.write("Please enter the number... \n") + io.flush() + + answer=io.read() + until (tableutils.haskey(Ferron.sitesarray, tonumber(answer))) == true + + Ferron.site = Ferron.sites[Ferron.sitesarray[tonumber(answer)]] + Ferron.site.config.SITE.BASEURL = (Ferron.devmode == true and Ferron.site.config.SITE.URLDEV or Ferron.site.config.SITE.URL) + Ferron.site.config.SITE.PREFETCHLIST = {} + + return Ferron.site +end + +return setsite diff --git a/functions/table-utils.lua b/ferron/table-utils.lua diff --git a/ferron/template-utils.lua b/ferron/template-utils.lua @@ -0,0 +1,20 @@ +-- +local lustache = require("lustache") +local fileutils = require("ferron.file-utils") + +local templateutils = {} + +-- setmustache +function templateutils.setmustache(tpl, partialspath, data) + local partials = {} + + for i,v in ipairs(lustache:parse(tpl)) do + if v.type == ">" then + partials[v.value] = fileutils.pullfilecontent(partialspath .. "/" .. v.value .. ".mustache") + end + end + + return lustache:render(tpl, data, partials) +end + +return templateutils diff --git a/functions/create-archetype-content.lua b/functions/create-archetype-content.lua @@ -1,55 +0,0 @@ --- -local fileutils = require("functions.file-utils") -local path = require("path") -local tableutils = require("functions.table-utils") -local templateutils = require("functions.template-utils") - -local function createarchetypecontent() - if tableutils.hasvalue(Ferron.archetypes, arg[1]) and type(arg[2]) == "string" then - local archetype = {} - local contentpath = Ferron.site.path .. Ferron.site.config.SITE.PATHS.CONTENT .. "/" .. arg[1] .. "/" .. os.date("%Y") .."/"..os.date("%m") .. "/" - local archetypepath = Ferron.site.path .. Ferron.site.config.SITE.PATHS.ARCHETYPES .. "/" - - archetype.title = arg[2] - archetype.filename = string.lower(archetype.title:gsub('%p','-'):gsub('%s','-')) - archetype.date = os.date("%Y-%m-%d") - archetype.datetime = os.date("%H:%M:%S") - archetype.template = arg[1] - - if path.isdir(contentpath) == false then - fileutils.mkdir(contentpath) - end - - -- Build the markdown file - fileutils.pushfilecontent( - contentpath .. archetype.filename .. ".md", - templateutils.setmustache( - fileutils.pullfilecontent(archetypepath .. arg[1] .. ".md" ), - Ferron.site.path .. Ferron.site.config.SITE.PATHS.TEMPLATES .. "/partials", - archetype - ) - ) - - -- Build the JSON file - fileutils.pushfilecontent( - contentpath .. archetype.filename .. ".json", - templateutils.setmustache( - fileutils.pullfilecontent(archetypepath .. arg[1] .. ".json"), - Ferron.site.path .. Ferron.site.config.SITE.PATHS.TEMPLATES .. "/partials", - archetype - ) - ) - - if path.isfile(contentpath .. archetype.filename .. ".md") - and path.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 - - os.exit() - end -end - -return createarchetypecontent diff --git a/functions/dispatch-nontextuals.lua b/functions/dispatch-nontextuals.lua @@ -1,35 +0,0 @@ --- -local lfs = require("lfs") -local mimetypes = require('mimetypes') -local path = require("path") -local ferronutils = require("functions.ferron-utils") -local tableutils = require("functions.table-utils") - -local function dispatchnontextuals(file) - local mimestable = Ferron.site.config.SITE.MIMETYPES - local prefetchedtable = Ferron.site.config.SITE.PREFETCHLIST - - path.each( - path.dirname(file) .. "/*", "f", - function(f) - if tableutils.hasvalue(mimestable, mimetypes.guess(f)) then - local listindex_dirname = path.dirname(file) - local img = f - local img_name = img:match("^.+/(.+)$") - local img_relpath = ferronutils.getrelpath(img) - local htmlfolder = Ferron.site.path .. Ferron.site.config.SITE.PATHS.HTML - - -- Then symlinks from those non-textuals for list index pages - lfs.link("." .. img:sub((listindex_dirname):len() + 1), listindex_dirname .. "/" .. img_name, true) - - -- Copy all non-textual contents (jpg, pdf, png, svg, etc.) to `public_html/` - path.copy(img, htmlfolder .. img_relpath) - - prefetchedtable[#prefetchedtable + 1] = img_relpath - end - end, - {recurse = true} - ) -end - -return dispatchnontextuals diff --git a/functions/file-utils.lua b/functions/file-utils.lua @@ -1,76 +0,0 @@ --- -local lfs = require("lfs") - -local fileutils = {} - --- loadlocalconfig -function fileutils.loadlocalconfig(file) - local env = {} - local chunk, err = loadfile(file, 'bt', env) - - if not err then - chunk() - end - - return env, err -end - --- getdirtree -function fileutils.getdirtree(dir) - assert(dir and dir ~= "", "directory parameter is missing or empty") - - 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 attr = lfs.attributes(entry) - - coroutine.yield(entry,attr) - - if attr.mode == "directory" then - yieldtree(entry) - end - end - end - end - - return coroutine.wrap(function() yieldtree(dir) end) -end - --- mkdir -function fileutils.mkdir(path) - local sep, pStr = package.config:sub(1, 1), "" - - for dir in path:gmatch("[^" .. sep .. "]+") do - pStr = pStr .. sep .. dir - - lfs.mkdir(pStr) - end -end - --- pullfilecontent -function fileutils.pullfilecontent(pathtofile) - local file = assert(io.open(pathtofile, "r")) - local content = file:read "*a" - - file:close() - - return content -end - --- pushfilecontent -function fileutils.pushfilecontent(pathtofile, data) - local file = io.open(pathtofile, "w+") - - file:write(data) - file:close() -end - - --- Export `fileutils` module -return fileutils diff --git a/functions/get-archetypes.lua b/functions/get-archetypes.lua @@ -1,21 +0,0 @@ --- -local path = require("path") -local fileutils = require("functions.file-utils") - -local function getarchetypes() - local archetypesdir = Ferron.site.path .. Ferron.site.config.SITE.PATHS.ARCHETYPES - - if path.isdir(archetypesdir) then - for archetype, attr in fileutils.getdirtree(archetypesdir) do - if attr.mode ~= "directory" - and archetype:match("^.+(%..+)$") == ".json" - then - Ferron.archetypes[#Ferron.archetypes+1] = archetype:match("^.+/(.+)$"):match("(.+)%..*") - end - end - - return Ferron.archetypes - end -end - -return getarchetypes diff --git a/functions/get-sites.lua b/functions/get-sites.lua @@ -1,28 +0,0 @@ --- -local path = require("path") -local fileutils = require("functions.file-utils") - -local function getsites() - -- Create a table with the content of `Ferron.config.paths.sites` - for site in path.each(Ferron.config.paths.sites .. "/*", "f", {delay = true; reverse = true;}) do - if path.isdir(site) then - -- Load site configuration - local siteconfig, siteconfig_err = fileutils.loadlocalconfig(site .. "/site.config.lua") - - -- Create a table with the basic infos of the site - Ferron.sites[site:match("^.+/(.+)$")] = { - path = site, - config = siteconfig, - pagestable = {} - } - - -- Create a simple array with the name of the sites - Ferron.sitesarray[#Ferron.sitesarray+1] = site:match("^.+/(.+)$") - - end - end - - return Ferron.sites, Ferron.sitesarray -end - -return getsites diff --git a/functions/make-atom-feed.lua b/functions/make-atom-feed.lua @@ -1,53 +0,0 @@ --- -local path = require("path") -local fileutils = require("functions.file-utils") -local tableutils = require("functions.table-utils") -local templateutils = require("functions.template-utils") - -local function makeatomfeed() - local feed = {} - local feedtemplate = path.isfile(Ferron.site.path .. Ferron.site.config.SITE.PATHS.TEMPLATES .. "/feed.mustache") - local feedrsstemplate = path.isfile(Ferron.site.path .. Ferron.site.config.SITE.PATHS.TEMPLATES .. "/rss2.mustache") - local feedpartials = path.isdir(Ferron.site.path .. Ferron.site.config.SITE.PATHS.TEMPLATES .. "/partials") - local feedfile = Ferron.site.path .. Ferron.site.config.SITE.PATHS.HTML .. "/feed.atom.xml" - local feedrssfile = Ferron.site.path .. Ferron.site.config.SITE.PATHS.HTML .. "/feed.rss.xml" - - print("§ Make an ATOM feed with all the pages of the site ...") - - feed["SITE"] = Ferron.site.config.SITE - feed["entries"] = {} - - for k, v in tableutils.sortdescendingpairs(Ferron.site.pagestable) do - table.insert(feed["entries"], v) - end - - feed["lastupdate"] = feed["entries"][1].updated - - -- Build the Atom XML file - fileutils.pushfilecontent( - feedfile, - templateutils.setmustache( - fileutils.pullfilecontent(feedtemplate), - feedpartials, - feed - ) - ) - - -- Build the RSS 2 XML file - fileutils.pushfilecontent( - feedrssfile, - templateutils.setmustache( - fileutils.pullfilecontent(feedrsstemplate), - feedpartials, - feed - ) - ) - - if path.isfile(feedfile) == false then - print(" !! /feed.atom.xml - error!") - end - - print("==========") -end - -return makeatomfeed diff --git a/functions/make-lists-of-pages.lua b/functions/make-lists-of-pages.lua @@ -1,124 +0,0 @@ --- -local json = require("dkjson") -local markdown = require("markdown") -local path = require("path") -local ferronutils = require("functions.ferron-utils") -local fileutils = require("functions.file-utils") -local tableutils = require("functions.table-utils") -local templateutils = require("functions.template-utils") -local dispatchnontextuals = require("functions.dispatch-nontextuals") - -local function makelistsofpages() - local contentpath = Ferron.site.path .. Ferron.site.config.SITE.PATHS.CONTENT - - path.each( - contentpath .. "/*.md", - function(listindex) - if path.basename(listindex) == "index.md" and listindex ~= contentpath .. "/index.md" then - local listindex = listindex - local listindex_noextension = listindex:match("(.+)%..*") - local listindex_plainname = listindex_noextension:match("^.+/(.+)$") - local listindex_dir = path.dirname(listindex) - local listindex_relpath = ferronutils.getrelpath(listindex_noextension) - local listindex_htmlpath = ferronutils.sethtmlpath(ferronutils.getrelpath(path.dirname(listindex))) - local listindex_section = path.dirname(listindex):match("^.+/(.+)$") - local listindex_metadatas = json.decode(fileutils.pullfilecontent(listindex_noextension .. ".json")) - local listindex_metadatas_mt = setmetatable({}, { __index = listindex_metadatas }) - local listindex_length = listindex_metadatas_mt.length ~= nil and listindex_metadatas_mt.length or nil - local pagecounter = listindex_length ~= nil and 0 or nil - - print("§ Make an index page for the `" .. ferronutils.getrelpath(listindex_dir) .. "` section ...") - - -- Convert the markdown file to HTML - listindex_metadatas_mt.content = markdown(fileutils.pullfilecontent(listindex)) - -- Set a dynamic permalink - listindex_metadatas_mt.permalink = Ferron.site.config.SITE.BASEURL .. path.dirname(listindex_relpath) - -- Import site configuration in the metatable - listindex_metadatas_mt["SITE"] = Ferron.site.config.SITE - -- Set a table for the list of entries - listindex_metadatas_mt["entries"] = {} - - local function setlistindexentries() - local listindex_tmp_tab = {} - - path.each( - listindex_dir .. "/*.md", - function(md) - if path.basename(md) ~= "index.md" or md == contentpath .. "/index.md" then - local md_noextension = md:match("(.+)%..*") - local md_relpath = ferronutils.getrelpath(md_noextension) - local md_section = md_relpath:match("/(%a-)/") - local md_metadatas = json.decode(fileutils.pullfilecontent(md_noextension .. ".json")) - local md_key = md_metadatas.date .. "|" .. md_metadatas.datetime .. "|" .. (md_section ~= nil and md_section or "root") .. "|" .. md_relpath - - listindex_tmp_tab[md_key] = Ferron.site.pagestable[md_key] - end - end, - { - delay = true; -- use snapshot of directory - recurse = true; -- include subdirs - reverse = false; -- subdirs at first - } - ) - - local function sortentries() - if pagecounter ~= nil then - for k, v in tableutils.sortdescendingpairs(listindex_tmp_tab) do - if pagecounter < listindex_length then - table.insert(listindex_metadatas_mt["entries"], v) - - pagecounter = pagecounter + 1 - end - end - else - for k, v in tableutils.sortdescendingpairs(listindex_tmp_tab) do - table.insert(listindex_metadatas_mt["entries"], v) - end - end - end - - sortentries() - - return listindex_metadatas_mt["entries"] - end - - setlistindexentries() - - if path.isdir(listindex_htmlpath) == false then - fileutils.mkdir(listindex_htmlpath) - end - - dispatchnontextuals(listindex) - - -- Build the HTML file - fileutils.pushfilecontent( - listindex_htmlpath .. "/" .. listindex_plainname .. ".html", - templateutils.setmustache( - fileutils.pullfilecontent(Ferron.site.path .. Ferron.site.config.SITE.PATHS.TEMPLATES .. "/" .. listindex_metadatas.template .. ".mustache"), - Ferron.site.path .. Ferron.site.config.SITE.PATHS.TEMPLATES .. "/partials", - listindex_metadatas_mt - ) - ) - - if path.isfile(listindex_htmlpath .. "/" .. listindex_plainname .. ".html") == false then - print(" !! " .. listindex_relpath .. ".html - error!") - end - - print("==========") - - -- Update the JSON file data - listindex_metadatas["entries"] = nil - listindex_metadatas["SITE"] = nil - - fileutils.pushfilecontent(listindex_noextension .. ".json", json.encode(listindex_metadatas, {indent = true, keyorder = {"bridgy","cite","citeurl","content","date","datetime","description","id","keywords","permalink","section","template","title","updated"}})) - end - end, - { - delay = true; -- use snapshot of directory - recurse = true; -- include subdirs - reverse = false; -- subdirs at first - } - ) -end - -return makelistsofpages diff --git a/functions/make-pages.lua b/functions/make-pages.lua @@ -1,89 +0,0 @@ --- -local json = require("dkjson") -local markdown = require("markdown") -local path = require("path") -local ferronutils = require("functions.ferron-utils") -local fileutils = require("functions.file-utils") -local tableutils = require("functions.table-utils") -local templateutils = require("functions.template-utils") - -local function makepages() - local contentpath = Ferron.site.path .. Ferron.site.config.SITE.PATHS.CONTENT - local datapath = Ferron.site.path .. Ferron.site.config.SITE.PATHS.DATA - local pagesrelpath = {} - local shortlinks = {} - - -- Loop in the content directory - print("- Looking for markdown in " .. contentpath .. " ...") - print(" ¬ Then make the HTML pages of the site ...") - - path.each( - contentpath .. "/*.md", - function(md) - if path.basename(md) ~= "index.md" or md == contentpath .. "/index.md" then - local md = md - local md_noextension = md:match("(.+)%..*") - local md_plainname = md_noextension:match("^.+/(.+)$") - local md_relpath = ferronutils.getrelpath(md_noextension) - local md_htmlpath = ferronutils.sethtmlpath(ferronutils.getrelpath(path.dirname(md))) - local md_section = md_relpath:match("/(%a-)/") - local md_metadatas = json.decode(fileutils.pullfilecontent(md_noextension .. ".json")) - local md_metadatas_mt = setmetatable({}, { __index = md_metadatas }) - local md_key = md_metadatas.date .. "|" .. md_metadatas.datetime .. "|" .. (md_section ~= nil and md_section or "root") .. "|" .. md_relpath - - md_metadatas.updated = os.date("%Y-%m-%dT%H:%M:%S", path.mtime(md)) - md_metadatas.id = "tag:" .. Ferron.site.config.SITE.DOMAINNAME .. "," .. md_metadatas.date .. ":" .. string.sub(md_metadatas.date, 0, 4) .. "/" .. string.sub(md_metadatas.date, 6, 7) .. "/" .. md_plainname - - -- Convert the markdown file to HTML - -- And put it in a metatable - md_metadatas_mt.content = markdown(fileutils.pullfilecontent(md)) - - md_metadatas_mt.permalink = Ferron.site.config.SITE.BASEURL .. (md_plainname ~= "index" and md_relpath .. ".html" or "") - md_metadatas_mt.section = md_section - md_metadatas_mt["SITE"] = Ferron.site.config.SITE - - Ferron.site.pagestable[md_key] = md_metadatas_mt - - if path.isdir(md_htmlpath) == false then - fileutils.mkdir(md_htmlpath) - end - - -- Build the HTML file - fileutils.pushfilecontent( - md_htmlpath .. "/" .. md_plainname .. ".html", - templateutils.setmustache( - fileutils.pullfilecontent(Ferron.site.path .. Ferron.site.config.SITE.PATHS.TEMPLATES .. "/" .. md_metadatas.template .. ".mustache"), - Ferron.site.path .. Ferron.site.config.SITE.PATHS.TEMPLATES .. "/partials", - md_metadatas_mt - ) - ) - - if path.isfile(md_htmlpath .. "/" .. md_plainname .. ".html") == false then - print(" !! " .. md_relpath .. ".html - error!") - end - - --pagesrelpath[#pagesrelpath +1] = md_relpath - - -- Update the JSON file data - fileutils.pushfilecontent(md_noextension .. ".json", json.encode(md_metadatas, {indent = true, keyorder = {"bridgy","cite","citeurl","content","date","datetime","description","id","keywords","permalink","section","template","title","updated"}})) - end - end, - { - delay = true; -- use snapshot of directory - recurse = true; -- include subdirs - reverse = true; -- subdirs at first - } - ) - - -- for k, v in pairs(pagesrelpath) do - -- shortlinks[v] = ferronutils.shorturlencode(k) - -- end - - -- print(inspect(shortlinks)) - - fileutils.pushfilecontent(datapath .. "/shortlinks.json", json.encode(shortlinks, {indent = true})) - - print("==========") -end - -return makepages diff --git a/functions/set-site.lua b/functions/set-site.lua @@ -1,28 +0,0 @@ --- -local tableutils = require("functions.table-utils") - -local function setsite() - -- Site chooser: Which site do you want to build? - local answer - - repeat - io.write("Welcome to Ferron! Which site do you want to build? \n") - - for k, v in ipairs(Ferron.sitesarray) do - io.write(k .. ") " .. v .. "\n") - end - - io.write("Please enter the number... \n") - io.flush() - - answer=io.read() - until (tableutils.haskey(Ferron.sitesarray, tonumber(answer))) == true - - Ferron.site = Ferron.sites[Ferron.sitesarray[tonumber(answer)]] - Ferron.site.config.SITE.BASEURL = (Ferron.devmode == true and Ferron.site.config.SITE.URLDEV or Ferron.site.config.SITE.URL) - Ferron.site.config.SITE.PREFETCHLIST = {} - - return Ferron.site -end - -return setsite diff --git a/functions/template-utils.lua b/functions/template-utils.lua @@ -1,20 +0,0 @@ --- -local lustache = require("lustache") -local fileutils = require("functions.file-utils") - -local templateutils = {} - --- setmustache -function templateutils.setmustache(tpl, partialspath, data) - local partials = {} - - for i,v in ipairs(lustache:parse(tpl)) do - if v.type == ">" then - partials[v.value] = fileutils.pullfilecontent(partialspath .. "/" .. v.value .. ".mustache") - end - end - - return lustache:render(tpl, data, partials) -end - -return templateutils