summaryrefslogtreecommitdiff
path: root/src/lua-script/script.lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/lua-script/script.lua')
-rw-r--r--src/lua-script/script.lua204
1 files changed, 196 insertions, 8 deletions
diff --git a/src/lua-script/script.lua b/src/lua-script/script.lua
index e44ece5..65bf0cf 100644
--- a/src/lua-script/script.lua
+++ b/src/lua-script/script.lua
@@ -1,3 +1,133 @@
+local RssChannel = {}
+RssChannel.new = function(title, link, description, settings)
+ local settings = settings or {}
+
+ local channel = {
+ title=title,
+ link=link,
+ description=description,
+ }
+
+ channel.language = settings.language
+ channel.copyright = settings.copyright
+ channel.managingEditor = settings.managingEditor
+ channel.webMaster = settings.webMaster
+ channel.lastBuildDate = settings.lastBuildDate
+ channel.category = settings.category
+ channel.generator = 'argent v0.1.0'
+ channel.docs = 'https://www.rssboard.org/rss-specification'
+
+ channel.items = {}
+
+ setmetatable(
+ channel,
+ {
+ __index=RssChannel,
+ __tostring=RssChannel.tostring,
+ }
+ )
+ return channel
+end
+
+
+RssChannel.addItem = function(self, tbl)
+ local to_rfc822 = function(datestring, zone)
+ if not string.match(datestring, '^%d%d%d%d%-%d%d%-%d%d$') then
+ error(string.format('%q is not a valid date string', datestring))
+ end
+
+ local year = string.match(datestring, '^%d%d%d%d')
+ local month = string.match(datestring, '-(%d%d)-')
+ local day = string.match(datestring, '%d%d$')
+
+ local month_names = {'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'}
+ month = month_names[tonumber(month)]
+
+ return string.format('%s %s %s 00:00:00 %s', day, month, year, zone)
+ end
+
+ if not (tbl.title or tbl.description) then
+ error('items must specify either a title or description!')
+ end
+
+ if not tbl.pubDate then
+ error('items must specify a pubDate!')
+ else
+ tbl.pubDate = to_rfc822(tbl.pubDate, 'Z')
+ print(tbl.pubDate)
+ end
+
+ table.insert(self.items, tbl)
+end
+
+
+local tag_builder = function(source_table, indent_level)
+ local str = ''
+ local indent = string.rep(' ', indent_level)
+ local add_tag = function(tag)
+ if source_table[tag] then
+ str = str ..
+ string.format('%s<%s>%s</%s>\n',
+ indent, tag, source_table[tag], tag)
+ end
+ end
+ local content = function()
+ return str
+ end
+ return add_tag, content
+end
+
+local render_item = function(item_tbl)
+ local add_tag, content = tag_builder(item_tbl, 2)
+ add_tag('title')
+ add_tag('link')
+ add_tag('description')
+ add_tag('author')
+ add_tag('category')
+ add_tag('comments')
+ add_tag('guid')
+ add_tag('pubDate')
+
+ local indent = string.rep(' ', 1)
+ return string.format('%s<item>\n%s%s</item>',
+ indent, content(), indent)
+end
+
+RssChannel.tostring = function(self)
+ local add_tag, content = tag_builder(self, 1)
+ add_tag('title')
+ add_tag('link')
+ add_tag('description')
+
+ add_tag('language')
+ add_tag('copyright')
+ add_tag('managingEditor')
+ add_tag('webMaster')
+ add_tag('pubDate')
+ add_tag('lastBuildDate')
+ add_tag('category')
+ add_tag('generator')
+ add_tag('docs')
+
+ items_str = ''
+
+ for _, item in ipairs(self.items) do
+ items_str = items_str .. render_item(item) .. '\n'
+ end
+
+ return string.format(
+ '<rss version="2.0">\n<channel>\n%s\n%s</channel>\n</rss>',
+ content(), items_str)
+end
+
+
+RssChannel.save = function(self, filename)
+ file = io.open(filename, 'w')
+ file:write(self:tostring())
+ file:close()
+end
+
+
return function(config)
local fmt = string.format
@@ -21,6 +151,7 @@ return function(config)
function set_tostring(set)
local str = '[empty]'
+ if not set then return str end
for element in pairs(set) do
if str == '[empty]' then
str = tostring(element)
@@ -82,17 +213,30 @@ return function(config)
function setup(config)
argent.log('debug', 'begin setup')
-
+
+ if not config.site_name then
+ error('site_name MUST be set!')
+ end
+
argent.config = {
+ site_name = config.site_name,
+ site_address = add_end_slash(config.site_address) or nil,
+ site_description = config.site_description or '',
+ site_language = config.site_language,
+ site_copyright = config.site_copyright,
+
site_directory = add_end_slash(config.site_directory) or 'site/',
output_directory = add_end_slash(config.output_directory) or 'public/',
layout_directory = add_end_slash(config.layout_directory) or nil,
plugin_directory = add_end_slash(config.plugin_directory) or nil,
+
exclude = Set(config.exclude, strip_end_slash) or {},
include = Set(config.include, strip_end_slash) or {},
keep = Set(config.keep, strip_end_slash) or {},
noprocess = Set(config.noprocess, strip_end_slash) or {},
- rss_include = Set(config.rss_include, strip_end_slash) or {},
+
+ rss_include = Set(config.rss_include, strip_end_slash) or nil,
+ webmaster_email = config.webmaster_email,
}
argent.log('info', fmt('site directory: %s', argent.config.site_directory))
@@ -118,6 +262,22 @@ return function(config)
add_end_slash(argent.currentWorkingDirectory())
..argent.config.plugin_directory..'?.lua;'..package.path
end
+
+ if argent.config.rss_include then
+ if not argent.config.site_address then
+ error('rss_include is set, but site_address is not!')
+ end
+ argent.rss_channel = RssChannel.new(
+ argent.config.site_name,
+ argent.config.site_address,
+ argent.config.site_description,
+ { language = argent.config.site_language,
+ copyright = argent.config.site_copyright,
+ webMaster = argent.config.webmaster_email,
+ }
+ )
+ end
+
argent.log('debug', 'end setup')
end
@@ -175,11 +335,11 @@ return function(config)
end
argent.log('debug', fmt('obliterating files in %q', parent..dir))
- return obliterate_directory(dir, parent)
+ return obliterate(dir, parent)
end
- function obliterate_directory(dirname, parent)
+ function obliterate(dirname, parent)
local dirname = add_end_slash(dirname) or ''
local parent = parent or ''
@@ -324,6 +484,30 @@ return function(config)
local output_file = io.open(argent.config.output_directory..parent..output_name, 'w')
output_file:write(output_data)
output_file:close()
+
+ for pattern in pairs(argent.config.rss_include) do
+ if string.match(filename, pattern)
+ or string.match(parent..filename, pattern)
+ then -- add to the RSS feed!
+ if not result.date then
+ argent.log(
+ 'warn',
+ fmt(
+ '%q did not specify a date; it will not be included in rss.xml!',
+ parent..filename
+ )
+ )
+ return
+ end
+
+ argent.rss_channel:addItem{
+ title=result.title,
+ link=argent.config.site_address..parent..output_name,
+ description = result.description,
+ pubDate = result.date,
+ }
+ end
+ end
end
@@ -336,11 +520,11 @@ return function(config)
if not directory_exists(directory, parent) then
argent.createDirectory(argent.config.output_directory..parent..directory)
end
- process_directory(directory, parent)
+ process(directory, parent)
end
- function process_directory(directory, parent)
+ function process(directory, parent)
local directory = add_end_slash(directory) or ''
local parent = add_end_slash(parent) or ''
local dirs, files = argent.scanDirectory(argent.config.site_directory..parent..directory)
@@ -366,7 +550,11 @@ return function(config)
if not output_directory_exists() then
argent.createDirectory(argent.config.output_directory)
else
- obliterate_directory()
+ obliterate()
+ end
+ process()
+
+ if argent.rss_channel then
+ argent.rss_channel:save(argent.config.output_directory..'rss.xml')
end
- process_directory()
end