Jump to content

Module:Election box US auto

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Legoktm (talk | contribs) at 02:07, 12 November 2018 (Legoktm moved page Module:Sandbox/Legoktm/elections to Module:Election box US auto without leaving a redirect: un-sandboxing). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

local p = {}
local mRedirect = require('Module:Redirect')
local mError = require('Module:Error')

function percent( part, total )
	if total >= 1000000 then
		-- if > 1 million votes, then round to 2 decimals
		round_to = 2
	else
		round_to = 1
	end
	local ret = mw.ext.ParserFunctions.expr( "" .. 100 * part / total .. " round " .. round_to )
	if not string.find( ret, ".", 1, true ) then
		-- add the decimals that expr doesn't
		ret = ret .. "." .. string.rep("0", round_to)
	end
	return ret
end

function p.make( frame )
	return frame:preprocess( make( frame ) )
end

function make( frame )
	local state = frame.args[1]
	if not state then
		return mError.error({message="State is missing"})
	end
	local year = frame.args[2]
	if not year then
		return mError.error({message="Year is missing"})
	end
	local contest = frame.args[3]
	if not contest then
		return mError.error({message="Contest is missing"})
	end
	local type = "General"
	if frame.args.type then
		if frame.args.type == "Primary" then
			type = "Primary"
		else
			return mError.error({message="Invalid value for |type="})
		end
	end
	local tab_name = state .. " Elections/" .. year .. "/" .. type .. "/Candidates.tab"
	local tabular = mw.ext.data.get(tab_name)
	if not tabular then
		return mError.error({message="Unable to find tabular data: " .. tab_name})
	end
	local data = tabular.data
	local candidates = {}
	for k,v in pairs(data) do
		if v[1] == contest then
			table.insert(candidates, v)
		end
	end
	local total_votes = 0
	local winner = {}
	winner[5] = 0
	for k,v in pairs(candidates) do
		total_votes = total_votes + v[5]
		if v[5] > winner[5] then
			winner = v
		end
	end
	if mw.ustring.find(contest, "United States Representative", 1, true) then
		title = "[[United States House of Representatives elections, " .. year .. "]]"
	elseif contest == "President" then
		title = "U.S. presidential election in " .. state .. ", " .. year
	else
		title = "...????"
	end
	local ret = "{{Election box begin no change| title=" .. title .. '<ref name="' .. tab_name .. '">' .. tabular.sources .. "</ref>}}"
	function sort_candidates(a,b)
		return a[5] > b[5]
	end
	table.sort(candidates, sort_candidates)
	local linked_write_in = false
	for k,v in pairs(candidates) do
		local temp = "{{"
		if v[2] == winner[2] then
			temp = temp .. "Election box winning candidate"
		else
			temp = temp .. "Election box candidate"
		end
		local n_party = normalize_parties( v[3] )
		if n_party then
			temp = temp .. " with party link no change|party=" .. n_party
		else
			temp = temp .. " no party link no change"
		end
		link = frame.args[v[2] .. " link"]
		if not link then
			-- bypass redirects, which is mostly important for display names
			link = mRedirect.luaMain(v[2], false)
		end
		-- Strip disambiguators since we can't use the pipe trick
		display_name, ignore = mw.ustring.gsub(link, "%b()", "")
		temp = temp .. "|candidate=[[" .. link .. "|" .. display_name .. "]]"
		if v[4] then
			-- incumbent
			temp  = temp .. " ([[incumbent]])"
		end
		if v[6] then
			-- write in
			if linked_write_in then
				temp = temp .. " (write-in)"
			else
				temp = temp .. " ([[Write-in candidate|write-in]])"
				linked_write_in = true -- only link it once
			end
		end
		temp = temp .. "|votes={{formatnum:" .. v[5] .. "}}"
		temp = temp .. "|percentage=" .. percent(v[5], total_votes) .. "%"
		temp = temp .. "}}"
		ret = ret .. temp
	end
	ret = ret .. "{{Election box total no change|votes= {{formatnum:" .. total_votes .. "}}|percentage = " .. percent(total_votes, total_votes) .. "%}}"
	local hold = frame.args.hold
	local gain = false
	if hold == "held" or winner[4] then
		ret = ret .. "{{Election box hold with party link without swing|winner=" .. normalize_parties(winner[3]) .. "}}"
	elseif hold == "flip" then
		-- shorthand for D->R/R->D
		win_party = winner[3]
		if win_party == "Democratic" then
			lose_party = normalize_parties("Republican")
		else
			lose_party = normalize_parties("Democratic")
		end
		win_party = normalize_parties(win_party)
		gain = true
	elseif frame.args.gain then
		win_party = normalize_parties(frame.args.gain)
		lose_party = normalize_parties(frame.args.loser)
		gain = true
	end
	if gain then
		ret = ret .. "{{Election box gain with party link without swing|winner=" .. win_party .. "|loser=" .. lose_party .. "}}"
	end

	ret = ret .. "{{Election box end}}"
	return ret
end

function normalize_parties( party )
	-- Drop all parties after the first one?
	party = mw.text.split( party, ",", true )[1]
	local parties = {
		Democratic = "Democratic Party (United States)",
		Republican = "Republican Party (United States)",
		Blank = "Independent (politician)",
		Independent = "Independent (politician)",
		Libertarian = "Libertarian Party (United States)",
		Green = "Green Party (United States)",
	}
	parties["Peace and Freedom"] = "Peace and Freedom Party"
	parties["No Party Preference"] = "Independent (politician)"
	
	for k, v in pairs(parties) do
		if k == party then
			return v
		end
	end
	-- not found, return false
	return false
end

return p