Module:For batched parameters
Documentation for this module may be created at Module:For batched parameters/doc
local p = {}
-- Find "{{{x|" where "x" is an arg name
local function findDefStart (code, i, argstosub)
while true do
local s, e, a = code:find("{{{([^{}|]+)|", i)
if not s then return nil end
if argstosub[a] then return s, e, a end
i = e + 1
end
end
-- Skip stuff after "{{{x|", find "}}}"
local function findDefEnd (code, i)
while true do
local s, e = code:find("^[^{}]*", i) -- skip non-braces
i = e + 1
s, e = code:find("^%b{}", i) -- skip balanced braces
if not s then break end
i = e + 1
end
return code:find("^}}}", i)
end
-- Replace "{{{x|...}}}" by "{{{x}}}" where "x" is an arg name.
-- Without this, we'd have to handle both "{{{x}}}" and "{{{x|...}}}"
-- in the main loop, which would be cumbersome and inefficient.
-- All but the last batch are guaranteed to have the full size,
-- so we know that the parameters don't need defaults.
local function dropDefs (code, size)
local argstosub = {}
argstosub["i"] = "{{{i}}}"
for i = 1, size do
argstosub[tostring(i)] = "{{{" .. i .. "}}}"
end
local result = {}
local i = 1
while true do
local s, e, a = findDefStart(code, i, argstosub)
if not s then break end -- no more "{{{x|", done
_, e = findDefEnd(code, e + 1)
if not e then break end -- no "}}}", bad syntax, let wiki deal with it
table.insert(result, code:sub(i, s - 1)) -- append up to "{{{x|"
table.insert(result, argstosub[a]) -- append "{{{x}}}"
i = e + 1
end
table.insert(result, code:sub(i))
return table.concat(result)
end
function p.main(frame)
local size = tonumber(frame.args[1])
local sep = frame.args[2]
local code = frame.args[3] or frame.args.code
local result = {}
local batch = {}
code = mw.text.unstripNoWiki(code)
code = code:gsub('<', '<'):gsub('>', '>')
local cleanCode = dropDefs(code, size)
local idx = 0
for i, value in ipairs(frame:getParent().args) do
table.insert(batch, value)
if #batch == size then
idx = idx + 1
local argstosub = {}
for j, value2 in pairs(batch) do
argstosub[tostring(j)] = value2
end
argstosub["i"] = idx
local actualCode = cleanCode:gsub("{{{([^{}]+)}}}", argstosub)
table.insert(result, frame:preprocess(actualCode))
batch = {}
end
end
if #batch > 0 then
idx = idx + 1
local argstosub = {}
for j, value2 in pairs(batch) do
argstosub[tostring(j)] = value2
end
argstosub["i"] = idx
-- Do the last sub in a child frame and use the original code to handle defaults
local childFrame = frame:newChild{title=frame:getParent().title, args = argstosub}
table.insert(result, childFrame:preprocess(code))
end
if frame.args.conjunction then
return mw.text.listToText(result, sep, frame.args.conjunction)
else
return table.concat(result, sep)
end
end
return p