Module:MaroScaleSandbox: Difference between revisions

From MTG Wiki
Jump to navigation Jump to search
>Jerodast
(better comment format. grabbed some notes on current usage for future reference)
>Jerodast
(new sets. still getting to the part for what they're for haha.)
Line 1: Line 1:
--[[ Sandbox page for the MaroScale lua script
--[[ Sandbox page for the MaroScale lua script
jerodast will request to delete this page once any useful changes are merged to
  the live MaroScale page


Goals for jerodast:
Goals for jerodast:
Line 12: Line 15:
   * add column for additional notes - note that Beeble Scale crams notes into
   * add column for additional notes - note that Beeble Scale crams notes into
       Timeline column already
       Timeline column already
jerodast will request to delete this page once any useful changes are merged to
  the live MaroScale page
]]
]]


Line 47: Line 47:


local sub, match, gsub = mw.ustring.sub, mw.ustring.match, mw.ustring.gsub
local sub, match, gsub = mw.ustring.sub, mw.ustring.match, mw.ustring.gsub
-- ustring is string library equivalents that work on UTF-8 aka mediawiki text


local MAX_ENTRIES = 500
local MAX_ENTRIES = 500
-- A list of all sets which have been Standard-legal since the introduction of the Storm Scale (September 2012)
-- A list of all sets which have been Standard-legal since the introduction of the Storm Scale (September 2012)
local LEGAL_EXPANSIONS = {
local LEGAL_EXPANSIONS = {
["Return to Ravnica"] = "2012-10-05",
["Return to Ravnica"] = "2012-10-05",
["Gatecrash"] = "2013-02-01",
["Gatecrash"] = "2013-02-01",
["Dragon's Maze"] = "2013-05-03",
["Dragon's Maze"] = "2013-05-03",
["Magic 2014"] = "2013-06-13",
["Magic 2014"] = "2013-06-13",
["Theros"] = "2013-09-27",
["Theros"] = "2013-09-27",
["Born of the Gods"] = "2014-02-07",
["Born of the Gods"] = "2014-02-07",
["Journey into Nyx"] = "2014-05-02",
["Journey into Nyx"] = "2014-05-02",
["Magic 2015"] = "2014-07-18",
["Magic 2015"] = "2014-07-18",
["Khans of Tarkir"] = "2014-09-26",
["Khans of Tarkir"] = "2014-09-26",
["Fate Reforged"] = "2015-01-23",
["Fate Reforged"] = "2015-01-23",
["Dragons of Tarkir"] = "2015-03-17",
["Dragons of Tarkir"] = "2015-03-17",
["Magic Origins"] = "2015-07-15",
["Magic Origins"] = "2015-07-15",
["Battle for Zendikar"] = "2015-10-02",
["Battle for Zendikar"] = "2015-10-02",
["Oath of the Gatewatch"] = "2016-01-22",
["Oath of the Gatewatch"] = "2016-01-22",
["Shadows over Innistrad"] = "2016-04-08",
["Shadows over Innistrad"] = "2016-04-08",
["Eldritch Moon"] = "2016-06-22",
["Eldritch Moon"] = "2016-06-22",
["Kaladesh"] = "2016-09-30",
["Kaladesh"] = "2016-09-30",
["Aether Revolt"] = "2016-01-20",
["Aether Revolt"] = "2016-01-20",
["Amonkhet"] = "2017-04-28",
["Amonkhet"] = "2017-04-28",
["Hour of Devastation"] = "2017-07-14",
["Hour of Devastation"] = "2017-07-14",
["Ixalan"]                  = "2017-09-29",
["Rivals of Ixalan"]        = "2018-01-19",
["Dominaria"]                = "2018-04-27",
["Core Set 2019"]            = "2018-07-13",
["Guilds of Ravnica"]        = "2018-10-05",
["Ravnica Allegiance"]      = "2019-01-25",
["War of the Spark"]        = "2019-05-03",
["Core Set 2020"]            = "2019-07-12",
["Throne of Eldraine"]      = "2019-10-04",
["Theros Beyond Death"]      = "2020-01-24",
["Ikora: Lair of Behemoths"] = "2020-05-15",
["Core Set 2021"]            = "2020-07-03",
["Zendikar Rising"]          = "2020-09-25",
["Kaldheim"]                = "2021-02-05",
["Strixhaven"]              = "2021-04-23",
["Dungeons & Dragons: Adventures in the Forgotten Realms"] = "2021-07-23",
["Innistrad: Midnight Hunt"] = "2021-09-24",
["Innistrad: Crimson Vow"]  = "2021-11-19",
["Kamigawa: Neon Dynasty"]  = "2022-02-18",
["Streets of New Capenna"]  = "2022-04-29",
["Dominaria United"]        = "2020-09-09",
["The Brothers' War"]        = "2020-11-18",
}
}



Revision as of 05:35, 2 July 2022

This is a sandbox page for experimenting with the Module:MaroScale lua script. Click for /doc access.

Goals:

  • Learn a bit more how it's used/about Modules
  • Make some updates/improvements (see script comments for details)

User:jerodast (talk) will request to delete this page once any useful changes are merged to core MaroScale page.

Since this module gets arguments from frame:getParent(), its use is best exemplified / tested via the calling template. These examples don't use real references, which in practice would be true citations with a full reference footnote. In these examples, ratings will always be EXPECTED to be in ascending order once sorted by date, to easily verify correctness.

Let's put[a] in some[b] fake footnotes to test compatibility of tables & other footnotes.[c]

PlaneLatest rankingTimeline
Innistrad1
  • 1[4]
Ravnica[d]1
  • 1[4]
  1. First fake footnote
  2. Second
  3. Final fake footnote!
  4. Worst plane ever
MechanicLatest rankingTimeline
-1/-1 counters2
  • 1[4]
  • 2[4]
Grind6
  • 5[4]
  • 6[4]
Rhystic9
  • 9[4]
Creature typeLatest rankingTimeline
Beeble10
  • 8[4]
  • 10[4]
Dauthi6
  • 6[4]
Djinn4
Dragon1
Elf1
Goblin1
Human1
Hydra1
Werewolf3
PlaneswalkerLatest rankingTimeline
Kiora4
  • 4[4]
Nahiri4
  • 3[4]
  • 4[4]
Tibalt7
  • 5[4]
  • 6[4]
  • 7[4]
Urza9
  • 9[4]

Quick links for live pages:

Lua error at line 174: attempt to compare nil with string.

Footnotes


--[[ Sandbox page for the MaroScale lua script

jerodast will request to delete this page once any useful changes are merged to
  the live MaroScale page

Goals for jerodast:
  * learn a bit more how it's used, AND about Modules in general
  * update LEGAL_EXPANSIONS
  * allow for not-a-single-number phrasings to be given an approximate number
      for sorting but still display, e.g. "about a 9" (treated as 9) or
      "7 or 8" (treated as 7.5)
  * explore possibility of having dates show up in the list of ratings changes,
      since the current simple serial list presentation makes ratings appear
      uniformly spaced when they're not
  * add column for additional notes - note that Beeble Scale crams notes into
      Timeline column already
]]

--[[ Beeble scale currently includes notes simply by placing them after the ref
     part of an entry:
    
	| entry25  = Phelddagrif
	| ratings25= {9,2018-10-21,<ref>{{EzTumblr|http://markrosewater.tumblr.com/post/179292907638/|title=Where is Phelddagriff on the Beeble Scale?|October 21, 2018}}</ref>}, 
	{9,2018-11-26,<ref>{{EzTumblr|http://markrosewater.tumblr.com/post/180506854918/|title=Where are phelddagrifs on the beeble scale? |November 26, 2018}}</ref> (actually 9 ½.)},
	
	Shows as:           9[32], 9[33] (actually 9 ½.)
	
	
	| entry4   = Dwarf
	| ratings4 = {1,2013-01-23,<ref>{{EzTumblr|http://markrosewater.tumblr.com/post/41287858160/|title=I like your "storm scale" invention so I hope...|2013-01-23}}</ref>},
	{1,2013-10-25,<ref>{{EzTumblr|http://markrosewater.tumblr.com/post/65064665515/|title=Where are dwarves on the storm scale? I know that orcs and dwarves...|2013-10-25}}</ref>},
	{1,2016-06-04,<ref>{{EzTumblr|http://markrosewater.tumblr.com/post/145378547208/|title=Hello Mr. Rosewater! Can you tell us where are dwarves on the Storm Scale?|2016-06-04}}</ref> Reprinted in ''[ [Kaladesh] ]''}, 
	{2,2018-03-20,<ref>{{EzTumblr|http://markrosewater.tumblr.com/post/172073275828/|title=What’s the current outlook for Dwarves in Magic?|2018-03-20}}</ref>}, 
	{3,2018-10-23,<ref>{{EzTumblr|http://markrosewater.tumblr.com/post/17934156953/|title=Where are dwarves on the Beeble Scale?|October 23, 2018}}</ref>}, 
	{2,2019-08-21,<ref name="D&O">{{EzTumblr|https://markrosewater.tumblr.com/post/187167710678/|title=So what are Dwarves and Orcs on the Beeble scale?|August 21, 2019}}</ref>},
	{2,2019-09-30,<ref>{{EzTumblr|https://markrosewater.tumblr.com/post/188050238433/|title=Hi Mark, Since we got some pretty sweet Dwarf cards in Eldraine|September 30, 2019}}</ref>}, 
	{4,2020-03-29,<ref>{{EzTumblr|http://markrosewater.tumblr.com/post/613949342837096448/|title=Judging by my playgroup and another Question Marks...|2020-03-29}}</ref>},
	
	Shows as:     1[5], 1[6], 1[7] Reprinted in Kaladesh, 2[8], 3[9], 2[10], 2[11], 4[12]
]]

-- Little bit of Lua for building tables for the Storm and Rabiah scales.
-- Mechanics have been re-ranked in the past, and it's probably interesting to track their drift.
-- Rather than force editors to track the newest one, let's see if we can't do it in code.

local MaroScaleSandbox = {}

local sub, match, gsub = mw.ustring.sub, mw.ustring.match, mw.ustring.gsub
-- ustring is string library equivalents that work on UTF-8 aka mediawiki text

local MAX_ENTRIES = 500
-- A list of all sets which have been Standard-legal since the introduction of the Storm Scale (September 2012)
local LEGAL_EXPANSIONS = {
	["Return to Ravnica"]		 = "2012-10-05",
	["Gatecrash"] 				 = "2013-02-01",
	["Dragon's Maze"] 			 = "2013-05-03",
	["Magic 2014"] 				 = "2013-06-13",
	["Theros"] 					 = "2013-09-27",
	["Born of the Gods"] 		 = "2014-02-07",
	["Journey into Nyx"]		 = "2014-05-02",
	["Magic 2015"] 				 = "2014-07-18",
	["Khans of Tarkir"] 		 = "2014-09-26",
	["Fate Reforged"] 			 = "2015-01-23",
	["Dragons of Tarkir"] 		 = "2015-03-17",
	["Magic Origins"] 			 = "2015-07-15",
	["Battle for Zendikar"] 	 = "2015-10-02",
	["Oath of the Gatewatch"] 	 = "2016-01-22",
	["Shadows over Innistrad"] 	 = "2016-04-08",
	["Eldritch Moon"] 			 = "2016-06-22",
	["Kaladesh"] 				 = "2016-09-30",
	["Aether Revolt"] 			 = "2016-01-20",
	["Amonkhet"] 				 = "2017-04-28",
	["Hour of Devastation"] 	 = "2017-07-14",
	["Ixalan"]                   = "2017-09-29",
	["Rivals of Ixalan"]         = "2018-01-19",
	["Dominaria"]                = "2018-04-27",
	["Core Set 2019"]            = "2018-07-13",
	["Guilds of Ravnica"]        = "2018-10-05",
	["Ravnica Allegiance"]       = "2019-01-25",
	["War of the Spark"]         = "2019-05-03",
	["Core Set 2020"]            = "2019-07-12",
	["Throne of Eldraine"]       = "2019-10-04",
	["Theros Beyond Death"]      = "2020-01-24",
	["Ikora: Lair of Behemoths"] = "2020-05-15",
	["Core Set 2021"]            = "2020-07-03",
	["Zendikar Rising"]          = "2020-09-25",
	["Kaldheim"]                 = "2021-02-05",
	["Strixhaven"]               = "2021-04-23",
	["Dungeons & Dragons: Adventures in the Forgotten Realms"] = "2021-07-23",
	["Innistrad: Midnight Hunt"] = "2021-09-24",
	["Innistrad: Crimson Vow"]   = "2021-11-19",
	["Kamigawa: Neon Dynasty"]   = "2022-02-18",
	["Streets of New Capenna"]   = "2022-04-29",
	["Dominaria United"]         = "2020-09-09",
	["The Brothers' War"]        = "2020-11-18",
}

local function generateLink(target, displayText)
	if displayText then
		return "[["..displayText.."|"..target.."]]"
	else
		return "[["..target.."]]"
	end
end

local function parseRatings(raw)
	local outputList = {}
	local newestDate, newestRating = 0, 0
	local rating, refDate, refString, t
	gsub(raw, "{(.-)}", function(a)
		rating, refDate, refString = match(a, "(%d+),([%d%-]+),(.+)")
		rating = tonumber(rating)
		
		-- Dates MUST be yyyy-mm-dd
		t = os.time({year=sub(refDate, 1,4), month=sub(refDate, 6,7), day=sub(refDate, 9,10),})
		if t > newestDate then
			newestDate = t
			newestRating = rating
		end
		
		table.insert(outputList, {text = rating..refString, t = t})
	end)
	
	return newestRating, outputList
end

local function addPrintings(timeline, printings)
	local releaseDate, t
	-- Comma-separated list
	gsub(printings, "([^,]+)", function(set)
		releaseDate = LEGAL_EXPANSIONS[set]
		
		-- The set name provided doesn't match a post-Storm Scale set
		if not releaseDate then return end
		
		-- Dates MUST be yyyy-mm-dd
		t = os.time({year=sub(releaseDate, 1,4), month=sub(releaseDate, 6,7), day=sub(releaseDate, 9,10),})
		
		table.insert(timeline, {text = generateLink(set), t = t})
	end)
	
	return timeline
end

local function sortTimeline(events)
	-- Sort all events into chronological order
	table.sort(events, function(a,b) return a.t < b.t end)
	return events
end

	
function MaroScaleSandbox.TableBuilder(frame)
	local args = frame:getParent().args -- coming from one layer up
	
	-- Imitating navbox, here. I trust they know what they're doing.
	-- Read the arguments in the order they'll be output in, to make references number in the right order.
    local _
    _ = args.type
    _ = args.above
    for i = 1, MAX_ENTRIES do
        _ = args["name" .. tostring(i)]
        _ = args["entry" .. tostring(i)]
        _ = args["note" .. tostring(i)]
        _ = args["ratings" .. tostring(i)]
        _ = args["printings" .. tostring(i)]
    end
	
	-- Seriously this loop is entirely too clever
	local listnums = {}
	for k, v in pairs(args) do
		local listnum = match('' .. k, '^ratings(%d+)$')
		if listnum then table.insert(listnums, {num = tonumber(listnum), alpha = args["entry"..listnum]}) end
	end
	table.sort(listnums, function(a,b) return a.alpha < b.alpha end)

	
	-- Build the table header row
	local type = args.type
	local tbl = mw.html.create("table"):addClass("wikitable"):addClass("sortable")
	tbl:tag("tr")
		:tag("th"):wikitext(type):done()
		:tag("th"):wikitext("Latest ranking"):done()
		:tag("th"):addClass("unsortable"):wikitext("Timeline"):done() -- Last column can't be sorted
	
	local hasNotes = false
	
	-- Reusable loop vars for performance
	local name, entry, note, ratings, printings
	local linkedEntry, lastRating, timeline
	local row, list, cellText
	for i, listnum in ipairs(listnums) do
		listnum = listnum.num
		-- Retrieve the relevant args for this row
		name, entry, note, ratings, printings = args["name"..listnum], args["entry"..listnum], args["note"..listnum], args["ratings"..listnum], args["printings"..listnum]
		
		-- Create a wikilink for the entry, using name as the target article if provided
		linkedEntry = generateLink(entry, name)
		if note then
			if not hasNotes then hasNotes = true end
			linkedEntry = linkedEntry .. frame:expandTemplate({title = "efn", args = { note }})
		end
		
		-- Decode the ratings into a table
		lastRating, timeline = parseRatings(ratings)
		-- Add any printings
		if printings then
			timeline = addPrintings(timeline, printings)
		end
		-- Sort chronologically
		timeline = sortTimeline(timeline)
		
		-- Make the row
		row = tbl:tag("tr")
		
		-- First cell
		row:tag("td"):wikitext(linkedEntry)
		
		-- Second cell
		row:tag("td"):wikitext(lastRating)
			
		-- Third cell
		list = row:tag("td"):tag("ul"):cssText("display:block; margin-top:0; margin-left:0;")
		
		for n, event in pairs(timeline) do
			if n ~= #timeline then
				list:tag("li"):cssText("display:inline-block;"):wikitext(event.text .. ",&nbsp;")
			else
				list:tag("li"):cssText("display:inline-block;"):wikitext(event.text)
			end
		end
	end
	
	if hasNotes then
		return tostring(tbl) .. frame:expandTemplate({title = "notelist"})
	else
		return tbl
	end
end

return MaroScaleSandbox