Module:Political groupings
Appearance
| This module depends on the following other modules: |
This module implements {{Political groupings}}. Please see the template page for documentation.
local p = {}
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local partyFetch = require('Module:Political party')._fetch
local colorCache = {}
local shortCache = {}
local function getSum(text)
if string.match(text, "[^%d%+]") then
return nil
end
local sum = 0
for num in text:gmatch("%d+") do
sum = sum + tonumber(num)
end
return sum
end
local function getBaseName(party)
return mw.ustring.gsub(party, "%s*%b()", "")
end
function p._getColor(party)
if string.sub(party, 1, 1) == "#" then
return party
end
local cached = colorCache[party]
if string.lower(getBaseName(party)) == "independent" then
party = "Independent"
end
if cached then
return cached
end
local color = partyFetch({party, "color"}) or "black"
color = mw.text.decode(mw.text.trim(color))
colorCache[party] = color
return color
end
local function getShort(party, displayNames)
if displayNames and displayNames[party] then
return displayNames[party]
end
local cached = shortCache[party]
if cached then
return cached
end
local short = partyFetch({party, "shortname"}) or party
short = mw.text.trim(short)
shortCache[party] = short
return short
end
local function makeLink(party, useShort, displayNames)
local base = getBaseName(party)
if string.lower(base) == "independent" then
return "Independent"
end
local target = mw.title.new(party, mw.site.namespaces.Main)
if not target.exists then
if useShort then
return getShort(party, displayNames)
end
return party
end
if useShort then
return "[[" .. party .. "|" .. getShort(party, displayNames) .. "]]"
end
return "[[" .. party .. "|" .. base .. "]]"
end
local function capitalizeFirst(str)
return mw.language.getContentLanguage():ucfirst(str or "")
end
local function makeColorBox(color)
local moreStyle = "background-color: " .. color .. "; border: 1px solid darkgray;"
return [[<span class="legend-color mw-no-invert" style="forced-color-adjust:none;]] .. moreStyle .. [["> </span>]]
end
local function isVacancy(party)
party = string.lower(party)
return party == "vacant" or party == "vacancy" or party == "casual vacancy"
end
local function processColor(party)
if string.sub(party, 1, 5) == "#" then
return "#" .. string.sub(party, 6)
end
if string.sub(party, 1, 6) == "#" then
return "#" .. string.sub(party, 7)
end
return party
end
function p._buildTable(args, tableMode)
local parties = {}
local seats = {}
local seatCounts = {}
local groupingsSeen = {}
local groupings = {}
local partyGrouping = {}
local groupCounts = {}
local partyColors = {}
local borderColors = {}
local total = 0
local vacancies = 0
local displayNames = {}
local lastParty
local addedParty
local lastDisplayName
for _, v in ipairs(args) do
if not getSum(v) then
if string.sub(v, 1, 1) == ":" then
local grouping = string.sub(v, 2)
if not groupingsSeen[grouping] then
groupingsSeen[grouping] = true
table.insert(groupings, grouping)
groupCounts[grouping] = 0
end
partyGrouping[addedParty] = grouping
groupCounts[grouping] = groupCounts[grouping] + getSum(seats[addedParty])
elseif lastParty then
lastDisplayName = v
else
lastParty = v
lastDisplayName = nil
end
else
if isVacancy(lastParty) and not tableMode then
vacancies = vacancies + v
total = total + (getSum(v) or 0)
else
table.insert(parties, lastParty)
seats[lastParty] = v
seatCounts[lastParty] = getSum(v) or 0
total = total + (getSum(v) or 0)
displayNames[lastParty] = lastDisplayName
partyColors[lastParty] = p._getColor(lastParty)
addedParty = lastParty
end
lastParty = nil
end
end
local idx = 1
while true do
local partySeats = args["n" .. idx]
if not partySeats then
break
end
local partyName = args["p" .. idx] or args["c" .. idx]
if partyName then
table.insert(parties, partyName)
seats[partyName] = partySeats
partySeats = getSum(partySeats) or 0
partyColors[partyName] = processColor(args["c" .. idx] or p._getColor(partyName))
seatCounts[partyName] = partySeats
local border = args["b" .. idx]
if border then
borderColors[partyName] = border
end
total = total + partySeats
displayNames[partyName] = nil
end
idx = idx + 1
end
return {groupings = groupings,
parties = parties,
partyGrouping = partyGrouping,
groupCounts = groupCounts,
seats = seats,
seatCounts = seatCounts,
displayNames = displayNames,
vacancies = vacancies,
partyColors = partyColors,
borderColors = borderColors,
total = total}
end
function p._getListing(args)
local tableMode = yesno(args.table)
local parsed = p._buildTable(args, tableMode)
local groupings = parsed.groupings
local parties = parsed.parties
local partyGrouping = parsed.partyGrouping
local groupCounts = parsed.groupCounts
local seats = parsed.seats
local displayNames = parsed.displayNames
local vacancies = parsed.vacancies
local useShort = not yesno(args.full_names)
local hadOthers = false
local otherName = "other parties"
if #groupings == 0 then
otherName = "all parties"
end
for i, party in ipairs(parties) do
if not partyGrouping[party] then
partyGrouping[party] = otherName
groupCounts[otherName] = (groupCounts[otherName] or 0) + (getSum(seats[party]) or 0)
hadOthers = true
end
end
if hadOthers then
table.insert(groupings, otherName)
end
local output = {}
if args.total and tonumber(args.total) ~= parsed.total then
table.insert(output, mw.text.tag(
'strong',
{ class = 'error' },
string.format('Number of seats (%d) mismatches specified total (%d)\n',
parsed.total, tonumber(args.total))
))
end
if tableMode then
table.insert(output, "{| class=\"wikitable\"\n")
table.insert(output, "! colspan=2| Party\n")
table.insert(output, "! " .. (args["seat_header"] or args["seat-header"] or "Seats") .. "\n")
for j, party in ipairs(parties) do
local color = p._getColor(party)
table.insert(output, "|-\n")
table.insert(output, "|style=\"background-color:" .. color .. "\"|\n")
table.insert(output, "|" .. makeLink(party, useShort, displayNames) .. "||align=center|" .. seats[party] .. "\n")
end
table.insert(output, "|-\n")
table.insert(output, "!colspan=2|Total\n")
table.insert(output, "!align=center|" .. parsed.total .. "\n")
table.insert(output, "|}\n")
else
for i, group in ipairs(groupings) do
table.insert(output, ";" .. capitalizeFirst(group) .. " (" .. groupCounts[group] .. ")\n")
for j, party in ipairs(parties) do
if partyGrouping[party] == group then
local span = "nowrap"
if yesno(args.wrap) then
span = ""
end
table.insert(output, ": " .. "<span class='" .. span .. "'>" .. makeColorBox(p._getColor(party)) .. " " .. makeLink(party, useShort, displayNames) .. " (" .. seats[party] .. ")</span>\n")
end
end
end
if vacancies > 0 then
local vacanciesString = "Vacancies"
if vacancies == 1 then
vacanciesString = "Vacancy"
end
table.insert(output, ";" .. vacanciesString .. " (" .. vacancies .. ")\n")
local party = "Casual vacancy"
table.insert(output, ": " .. "<span class='nowrap'>" .. makeColorBox(p._getColor(party)) .. " " .. makeLink(party, useShort) .. " (" .. vacancies .. ")</span>\n")
end
end
return table.concat(output)
end
function p.getListing(frame)
local args = getArgs(frame, {
wrappers = 'Template:political groupings'
})
return p._getListing(args)
end
return p