Module:For loop

p = {} local args local function callTemplate(template, targs) return mw.getCurrentFrame:expandTemplate{title = template, args = targs} end local function getArgNums(prefix, suffix) -- Returns a table containing the numbers of the arguments that exist -- for the specified prefix. For example, if the prefix was 'data', and -- 'data1', 'data2', and 'data5' exist, it would return {1, 2, 5}. local nums = {} for k, v in pairs(args) do       local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)' .. suffix .. '$') if num then table.insert(nums, tonumber(num)) end end table.sort(nums) return nums end local function getConstants local constantArgNums = getArgNums('pc', 'n') local constantArgs = {} for _, v in ipairs(constantArgNums) do       local keyArgName = 'pc' .. tostring(v) .. 'n'       local valArgName = 'pc' .. tostring(v) .. 'v'       constantArgs[args[keyArgName]] = args[valArgName] end return constantArgs end local function getVariableVals local variableVals = {} for i, v in ipairs(args) do       if i ~= 1 then variableVals[i - 1] = v       end end return variableVals end local function _main local template = args.call or error('No template specified') local variableParam = args.pv   local variableValPrefix = args.prefix local variableValPostfix = args.postfix local sep = args[1] or '' local constantArgs = getConstants local variableVals = getVariableVals result = '' for i, v in ipairs(variableVals) do       local targs = constantArgs targs[variableParam or 1] = (variableValPrefix or '') .. tostring(v) .. (variableValPostfix or '') result = result .. tostring(callTemplate(template, targs)) if variableVals[i + 1] then result = result .. sep end end return result end function p.main(frame) -- If called via #invoke, use the args passed into the invoking template. -- Otherwise, for testing purposes, assume args are being passed directly in. if frame == mw.getCurrentFrame then args = frame:getParent.args else args = frame end return _main end return p