Module:Sandbox/TheThomanski/Esc explained

----- Cell colors -----local COL_FST = 'gold' -- 1st placelocal COL_SND = 'silver' -- 2nd placelocal COL_TRD = '#C96' -- 3rd placelocal COL_LST = '#FE8080' -- Last placelocal COL_SFQ = 'navajowhite' -- Semi-Final qualifierlocal COL_BJQ = 'paleturquoise' -- Backup jury qualifierlocal COL_DSQ = '#A4EAA9' -- Disqualifed / withdrawn entry

----- Text -----local AQ = 'Automatic qualifier'local NQ = 'Failed to qualify'local NOSEMI = 'No semi-finals'local NA = 'N/A'local MILLSTREET = 'Kvalifikacija za Millstreet'local ESC1996Q = 'Eurovision Song Contest 1996#Qualifying round'

----------------------------------------------------------------------------------------------------

local getArgs = require('Module:Arguments').getArgslocal p =

local amountOfEntrieslocal usedLanguages =

function p.entry(f) return main(f, 'entry') endfunction p.year(f) return main(f, 'year') endfunction p.country(f) return main(f, 'country') endfunction p.list(f) return main(f, 'list') end

function main(f, reqOutput) local args = getArgs(f) local html = local contest = getContest(args['cont']) local id = args['id'] local country = args['cnty'] local year = args['y'] local show = args['s'] local entryNo = args['no'] local sortMethod = if not show then show = 'gf' end if not entryNo then entryNo = 1 end if show

'gf' then sortMethod = 'draw' end local entries if reqOutput

'year' or reqOutput

'list' then -- Get all entries from country entries = getAllEntriesFrom elseif reqOutput

'country' then -- Get all entries from year entries = getAllEntriesFrom else end amountOfEntries = tableLen(entries) local function getEntryNo(entry) local entryNo = 1 if entry.cntye then entryNo = entry.cntye end return entryNo end if reqOutput

'entry' then if country and year then html = table.concat(createEntryRow) elseif id then entryNo = getEntryNo(getEntry) html = table.concat(createEntryRow) end else for _, entry in ipairs(entries) do entryNo = getEntryNo(entry) html = html .. table.concat(createEntryRow) end end return htmlend

--------------------------------------------------

local row = 0local spannedRows = local spannedCols = function createEntryRow(args) local html = local f = mw.getCurrentFrame local contest = args.contest local year = args.year local country = args.country if country and country['name'] then for i, name in ipairs(country['name']) do if name[2] then if contest.dates[tostring(year)] < name[2] then country = name[1] break end end country = name[1] end end local id = args.id local entryNo = args.entryNo local reqOutput = args.reqOutput local show = args.show local entry if country and year then entry = getEntry elseif id then entry = getEntry end if entry then row = row + 1 spannedCols = local id = entry.id local year = f:expandTemplate local draw local sf_draw = insertZeroBeforeSingleDigit(entry.sf_d) local gf_draw = insertZeroBeforeSingleDigit(entry.gf_d) if not sf_draw then sf_draw = entry.sf_h end if not gf_draw then gf_draw = entry.gf_h end local pl, pt local sf_pl = entry.sf_pl local gf_pl = entry.gf_pl local sf_pt = entry.sf_pt local gf_pt = entry.gf_pt if show then if show

'gf' then draw = gf_draw pl = gf_pl pt = gf_pt else draw = sf_draw pl = sf_pl pt = sf_pt end else if sf_draw then if gf_draw then -- Took part in both semi-final and grand-final pl = gf_pl pt = gf_pt draw = gf_draw else -- Only took part in semi-final pl = sf_pl pt = sf_pt draw = sf_draw end elseif gf_draw then -- Only took part in grand final pl = gf_pl pt = gf_pt draw = gf_draw end end local flag if entry.cnty['flag'] then for _, version in ipairs(entry.cnty['flag']) do if contest.dates[tostring(entry.y)] < version[2] then flag = version[1] break end end end country = f:expandTemplate local country_entry = getEntryNoFromCountry(contest, id) local artist = entry.art local song = entry.song local lang = local function createLangLink(songLang) if songLang[2] then songLang = '' .. songLang[2] .. '' else songLang = '' .. songLang[1] .. '' end return songLang end for _, songLang in ipairs(entry.lang) do if usedLanguages[1] then local found = false for _, usedLang in ipairs(usedLanguages) do if songLang[1]

