Module:User:Chetsford/PickFive

From Wikipedia, the free encyclopedia
Jump to navigation Jump to search
-- Module:User:John/PickFive
local M = {}

-- Fisher–Yates shuffle
local function shuffle(t, seed)
	math.randomseed(seed)
	for i = #t, 2, -1 do
		local j = math.random(i)
		t[i], t[j] = t[j], t[i]
	end
	return t
end

-- Extract [[Target|Label]] or [[Target]] links from raw wikitext
local function extractLinks(raw)
	local out = {}
	for target, label in raw:gmatch("%[%[([^%]|]+)|?([^%]]*)%]%]") do
		local text = (label ~= '' and label) or target
		out[#out+1] = string.format('[[%s|%s]]', target, text)
	end
	return out
end

function M.fromPage(frame)
	local args = frame.args
	local listPage = args.page or args[1] or ''
	if listPage == '' then return '*(no page given)*' end

	local title = mw.title.new(listPage)
	if not title then return '*(bad title)*' end

	local raw = title:getContent() or ''
	local links = extractLinks(raw)
	if #links == 0 then return '*(no links found on list page)*' end

	-- How many to show? default 5; clamp to list size
	local n = tonumber(args.n) or 5
	if n < 1 then n = 1 end
	if n > #links then n = #links end

	-- Separator between items (default: space • space)
	local sep = args.sep or ' • '

	-- Minute-level seed so output varies over time & on purge
	local ts = frame:preprocess('{{CURRENTTIMESTAMP}}') -- e.g. 20250809010203
	local seed = tonumber(ts:sub(1,12)) or math.floor(mw.now())
	seed = seed + #links -- nudge per list size to reduce collisions
	shuffle(links, seed)

	-- Emit inline list
	local out = {}
	for i = 1, n do
		out[#out+1] = links[i]
	end
	return table.concat(out, sep)
end

return M