Module:Team appearances list: Difference between revisions

Content deleted Content added
rmv anything more than a year in the future (2018+ pages will not have been created yet)
major refactor to handle ranges of absences and automatically merge ranges of absences in the output; use four-digit years in ranges per MOS:DATERANGE
Line 3:
 
local p = {}
local compressSparseArray = require('Module:TableTools').compressSparseArray
local hlist = require('Module:List').horizontal
local valueUnion = require('Module:Set').valueUnion
 
local COMPETITIONSall_competitions = {
["All-Africa Games"] = {
1965, 1973, 1978, 1987, 1991, 1995, 1999, 2003, 2007, 2011, 2015},
 
-----Asian Games----
["Asian Games"] = {
1951, 1954, 1958, 1962, 1966, 1970, 1974, 1978, 1985, 1986, 1990, 1994,
1998, 2002, 2006, 2010, 2014},
["Asian Beach Games"] = {
Line 34 ⟶ 31:
["West Asian Games"] = {
1997, 2002, 2005, 2016},
 
-----Commonwealth Games-----
["Commonwealth Games"] = {
Line 41 ⟶ 38:
["Commonwealth Youth Games"] = {
2000, 2004, 2008, 2011, 2015, 2017},
 
-----European Games-----
["European Athletics Championships"] = {
Line 51 ⟶ 48:
1951, 1955, 1959, 1963, 1967, 1971, 1975, 1979, 1983, 1987, 1991, 1993,
1997, 2001, 2005, 2009, 2013, 2017},
 
----- Olympics -----
["Summer Olympics"] = {
Line 69 ⟶ 66:
["Winter Youth Olympics"] = {
2012, 2016},
 
----- Misc / World -----
["FEI World Equestrian Games"] = {
Line 91 ⟶ 88:
2011, 2013, 2015, 2017},}
 
local function p._mainstrip_to_nil(argstext)
-- If text is a string, return its trimmed content, or nil if empty.
local begin_year = args.begin_year and tonumber(args.begin_year)
-- Otherwise return text (which may, for example, be nil).
local end_year = args.end_year and tonumber(args.end_year)
if type(text) == 'string' then
text = text:match('(%S.-)%s*$')
end
return text
end
 
local function competition_years(args)
local appearances = {}
-- Return list of competition years specified in args.
local absences = {}
local result = {}
for _, v in pairs(compressSparseArray(args)) do
local begin_year = tonumber(args.begin_year)
absences[string.sub(v, 1, 4)] = mw.getCurrentFrame():expandTemplate{
local end_year = tonumber(args.end_year)
title='Gray', args={v}}
local competitions = all_competitions[args.competition]
if competitions then
begin_year = begin_year or 0
end_year = end_year or 9999
for _, y in ipairs(competitions) do
if y > end_year then
break
elseif y >= begin_year then
table.insert(result, y)
end
end
else
if not (begin_year and 1800 <= begin_year and begin_year <= 2100) then
error('Parameter begin_year is not a valid year: ' .. tostring(args.begin_year))
end
local interval = tonumber(args.interval)
if not interval then
if not args.interval then
error('Parameter interval is missing')
end
error('Parameter interval is not a number: ' .. tostring(args.interval))
end
if not (1 <= interval and interval <= 30) then
error('Parameter interval is not valid: ' .. interval)
end
end_year = end_year or (os.date('!*t').year + interval)
for y = begin_year, end_year, interval do
table.insert(result, y)
end
end
return result
end
 
local function processYearextract_range(ytext)
-- Return first (if text is a single year), or first, last if a range.
y = tostring(y)
-- The returned values are numbers.
if absences[y] then
-- Return nothing if text is invalid.
table.insert(appearances, absences[y])
local year = text:match('^(%d+)$')
absences[y] = nil
if year then
else
if #year == 4 then
table.insert(appearances, string.format(
return tonumber(year)
'[[%s at the %s %s|%s]]', args.team, y, args.competition, y))
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 dash == '-' or dash == '–' then
if #last ~= 4 then
if #last == 2 then
last = first:sub(1, 2) .. last
else
return
end
end
end
first = tonumber(first)
last = tonumber(last)
if first < last then
return first, last
elseif first == last then
return first
end
end
 
-- TODO Missing parameters generate an ugly error (say if args.team is nil).
if COMPETITIONS[args.competition] then
-- Should show error if begin_year > end_year.
for _, y in pairs(COMPETITIONS[args.competition]) do
function p._main(args)
if end_year and y > end_year then
local hlist = require('Module:List').horizontal
break
local absent_years, absent_ranges = {}, {}
elseif not begin_year or y >= begin_year then
for _, v in ipairs(args) do
processYear(y)
-- Extract absent years from numeric parameters.
-- Skip blank parameters (and non-strings that may be passed by a module).
v = strip_to_nil(v)
if type(v) == 'string' then
local first, last = extract_range(v)
if not first then
error('Invalid year: "' .. v .. '"')
end
if last then
table.insert(absent_ranges, {first, last})
else
absent_years[first] = true
end
end
end
elseif not tonumber(args.interval) then
local function is_absent(y)
error('Interval is not a number: ' .. tostring(args.interval))
if absent_years[y] then
else
return true
for y = begin_year, (end_year or os.date('%Y')+args.interval),
end
args.interval do
for _, range in ipairs(absent_ranges) do
processYear(y)
if range[1] <= y and y <= range[2] then
return true
end
end
return false
end
local appearances = {}
local absent_first, absent_last
local competitions = competition_years(args)
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
table.insert(appearances, string.format(
'[[%s at the %d %s|%d]]',
args.team, y, args.competition, y
))
end
end
end
return hlist(valueUnion(absences, appearances))
end
 
function p.main(frame)
return p._main(frame:getParent().args)
local args = require('Module:Arguments').getArgs(frame, {parentOnly=true})
return p._main(args)
end