usedLang then if songLang[2] then table.insert(lang, songLang[2]) else table.insert(lang, songLang[1]) end found = true end end if not found then table.insert(lang, createLangLink(songLang)) table.insert(usedLanguages, songLang[1]) end else table.insert(lang, createLangLink(songLang)) table.insert(usedLanguages, songLang[1]) end end if reqOutput

'entry' then entryData = entryDataText = replaceNilValues(entryData, entryData) elseif reqOutput

'year' then entryData = entryDataText = replaceNilValues(entryData, entryData) elseif reqOutput

'country' then entryData = entryDataText = replaceNilValues(entryData, entryDataText) elseif reqOutput

'list' then entryData = entryDataText = replaceNilValues(entryData, entryData) end local function isNil(row) if entryData[row]

'nil_' .. row then return true else return false end end local tr = '\n' -- Default no row styling local rowStyling = if reqOutput

'year' then if (show

'gf') and gf_pl

1 then rowStyling = 'font-weight:bold; background:' .. COL_FST .. ';' elseif (show

'sf' or show

'sf1' or show

'sf2') and (gf_draw or entry.q) then if entry.jury then rowStyling = 'font-weight:bold; background:' .. COL_BJQ .. ';' else rowStyling = 'font-weight:bold; background:' .. COL_SFQ .. ';' end end end tr = '\n' table.insert(html, tr) if entryData then for i, data in ipairs(entryData) do if not getIndex(spannedRows, row) and not getIndex(spannedCols, entryDataText[i]) then local cellStyling = if type(data)

'string' and string.sub(data, 1, 4)

'nil_' then -- If the value is nil data = nil if reqOutput

'country' then local gf_pl = getIndex(entryDataText, 'gf_pl') local gf_pt = getIndex(entryDataText, 'gf_pt') local sf_pl = getIndex(entryDataText, 'sf_pl') local sf_pt = getIndex(entryDataText, 'sf_pt') local colspan = 1 if not entry.id and entry.dq then if entryDataText[i]

'gf_pl' then if entry.y

2020 then data = 'Contest cancelled' else data = entry.dq end data = data .. ' X' colspan = 4 else break end else if gf_pt and isNil(gf_pt) then -- If no gf points if not isNil(sf_pl) or not isNil(sf_pt) then if entryDataText[i]

'gf_pl' and gf_pl and isNil(gf_pl) then -- If no gf points and no gf placement data = NQ if contest.id

'esc' then if entry.y

1993 then data = '' .. NQ .. ' X' end if entry.y

1996 then data = '' .. NQ .. ' X' end end colspan = 2 end else if entryDataText[i]

'gf_pt' and not isNil(gf_pl) then -- If no gf points but there is placement (e.g. ESC 1956) data = NA end end elseif not gf_pt then if entryDataText[i]

'gf_pl' and gf_pl and isNil(gf_pl) then -- If no gf points and no gf placement data = NQ end end if entryDataText[i]

'sf_pl' and sf_pl then if isNil(sf_pl) then -- if no semi results if contest.id

'esc' and entry.y

1993 then data = f:expandTemplate colspan = 2 elseif contest.id

'esc' and entry.y >= 2004 then if (not isNil(gf_pl) and not isNil(gf_pt)) or entry.q then data = AQ colspan = 2 end else data = NOSEMI colspan = 2 end end end end if data then cellStyling = f:expandTemplate else data = end if colspan > 1 then cellStyling = cellStyling .. '; colspan="' .. colspan .. '"' if data

rowspanData then cellStyling = cellStyling .. '; rowspan="' .. spannedRows .. '"' --cellStyling = cellStyling .. '; colspan="2"' table.insert(spannedRows, row + 1) else spannedRows = 1 end table.insert(spannedCols, entryDataText[i + 1]) end end if not data then data = end elseif entryDataText[i]

'id' or entryDataText[i]

'country_entry' then cellStyling = 'text-align:right' if show

'gf' and sf_draw then data = '' .. data .. '' end elseif entryDataText[i]

