<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://kingwarzcharts.com/index.php?action=history&amp;feed=atom&amp;title=Module%3ASongPeak</id>
	<title>Module:SongPeak - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://kingwarzcharts.com/index.php?action=history&amp;feed=atom&amp;title=Module%3ASongPeak"/>
	<link rel="alternate" type="text/html" href="https://kingwarzcharts.com/index.php?title=Module:SongPeak&amp;action=history"/>
	<updated>2026-07-21T17:11:36Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://kingwarzcharts.com/index.php?title=Module:SongPeak&amp;diff=3228&amp;oldid=prev</id>
		<title>Kingwarz: Created page with &quot;-- Module:SongPeak -- Pulls the last PK value from the first table under &quot;== Chart History ==&quot; on the same page (or an optional page). -- Returns the value (e.g., &quot;1²⁰&quot;) 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 ~= &quot;&quot; then 		titleObj = mw.title.new(titleArg) 	else 		titleObj = mw.title.getCurr...&quot;</title>
		<link rel="alternate" type="text/html" href="https://kingwarzcharts.com/index.php?title=Module:SongPeak&amp;diff=3228&amp;oldid=prev"/>
		<updated>2025-10-17T03:33:28Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;-- Module:SongPeak -- Pulls the last PK value from the first table under &amp;quot;== Chart History ==&amp;quot; on the same page (or an optional page). -- Returns the value (e.g., &amp;quot;1²⁰&amp;quot;) 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 ~= &amp;quot;&amp;quot; then 		titleObj = mw.title.new(titleArg) 	else 		titleObj = mw.title.getCurr...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- Module:SongPeak&lt;br /&gt;
-- Pulls the last PK value from the first table under &amp;quot;== Chart History ==&amp;quot; on the same page (or an optional page).&lt;br /&gt;
-- Returns the value (e.g., &amp;quot;1²⁰&amp;quot;) so it can be used as |peak= in the infobox.&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local function getPageText(titleArg)&lt;br /&gt;
	-- If a title is passed (args.title), read that page; else read the current page&lt;br /&gt;
	local titleObj&lt;br /&gt;
	if titleArg and titleArg ~= &amp;quot;&amp;quot; then&lt;br /&gt;
		titleObj = mw.title.new(titleArg)&lt;br /&gt;
	else&lt;br /&gt;
		titleObj = mw.title.getCurrentTitle()&lt;br /&gt;
	end&lt;br /&gt;
	if not titleObj then return &amp;quot;&amp;quot; end&lt;br /&gt;
	return titleObj:getContent() or &amp;quot;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Extract the wikitext for the first table following the &amp;quot;== Chart History ==&amp;quot; section header.&lt;br /&gt;
local function getChartHistoryTableText(pageText)&lt;br /&gt;
	if not pageText or pageText == &amp;quot;&amp;quot; then return nil end&lt;br /&gt;
&lt;br /&gt;
	-- Find the &amp;quot;== Chart History ==&amp;quot; header&lt;br /&gt;
	local secStart, secEnd = pageText:find(&amp;quot;==%s*Chart%s+History%s*==&amp;quot;)&lt;br /&gt;
	if not secEnd then&lt;br /&gt;
		-- Some editors might write &amp;quot;== Chart history ==&amp;quot; (lowercase) – handle case-insensitively&lt;br /&gt;
		secStart, secEnd = pageText:lower():find(&amp;quot;==%s*chart%s+history%s*==&amp;quot;)&lt;br /&gt;
		if not secEnd then return nil end&lt;br /&gt;
		-- map back to original positions is not needed since we only slice *after* secEnd&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Everything after that header&lt;br /&gt;
	local after = pageText:sub(secEnd + 1)&lt;br /&gt;
&lt;br /&gt;
	-- Find the first table start&lt;br /&gt;
	local tStart = after:find(&amp;quot;{|&amp;quot;)&lt;br /&gt;
	if not tStart then return nil end&lt;br /&gt;
	local rest = after:sub(tStart)&lt;br /&gt;
&lt;br /&gt;
	-- Grab until the matching table close. The first occurrence of &amp;quot;\n|}&amp;quot; should end this table.&lt;br /&gt;
	local tClose = rest:find(&amp;quot;\n|}%s*&amp;quot;)&lt;br /&gt;
	local tableText = tClose and rest:sub(1, tClose) or rest&lt;br /&gt;
