local env = require 'argcheck.env' local sdascii pcall(function() sdascii = require 'sundown.ascii' end) local usage = {} local function generateargp(rules) local txt = {} for idx, rule in ipairs(rules) do local isopt = rule.opt or rule.default ~= nil or rules.defauta or rule.defaultf table.insert(txt, (isopt and '[' or '') .. ((idx == 1) and '' or ', ') .. rule.name .. (isopt and ']' or '')) end return table.concat(txt) end local function generateargt(rules) local txt = {} table.insert(txt, '```') table.insert(txt, string.format( '%s%s', rules.noordered and '' or '(', rules.nonamed and '' or '{')) local size = 0 for _,rule in ipairs(rules) do size = math.max(size, #rule.name) end local arg = {} local hlp = {} for _,rule in ipairs(rules) do table.insert(arg, ((rule.opt or rule.default ~= nil or rule.defaulta or rule.defaultf) and '[' or ' ') .. rule.name .. string.rep(' ', size-#rule.name) .. (rule.type and (' = ' .. rule.type) or '') .. ((rule.opt or rule.default ~= nil or rule.defaulta or rule.defaultf) and ']' or '') ) local default = '' if rule.defaulta then default = string.format(' [defaulta=%s]', rule.defaulta) elseif rule.defaultf then default = string.format(' [has default]') elseif type(rule.default) ~= 'nil' then if type(rule.default) == 'string' then default = string.format(' [default=%s]', rule.default) elseif type(rule.default) == 'number' then default = string.format(' [default=%s]', rule.default) elseif type(rule.default) == 'boolean' then default = string.format(' [default=%s]', rule.default and 'true' or 'false') else default = ' [has default value]' end end table.insert(hlp, (rule.help or '') .. (rule.doc or '') .. default) end local size = 0 for i=1,#arg do size = math.max(size, #arg[i]) end for i=1,#arg do table.insert(txt, string.format(" %s %s -- %s", arg[i], string.rep(' ', size-#arg[i]), hlp[i])) end table.insert(txt, string.format( '%s%s', rules.nonamed and '' or '}', rules.noordered and '' or ')')) table.insert(txt, '```') txt = table.concat(txt, '\n') return txt end function usage.render(doc) -- We render any markdown in the input into ANSI color codes using sundown, but only if stdout and stderr are terminals if sdascii and pcall(require, 'torch') and torch.isatty(io.stderr) and torch.isatty(io.stdout) then doc = sdascii.render(doc) end return doc end function usage.usage(truth, rules, ...) if truth then local norender = select(1, ...) local doc = rules.help or rules.doc if doc then doc = doc:gsub('@ARGP', function() return generateargp(rules) end) doc = doc:gsub('@ARGT', function() return generateargt(rules) end) end if not doc then doc = '\n*Arguments:*\n' .. generateargt(rules) end return doc else local self = rules local args = {} for i=1,select('#', ...) do table.insert(args, string.format("**%s**", env.type(select(i, ...)))) end local argtblidx if self:hasruletype('N') then if select("#", ...) == 1 and env.istype(select(1, ...), "table") then argtblidx = 1 end elseif self:hasruletype('M') then if select("#", ...) == 2 and env.istype(select(2, ...), "table") then argtblidx = 2 end end if argtblidx then local argtbl = {} local tbl = select(argtblidx, ...) local n = 0 for k,v in pairs(tbl) do n = n + 1 if n > 20 then table.insert(argtbl, '...') break end if type(k) == 'string' then table.insert(argtbl, string.format("**%s=%s**", k, env.type(v))) else table.insert(argtbl, string.format("**[%s]**=?", env.type(k))) end end args[argtblidx] = string.format("**table**={ %s }", table.concat(argtbl, ', ')) end local doc = string.format("*Got:* %s", table.concat(args, ', ')) return doc end end return usage