Module:Loops
Appearance
Loops support module. It is intended for use by other Lua modules, and should not be called from an invocation (#invoke) directly.
This is an experimental module meant to be a drop-in replacement for Extension:Loops for some of its use cases.
See Module:Loops for original source.
local p = {};
local getArgs = require("Module:Arguments").getArgs;
-- Note to dev wiki editors: this function is copied from Module:Example.
-- Changes to this function should be synced with the source.
local function unescape(text)
if not text:match("UNIQ") then
return text;
end
local unescaped = mw.text.unstripNoWiki(text);
local text = unescaped:gsub('<', '<')
:gsub('>', '>')
:gsub('"', '"')
-- Taken from Wikipedia's Module:Demo
:gsub('}%-', '}-')
:gsub('%-{', '-{')
:gsub("<//nowiki>", "</nowiki>");
return text;
end
-- This feature is experimental and therefore undocumented.
function formatConcat(result, args)
local outputFormat = args['format'] or '';
local ret;
if outputFormat == "custom" then
ret = unescape(args['intro'] or '') .. table.concat(result, unescape(args['delimiter'] or '')) .. unescape(args['outro'] or '');
else
ret = table.concat(result, "");
end
if args['debug'] then
mw.log("Before preproces:");
mw.log(ret);
end
return ret;
end
function getMarkup(arg, args)
local markup = unescape(arg);
if args['debug'] then
mw.log("Unescaped string:");
mw.log(markup);
end
return markup;
end
function p.loop(frame)
local args = getArgs(frame);
local variableName = args[1];
local startingValue = tonumber(args[2]) or 1;
local loopNum = tonumber(args[3]) or 0;
local markup = getMarkup(args[4], args);
local result = {};
for i = startingValue, startingValue + loopNum - 1 do
local s = markup:gsub(variableName, tostring(i));
table.insert(result, s);
end
return frame:getParent():preprocess(formatConcat(result, args));
end
function p.fornumargs(frame)
local args = getArgs(frame, { removeBlanks = false });
local keyName = args['key'] or "DNE";
local valueName = args['value'] or "DNE";
local markup = getMarkup(args['pattern'], args);
local keys = {};
for k, v in pairs(args) do
if type(k) == "number" then
table.insert(keys, k);
end
end
table.sort(keys);
local result = {};
for _, key in ipairs(keys) do
local value = args[key];
local s = markup:gsub(keyName, key):gsub(valueName, value);
table.insert(result, s);
end
return frame:getParent():preprocess(formatConcat(result, args));
end
function p.forargs(frame)
local args = getArgs(frame, { removeBlanks = false });
local prefix = args[1] or "";
local keyName = args[2] or "DNE";
local valueName = args[3] or "DNE";
local markup = getMarkup(args[4], args);
for i = 1, 4 do
table.remove(args, i);
end
local keys = {};
for k, v in pairs(args) do
if type(k) == "string" then
i, j = k:find(prefix);
if i ~= nil and i == 1 then
k = k:sub(j + 1)
if tonumber(k) ~= nil then
k = tonumber(k)
end
table.insert(keys, k);
end
end
end
table.sort(keys, function(a, b)
local ta, tb = type(a), type(b)
if ta ~= tb then
-- Number before string
return ta == "number"
end
-- Same type. Compare normally.
return a < b
end);
local result = {};
for _, key in ipairs(keys) do
local value = args[prefix .. key];
local s = markup:gsub(keyName, key):gsub(valueName, value);
table.insert(result, s);
end
return frame:getParent():preprocess(formatConcat(result, args));
end
return p;