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:SongPeak

From King Warz Charts

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

-- Module:SongPeak
-- Pulls the last PK value from the first table under "== Chart History ==" on the same page (or an optional page).
-- Returns the value (e.g., "1²⁰") so it can be used as |peak= in the infobox.

local p = {}

local function getPageText(titleArg)
	-- If a title is passed (args.title), read that page; else read the current page
	local titleObj
	if titleArg and titleArg ~= "" then
		titleObj = mw.title.new(titleArg)
	else
		titleObj = mw.title.getCurrentTitle()
	end
	if not titleObj then return "" end
	return titleObj:getContent() or ""
end

-- Extract the wikitext for the first table following the "== Chart History ==" section header.
local function getChartHistoryTableText(pageText)
	if not pageText or pageText == "" then return nil end

	-- Find the "== Chart History ==" header
	local secStart, secEnd = pageText:find("==%s*Chart%s+History%s*==")
	if not secEnd then
		-- Some editors might write "== Chart history ==" (lowercase) – handle case-insensitively
		secStart, secEnd = pageText:lower():find("==%s*chart%s+history%s*==")
		if not secEnd then return nil end
		-- map back to original positions is not needed since we only slice *after* secEnd
	end

	-- Everything after that header
	local after = pageText:sub(secEnd + 1)

	-- Find the first table start
	local tStart = after:find("{|")
	if not tStart then return nil end
	local rest = after:sub(tStart)

	-- Grab until the matching table close. The first occurrence of "\n|}" should end this table.
	local tClose = rest:find("\n|}%s*")
	local tableText = tClose and rest:sub(1, tClose) or rest

	return tableText
end

-- From a table’s wikitext, grab the last data row, then return the last cell (the PK column).
local function getLastPkFromTable(tableText)
	if not tableText or tableText == "" then return nil end

	-- Find the last row separator "|-" within this table
	local lastRowPos
	local searchFrom = 1
	while true do
		local pos = tableText:find("\n|%-", searchFrom)
		if not pos then break end
		lastRowPos = pos
		searchFrom = pos + 3
	end
	if not lastRowPos then return nil end

	-- Slice from the start of the last row to the next row (or end of table)
	local rowsTail = tableText:sub(lastRowPos + 3)
	local nextRowPos = rowsTail:find("\n|%-")
	if nextRowPos then
		rowsTail = rowsTail:sub(1, nextRowPos - 1)
	end

	-- The last row will have a first cell that starts with "|" then "||" separating subsequent cells.
	-- Normalize newlines to spaces for simpler splitting.
	rowsTail = rowsTail:gsub("^%s*|%s*", "")      -- remove leading "|"
	rowsTail = rowsTail:gsub("\n", " ")

	-- Split by "||" into cells
	local cells = {}
	for part in mw.text.gsplit(rowsTail, "||", true) do
		table.insert(cells, mw.text.trim(part))
	end
	if #cells == 0 then return nil end

	-- The last cell should be the PK value (e.g., "1", "1²⁰", "5", etc.)
	local lastCell = mw.text.trim(cells[#cells] or "")
	-- Defensive cleanup: if there’s any trailing table syntax left, drop it.
	-- (e.g., some editors might put a stray "|" at the end)
	lastCell = lastCell:gsub("%s*|%s*$", "")
	return lastCell ~= "" and lastCell or nil
end

function p.inferPeak(frame)
	local args = frame.args or {}
	local titleArg = args.title  -- optional: {{#invoke:SongPeak|inferPeak|title=Some Page}}

	local pageText = getPageText(titleArg)
	if pageText == "" then return "" end

	local tableText = getChartHistoryTableText(pageText)
	if not tableText then return "" end

	local pk = getLastPkFromTable(tableText)
	-- Return the exact value (including superscripts) so color/type modules keep working.
	return pk or ""
end

return p