'draw' then if (show

'gf' and not entry.gf_d and entry.gf_h) or (show

'sf1' or show

'sf2' or show

'sf' and not entry.gf_d and entry.gf_h) then if data

1 then data = '1st half' end if data

2 then data = '2nd half' end end cellStyling = 'text-align:center' elseif entryDataText[i]

'year' then -- Year column cellStyling = 'text-align:center' elseif entryDataText[i]

'song' then local title = song local og_title = if entry.tlang then -- If it's a non-English song title if entry.og then -- If it's a transliterated title title = f:expandTemplate og_title = '(' .. f:expandTemplate .. ')' else title = f:expandTemplate end end data = '"' .. title .. '" ' .. og_title elseif entryDataText[i]

'lang' then if type(data)

'table' then data = processTable(data) end if entry.langm then -- If there are 'minor' languages local function createNote(lang) lang = createLangLink(lang) data = data .. f:expandTemplate end if type(entry.langm)

'table' then for _, v in ipairs(entry.langm) do createNote(v) end else createNote(langm) end end elseif entryDataText[i]

'pl' or entryDataText[i]

'pt' or entryDataText[i]

'gf_pl' or entryDataText[i]

'gf_pt' or entryDataText[i]

'sf_pl' or entryDataText[i]

'sf_pt' then cellStyling = 'text-align:right;' if reqOutput

'list' or reqOutput

'country' then if reqOutput

'country' then if entryDataText[i]

'gf_pl' or entryDataText[i]

'gf_pt' then show = 'gf' elseif entryDataText[i]

'sf_pl' or entryDataText[i]

'sf_pt' then semi = getSemi(contest, entry.id) if semi then show = semi end end end if show then calcAmountOfEntries(contest.id, entry.y, show) end if ((entryDataText[i]

'sf_pl' or entryDataText[i]

'sf_pt') and sf_pl

amountOfEntries) or ((entryDataText[i]

'gf_pl' or entryDataText[i]

'gf_pt') and gf_pl

amountOfEntries) or ((entryDataText[i]

'pl' or entryDataText[i]

'pt') and pl

amountOfEntries) then cellStyling = cellStyling .. ' background:' .. COL_LST .. '"' --data = tostring(data) .. ' ◁' else if show

'gf' or reqOutput

'country' then local pl = gf_pl if entryDataText[i]

'sf_pl' or entryDataText[i]

'sf_pt' then pl = sf_pl end if pl

1 then cellStyling = cellStyling .. ' background:' .. COL_FST .. '"' end if pl

2 then cellStyling = cellStyling .. ' background:' .. COL_SND .. '"' end if pl

3 then cellStyling = cellStyling .. ' background:' .. COL_TRD .. '"' end elseif (show

'sf' or show

'sf1' or show

'sf2') and (gf_pl or gf_pt) then if entry.jury then cellStyling = cellStyling .. ' background:' .. COL_BJQ .. '"' --data = tostring(data) .. ' ‡' else cellStyling = cellStyling .. ' background:' .. COL_SFQ .. '"' --data = tostring(data) .. ' †' end end end end if data

0 then data = '' .. data .. '' end -- Make digit bold if nul points end if reqOutput

'country' and entryDataText[i] ~= 'year' and entryDataText[i] ~= 'sf_pl' and entryDataText[i] ~= 'sf_pt' then calcAmountOfEntries(contest.id, entry.y, 'gf') local x = amountOfEntries if gf_pl

1 then cellStyling = cellStyling .. ' background:' .. COL_FST end if gf_pl

2 then cellStyling = cellStyling .. ' background:' .. COL_SND end if gf_pl

3 then cellStyling = cellStyling .. ' background:' .. COL_TRD end if gf_pl

x then cellStyling = cellStyling .. ' background:' .. COL_LST end if entry.dq or entry.nq then cellStyling = cellStyling .. ' background:' .. COL_DSQ end end if i

1 then cell = '\n' cellClose = '\n' else cell = '\n' cellClose = '\n' end table.insert(html, cell .. data .. '\n') end end table.insert(html, '\n') end end return htmlend

function getContest(x) local contests = mw.loadData('Module:Sandbox/TheThomanski/Esc/data').contests local reqContest = 'esc' -- Default ESC if x then reqContest = string.lower(x) end local result for _, contest in ipairs(contests) do -- For every contest do if contest.id

