#!/usr/bin/env lua5.1 --[[ This is a Gemtext→HTML static site generator. This program: * Searches src/ for directories, then mirrors the directory tree to html/ * Reads all files in src/, attempts to render them from Gemtext to html, then outputs to the appropriate .html file in html/ * Reads files in src/w/ for h2 elements with dates in YYYY-MM-DD format, using them to render an RSS feed to html/index.xml; entries in the feed are sorted in descending order by file name so be sure to name them by date * Recursively copies files from static/ to html/ This site generator depends on LuaFileSystem and geez https://lunarmodules.github.io/luafilesystem/ https://pixelo789.codeberg.page/geez It is assumed that LuaFileSystem is installed using LuaRocks, and that geez's geez.lua is placed in the same directory as this file. ]]-- local lfs = require "lfs" local function iteratefiles(path, mode) local dattr = lfs.attributes(path) assert(dattr.mode == "directory") for file in lfs.dir(path) do if file ~= "." and file ~= ".." then local filepath = ("%s/%s"):format(path, file) local attr = lfs.attributes(filepath) if attr.mode == mode then coroutine.yield(filepath) end if attr.mode == "directory" then iteratefiles(filepath, mode) end end end end local function eachfile(path, mode) return coroutine.wrap(function() iteratefiles(path, mode) end) end local dirs = {} for dir in eachfile("src", "directory") do table.insert(dirs, dir) end do -- Set up output directory local hattr = lfs.attributes "html" if hattr and hattr.mode ~= "directory" then os.execute "rm html" hattr = nil end if not hattr then lfs.mkdir("html") end os.execute "cp -r static/* html" end -- Recreate the src/ directory tree in html/ for _, dir in ipairs(dirs) do local path = dir:gsub("^src", "html") lfs.mkdir(path) end -- File Rendering local files = {} for file in eachfile("src", "file") do table.insert(files, file) end table.sort(files, function(a, b) return a > b end) local htmltemplate = "" do local file = io.open("templates/index.html", "r") or error "failed to load templates/index.html" for line in file:lines() do htmltemplate = htmltemplate .. line .. "\n" end end local geez = require "geez" local function rendergemtext(path) local source = io.open(path, "r") local ast = geez.GeminiAST() local gemtext = "" local isroot = path:match "^src/index.gmi" local ispost = path:match "^src/w/" -- Manually insert links at the top of pages if not isroot then gemtext = gemtext .. "=> /index.gmi vtrlx.ca (Victoria Lacroix)\n" end if ispost then gemtext = gemtext .. "=> /posts.gmi All posts\n" end for line in source:lines() do gemtext = gemtext .. line .. "\n" end ast:load_str(gemtext) local html = ast:get_html_doc { indent_level = 1, } local path = path:gsub("^src", "html"):gsub(".gmi$", ".html") local dest = io.open(path, "w") local title = html:match "