ข้ามไปเนื้อหา

มอดูล:Team appearances list

จากวิกิพีเดีย สารานุกรมเสรี
Documentation icon คู่มือการใช้งานมอดูล[สร้าง]
-- This module implements [[Template:Team appearances list]].

local p = {}

local data_competitions
local data_old_names
local function load_data(frame)
	-- Load data module (or its sandbox) and set variables from its exported data.
	if not data_competitions then
		frame = frame or mw.getCurrentFrame()
		local sandbox = frame:getTitle():find('sandbox', 1, true) and '/sandbox' or ''
		local datamod = mw.loadData('Module:Team appearances list/data' .. sandbox)
		data_competitions = datamod.competitions
		data_old_names = datamod.old_names
	end
end

local function strip_to_nil(text)
	-- If text is a string, return its trimmed content, or nil if empty.
	-- Otherwise return text (which may, for example, be nil).
	if type(text) == 'string' then
		text = text:match('(%S.-)%s*$')
	end
	return text
end

local function make_options(args)
	-- Return table of options from validated args or throw error.
	local options = {}
	local function valid_integer(name, min, max, is_optional)
		local arg = args[name]
		if arg == nil or arg == '' then
			if is_optional then
				return nil
			end
			error('Parameter ' .. name .. ' is missing')
		end
		arg = tonumber(arg)
		if type(arg) ~= 'number' then
			error('Parameter ' .. name .. ' is not a number')
		end
		if math.floor(arg) ~= arg then
			error('Parameter ' .. name .. ' is not an integer')
		end
		if not (min <= arg and arg <= max) then
			error('Parameter ' .. name .. ' is not valid')
		end
		return arg
	end
	local function valid_text(name)
		local arg = args[name]
		if arg == nil or arg == '' then
			error('Parameter ' .. name .. ' is missing')
		end
		if type(arg) ~= 'string' then
			error('Parameter ' .. name .. ' is not a string')
		end
		return arg
	end
	options.competition = valid_text('competition')
	options.team = valid_text('team')
	-- Check ROC/TPE
	if options.team=='สาธารณรัฐจีน' then
		local pageYear = tonumber(mw.ustring.match(mw.title.getCurrentTitle().text, '[%d]+')) -- mw.title.getCurrentTitle().text:match('^%d+')
		if pageYear and pageYear > 1950 and pageYear < 1980 then
			options.team = 'จีนไทเป'
		end
	end
	-- end of ROC/TPE check
	options.competitions = data_competitions[options.competition] or data_competitions[data_old_names[options.competition]]
	local begin_optional
	if options.competitions then
		begin_optional = true
	else
		options.interval = valid_integer('interval', 1, 30)
	end
	options.begin_year = valid_integer('begin_year', 1800, 2100, begin_optional)
	options.end_year = valid_integer('end_year', 1800, 2100, true)
	if options.begin_year and options.end_year then
		if options.begin_year > options.end_year then
			error('Parameter end_year must not be before begin_year')
		end
	end
	options.disqualified_year = valid_integer('disqualified_year', 1800, 2100, true)
	return options
end

