Module:Sandbox/Χ/InfoboxMaker explained

local ga = require('Module:Arguments').getArgslocal tt = require('Module:TableTools')local ib = require('Module:Infobox').infoboxlocal ii = require('Module:InfoboxImage').InfoboxImage

local origArgs -- Args received from the the initalizing module.local ibArgs = -- Args sent to Module:Infoboxlocal categories = -- Categories appended to the Infoboxlocal counter = local params =

local functions = setmetatable(functions,)

----------------------------------------------------------------------------------------------------------------- Helper functions -----------------------------------------------------------------------------------------------------------------

---- Checks whether x is nil, empty or false--local function isEmpty(x) return x

nil or x

or x

false or (type(x)

'table' and tt.size(x)

0)end

---- Transforms x into a table--function totable(x) return type(x)

'table' and x or end

---- Replaces one or multiple arguments with their associated value in origArgs.-- There is an optional "n" suffix, intended to be a number.--local function argToVal(args, n) n = n and tostring(n) or "" if type(args)

'table' then if n

'1' then for i, v in pairs(args) do args[i] = origArgs[v .. '1'] or origArgs[v] end else for i, v in pairs(args) do args[i] = origArgst[v .. n] end end elseif type(args)

'string' then if n

'1' then args = origArgs[args .. '1'] or origArgs[args] else args = origArgs[args .. n] end end return argsend

---- Used to build "repeated" things.-- Filters out values and arguments using their indices.--function filter(args, params, valIndex, argIndex) local newArgs = for _, param in ipairs(params) do local paramArg = args[param .. "Arg"] local paramVal = args[param] local default if type(paramVal) ~= 'table' then default = paramVal paramVal = end newArgs[param] = paramVal[valIndex] or argToVal(paramArg, argIndex) or default newArgs[param .. "Func"] = args[param .. "Func"] end return newArgsend

---- Sets up unique elements like title, above, below, etc.--local function uniqueElement(prefix, args) if type(args) ~= 'table' then ibArgs[prefix] = args or ibArgs[prefix] else ibArgs[prefix] = args[prefix] or ibArgs[prefix] ibArgs[prefix .. 'class'] = args.class or args[prefix .. 'class'] or ibArgs[prefix .. 'class'] ibArgs[prefix .. 'style'] = args.style or args[prefix .. 'style'] or ibArgs[prefix .. 'style'] endend

---- Sets up incremental elements like images, subheader, and data rows-- Optional n parameter.--function addElement(elem, args, n) local i if n

nil then i = tostring(counter[elem]) counter[elem] = counter[elem] + 1 else i = tostring(n) end for _, param in ipairs(params[elem]) do local func = args[param .. "Func"] if type(func) ~= 'function' then func = functions[func] end local value = args[param] or argToVal(args[param .. "Arg"]) ibArgs[param .. i] = pcall(function func(value) end) and func(value) or value endend

----------------------------------------------------------------------------------------------------------------- Member functions -----------------------------------------------------------------------------------------------------------------local p =

function p.initialize(args) -- Modules using InfoboxMaker must first initialize it with a set of args. origArgs = argsend

---- Global styling and class assignments--function p.setup(args) for _, param in ipairs(params.global) do ibArgs[param] = args[param] endend

function p.title(args) uniqueElement('title', args)endfunction p.above(args) uniqueElement('above', args)endfunction p.below(args) uniqueElement('below', args)end

---- Adds a single subheader--function p.addSubheader(args) uniqueElement('subheader',) addElement('subheader', args)end

---- Adds a single image and caption--function p.addImage(args) uniqueElement('image',) local imgArgs = local i = tostring(counter.image) counter.image = counter.image + 1 for _, param in ipairs(params.image) do local func = args[param .. "Func"] if type(func) ~= 'function' then func = functions[func] end local value = args[param] or argToVal(args[param .. "Arg"]) imgArgs[param] = pcall(function func(value) end) and func(value) or value end ibArgs['image' .. i] = ii ibArgs['imagerowclass' .. i] = imgArgs.imagerowclass ibArgs['caption' .. i] = imgArgs.captionend

