Edge Rewrite
// HTMLRewriter · presentation

This page was redesigned at the edge.

Cloudflare fetched the original article and streamed it through HTMLRewriter to apply an entirely new visual system without rebuilding the source page.

// request.cf · coarse context

A page that knows where it met you.

Only coarse request metadata is shown. This demo does not display or persist visitor IP addresses.

Country
US
Cloudflare location
CMH
Connection
HTTP/2
Language
Not provided

Ray ID: a226e60f9cf88a31

Jump to content

Module:Political groupings

Permanently protected module
From Wikipedia, the free encyclopedia

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 .. [[">&nbsp;&nbsp;&nbsp;</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) == "&#35;" then
		return "#" .. string.sub(party, 6)
	end
	if string.sub(party, 1, 6) == "&#x23;" 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