Module:MaroScale
Documentation for this module may be created at Module:MaroScale/doc
-- 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 MaroScale = {} local sub, match, gsub = mw.ustring.sub, mw.ustring.match, mw.ustring.gsub -- 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", } local function generateLink(target, displayText) if displayText then return "[["..target.."|"..displayText.."]]" 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 MaroScale.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, 200 do _ = args["name" .. tostring(i)] _ = args["entry" .. tostring(i)] _ = args["ratings" .. 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, tonumber(listnum)) end end table.sort(listnums) -- 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 -- Reusable loop vars for performance local name, entry, ratings, printings local linkedEntry, lastRating, timeline local row, list, cellText for i, listnum in ipairs(listnums) do -- Retrieve the relevant args for this row name, entry, ratings, printings = args["name"..listnum], args["entry"..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) -- 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 .. ", ") else list:tag("li"):cssText("display:inline-block;"):wikitext(event.text) end end end return tbl end return MaroScale