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", "Gatecrash", "Dragon's Maze", "Magic 2014", "Theros", "Born of the Gods", "Journey into Nyx", "Magic 2015", "Khans of Tarkir", "Fate Reforged", "Dragons of Tarkir", "Magic Origins", "Battle for Zendikar", "Oath of the Gatewatch", "Shadows over Innistrad", "Eldritch Moon", "Kaladesh", "Aether Revolt", "Amonkhet", "Hour of Devastation", } 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), sub(refDate, 6,7), 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), sub(releaseDate, 6,7), sub(releaseDate, 9,10),}) table.insert(timeline, {text = generateLink(set), t = t}) end) return timeline end local function sortHistory(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, 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(name, entry) -- Decode the ratings into a table lastRating, timeline = parseRatings(ratings) -- Add any printings timeline = addPrintings(timeline, printings) -- 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 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