---- Adds a single category--function p.addCategory(catArgs) local name = catArgs.name or "" local key = catArgs.key or "" if not isEmpty(name) then if isEmpty(key) then table.insert(categories, "") else table.insert(categories, "") end endend

---- Adds a single row--function p.addRow(rowArgs, n) local i if n

nil then i = tostring(counter.row) counter.row = counter.row + 1 else i = tostring(n) end for _, param in ipairs(params.row) do local func = rowArgs[param .. "Func"] if type(func) ~= 'function' then func = functions[func] end local value = rowArgs[param] or argToVal(rowArgs[param .. "Arg"]) ibArgs[param .. i] = pcall(function func(value) end) and func(value) or value end if ibArgs["header" .. i] or ibArgs["data" .. i] then return true else return false endend

---- Adds multiple rows. Useful for numbered parameters.--function p.addRepeatedRow(rowArgs) local added = false -- First, determine how many rows will be needed local n = local m = 0 for _, param in ipairs(params.row) do -- Number of paramArgs local paramArg = totable(rowArgs[param .. "Arg"]) for _, prefix in pairs(paramArg) do for _, v in ipairs(tt.affixNums(origArgs, prefix)) do table.insert(n, v) end end -- Number of paramVals local paramVal = totable(rowArgs[param]) m = math.max(m, #paramVal) end if isEmpty(n) then for i=1,m do table.insert(n, i) end else n = tt.removeDuplicates(n) table.sort(n) end -- Second, actually generate the rows if not isEmpty(n) then for i, j in ipairs(n) do local newRowArgs = filter(rowArgs, params.row, i, j) added = p.addRow(newRowArgs) or added end end return addedend

---- Adds a set of rows. The "first" row is added only if the rest is not empty.-- Individual rows can actually be sections, repeated rows, or single rows.-- First row must be a single row.--function p.addSection(sectionArgs) local rows = sectionArgs.rows or local first = sectionArgs[1] or local added = false local h = counter.row counter.row = counter.row + 1 for _, row in ipairs(rows) do if row.mode

'section' then added = p.addSection(row) or added elseif row.mode

'repeated' then added = p.addRepeatedRow(row) or added else added = p.addRow(row) or added end end if added then p.addRow(first, h) end return addedend

---- Adds multiple sections sharing the same definition.-- Useful with numbered parameters.-- Only single rows are accepted.--function p.addRepeatedSection(sectionArgs) local rows = sectionArgs.rows or local first = sectionArgs[1] or local added = false local added_row = false local h -- First, determine how many rows will be needed local n = local m = 0 for _, rowArgs in ipairs(rows) do for _, param in ipairs(params.row) do -- Number of paramArgs local paramArg = totable(rowArgs[param .. "Arg"]) for _, prefix in pairs(paramArg) do for _, v in ipairs(tt.affixNums(origArgs, prefix)) do table.insert(n, v) end end -- Number of paramVals local paramVal = totable(rowArgs[param]) m = math.max(m, #paramVal) end end if isEmpty(n) then for i=1,m do table.insert(n, i) end else n = tt.removeDuplicates(n) table.sort(n) end -- Second, actually generate the rows if not isEmpty(n) then for i, j in ipairs(n) do added_row = false h = counter.row counter.row = counter.row + 1 for _, rowArgs in ipairs(rows) do local newRowArgs = filter(rowArgs, params.row, i, j) added_row = p.addRow(newRowArgs) or added end if added_row then local newFirst = filter(first, params.row, i, j) added = p.addRow(newFirst, h) or added_row or added end end end return addedend

---- Generate the infobox! Append categories if any.--function p.makeInfobox return ib(ibArgs) .. mw.text.listToText(categories, , )end

return p