diff options
-rw-r--r-- | Makefile | 7 | ||||
-rwxr-xr-x | generate-atom.lua | 21 | ||||
-rwxr-xr-x | generate-index.lua | 70 | ||||
-rw-r--r-- | huh/blog.lua | 37 | ||||
-rw-r--r-- | huh/config.lua | 27 | ||||
-rw-r--r-- | huh/datetime.lua | 24 |
6 files changed, 121 insertions, 65 deletions
@@ -1,15 +1,22 @@ +LUA_VERSION=5.4 DESTDIR= PREFIX=/usr/local PREFIX_EXEC=$(PREFIX) BINDIR=$(PREFIX_EXEC)/bin +DATADIR=$(PREFIX)/share +LUA_LMOD=$(DATADIR)/lua/$(LUA_VERSION) all: @echo nothing to do install: + install -m755 -DT generate-atom.lua $(DESTDIR)$(BINDIR)/generate-atom install -m755 -DT generate-index.lua $(DESTDIR)$(BINDIR)/generate-index + install -m644 -Dt $(DESTDIR)$(LUA_LMOD)/huh huh/*.lua uninstall: + rm -f $(DESTDIR)$(BINDIR)/generate-atom rm -f $(DESTDIR)$(BINDIR)/generate-index + rm -rf $(DESTDIR)$(LUA_LMOD)/huh .PHONY: all install uninstall diff --git a/generate-atom.lua b/generate-atom.lua new file mode 100755 index 0000000..075dbb5 --- /dev/null +++ b/generate-atom.lua @@ -0,0 +1,21 @@ +#!/usr/bin/env lua +local datetime = require"huh.datetime" +local config = require"huh.config".load(arg[1]) +local posts = require"huh.blog".posts(config) +local prefix = "https://ignore.pl/" +local count = 5 +for _, page in pairs(posts) do + if count <= 0 then + break + end + local url = prefix .. page.filename + print"<entry>" + print(string.format("<title>%s</title>", page.title)) + print(string.format("<id>%s</id>", url)) + print(string.format([[<link href="%s"/>]], url)) + -- TODO: Unlike shell implementation, updated date here is sourced only from the file and never from git! + print(string.format("<updated>%s</updated>", page.updated or page.published)) + print(string.format("<published>%s</published>", page.published)) + print"</entry>" + count = count - 1 +end diff --git a/generate-index.lua b/generate-index.lua index 1ab4db4..b53beb2 100755 --- a/generate-index.lua +++ b/generate-index.lua @@ -1,78 +1,18 @@ #!/usr/bin/env lua -local config = require"pl.config" -local dir = require"pl.dir" -local gumbo = require"gumbo" -local tablex = require"pl.tablex" - - -local function parse (stamp) - local year, month, day, hour, min, sec = stamp:match"(%d+)-(%d?%d)-(%d?%d)T(%d?%d):(%d?%d):(%d?%d)" - return { - year = tonumber(year), - month = tonumber(month), - day = tonumber(day), - hour = tonumber(hour), - min = tonumber(min), - sec = tonumber(sec), - } -end - - -local function describe (date) - -- strftime(3) still does not support printing day of month without leading zero or space. - return string.format("%d %s", date.day, os.date("%B", os.time(date))) -end - - -config = config.read(arg[1] or "huh.conf") or {} -config.excludes = tablex.makeset(config.excludes or {}) - - -local function matches (str) - if config.pattern then - return str:match(config.pattern) - end - return str -end - - -local pages = dir.getfiles(".", "*.html") -local takeaways = { - ["published-on"] = "published", - ["last-modified-on"] = "modified", -} -local posts = {} -for _, filename in pairs(pages) do - local document = gumbo.parseFile(filename) - local metas = document:getElementsByTagName"meta" - local properties = {title=document.title, filename=filename:sub(3), published=""} - for _, meta in ipairs(metas) do - local take = nil - for _, attribute in ipairs(meta.attributes) do - if attribute.name == "name" then - take = takeaways[attribute.value] - end - if take and attribute.name == "content" then - properties[take] = attribute.value - end - end - end - if matches(properties.filename) and not config.excludes[properties.filename] then - table.insert(posts, properties) - end -end -table.sort(posts, function (lhs, rhs) return lhs.published > rhs.published end) +local datetime = require"huh.datetime" +local config = require"huh.config".load(arg[1]) +local posts = require"huh.blog".posts(config) print[[<table class="index">]] local year = nil local previous = nil for _, page in pairs(posts) do - local date = parse(page.published) + local date = datetime.parse(page.published) if date and year ~= date.year then year = date.year previous = nil print(string.format("<tr><td><b>%d</b><td><td>", year)) end - date = describe(date) + date = datetime.describe(date) if date == previous then date = "" else diff --git a/huh/blog.lua b/huh/blog.lua new file mode 100644 index 0000000..fbfb95b --- /dev/null +++ b/huh/blog.lua @@ -0,0 +1,37 @@ +local dir = require"pl.dir" +local gumbo = require"gumbo" +local blog = {} +local takeaways = { + ["published-on"] = "published", + ["last-modified-on"] = "modified", +} + + +function blog.posts (config) + local pages = dir.getfiles(".", "*.html") + local posts = {} + for _, filename in pairs(pages) do + local document = gumbo.parseFile(filename) + local metas = document:getElementsByTagName"meta" + local properties = {title=document.title, filename=filename:sub(3), published=""} + for _, meta in ipairs(metas) do + local take = nil + for _, attribute in ipairs(meta.attributes) do + if attribute.name == "name" then + take = takeaways[attribute.value] + end + if take and attribute.name == "content" then + properties[take] = attribute.value + end + end + end + if config:check(properties.filename) then + table.insert(posts, properties) + end + end + table.sort(posts, function (lhs, rhs) return lhs.published > rhs.published end) + return posts +end + + +return blog diff --git a/huh/config.lua b/huh/config.lua new file mode 100644 index 0000000..3f747b6 --- /dev/null +++ b/huh/config.lua @@ -0,0 +1,27 @@ +local plconf = require"pl.config" +local tablex = require "pl.tablex" +local config = {} +local mt = {__index=config} + + +function config.load (filename) + local cfg = plconf.read(filename or "huh.conf") or {} + cfg.excludes = tablex.makeset(cfg.excludes or {}) + return setmetatable(cfg, mt) +end + + +function config:check_with_pattern (str) + if self.pattern then + return str:match(self.pattern) + end + return str +end + + +function config:check (str) + return self:check_with_pattern(str) and not self.excludes[str] +end + + +return config diff --git a/huh/datetime.lua b/huh/datetime.lua new file mode 100644 index 0000000..361177a --- /dev/null +++ b/huh/datetime.lua @@ -0,0 +1,24 @@ +local datetime = {} + + +--- Create an os.time() compatible datetime table from a ISO 8601 compliant [[stamp]]. +function datetime.parse (stamp) + local year, month, day, hour, min, sec = stamp:match"(%d+)-(%d?%d)-(%d?%d)T(%d?%d):(%d?%d):(%d?%d)" + return { + year = tonumber(year), + month = tonumber(month), + day = tonumber(day), + hour = tonumber(hour), + min = tonumber(min), + sec = tonumber(sec), + } +end + + +function datetime.describe (date) + -- strftime(3) still does not support printing day of month without leading zero or space. + return string.format("%d %s", date.day, os.date("%B", os.time(date))) +end + + +return datetime |