Documentation for this module may be created at Module:Covers/doc
-- Module:Covers
-- Displays a gallery of cover images based on a naming convention:
-- Base cover: File:<base>.png -> labeled "Cover A"
-- Variants: File:<base>_(Cover_B).png, ... (C..Z) -> labeled "Cover B", etc.
--
-- Defaults:
-- widths=140px, heights=215px, perrow=6
-- include_base=yes (adds Cover A if File:<base>.png exists)
-- start_letter=B, end_letter=Z
-- max_gap=2 (stop scanning once we hit 2 consecutive missing variants)
--
-- You can override the inferred base with |base=Your_File_Base (no ".png")
-- Example:
-- {{#invoke:Covers|coverGallery}}
-- {{#invoke:Covers|coverGallery|widths=160px|perrow=5}}
-- {{#invoke:Covers|coverGallery|base=Superman_Vol._2_1|max_gap=3}}
local p = {}
local u = mw.ustring
local function trim(s) return (u.gsub(s or "", "^%s*(.-)%s*$", "%1")) end
-- Infer a sane default base from the current page title, unless |base=... is provided.
-- We remove any trailing _(Cover_X) and any trailing ".png" just in case.
local function getBase(args)
if args.base and args.base ~= "" then
return (args.base:gsub("%.png$", ""))
end
local title = mw.title.getCurrentTitle()
local name = title.text or "" -- unprefixed title (no namespace)
name = name:gsub(" ", "_") -- wiki file names use underscores
name = name:gsub("%.(png)$", "") -- strip accidental .png
name = name:gsub("%_%(Cover%_[A-Z]%)$", "") -- strip _(Cover_X) suffix if present
return name
end
-- Test existence of a File: page
local function fileExists(fileName)
local t = mw.title.new("File:" .. fileName)
return t and t.exists
end
-- Build one gallery item line: "File:...|<center>Label</center>"
local function itemLine(fileName, label)
return string.format("File:%s|<center>%s</center>", fileName, label)
end
-- Main renderer
function p.coverGallery(frame)
local args = frame:getParent() and frame:getParent().args or frame.args or {}
local widths = trim(args.widths or "140px")
local heights = trim(args.heights or "215px")
local perrow = trim(args.perrow or "6")
-- Scanning controls
local include_base = (args.include_base or "yes")
include_base = include_base:lower() ~= "no"
local start_letter = (args.start_letter or "B"):upper()
local end_letter = (args.end_letter or "Z"):upper()
local max_gap = tonumber(args.max_gap or 2) or 2
local base = getBase(args)
if base == "" then
return "" -- Nothing to do
end
local items = {}
-- Cover A (base .png)
if include_base then
local baseFile = base .. ".png"
if fileExists(baseFile) then
table.insert(items, itemLine(baseFile, "Cover A"))
end
end
-- Letters range (B..Z by default)
local function letterRange(a, b)
return string.byte(a), string.byte(b)
end
local aCode, zCode = letterRange(start_letter, end_letter)
local consecutive_missing = 0
for code = aCode, zCode do
local letter = string.char(code)
local fname = string.format("%s_(Cover_%s).png", base, letter)
if fileExists(fname) then
table.insert(items, itemLine(fname, "Cover " .. letter))
consecutive_missing = 0
else
consecutive_missing = consecutive_missing + 1
if consecutive_missing >= max_gap then
break
end
end
end
if #items == 0 then
return "" -- no covers found
end
-- Build gallery via the extension tag (equivalent to {{#tag:gallery|...|attrs...}})
local galleryContent = table.concat(items, "\n")
return frame:extensionTag("gallery", galleryContent, {
widths = widths,
heights = heights,
perrow = perrow,
})
end
return p