reqContest then result = contest end end return resultend

function getEntry(args) local result local contest = args.contest local country = args.country -- Table, macedonia local year = args.year local id = args.id local entryNo = args.entryNo -- For multiple entries per country in a year (e.g. ESC 1956) if type(contest)

'string' then contest = getContest(contest) end for _, entry in ipairs(contest.values) do -- For every entry in the contest do result = nil if country and year then if (hasValue(entry.cnty, country)) then -- If the entry is from the requested country if (entry.y

year) then -- If the entry is from the requested year result = entry end end elseif id then if (entry.id

tonumber(id)) then -- If the entry is the requested entry then result = entry end end if result then if entryNo and entryNo > 1 then entryNo = entryNo - 1 else return result end end end return resultend

function getAllEntriesFrom(args) local contest = getContest(args.contest) local entries = local draw = 1 local q_d = 0 local firstEntry = nil for i, entry in ipairs(contest.values) do -- For every entry in the contest do if args.from

'year' and entry.y

tonumber(args.year) then -- Get all entries from year if args.show then if (args.show

'sf' and entry.sf_d and not entry.sf) or -- Get all entries from Semi-Final (args.show

'sf1' and entry.sf

1) or -- Get all entries from Semi-Final 1 (args.show

'sf2' and entry.sf

2) or -- Get all entries from Semi-Final 2 (args.show

'gf' and (entry.gf_d or entry.q)) -- Get all entries from Grand Final then if args.show

'gf' and args.sortMethod

'draw' and entry.id then local found = false local oldEntry = entry.id local newEntry = entry.id if firstEntry

nil then firstEntry = entry end local gf_d = entry.gf_d while not found do if entry.q then q_d = q_d + 1 gf_d = q_d end if gf_d

draw then table.insert(entries, entry) draw = draw + 1 found = true else newEntry = newEntry + 1 entry = getEntry if not entry or entry.y ~= firstEntry.y then entry = firstEntry newEntry = entry.id end gf_d = entry.gf_d end end else table.insert(entries, entry) end end else table.insert(entries, entry) end elseif args.from

'country' and hasValue(entry.cnty, args.country) then -- Get all entries from country table.insert(entries, entry) end end return entriesend

function getEntryNoFromCountry(contest, id) if id then local entry = getEntry local country = entry.cnty if country['name'] then country = country['name'][1][1] end local entries = getAllEntriesFrom local extraEntries = -- For more than one entry in a year (e.g. ESC 1956) for i, v in ipairs(entries) do if extraEntries[v.y] then extraEntries[v.y] = extraEntries[v.y] + 1 else extraEntries[v.y] = 0 end if v.id

entry.id then local removal = 0 for _, v in pairs(extraEntries) do removal = removal + v end local result = i - removal if entry.cntye then result = result .. ' (' .. entry.cntye .. ')' end return result end end endend

function getSemi(contest, id) local entry = getEntry if entry then if entry.sf then return 'sf' .. tostring(entry.sf) elseif entry.sf_d then return 'sf' end end return nilend

function replaceNilValues(entryData, entryDataText) local length = tableLen(entryDataText) for i = 1, length do if not entryData[i] then entryData[i] = 'nil_' .. i end endend

function calcAmountOfEntries(contest, year, show) amountOfEntries = tableLen(getAllEntriesFrom)end

--------------------------------------------------

function insertZeroBeforeSingleDigit(x) if x then if x < 10 then x = '0' .. x end end return xend

function getIndex(tab, reqV) if type(tab)

'table' then for i, v in ipairs(tab) do if v

reqV then return i end end end return nilend

function processTable(tab) local str = if type(tab)

'table' then for i, v in ipairs(tab) do str = str .. v if i ~= tableLen(tab) then str = str .. ', ' end end return str else return tab endend

function tableLen(tab) local x = 0 if tab then for _ in pairs(tab) do x = x + 1 end end return xend

function hasValue(tab, val) if tab then if type(tab)

'table' then for _, v in pairs(tab) do if v

val or (type(v)

'table' and hasValue(v, val)) then return val end end elseif type(tab)

'string' then if tab

val then return val end end end return falseend

return p