local function extract_range(text)
	-- Return first (if text is a single year), or first, last if a range.
	-- The returned values are numbers.
	-- Return nothing if text is invalid.
	local year = text:match('^(%d+)$')
	if year then
		if #year == 4 then
			return tonumber(year)
		end
		return
	end
	local first, dash, last = text:match('^(%d+)(%D+)(%d+)$')
	if not (first and #first == 4) then
		return
	end
	dash = strip_to_nil(dash)
	if not (dash == '-' or dash == '–') then
		return
	end
	if #last ~= 4 then
		if #last == 2 then
			last = first:sub(1, 2) .. last
		else
			return
		end
	end
	first = tonumber(first)
	last = tonumber(last)
	if first < last then
		return first, last
	elseif first == last then
		return first
	end
end

local function competition_absences(data)
	-- Return two tables with absent years and absent year ranges.
	-- Parameter data is an array of strings from template parameters, or
	-- numbers or strings from built-in data.
	-- Parameters that are blank or not numbers or strings are ignored.
	local absent_years, absent_ranges = {}, {}
	for _, item in ipairs(data) do
		if type(item) == 'number' then
			absent_years[item] = true
		else
			item = strip_to_nil(item)
			if type(item) == 'string' then
				local first, last = extract_range(item)
				if not first then
					error('Year ' .. item .. ' is not valid')
				end
				if last then
					table.insert(absent_ranges, {first, last})
				else
					absent_years[first] = true
				end
			end
		end
	end
	return absent_years, absent_ranges
end

local function competition_information(args)
	-- Return four tables with competition and team information:
	-- * List of competition years that the team attended or could have attended.
	-- * Table of disqualified years (the team was absent, but there is an
	--   article regarding the absent year).
	-- * Table of absent years (when the team did not attend).
	-- * List of pairs of years (absent for each year in range, inclusive).
	local options = make_options(args)
	local absences
	local comp_years = {}
	local begin_year = options.begin_year
	local end_year = options.end_year
	local competitions = options.competitions
	if competitions then
		absences = competitions[options.team] or competitions[data_old_names[options.team]]
		begin_year = begin_year or (absences and absences.begin_year) or 0
		end_year = end_year or (absences and absences.end_year) or 9999
		for _, y in ipairs(competitions) do
			if y > end_year then
				break
			elseif y >= begin_year then
				table.insert(comp_years, y)
			end
		end
	else
		end_year = end_year or (os.date('!*t').year + options.interval)
		for y = begin_year, end_year, options.interval do
			table.insert(comp_years, y)
		end
	end
	local disqualified_years = {}
	if options.disqualified_year then
		-- Input currently only allows entry of a single disqualified year.
		-- However processing works for any number of such years.
		disqualified_years[options.disqualified_year] = true
	end
	return comp_years, disqualified_years, competition_absences(absences or args)
end

local function gameName(year, inputName)
	-- Modifies output of display being sent back to the list
	--  for games that have had a name change but are still considered
	--  the same competition.
	if (inputName=="กีฬาจักรวรรดิบริติช"
		or inputName=="กีฬาเครือจักรภพและจักรวรรดิบริติช"
		or inputName=="กีฬาเครือจักรภพบริติช"
		or inputName=="กีฬาเครือจักรภพ") then
			if year <= 1950 then
				return "กีฬาจักรวรรดิบริติช"
			elseif year <= 1966 then
				return "กีฬาเครือจักรภพและจักรวรรดิบริติช"
			elseif year <= 1974 then
				return "กีฬาเครือจักรภพบริติช"
			else
				return "กีฬาเครือจักรภพ"
			end
	elseif inputName=="กีฬาแหลมทอง"
		or inputName=="ซีเกมส์" then
			if year <= 1975 then
				return "กีฬาแหลมทอง"
			else
				return "ซีเกมส์"
			end
	elseif inputName=="เอเชียนอินดอร์เกมส์" or inputName=="เอเชียนอินดอร์และมาร์เชียลอาตส์เกมส์" then
		if year <= 2009 then
			return "เอเชียนอินดอร์เกมส์"
		else
			return "เอเชียนอินดอร์และมาร์เชียลอาตส์เกมส์"
		end
	elseif inputName=="เซาท์เทิร์นครอสเกมส์" or inputName=="เซาท์อเมริกันเกมส์" then
		if year <= 1982 then
			return "เซาท์เทิร์นครอสเกมส์"
		else
			return "เซาท์อเมริกันเกมส์"
		end
	elseif inputName=="ออลแอฟริกาเกมส์" or inputName=="แอฟริกันเกมส์" then
		if year <= 2011 then
			return "ออลแอฟริกาเกมส์"
		else
			return "แอฟริกันเกมส์"
		end
	else
		return inputName
	end
end

local function teamName(year, inputName, comp)
	-- Modifies output of display being sent back to the list
	--  for games that have had a name change but are still considered
	--  the same competition.
	if inputName=="ประเทศเอสวาตินี" or inputName=="ประเทศสวาซิแลนด์" then
		if year < 2018 or year == 2018 and comp == 'กีฬาเครือจักรภพ' then
			return "ประเทศสวาซิแลนด์"
		else
			return "ประเทศเอสวาตินี"
		end
	elseif inputName=="เซาเทิร์นโรดีเชีย" or inputName=="ประเทศโรดีเชีย" or inputName=="ประเทศซิมบับเว" then
			if year < 1980 then
				if (comp=="กีฬาจักรวรรดิบริติช "
					or comp=="กีฬาเครือจักรภพและจักรวรรดิบริติช"
					or comp=="กีฬาเครือจักรภพบริติช"
					or comp=="กีฬาเครือจักรภพ") then
						return "เซาเทิร์นโรดีเชีย"
				elseif comp=="โอลิมปิกฤดูร้อน"or comp=="พาราลิมปิกฤดูร้อน" then
						return "ประเทศโรดีเชีย"
				end
			else
				return "ประเทศซิมบับเว"
			end
	elseif (inputName=="สาธารณรัฐจีน"
			or inputName=="ฟอร์โมซา"
			or inputName=="ประเทศไต้หวัน"
			or inputName=="จีนไทเป") then
				if year <= 1956 or year == 1972 or year == 1976 then
					return "สาธารณรัฐจีน"
				elseif year==1960 then
					return "สาธารณรัฐจีน (ฟอร์โมซา) "
				elseif year==1964 or year==1968 then
					return "ประเทศไต้หวัน"
				elseif year > 1976 then
					return "จีนไทเป"
				end
	elseif inputName=="นอร์เทิร์นโรดีเชีย" or inputName=="ประเทศแซมเบีย" then
			if year <= 1964 then
				return "นอร์เทิร์นโรดีเชีย"
			else
				return "ประเทศแซมเบีย"
			end
	elseif inputName=="เอเดน" or inputName=="สหพันธรัฐอาระเบียใต้" then
			if year < 1966 then
				return "เอเดน"
			else
				return "สหพันธรัฐอาระเบียใต้"
			end
	elseif inputName=="บริติชกีอานา" or inputName=="ประเทศกายอานา" then
			if year < 1966 then
				return "บริติชกีอานา"
			else
				return "ประเทศกายอานา"
			end
	elseif inputName=="ประเทศแทนซาเนีย" or inputName=="ประเทศแทนกันยีกา" then
			if year < 1966 then
				return "ประเทศแทนกันยีกา"
			else
				return "ประเทศแทนซาเนีย"
			end
	elseif inputName=="ประเทศซีลอน" or inputName=="ประเทศศรีลังกา" then
			if year <= 1972 then
				return "ประเทศซีลอน"
			else
				return "ประเทศศรีลังกา"
			end
	elseif inputName=="บริติชฮอนดูรัส" or inputName=="ประเทศเบลีซ" then
			if year <= 1973 then
				return "บริติชฮอนดูรัส"
			else
				return "ประเทศเบลีซ"
			end
	elseif inputName=="สาธารณรัฐดาโฮมีย์" or inputName=="ประเทศเบนิน" then
			if year <= 1975 then
				return "สาธารณรัฐดาโฮมีย์"
			else
				return "ประเทศเบนิน"
			end
	elseif inputName=="ประเทศอัปเปอร์วอลตา" or inputName=="ประเทศบูร์กินาฟาโซ" then
			if year <= 1983 then
				return "ประเทศอัปเปอร์วอลตา"
			else
				return "ประเทศบูร์กินาฟาโซ"
			end
	elseif inputName=="ประเทศเยอรมนี" or inputName=="ประเทศเยอรมนีตะวันตก" then
		if comp == "พาราลิมปิกฤดูร้อน" or comp == "พาราลิมปิกฤดูหนาว" then
			if year < 1992 then
				return "ประเทศเยอรมนีตะวันตก"
			else
				return "ประเทศเยอรมนี"
			end
		end
	elseif inputName=="สาธารณรัฐประชาธิปไตยคองโก" or inputName=="สาธารณรัฐซาอีร์" then
		if year < 1971 then
			return "สาธารณรัฐประชาธิปไตยคองโก"
		elseif year >= 1971 and year <=1996 then
			return "สาธารณรัฐซาอีร์"
		else
			return "สาธารณรัฐประชาธิปไตยคองโก"
		end
	elseif (inputName=="นักกีฬาโอลิมปิกเฉพาะบุคคล" 
		or inputName=="นักกีฬาโอลิมปิกอิสระ" 
		or inputName=="ผู้เข้าร่วมโอลิมปิกโดยอิสระ"
		or inputName=="นักกีฬาโอลิมปิกจากประเทศรัสเซีย"
		or inputName=="อาร์โอซี"
		or inputName=="นักกีฬาเป็นกลางรายบุคคล") then
		if year == 1992 or year==2014 then
			return "ผู้เข้าร่วมโอลิมปิกโดยอิสระ"
		elseif year == 2000 then
			return "นักกีฬาโอลิมปิกเฉพาะบุคคล"
		elseif year == 2012 or year==2016 then
			return "นักกีฬาโอลิมปิกอิสระ"
		elseif year == 2018 then
			return "นักกีฬาโอลิมปิกจากประเทศรัสเซีย"
		elseif year == 2020 then
			return "นักกีฬาคณะกรรมการโอลิมปิกรัสเซีย"
		elseif year == 2024 then
			return "นักกีฬาเป็นกลางรายบุคคล"
		else
			return inputName
		end
	elseif inputName=="ประเทศเซอร์เบียและมอนเตเนโกร" or inputName=="สหพันธ์สาธารณรัฐยูโกสลาเวีย" then
		if year < 2004 then
			if comp == "เมดิเตอร์เรเนียนเกมส์" then
				return "สหพันธ์สาธารณรัฐยูโกสลาเวีย"
			else
				return "ประเทศยูโกสลาเวีย"
			end
		else
			return "ประเทศเซอร์เบียและมอนเตเนโกร"
		end
	elseif (inputName=="ผู้เข้าร่วมพาราลิมปิกโดยอิสระ"
		or inputName=="นักกีฬาพาราลิมปิกเฉพาะบุคคล"
		or inputName=="นักกีฬาพาราลิมปิกอิสระ"
		or inputName=="อาร์พีซี"
		or inputName=="นักกีฬาพาราลิมปิกที่เป็นกลาง") then
		if year == 1992 then
			return "ผู้เข้าร่วมพาราลิมปิกโดยอิสระ"
		elseif year == 2000 then
			return "นักกีฬาพาราลิมปิกเฉพาะบุคคล"
		elseif year==2016 then
			return "นักกีฬาพาราลิมปิกอิสระ"
		elseif year==2018 then
			return "นักกีฬาพาราลิมปิกที่เป็นกลาง"
		elseif year == 2020 or year==2022 then
			return "นักกีฬาคณะกรรมการพาราลิมปิกรัสเซีย"
		else
			return inputName
		end
	elseif inputName=="ประเทศมาซิโดเนียเหนือ" or inputName=="ประเทศมาซิโดเนีย" then
		if year < 2019 then
			return "ประเทศมาซิโดเนีย"
		else
			return "ประเทศมาซิโดเนียเหนือ"
		end
	elseif inputName=="ประเทศมาเลเซีย" or inputName=="สหพันธรัฐมาลายา" then
		if year < 1963 then
			return "สหพันธรัฐมาลายา"
		else
			return "ประเทศมาเลเซีย"
		end
	elseif inputName=="ประเทศกานา" or inputName=="โกลด์โคสต์" then
		if year < 1957 then
			return "โกลด์โคสต์"
		else
			return "ประเทศกานา"
		end
	elseif inputName=="นักกีฬาอิสระฟีน่า"
		or inputName=="ทีมฟีน่าผู้ลี้ภัย"
		or inputName=="นักกีฬาฟีน่า" then
		if year==2017 or year==2019 then
			return "นักกีฬาอิสระฟีน่า"
		elseif year==2022 then
			return "ทีมฟีน่าผู้ลี้ภัย"
		else
			return "นักกีฬาฟีน่า"
		end
	elseif inputName=="ประเทศซามัว" or inputName=="ซามัวตะวันตก" then
		if year < 1997 then
			return "ซามัวตะวันตก"
		else
			return "ประเทศซามัว"
		end
	elseif inputName=="สิงคโปร์" or inputName=="ประเทศสิงคโปร์" then
		if year <= 1965 then
			return "สิงคโปร์"
		else
			return "ประเทศสิงคโปร์"
		end
	end
	
	return inputName
end

function p._main(args)
	load_data()  -- in case this function is called by another module
	local list = require('Module:List').horizontal
	local competitions, disqualified_years, absent_years, absent_ranges = competition_information(args)
	local current_year = os.date('!*t').year
	local function is_absent(y)
		if absent_years[y] then
			return true
		end
		for _, range in ipairs(absent_ranges) do
			if range[1] <= y and y <= range[2] then
				return true
			end
		end
		return false
	end
	local appearances = {}
	local absent_first, absent_last
	for i = 1, #competitions + 1 do  -- +1 to handle any trailing absences
		local y = competitions[i]
		if y and is_absent(y) then
			if absent_first then
				absent_last = y
			else
				absent_first = y
			end
		else
			if absent_first then
				table.insert(appearances,
					'<span style="color:gray">' ..
					(absent_last and (absent_first .. '–' .. absent_last) or absent_first) ..
					'</span>')
				absent_first, absent_last = nil, nil
			end
			if y then
				local display = tostring(y)
				if y > current_year then
					display = '<i>' .. display .. '</i>'
				end
				if disqualified_years[y] then
					display = '<del>' .. display .. '</del>'
				end
				local compName = gameName(y, args.competition)
				local teamOut = teamName(y, args.team, args.competition)
				if compName == 'สกีลงเขาชิงแชมป์โลก' then
					table.insert(appearances, string.format(
					'[[%s di %s %d|%s]]',
					teamOut, compName, y, display
					))
				else
					table.insert(appearances, string.format(
						'[[%sใน%s %d|%s]]',
						teamOut, compName, y, display
					))
				end
			end
		end
	end
	return list(appearances)
end
				
function p.main(frame)
	load_data(frame)
	return p._main(frame.args['team'] and frame.args or frame:getParent().args)
end

return p