require('strict')local p =
local function items(args, year, oldrange) local itemList = -- First loop through is to find the lowest year range, if any. If oldrange is supplied, the year range must also be greater than it. local range = 0; if args[year .. '_to'] or args[year .. 'a_to'] then local newrange = tonumber(args[year .. '_to'] or args[year .. 'a_to']) if newrange and (oldrange
nil or newrange > oldrange) and (range
-- Find items, filtered by range if available. if args[year] or args[year .. 'a'] then local thisrange = tonumber(args[year .. '_to'] or args[year .. 'a_to']) if (range
nil) or (thisrange and thisrange
0 and thisrange
range) then table.insert(itemList, args[year .. string.char(asciiletter)]) end end end return table.maxn(itemList), itemList, rangeend
local function color(args, year, itemNum, to_range)
if args[year .. '_color'] then return args[year .. '_color'] end if to_range and args[year .. '_to_' .. to_range .. '_color'] then return args[year .. '_to_' .. to_range .. '_color'] end
for yearrange = 1, 10 do if args['range' .. yearrange] and args['range' .. yearrange .. '_color'] then local _, _, beginyear, endyear = string.find(args['range' .. yearrange], '^(%d%d%d%d)%D+(%d%d%d%d)$')
local year = tonumber(year) or 9999 -- For year
if year >= beginyear and year <= endyear then local _, _, color1, color2 = string.find(args['range' .. yearrange .. '_color'], '^(%S*)%s*(%S*)$') color2 = string.find(color2, '^#?%w+$') and color2 or color1 return itemNum > 0 and color1 or color2 end end end
return itemNum > 0 and '#0BDA51' or '#228B22'end
local function left(builder, args, year, itemNum, range) builder = builder:tag('th') :attr('scope', 'row') :css('border-right', '1.4em solid ' .. color(args, year, itemNum, range)) if itemNum > 1 then builder = builder:attr('rowspan', itemNum) end if year
local function right(builder, itemNum, itemList) if itemNum
if itemNum
-- if itemNum >= 2 builder:tag('td') :addClass('rt-first') :wikitext(itemList[1])
for key = 2, itemNum - 1 do builder = builder:tag('tr') :tag('td') :addClass('rt-next') :wikitext(itemList[key]) end
builder = builder:tag('tr') :tag('td') :addClass('rt-last') :wikitext(itemList[itemNum])
end
local function row(builder, args, year, emptyyear, lastyear, highrange) local oldrange = nil repeat local itemNum, itemList, range = items(args, year, oldrange) -- Now check for a new high range and catch it. We need to know what highrange was prior to update though. local oldhighrange = nil if(range > 0 and (highrange
-- If compressempty is set, check for empty items, track empty years and high ranges, and -- put out a compressed range when next year is found. if args.compressempty and oldrange
-- If emptyyear is below or equal the highrange, we need to make adjustments. if(emptyyear and oldhighrange and emptyyear <= oldhighrange) then -- If the current year is highrange or highrange +1, suppress empty row output entirely. -- If the current year is highrange+2 or more, adjust the emptyyear to be above highrange) if(year <= (oldhighrange+1)) then emptyyear = nil elseif(year > (oldhighrange+1)) then emptyyear = oldhighrange+1 end end
-- If we have items but are tracking an empty year, output compressed range row. if emptyyear ~= nil then builder = builder:tag('tr') if year
emptyyear then left(builder, args, emptyyear, 0, 0) else left(builder, args, emptyyear, 0, year-1) end end end end -- We can break out if this is the case. This means we have looped through more than once, but there were no more items remaining. if range
builder = builder:tag('tr') left(builder, args, year, itemNum, range) right(builder, itemNum, itemList)
if range ~= 0 then oldrange = range end until range
function p._main(args) -- Main module code goes here. local currentyear = os.date('%Y')
local ret local firstyear, lastyear local TBA = items(args, 'TBA') > 0 and true or false
ret = mw.html.create('table') :addClass('release-timeline wikitable') :addClass(args.align
ret:tag('caption') :wikitext((args.title or 'Release timeline') .. (args.subtitle and ('
'..args.subtitle..'
') or ))
if tonumber(args.first) then firstyear = tonumber(args.first) else for i = 1, currentyear do if items(args, i) > 0 then firstyear = i break end end firstyear = firstyear or (currentyear + 3) end
if tonumber(args.last) then lastyear = tonumber(args.last) else for i = currentyear + 3, TBA and currentyear or firstyear, -1 do if items(args, i) > 0 then lastyear = i break end end lastyear = lastyear or (currentyear - 1) end
local emptyyear = nil local highrange = nil for year = firstyear, lastyear do local yearcheck, newhighrange = row(ret, args, year, emptyyear, lastyear, highrange) if (emptyyear
nil) then emptyyear = yearcheck end highrange = newhighrange end
if TBA then row(ret, args, 'TBA') end
return mw.getCurrentFrame:extensionTag .. tostring(ret)end
function p.main(frame) local args = require('Module:Arguments').getArgs(frame) return p._main(args)end
return p