&lt;br /&gt;
	return tableText&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- From a table’s wikitext, grab the last data row, then return the last cell (the PK column).&lt;br /&gt;
local function getLastPkFromTable(tableText)&lt;br /&gt;
	if not tableText or tableText == &amp;quot;&amp;quot; then return nil end&lt;br /&gt;
&lt;br /&gt;
	-- Find the last row separator &amp;quot;|-&amp;quot; within this table&lt;br /&gt;
	local lastRowPos&lt;br /&gt;
	local searchFrom = 1&lt;br /&gt;
	while true do&lt;br /&gt;
		local pos = tableText:find(&amp;quot;\n|%-&amp;quot;, searchFrom)&lt;br /&gt;
		if not pos then break end&lt;br /&gt;
		lastRowPos = pos&lt;br /&gt;
		searchFrom = pos + 3&lt;br /&gt;
	end&lt;br /&gt;
	if not lastRowPos then return nil end&lt;br /&gt;
&lt;br /&gt;
	-- Slice from the start of the last row to the next row (or end of table)&lt;br /&gt;
	local rowsTail = tableText:sub(lastRowPos + 3)&lt;br /&gt;
	local nextRowPos = rowsTail:find(&amp;quot;\n|%-&amp;quot;)&lt;br /&gt;
	if nextRowPos then&lt;br /&gt;
		rowsTail = rowsTail:sub(1, nextRowPos - 1)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- The last row will have a first cell that starts with &amp;quot;|&amp;quot; then &amp;quot;||&amp;quot; separating subsequent cells.&lt;br /&gt;
	-- Normalize newlines to spaces for simpler splitting.&lt;br /&gt;
	rowsTail = rowsTail:gsub(&amp;quot;^%s*|%s*&amp;quot;, &amp;quot;&amp;quot;)      -- remove leading &amp;quot;|&amp;quot;&lt;br /&gt;
	rowsTail = rowsTail:gsub(&amp;quot;\n&amp;quot;, &amp;quot; &amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	-- Split by &amp;quot;||&amp;quot; into cells&lt;br /&gt;
	local cells = {}&lt;br /&gt;
	for part in mw.text.gsplit(rowsTail, &amp;quot;||&amp;quot;, true) do&lt;br /&gt;
		table.insert(cells, mw.text.trim(part))&lt;br /&gt;
	end&lt;br /&gt;
	if #cells == 0 then return nil end&lt;br /&gt;
&lt;br /&gt;
	-- The last cell should be the PK value (e.g., &amp;quot;1&amp;quot;, &amp;quot;1²⁰&amp;quot;, &amp;quot;5&amp;quot;, etc.)&lt;br /&gt;
	local lastCell = mw.text.trim(cells[#cells] or &amp;quot;&amp;quot;)&lt;br /&gt;
	-- Defensive cleanup: if there’s any trailing table syntax left, drop it.&lt;br /&gt;
	-- (e.g., some editors might put a stray &amp;quot;|&amp;quot; at the end)&lt;br /&gt;
	lastCell = lastCell:gsub(&amp;quot;%s*|%s*$&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
	return lastCell ~= &amp;quot;&amp;quot; and lastCell or nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.inferPeak(frame)&lt;br /&gt;
	local args = frame.args or {}&lt;br /&gt;
	local titleArg = args.title  -- optional: {{#invoke:SongPeak|inferPeak|title=Some Page}}&lt;br /&gt;
&lt;br /&gt;
	local pageText = getPageText(titleArg)&lt;br /&gt;
	if pageText == &amp;quot;&amp;quot; then return &amp;quot;&amp;quot; end&lt;br /&gt;
&lt;br /&gt;
	local tableText = getChartHistoryTableText(pageText)&lt;br /&gt;
	if not tableText then return &amp;quot;&amp;quot; end&lt;br /&gt;
&lt;br /&gt;
	local pk = getLastPkFromTable(tableText)&lt;br /&gt;
	-- Return the exact value (including superscripts) so color/type modules keep working.&lt;br /&gt;
	return pk or &amp;quot;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Kingwarz</name></author>
	</entry>
</feed>