Jump to content

Welcome to King Warz Charts Wiki! Please note that the site is still under construction as I work on creating past chart week pages, as well as templates and pages for artists, songs, and albums. Because of this, you may see a lot of red links throughout the site.

Module:SongColor

From King Warz Charts

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

-- Module:SongColor (fixed)
-- Uses named |type= when provided; otherwise infers type from |peak=.
-- The FIRST unnamed argument is treated as the default color (e.g., "#E6E8FA").
local p = {}
local map = {
  ["no.1 hit song"] = "khaki",
  ["major hit song"] = "#ffce1b",
  ["top 5 hit song"] = "#ffd27f",
  ["top 10 hit song"] = "#E6E8FA",
  ["top 20 hit song"] = "#dfefff",
  ["charted song"]   = "#f0f0f0",
}
local super_to_norm = {
  ["⁰"]="0", ["¹"]="1", ["²"]="2", ["³"]="3", ["⁴"]="4",
  ["⁵"]="5", ["⁶"]="6", ["⁷"]="7", ["⁸"]="8", ["⁹"]="9"
}
local function trim_collapse_lower(s)
  s = tostring(s or "")
  s = mw.ustring.gsub(s, "^%s+", "")
  s = mw.ustring.gsub(s, "%s+$", "")
  s = mw.ustring.gsub(s, "%s+", " ")
  s = mw.ustring.lower(s)
  return s
end
local function unlink(text)
  text = tostring(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 text
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 type_from_peak(peak_raw)
  local peak = tostring(peak_raw or "")
  peak = mw.ustring.gsub(peak, "^%s+", "")
  peak = mw.ustring.gsub(peak, "%s+$", "")
  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 "no.1 hit song"
    end
    -- superscripts?
    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
        if expn >= 5 then return "major hit song" else return "no.1 hit song" end
      end
    end
    -- caret form 1^N
    local caret_num = peak:match("^1%^%s*(%d+)$")
    if caret_num then
      local expn = tonumber(caret_num)
      if expn then
        return (expn >= 5) and "major hit song" or "no.1 hit song"
      end
    end
  elseif position >= 2 and position <= 60 then
    -- For non-1, ignore rest (superscripts), use position
    if position <= 5 then
      return "top 5 hit song"
    elseif position <= 10 then
      return "top 10 hit song"
    elseif position <= 20 then
      return "top 20 hit song"
    else
      return "charted song"
    end
  end
  return nil
end
local function color_for_type(raw_type, default_color)
  if not raw_type or raw_type == "" then return default_color end
  local key = trim_collapse_lower(unlink(raw_type))
  return map[key] or default_color
end
function p.color(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 {}
  -- FIRST unnamed arg is the default color; or use |default=
  local default_color = margs[1] or pargs[1] or margs.default or pargs.default or "#E6E8FA"
  -- Only accept named |type= (avoid collision with default color)
  local typ  = margs.type or pargs.type or ""
  local peak = margs.peak or pargs.peak
  if typ ~= "" then
    return color_for_type(typ, default_color)
  end
  local inferred = type_from_peak(peak)
  if inferred then
    return color_for_type(inferred, default_color)
  end
  return default_color
end
return p