From d2ba262c5307aa14c325ef53d8e4e56a5ece0376 Mon Sep 17 00:00:00 2001 From: Alexander Pickering Date: Sun, 5 Jul 2020 12:22:36 -0400 Subject: Initial Commit --- opt_parser.lua | 188 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 opt_parser.lua (limited to 'opt_parser.lua') diff --git a/opt_parser.lua b/opt_parser.lua new file mode 100644 index 0000000..d99c804 --- /dev/null +++ b/opt_parser.lua @@ -0,0 +1,188 @@ + +local lfs = require("lfs") +require("ext") +local ret = {} + +ret.options = { + paths = { + type = "folder", + multiple = true, + short = "-p", + long = "--path", + consumes = 1, + }, + output = { + type = "folder", + short = "-o", + long = "--output", + consumes = 1, + default = ".", + }, + title = { + type = "string", + short = "-t", + long = "--tile", + consumes = 1, + default = "Mdoc Generated Page", + }, + index = { + type = "file", + short = "-i", + long = "--index", + consumes = 1, + }, + document_paths = { + type = "folder", + multiple = true, + short = "-d", + long = "--document", + consumes = 1, + }, + parser = { + type = "executable", + short = "-m", + long = "--markup-parser", + consumes = 1, + default = "markdown", + }, + --append = { + --type = "file", + --short = "-a", + --long = "--append", + --consumes = 1, + --multiple = true, + --}, + verbose = { + type = "flag", + short = "-v", + long = "--verbose" + }, + help = { + type = "flag", + short = "-h", + long = "--help", + } +} + +local function check_file_type(path, type) + local attr, err = lfs.attributes(path) + if attr == nil then + return attr, err + end + if attr.mode == type then + return path + else + return false, string.format("%s was not a folder, it was a %s",path, attr.mode) + end +end + +ret.check_flag = function(...) + return true +end + +ret.check_folder = function(path) + if path:match("/$") then + path = path:sub(1,-2) + end + return check_file_type(path,"directory") +end + +ret.check_string = function(str) + if type(str) == "string" then + return str + else + return false, string.format("%s was not a string, it was a %s",tostring(str), type(str)) + end +end + +ret.check_file = function(path) + return check_file_type(path,"file") +end + +ret.check_executable = function(name) + local tmpname = "./" .. os.tmpname() + local pd = assert(io.popen(name .. " > " .. tmpname, "w")) + pd:write("Hello, world!") + pd:close() + local id = assert(io.open(tmpname,"r")) + local dat = id:read("*a") + id:close() + assert(os.remove(tmpname)) + if string.len(dat) > 0 then + return name + else + return false, string.format("Tried to execute %q, but it did not create any data with the input 'Hello, world!', are you sure it's an executale on your PATH?", name) + end +end + +local option_lookup = {} +for k,v in pairs(ret.options) do + if v.short then + option_lookup[v.short] = k + end + if v.long then + option_lookup[v.long] = k + end +end + +ret.parse_options = function(args) + print("parsing args:",args) + local parsed = {} + local i = 1 + while i <= #args do + local option_name = option_lookup[args[i]] + print("found option:",option_name) + if not option_name then + errorf("Unknown option #%d: %q",i, args[i]) + end + local option = ret.options[option_name] + assertf(#args > i + (option.consumes or 0) - 1, "Option #%d (%q) consumes %d arguments, but found end of arguments",i,args[i],option.consumes) + local args_for_option = {} + for j = i, i+(option.consumes or 0) do + table.insert(args_for_option,args[j+1]) + end + --special, if we only consume 1 option, just pass that. + if option.consumes == 1 then + args_for_option = args_for_option[1] + end + print("checking",option.type) + print("with",args_for_option) + local check = assert(ret["check_" .. option.type](args_for_option)) + if option.multiple then + parsed[option_name] = parsed[option_name] or {} + table.insert(parsed[option_name],check) + else + parsed[option_name] = check + end + i = i + 1 + (option.consumes or 0) + end + --Set defaults for things that don't have them yet + for option_name, option in pairs(ret.options) do + if parsed[option_name] == nil then + if option.multiple and not option.default then + parsed[option_name] = {} + else + parsed[option_name] = option.default + end + end + end + return parsed +end + +ret.help = function() + print([=[ +mdoc - lua documentation +mdoc -p [-p ...][ -o ][ -t "title"][ -i ][ -d [ -d ...]][ -m ][ -h] + + -p | --path : Path to search for source files + -o | --output = "." : Folder to output HTML files to (and a cache folder) + -t | --title "name" = "Mdoc Generated Page" : Title for the html files + -i | --index : File to use for the index file + -d | --document : Path to search for files to put inder the References section + -m | --markup-parser : Executable to use to parse the descriptions and refrence documents. + Executable should accept a file path as it's argument, and generate html as it's output. + -h | --help : print this help +]=]) +end + +return ret -- cgit v1.2.3-70-g09d2