Jump to content

Module:Categories by date

Permanently protected module
From Wikisource

local p = {}

local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local ordinal = require('Module:Ordinal')._ordinal

local function pad_number(n, pad)
	n = tostring(n)
	return string.rep('0', pad - string.len(n)) .. n
end

function p._categories_by_date(args)
	local testing = yesno(args.testing) or mw.title.getCurrentTitle().fullText == 'Template:Categories by date/testcases'
	
	local caption = args.caption or '{{{caption}}}'
	local name = args.name or '{{{name}}}'
	local supercatname = args.supercatname
	
	local year = tonumber(args.year)
	local decade = tonumber(args.decade)
	local century = tonumber(args.century) or 0
	
	local era_suffix = ''
	args.bce = args.era == 'BCE' or args.era == 'BC' or yesno(args.bce) == true
	if args.bce then
		era_suffix = ' BCE'
	end
	
	local century_intertext = ' '
	if yesno(args['century-hyphen']) then
		century_intertext = '-'
	end
	local supercat_century_intertext = ' '
	if yesno(args['supercat-century-hyphen']) then
		supercat_century_intertext = '-'
	end
	
	local year_num = 100 * century + 10 * (decade or 0) + (year or 0)
	local decade_num = 100 * century + 10 * (decade or 0)
	local century_num = 100 * century
	local century_suffix_text = ordinal(century + 1, false, false)
	local century_suffix_sup = ordinal(century + 1, false, true)
	
	local millennium = math.floor(century/10)
	local millennium_num = millennium * 1000
	local millennium_suffix_text = ordinal(millennium + 1, false, false)
	local millennium_suffix_sup = ordinal(millennium + 1, false, true)
	
	local caption_text = caption .. ' in the '
	local parent_category = args['parent-category']
	local parent_category_display = args['parent-category-display'] or parent_category
	local by_date_category = args['by-date-category']
	local supercat
	local nearby_categories = {}
	
	local parent_sortkey
	local by_date_sortkey
	if not args.bce then
		parent_sortkey = ' ' .. year_num
		by_date_sortkey = pad_number(year_num, 4)
	else
		parent_sortkey = ' -' .. year_num
		by_date_sortkey = '-' .. pad_number(year_num, 4)
	end
	
	if year then
		caption_text = caption_text .. 'year ' .. year_num
		
		parent_category = parent_category or decade_num .. 's' .. era_suffix .. ' ' .. name
		parent_category_display = parent_category_display or parent_category
		
		by_date_category = by_date_category or name .. ' by year'
		
		if supercatname then
			supercat = year_num .. era_suffix .. ' ' .. supercatname
		end
		
		local start_year = math.max(decade_num, 1)
		local end_year = decade_num + 9
		local inc = 1
		
		if args.bce then
			start_year = decade_num + 9
			end_year = math.max(decade_num, 1)
			inc = -1
		end
		
		local before_start_year = start_year - inc
		local after_end_year = end_year + inc
		
		local before_start_year_text = before_start_year .. era_suffix
		local after_end_year_text = after_end_year .. era_suffix
		if before_start_year == 0 then
			before_start_year_text = '1 BCE'
		end
		if after_end_year == 0 then
			after_end_year_text = '1'
		end
		
		table.insert(nearby_categories, {cat = before_start_year_text .. ' ' .. name, display = '← ' .. before_start_year_text})
		for y = start_year, end_year, inc do
			table.insert(nearby_categories, {cat = y .. era_suffix .. ' ' .. name, display = y .. era_suffix})
		end
		table.insert(nearby_categories, {cat = after_end_year_text .. ' ' .. name, display = after_end_year_text .. ' →'})
	elseif decade then
		caption_text = caption_text .. decade_num .. 's'
		
		parent_category = parent_category or century_suffix_text .. century_intertext .. 'century' .. era_suffix .. ' ' .. name
		parent_category_display = parent_category_display or century_suffix_sup .. ' ' .. 'century' .. era_suffix .. ' ' .. name
		
		by_date_category = by_date_category or name .. ' by decade'
		
		if supercatname then
			supercat = decade_num .. 's' .. era_suffix .. ' ' .. supercatname
		end
		
		local start_year = century_num
		local end_year = century_num + 90
		local inc = 10
		
		if args.bce then
			start_year = century_num + 90
			end_year = century_num
			inc = -10
		end
		
		local before_start_year = start_year - inc
		local after_end_year = end_year + inc
		
		local before_start_year_text = before_start_year .. 's' .. era_suffix
		local after_end_year_text = after_end_year .. 's' .. era_suffix
		if before_start_year == -10 then
			before_start_year_text = '0s BCE'
		end
		if after_end_year == -10 then
			after_end_year_text = '0s'
		end
		
		table.insert(nearby_categories, {cat = before_start_year_text .. ' ' .. name, display = '← ' .. before_start_year_text})
		for d = start_year, end_year, inc do
			table.insert(nearby_categories, {cat = d .. 's' .. era_suffix .. ' ' .. name, display = d .. 's' .. era_suffix})
		end
		table.insert(nearby_categories, {cat = after_end_year_text .. ' ' .. name, display = after_end_year_text .. ' →'})
	else
		caption_text = caption_text .. century_suffix_sup .. ' century'
		
		parent_category = parent_category or millennium_suffix_text .. ' millennium' .. era_suffix .. ' ' .. name
		parent_category_display = parent_category_display or millennium_suffix_sup .. ' millennium' .. era_suffix .. ' ' .. name
		
		by_date_category = by_date_category or name .. ' by century'
		
		if supercatname then
			supercat = century_suffix_text .. era_suffix .. supercat_century_intertext .. 'century ' .. supercatname
		end
		
		if not args.bce then
			by_date_sortkey = pad_number(century + 1, 2)
		else
			by_date_sortkey = '-' .. pad_number(century + 1, 2)
		end
		
		local start_year = millennium * 10
		local end_year = millennium * 10 + 9
		local inc = 1
		
		if args.bce then
			start_year = millennium * 10 + 9
			end_year = millennium * 10
			inc = -1
		end
		
		local before_start_year = start_year - inc
		local after_end_year = end_year + inc
		
		local before_start_year_text = ordinal(before_start_year + 1, false, false) .. century_intertext .. 'century' .. era_suffix
		local after_end_year_text = ordinal(after_end_year + 1, false, false) .. century_intertext .. 'century' .. era_suffix
	
		local before_start_year_display = ordinal(before_start_year + 1, false, true) .. ' century' .. era_suffix
		local after_end_year_display = ordinal(after_end_year + 1, false, true) .. ' century' .. era_suffix
		
		if before_start_year == -1 then
			before_start_year_text = ordinal(1, false, false) .. century_intertext .. 'century BCE'
			before_start_year_display = ordinal(1, false, true) .. ' century BCE'
		end
		if after_end_year == -1 then
			after_end_year_text = ordinal(1, false, false) .. century_intertext .. 'century'
			after_end_year_display = ordinal(1, false, true) .. ' century'
		end
		
		table.insert(nearby_categories, {
			cat = before_start_year_text .. ' ' .. name,
			display = '← ' .. before_start_year_display
		})
		for c = start_year, end_year, inc do
			table.insert(nearby_categories, {
				cat = ordinal(c + 1, false, false) .. century_intertext .. 'century' .. era_suffix .. ' ' .. name,
				display = ordinal(c + 1, false, true) .. ' century' .. era_suffix
			})
		end
		table.insert(nearby_categories, {
			cat = after_end_year_text .. ' ' .. name,
			display = after_end_year_display .. ' →'
		})
	end
	caption_text = caption_text .. era_suffix .. '.'
	
	nearby_category_list = mw.html.create('ul')
	for i = 1, #nearby_categories do
		nearby_category_list:tag('li')
			:wikitext('[[:Category:' .. nearby_categories[i]['cat'] .. '|' .. nearby_categories[i]['display'] .. ']]')
	end
	
	local cats = {}
	if testing or mw.title.getCurrentTitle():inNamespace(14) then
		table.insert(cats, '[[Category:' .. by_date_category .. '|' .. by_date_sortkey .. ']]')
		if parent_category ~= by_date_category then
			table.insert(cats, '[[Category:' .. parent_category .. '|' .. parent_sortkey .. ']]')
		end
		if supercat then
			table.insert(cats, '[[Category:' .. supercat .. '|' .. name .. ']]')
		end
	end
	
	local cats_by_date_div = mw.html.create('div')
		:tag('p')
			:wikitext(caption_text)
			:done()
		:tag('table')
			:addClass('toccolours plainlinks wst-cats-by-date-table')
			:tag('tr')
				:tag('td')
					:addClass('wst-cats-by-date-parent')
					:wikitext('[[:Category:' .. parent_category .. '|' .. parent_category_display .. ']]:')
					:done()
				:tag('td')
					:tag('div')
						:addClass('wst-flatlist')
						:node(nearby_category_list)
					:done()
				:done()
			:done()
		:wikitext(table.concat(cats))
		:allDone()
	
	return cats_by_date_div
end

function p.categories_by_date(frame)
	return p._categories_by_date(getArgs(frame))
end

return p