Module:SongType
Appearance
Documentation for this module may be created at Module:SongType/doc
-- Module:SongType (fixed)
-- Infers (and optionally links) a song "Type" from |peak=.
-- Honors a manual override via |type= (or |override=).
-- Use |link=no when you need plain text.
local p = {}
local super_to_norm = {
["⁰"]="0", ["¹"]="1", ["²"]="2", ["³"]="3", ["⁴"]="4",
["⁵"]="5", ["⁶"]="6", ["⁷"]="7", ["⁸"]="8", ["⁹"]="9"
}
local function trim(s)
return (tostring(s or ""):gsub("^%s+", ""):gsub("%s+$", ""))
end
local function superscripts_to_number(sup)
local norm = {}
for uchar in mw.ustring.gmatch(sup or "", ".") do
local d = super_to_norm[uchar]
if not d then return nil end
table.insert(norm, d)
end
return tonumber(table.concat(norm))
end
local function unlink(text)
text = trim(text or "")
text = mw.ustring.gsub(text, "^%s*%[%[", "")
text = mw.ustring.gsub(text, "%]%]%s*$", "")
local pipe = mw.ustring.find(text, "|", 1, true)
if pipe then text = mw.ustring.sub(text, 1, pipe - 1) end
return trim(text)
end
local function linkify(label, want_link)
label = trim(label or "")
if label == "" then return "" end
if want_link == false then return label end
return string.format("[[%s]]", label)
end
local function infer_from_peak(peak_raw, want_link)
local peak = trim(peak_raw)
if peak == "" then return nil end
-- Extract leading numeric part
local position_str, rest = peak:match("^(%d+)(.*)$")
if not position_str then return nil end
local position = tonumber(position_str)
if position == 1 then
if rest == "" then
return linkify("No.1 Hit Song", want_link)
end
local super_only = true
for uchar in mw.ustring.gmatch(rest, ".") do
if not super_to_norm[uchar] then super_only = false; break end
end
if super_only then
local expn = superscripts_to_number(rest)
if expn then
return (expn >= 5) and linkify("Major Hit Song", want_link)
or linkify("No.1 Hit Song", want_link)
end
end
local caret_num = peak:match("^1%^%s*(%d+)$")
if caret_num then
local expn = tonumber(caret_num)
if expn then
return (expn >= 5) and linkify("Major Hit Song", want_link)
or linkify("No.1 Hit Song", want_link)
end
end
elseif position >= 2 and position <= 60 then
-- For non-1, ignore rest (superscripts), use position
if position <= 5 then
return linkify("Top 5 Hit Song", want_link)
elseif position <= 10 then
return linkify("Top 10 Hit Song", want_link)
elseif position <= 20 then
return linkify("Top 20 Hit Song", want_link)
else
return linkify("Charted Song", want_link)
end
end
return nil
end
function p.inferType(frame)
-- IMPORTANT: prefer module-call args first, then fall back to parent
local margs = frame.args or {}
local pargs = (frame:getParent() and frame:getParent().args) or {}
local peak = margs.peak or pargs.peak or margs["peak"] or pargs["peak"] or ""
local link = margs.link or pargs.link
local want = not (link == "no" or link == "false" or link == "0")
-- Manual override (|type= or |override=), from either scope
local override = margs.override or pargs.override or margs.type or pargs.type
override = trim(override or "")
if override ~= "" then
local clean = unlink(override)
return linkify(clean, want)
end
local t = infer_from_peak(peak, want)
return t or ""
end
return p