Jump to content

Module:Timeline of release years

Permanently protected module
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Izno (talk | contribs) at 19:34, 4 January 2021 (move styles to _main, local for module:arguments rename classes because I'm bothered by underscore names which are not quite entirely unconventional, move caption class off to css, retarget tstyles to module version). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

require('Module:No globals')
local p = {}

local function items(args, year)
	local itemList = {}
	if args[year] or args[year .. 'a'] then
		table.insert(itemList, args[year] or args[year .. 'a'])
	end
	for asciiletter = 98, 106 do -- 98 > b, 106 > j
		if args[year .. string.char(asciiletter)] then
			table.insert(itemList, args[year .. string.char(asciiletter)])
		end
	end
	return table.maxn(itemList), itemList
end

local function color(args, year, itemNum)

	if args[year .. '_color'] then
		return args[year .. '_color'] 
	end
	
	if args.compressempty then
		if(string.len(year) > 4) then 
			year = string.sub(year,1,4)
		end
	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 == 'TBA'
			beginyear = tonumber(beginyear) or 0
			endyear =  tonumber(endyear) or 9999

			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)
	builder = builder:tag('th')
		:attr('scope', 'row')
		:css('border-right', '1.4em solid ' .. color(args, year, itemNum))
		:wikitext(year)
	if itemNum > 1 then
		builder = builder:attr('rowspan', itemNum)
	end
end

local function right(builder, itemNum, itemList)
	if itemNum == 0 then return end

	if itemNum == 1 then
		builder:tag('td')
			:wikitext(itemList[1])
		return
	end

	-- 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)
	local itemNum, itemList = items(args, year)

	-- If compressempty is set, check for empty items, track empty years, and
	-- put out a compressed range when next year is found.
	if args.compressempty then
		-- If we're compressing and there's no items, return this year for tracking.
		if #itemList < 1 then
			return year
		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 == 'TBA' then
				left(builder, args, emptyyear .. '–' .. lastyear, 0)
			else
				if year-1 == emptyyear then
					left(builder, args, emptyyear, 0)
				else
					left(builder, args, emptyyear .. '–' .. (year-1), 0)
				end
			end
		end
	end

	builder = builder:tag('tr')
	left(builder, args, year, itemNum)
	right(builder, itemNum, itemList)
	
	return nil
end

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 == 'left' and 'rt-left' or nil)

	ret:tag('caption')
		:wikitext((args.title or 'Release timeline') ..
			(args.subtitle and ('<div class="rt-subtitle">'..args.subtitle..'</div>') 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
	for year = firstyear, lastyear do
		local yearcheck = row(ret, args, year, emptyyear, lastyear)
		if (emptyyear == nil and yearcheck ~= nil) or (emptyyear ~= nil and yearcheck == nil) then
			emptyyear = yearcheck
		end
	end

	if TBA then
		row(ret, args, 'TBA')
	end

	return mw.getCurrentFrame():extensionTag{
		name = 'templatestyles', args = { src = 'Module:Timeline of release years/styles.css'}
	} .. tostring(ret)
end

function p.main(frame)
	local args = require('Module:Arguments').getArgs(frame)
	return p._main(args)
end

return p