Module:RandomGalleryAny
Lua
Documentation for this module may be created at Module:RandomGalleryAny/doc
Code
--[[
Module:RandomGalleryAny
This module reads the content of a specified wiki page, extracts each line
that appears to be a filename (allowing for captions/wikitext after a pipe |),
shuffles the list, and outputs a subset formatted as a <gallery> block with mode="packed".
--]]
local p = {}
-- 1. Helper function to trim whitespace (Defined on p table)
p.trim = function(s)
return s:match('^%s*(.*%S)%s*$') or ''
end
-- 2. HASHING FUNCTION: Generates a reliable integer seed from any string (Defined on p table)
p.string_to_seed = function(s)
local hash = 0
s = tostring(s)
for i = 1, #s do
hash = hash + s:byte(i)
hash = (hash * 65599) % 2147483647
end
if hash == 0 then return os.time() end
return hash
end
-- 3. Function to check if a line is likely an image file line (Defined on p table)
p.is_image_line = function(line)
-- This pattern looks for a common file extension (.jpg, .png, .gif, .svg, etc.)
-- Can start with File: or not
local extensions = {
'[%.][Jj][Pp][Ee]?[Gg]',
'[%.][Pp][Nn][Gg]',
'[%.][Gg][Ii][Ff]',
'[%.][Ss][Vv][Gg]',
'[%.][Tt][Ii][Ff][Ff]?',
'[%.][Bb][Mm][Pp]',
'[%.][Ww][Ee][Bb][Pp]',
'[%.][Jj][Pp][Ee][Gg]',
'[%.][Jj][2][Kk]',
'[%.][Cc][Ee][Ff]',
'[%.][Pp][Dd][Ff]',
'[%.][Dd][Jj][Vv][Uu]'
}
for _, ext in ipairs(extensions) do
if line:match(ext) then
return true
end
end
return false
end
-- 4. Function to normalize the filename (ensure it doesn't have File: prefix for gallery)
p.normalize_line = function(line)
-- Gallery tags don't need the "File:" prefix, so we remove it if present
-- but preserve everything else (including captions after |)
local normalized = line:gsub('^%s*[Ff][Ii][Ll][Ee]%s*:%s*', '')
return normalized
end
-- 5. Function to perform the Fisher-Yates shuffle (Defined on p table)
p.shuffle = function(t)
local n = #t
local rand = math.random
while n >= 2 do
local k = rand(n)
t[n], t[k] = t[k], t[n]
n = n - 1
end
return t
end
-- Main function
function p.showRandom(frame)
local args = frame:getParent().args
local page_title = args[1]
local height = tonumber(args['height'] or args[2] or 200)
local count = tonumber(args['count'] or args[3] or 12)
local seed = args['seed'] or args[4] or os.time()
local debug = args['debug']
if not page_title then
return '<span style="color: red; font-weight: bold;">Error: Missing required parameter 1 (page list title).</span>'
end
-- Use hashing to generate a safe integer seed
local final_seed = p.string_to_seed(seed)
-- Set the seed for randomization
math.randomseed(final_seed)
-- Get the content of the specified page
local title = mw.title.new(page_title)
if not title or not title.exists then
return '<span style="color: red; font-weight: bold;">Error: Page does not exist: ' .. page_title .. '</span>'
end
local page_content = title:getContent()
if not page_content then
return '<span style="color: red; font-weight: bold;">Error: Could not retrieve content for page: ' .. page_title .. '</span>'
end
local image_list = {}
-- Split the content into lines and filter for image lines
local lines = mw.text.split(page_content, '\n')
for _, line in ipairs(lines) do
local trimmed_line = p.trim(line)
-- Check if this line contains an image file
if trimmed_line ~= '' and p.is_image_line(trimmed_line) then
-- Normalize the line (remove File: prefix if present)
local normalized = p.normalize_line(trimmed_line)
table.insert(image_list, normalized)
end
end
if #image_list == 0 then
return '<span style="color: orange;">Warning: The list page is empty or contains no valid file entries: ' .. page_title .. '</span>'
end
-- Shuffle the list
local shuffled_list = p.shuffle(image_list)
-- Select the requested number of items
local final_items = {}
for i = 1, math.min(count, #shuffled_list) do
table.insert(final_items, shuffled_list[i])
end
-- Construct the output gallery
local output = {}
-- Uses mode="packed" as requested (This displays the captions)
table.insert(output, '<gallery mode="packed" heights="' .. height .. '">')
-- Add the selected items (which include the full filename and caption/wikitext)
for _, item in ipairs(final_items) do
table.insert(output, item)
end
table.insert(output, '</gallery>')
if debug then
table.insert(output, '<div style="border: 1px solid #ccc; padding: 5px; margin-top: 10px; background: #f9f9f9;">')
table.insert(output, '<b>DEBUG OUTPUT</b><br/>')
table.insert(output, 'Page: ' .. page_title .. '<br/>')
table.insert(output, 'Total Items Found: ' .. #image_list .. '<br/>')
table.insert(output, 'Items Selected: ' .. #final_items .. '<br/>')
table.insert(output, 'Seed: ' .. tostring(seed) .. ' (hashed to: ' .. final_seed .. ')<br/>')
table.insert(output, '<hr/>')
table.insert(output, '<b>Selected Items:</b><br/>')
for i, item in ipairs(final_items) do
table.insert(output, i .. '. <code>' .. mw.text.encode(item) .. '</code><br/>')
end
table.insert(output, '</div>')
end
local result = table.concat(output, '\n')
-- Preprocess the output so the gallery tag is properly parsed
return frame:preprocess(result)
end
return p