Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.
Revision as of 01:17, 21 February 2026 by Ayleria (talk | contribs) (Created page with "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, count = string.gsub(unescaped, "<", "<"); text, count = string.gsub(text, ">", ">"); text, count = string.gsub(text, "</...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Documentation for this module may be created at Module:Loops/doc

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, count = string.gsub(unescaped, "&lt;", "<");
	text, count = string.gsub(text, "&gt;", ">");
	text, count = string.gsub(text, "<//nowiki>", "</nowiki>");
	return text;
end

-- This feature is experimental and therefore undocumented.
local function sentenceJoin(lst, delimiter, beforeLast)
	if not delimiter then
		delimiter = ", ";
		if not beforeLast then
			beforeLast = "and";
		end
	elseif not beforeLast then
		beforeLast = delimiter;
	end
	local count = #lst;
	if count == 0 then
		return "";
	elseif count == 1 then
		return lst[1];
	elseif count == 2 then
		return string.format("%s %s %s", lst[1], beforeLast, lst[2]);
	else
		local last = lst[count];
		lst[count] = nil;
		return string.format("%s %s %s",
			table.concat(lst, delimiter),
			beforeLast,
			last
		);
	end
end

-- This feature is experimental and therefore undocumented.
function formatConcat(result, args)
	local outputFormat = args['format'] or nil;
	if not outputFormat then
		return table.concat(result, "");
	end
	if outputFormat == "concat" then
		return sentenceJoin(result, args['delimiter'], args['final-delimiter']);
	end
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 = unescape(args[4]);
	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 = unescape(args['pattern']);
	
	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 = unescape(args[4]);
	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
				table.insert(keys, k:sub(j + 1));
			end
		end
	end
	table.sort(keys);
	
	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;