summaryrefslogtreecommitdiff
path: root/src/lua-script
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2022-01-04 00:28:38 -0600
committersanine <sanine.not@pm.me>2022-01-04 00:28:38 -0600
commitcb4f641884ae6104f44967949f9b52a9a72f7baf (patch)
tree4819c0cc48f18b87d119d9b4bb393ef2bf4fe290 /src/lua-script
parent5830f684ba172664df43eee26636e99e5a228028 (diff)
write first-pass main lua script
Diffstat (limited to 'src/lua-script')
-rw-r--r--src/lua-script/cify.lua13
-rw-r--r--src/lua-script/script.h209
-rw-r--r--src/lua-script/script.lua207
3 files changed, 429 insertions, 0 deletions
diff --git a/src/lua-script/cify.lua b/src/lua-script/cify.lua
new file mode 100644
index 0000000..153feb3
--- /dev/null
+++ b/src/lua-script/cify.lua
@@ -0,0 +1,13 @@
+-- "C"-ify a lua program
+
+output_file = io.open(arg[2], 'w')
+
+
+output_file:write('const char *argent_script =\n')
+
+for line in io.lines(arg[1]) do
+ output_file:write(' "'..line..'\\n"\n')
+end
+
+output_file:write(';')
+output_file:close()
diff --git a/src/lua-script/script.h b/src/lua-script/script.h
new file mode 100644
index 0000000..e419923
--- /dev/null
+++ b/src/lua-script/script.h
@@ -0,0 +1,209 @@
+const char *argent_script =
+ "return function(config)\n"
+ "\n"
+ " --------------------------------\n"
+ " --\n"
+ " -- basics\n"
+ " --\n"
+ " --------------------------------\n"
+ "\n"
+ " function Set(array, transform)\n"
+ " if type(array) ~= 'table' then return nil end\n"
+ "\n"
+ " local transform = transform or function(x) return x end\n"
+ " \n"
+ " local set = {}\n"
+ " for _, element in ipairs(array) do\n"
+ " set[transform(element)] = true\n"
+ " end\n"
+ " return set\n"
+ " end\n"
+ "\n"
+ "\n"
+ " function add_end_slash(str)\n"
+ " if type(str) ~= 'string' then return nil end\n"
+ " if string.match(str, '/$') then return str end\n"
+ " return str .. '/'\n"
+ " end\n"
+ "\n"
+ "\n"
+ " function strip_end_slash(str)\n"
+ " if string.match(str, '/$') then return string.sub(str, 1, #str-1) end\n"
+ " return str\n"
+ " end\n"
+ "\n"
+ "\n"
+ " function setup(config)\n"
+ " argent.config = {\n"
+ " site_directory = add_end_slash(config.site_directory) or 'site/',\n"
+ " output_directory = add_end_slash(config.output_directory) or 'public/',\n"
+ " layout_directory = add_end_slash(config.layout_directory) or 'layouts/',\n"
+ " plugin_directory = add_end_slash(config.layout_directory) or 'plugins/',\n"
+ " exclude = Set(config.exclude, strip_end_slash) or {},\n"
+ " include = Set(config.include, strip_end_slash) or {},\n"
+ " keep = Set(config.keep, strip_end_slash) or {},\n"
+ " noprocess = Set(config.noprocess, strip_end_slash) or {},\n"
+ " rss_include = Set(config.rss_include, strip_end_slash) or {},\n"
+ " }\n"
+ "\n"
+ " package.path = argent.config.plugin_directory..'?.lua;'..package.path\n"
+ " end\n"
+ "\n"
+ "\n"
+ " function is_dotfile(filename)\n"
+ " if string.match(filename, '^%.') then return true end\n"
+ " return false\n"
+ " end\n"
+ "\n"
+ "\n"
+ " function directory_exists(directory, parent)\n"
+ " local directory = directory or ''\n"
+ " local parent = parent or ''\n"
+ " local dirs = argent.scanDirectory(argent.config.output_directory..parent)\n"
+ " for _, dir in ipairs(dirs) do\n"
+ " if strip_end_slash(directory) == dir then return true end\n"
+ " end\n"
+ " return false\n"
+ " end\n"
+ "\n"
+ "\n"
+ " function output_directory_exists()\n"
+ " local dirs = argent.scanDirectory('./')\n"
+ " for _, dir in ipairs(dirs) do\n"
+ " if add_end_slash(dir) == argent.config.output_directory then\n"
+ " return true\n"
+ " end\n"
+ " end\n"
+ " return false\n"
+ " end\n"
+ "\n"
+ "\n"
+ " --------------------------------\n"
+ " --\n"
+ " -- obliterating\n"
+ " --\n"
+ " --------------------------------\n"
+ "\n"
+ " function obliterate_file(file, parent)\n"
+ " if argent.config.keep[file] then\n"
+ " return true\n"
+ " end\n"
+ "\n"
+ " os.remove(argent.config.output_directory..parent..file)\n"
+ " return false\n"
+ " end\n"
+ "\n"
+ "\n"
+ " function obliterate_dir(dir, parent)\n"
+ " if argent.config.keep[strip_end_slash(dir)] then\n"
+ " return true\n"
+ " end\n"
+ "\n"
+ " return obliterate_directory(dir, parent)\n"
+ " end\n"
+ "\n"
+ "\n"
+ " function obliterate_directory(dirname, parent)\n"
+ " local dirname = add_end_slash(dirname) or ''\n"
+ " local parent = parent or ''\n"
+ " \n"
+ " if argent.config.keep[dirname] then return true end\n"
+ "\n"
+ " local keep_self = (dirname == '')\n"
+ "\n"
+ " local dirs, files = argent.scanDirectory(argent.config.output_directory..parent..dirname)\n"
+ " for _, file in ipairs(files) do\n"
+ " keep_self = obliterate_file(file, parent..dirname) or keep_self\n"
+ " end\n"
+ " for _, dir in ipairs(dirs) do\n"
+ " if dir ~= '.' and dir ~= '..' then\n"
+ " keep_self = obliterate_dir(dir, parent..dirname) or keep_self\n"
+ " end\n"
+ " end\n"
+ "\n"
+ " if not keep_self then\n"
+ " os.remove(argent.config.output_directory..parent..dirname)\n"
+ " return false\n"
+ " else\n"
+ " return true\n"
+ " end\n"
+ " end\n"
+ "\n"
+ "\n"
+ " --------------------------------\n"
+ " --\n"
+ " -- processing\n"
+ " --\n"
+ " --------------------------------\n"
+ "\n"
+ " function process_file(filename, parent)\n"
+ " if (is_dotfile(filename) and not argent.config.include[filename])\n"
+ " or argent.config.exclude[filename]\n"
+ " then return end\n"
+ "\n"
+ " if string.match(filename, '%.lua$') and not argent.config.noprocess[filename] then\n"
+ " process_lua_file(filename, parent)\n"
+ " else\n"
+ " argent.copyFile(\n"
+ " argent.config.site_directory..parent..filename,\n"
+ " argent.config.output_directory..parent..filename\n"
+ " )\n"
+ " end\n"
+ " end\n"
+ "\n"
+ "\n"
+ " function process_lua_file(filename, parent)\n"
+ " local success, result = pcall(loadfile(argent.config.site_directory..parent..filename))\n"
+ " if not success then\n"
+ " print('WARNING: '..result)\n"
+ " return\n"
+ " end\n"
+ "\n"
+ " print(filename, result)\n"
+ " end\n"
+ "\n"
+ "\n"
+ " function process_dir(directory, parent)\n"
+ " if (is_dotfile(directory) and not argent.config.include[strip_end_slash(directory)])\n"
+ " or argent.config.exclude[strip_end_slash(directory)]\n"
+ " then return end\n"
+ "\n"
+ " if not directory_exists(directory, parent) then\n"
+ " argent.createDirectory(argent.config.output_directory..parent..directory)\n"
+ " end\n"
+ " process_directory(directory, parent)\n"
+ " end\n"
+ "\n"
+ "\n"
+ " function process_directory(directory, parent)\n"
+ " local directory = add_end_slash(directory) or ''\n"
+ " local parent = add_end_slash(parent) or ''\n"
+ " local dirs, files = argent.scanDirectory(argent.config.site_directory..parent..directory)\n"
+ " for _, file in ipairs(files) do\n"
+ " process_file(file, parent..directory)\n"
+ " end\n"
+ "\n"
+ " for _, dir in ipairs(dirs) do\n"
+ " if dir ~= '.' and dir ~= '..' then\n"
+ " process_dir(dir, parent..directory)\n"
+ " end\n"
+ " end\n"
+ " end\n"
+ "\n"
+ "\n"
+ " --------------------------------\n"
+ " --\n"
+ " -- putting it all together\n"
+ " --\n"
+ " --------------------------------\n"
+ "\n"
+ " setup(config)\n"
+ " if not output_directory_exists() then\n"
+ " argent.createDirectory(argent.config.output_directory)\n"
+ " else\n"
+ " obliterate_directory()\n"
+ " end\n"
+ " process_directory()\n"
+ "end\n"
+ "\n"
+; \ No newline at end of file
diff --git a/src/lua-script/script.lua b/src/lua-script/script.lua
new file mode 100644
index 0000000..733c494
--- /dev/null
+++ b/src/lua-script/script.lua
@@ -0,0 +1,207 @@
+return function(config)
+
+ --------------------------------
+ --
+ -- basics
+ --
+ --------------------------------
+
+ function Set(array, transform)
+ if type(array) ~= 'table' then return nil end
+
+ local transform = transform or function(x) return x end
+
+ local set = {}
+ for _, element in ipairs(array) do
+ set[transform(element)] = true
+ end
+ return set
+ end
+
+
+ function add_end_slash(str)
+ if type(str) ~= 'string' then return nil end
+ if string.match(str, '/$') then return str end
+ return str .. '/'
+ end
+
+
+ function strip_end_slash(str)
+ if string.match(str, '/$') then return string.sub(str, 1, #str-1) end
+ return str
+ end
+
+
+ function setup(config)
+ argent.config = {
+ 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 'layouts/',
+ plugin_directory = add_end_slash(config.layout_directory) or 'plugins/',
+ 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 {},
+ }
+
+ package.path = argent.config.plugin_directory..'?.lua;'..package.path
+ end
+
+
+ function is_dotfile(filename)
+ if string.match(filename, '^%.') then return true end
+ return false
+ end
+
+
+ function directory_exists(directory, parent)
+ local directory = directory or ''
+ local parent = parent or ''
+ local dirs = argent.scanDirectory(argent.config.output_directory..parent)
+ for _, dir in ipairs(dirs) do
+ if strip_end_slash(directory) == dir then return true end
+ end
+ return false
+ end
+
+
+ function output_directory_exists()
+ local dirs = argent.scanDirectory('./')
+ for _, dir in ipairs(dirs) do
+ if add_end_slash(dir) == argent.config.output_directory then
+ return true
+ end
+ end
+ return false
+ end
+
+
+ --------------------------------
+ --
+ -- obliterating
+ --
+ --------------------------------
+
+ function obliterate_file(file, parent)
+ if argent.config.keep[file] then
+ return true
+ end
+
+ os.remove(argent.config.output_directory..parent..file)
+ return false
+ end
+
+
+ function obliterate_dir(dir, parent)
+ if argent.config.keep[strip_end_slash(dir)] then
+ return true
+ end
+
+ return obliterate_directory(dir, parent)
+ end
+
+
+ function obliterate_directory(dirname, parent)
+ local dirname = add_end_slash(dirname) or ''
+ local parent = parent or ''
+
+ if argent.config.keep[dirname] then return true end
+
+ local keep_self = (dirname == '')
+
+ local dirs, files = argent.scanDirectory(argent.config.output_directory..parent..dirname)
+ for _, file in ipairs(files) do
+ keep_self = obliterate_file(file, parent..dirname) or keep_self
+ end
+ for _, dir in ipairs(dirs) do
+ if dir ~= '.' and dir ~= '..' then
+ keep_self = obliterate_dir(dir, parent..dirname) or keep_self
+ end
+ end
+
+ if not keep_self then
+ os.remove(argent.config.output_directory..parent..dirname)
+ return false
+ else
+ return true
+ end
+ end
+
+
+ --------------------------------
+ --
+ -- processing
+ --
+ --------------------------------
+
+ function process_file(filename, parent)
+ if (is_dotfile(filename) and not argent.config.include[filename])
+ or argent.config.exclude[filename]
+ then return end
+
+ if string.match(filename, '%.lua$') and not argent.config.noprocess[filename] then
+ process_lua_file(filename, parent)
+ else
+ argent.copyFile(
+ argent.config.site_directory..parent..filename,
+ argent.config.output_directory..parent..filename
+ )
+ end
+ end
+
+
+ function process_lua_file(filename, parent)
+ local success, result = pcall(loadfile(argent.config.site_directory..parent..filename))
+ if not success then
+ print('WARNING: '..result)
+ return
+ end
+
+ print(filename, result)
+ end
+
+
+ function process_dir(directory, parent)
+ if (is_dotfile(directory) and not argent.config.include[strip_end_slash(directory)])
+ or argent.config.exclude[strip_end_slash(directory)]
+ then return end
+
+ if not directory_exists(directory, parent) then
+ argent.createDirectory(argent.config.output_directory..parent..directory)
+ end
+ process_directory(directory, parent)
+ end
+
+
+ function process_directory(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)
+ for _, file in ipairs(files) do
+ process_file(file, parent..directory)
+ end
+
+ for _, dir in ipairs(dirs) do
+ if dir ~= '.' and dir ~= '..' then
+ process_dir(dir, parent..directory)
+ end
+ end
+ end
+
+
+ --------------------------------
+ --
+ -- putting it all together
+ --
+ --------------------------------
+
+ setup(config)
+ if not output_directory_exists() then
+ argent.createDirectory(argent.config.output_directory)
+ else
+ obliterate_directory()
+ end
+ process_directory()
+end
+