local std = require("lib.std") local symbol = require("lib.symbol") local M = {} M.__index = M function M.fes(header, footer) local config = {} local site_config = {} local fes_mod = package.loaded.fes if fes_mod and fes_mod.config then config = fes_mod.config if config.site then site_config = config.site end end if site_config.favicon then site_config.favicon = '' end local self = { version = site_config.version, title = site_config.title, copyright = site_config.copyright, favicon = site_config.favicon, header = header or [[ {{FAVICON}} {{TITLE}}
]], footer = footer or [[
]], parts = {}, } return setmetatable(self, M) end function M:g(str) table.insert(self.parts, str) return self end function M:extend(name, tbl) if type(name) ~= "string" then error("First argument to extend must be a string (namespace name)") end if type(tbl) ~= "table" then error("Second argument to extend must be a table of functions") end self[name] = {} for k, v in pairs(tbl) do if type(v) ~= "function" then error("Extension values must be functions, got " .. type(v) .. " for key " .. k) end self[name][k] = function(...) return v(self, ...) end end return self end for name, func in pairs(std) do if type(func) == "function" then M[name] = function(self, ...) local result = func(...) table.insert(self.parts, result) return self end end end function M:build() local header = self.header header = header:gsub("{{TITLE}}", self.title or "Document") local favicon_html = self.favicon and ('') header = header:gsub( "{{FAVICON}}", favicon_html or [[]] ) local footer = self.footer:gsub("{{COPYRIGHT}}", self.copyright or symbol.legal.copyright .. "The Copyright Holder") return header .. table.concat(self.parts, "\n") .. footer end M.__tostring = function(self) return self:build() end return M