Module:Election results
Documentation for this module may be created at Module:Election results/doc
require('Module:No globals') local p = {} function p.main(frame) local args = require('Module:Arguments').getArgs(frame) local index, headings, showtotal = {}, {}, {} local cols, rounds = 0, 1 local winner, winner_votes = {0, 0}, {0, 0} local valid = {0, 0} local invalid = {tonumber(args.invalid) or 0, tonumber(args.invalid2) or 0} local majority = {tonumber(args.majority)} local majority2 = {tonumber(args.majority2)} local majoritypct = {tonumber(args.majoritypct)} local majoritypct2 = {tonumber(args.majoritypct2)} local totalvotes = {tonumber(args.totalvotes), tonumber(args.totalvotes2)} local electorate = {tonumber(args.electorate), tonumber(args.electorate2)} local turnout = {tonumber(args.turnout), tonumber(args.turnout2)} local seats = 0 local seats_2 = 0 local totseats = 0 local row, secondrow local tracking = '' local max_rows = 0 -- helper functions local lang = mw.getContentLanguage() local function fmt(n) return n and tonumber(n) and lang:formatNum(tonumber(n)) or nil end local function pct(n, d) n, d = tonumber(n), tonumber(d) if n and d and d > 0 then return string.format('%.2f', n / d * 100) end return '–' end local function tonumdash(s) if s then s = mw.ustring.gsub(s, '&[MmNn][Dd][Aa][Ss][Hh];', '-') s = mw.ustring.gsub(s, '&[Mm][Ii][Nn][Uu][Ss];', '-') s = mw.ustring.gsub(s, '[—–−]', '-') return tonumber(s) or 0 end end local function unlink(s) if s then s = s:match("^[^%[]-%[%[([^%]]-)|[^%]]-%]%].*$") or s s = s:match("^[^%[]-%[%[([^%]]-)%]%].*$") or s end return s end -- preprocess the input local stop_flag = false local i = 0 local has_votes = args['invalid'] or args['totalvotes'] or args['electorate'] or args['turnout'] local has_seats = args['seats' .. i .. '_2'] local has_sw = args['sw' .. i .. '_2'] local seats_only = has_seats and not has_votes while stop_flag == false do stop_flag = true for kk = 1, 20 do i = i + 1 for k, key in ipairs({'cand', 'vp', 'party', 'ivotes', 'ipct', 'iseats', 'sc', 'st1t', 'st2t', 'st3t', 'st4t', 'st5t', 'sw', 'seats', 'totalvotes', 'totseats', 'acolor'}) do if args[key .. i] then headings[key] = true stop_flag = false max_rows = i > max_rows and i or max_rows end end if args['row' .. i] then stop_flag = false max_rows = i > max_rows and i or max_rows end if args['row' .. i] or args['cand' .. i] or args['party' .. i] then table.insert(index, i) if args['votes' .. i] then has_votes = true if tonumber(args['votes' .. i]) then showtotal.votes = 1 end local votesi = tonumber(args['votes' .. i]) or 0 args['votes' .. i] = votesi if votesi > winner_votes[1] then winner[1] = i winner_votes[1] = votesi end valid[1] = valid[1] + votesi end if args['ivotes' .. i] then has_votes = true end if args['ipct' .. i] then has_votes = true end if args['sw' .. i .. '_2'] then has_sw = true rounds = 2 end if args['votes' .. i .. '_2'] then has_votes = true rounds = 2 if tonumber(args['votes' .. i .. '_2']) then showtotal.votes_2 = 1 end local votesi = tonumber(args['votes' .. i .. '_2']) or 0 args['votes' .. i .. '_2'] = votesi if votesi > winner_votes[2] then winner[2] = i winner_votes[2] = votesi end valid[2] = valid[2] + votesi end if args['seats' .. i] then if tonumber(args['seats' .. i]) then showtotal.seats = 1 end seats = seats + (tonumber(args['seats' .. i]) or 0) end if args['seats' .. i .. '_2'] then has_seats = true rounds = 2 if tonumber(args['seats' .. i ..'_2']) then showtotal.seats_2 = 1 end seats_2 = seats_2 + (tonumber(args['seats' .. i .. '_2']) or 0) end if args['totseats' .. i] then if tonumber(args['totseats' .. i]) then showtotal.totseats = 1 end totseats = totseats + (tonumber(args['totseats' .. i]) or 0) end if has_seats and not has_votes then seats_only = true end end end end local ovalid = {valid[1], valid[2]} seats = ((args['total_seats'] or '') == 'TOTAL' and seats) or args['total_seats'] or seats totseats = ((args['total_totseats'] or '') == 'TOTAL' and totseats) or args['total_totseats'] or totseats if seats or totseats or args['total_sc'] or args['total_st1t'] or args['total_st2t'] or args['total_st3t'] or args['total_st4t'] or args['total_st5t'] or args['valid'] or ((rounds > 1) and args['valid2']) then max_rows = max_rows + 1 local i = max_rows table.insert(index, i) args['votes' .. i] = showtotal.votes and valid[1] or nil args['votes' .. i .. '_2'] = showtotal.votes_2 and valid[2] or nil args['colour' .. i] = 'inherit' args['color' .. i] = 'inherit' args['row' .. i] = 'Total' args['sw' .. i] = '–' args['sw' .. i .. '_2'] = '–' args['seats' .. i] = showtotal.seats and seats or nil args['seats' .. i .. '_2'] = showtotal.seats_2 and seats_2 or nil args['sc' .. i] = args['total_sc'] args['st1t' .. i] = args['total_st1t'] args['st2t' .. i] = args['total_st2t'] args['st3t' .. i] = args['total_st3t'] args['st4t' .. i] = args['total_st4t'] args['st5t' .. i] = args['total_st5t'] args['totseats' .. i] = showtotal.totseats and totseats or nil args['font-weight' .. i] = 'bold' args['class' .. i] = 'sortbottom' ovalid[1] = tonumber(args['valid']) or valid[1] ovalid[2] = tonumber(args['valid2']) or valid[2] end -- build the table local root = mw.html.create('table') root :addClass('wikitable sortable') :tag('caption') :wikitext(args.caption) :done() local topcell = nil if args['image'] then topcell = root :tag('tr') :tag('td') :wikitext(args['image']) :css('text-align', 'center') end local rowspan = (rounds > 1) and 2 or headings['st1t'] and 2 or nil row = root:tag('tr') if args['dsv'] then row :tag('th') :wikitext('Party') :attr('scope', 'col') :attr('colspan', 2) :attr('rowspan', rowspan) :done() cols = cols + 2 row :tag('th') :wikitext(args.candtitle or 'Candidate') :attr('scope', 'col') :attr('rowspan', rowspan) :done() cols = cols + 1 elseif headings['cand'] then row :tag('th') :wikitext('Candidate') :attr('scope', 'col') :attr('colspan', 2) :attr('rowspan', rowspan) :done() cols = cols + 2 if headings['vp'] then row :tag('th') :wikitext('Running mate') :attr('scope', 'col') :attr('rowspan', rowspan) :done() cols = cols + 1 end if headings['party'] then row :tag('th') :wikitext('Party') :attr('scope', 'col') :attr('rowspan', rowspan) :done() cols = cols + 1 end else row :tag('th') :wikitext(headings['party'] and 'Party' or '') :attr('scope', 'col') :attr('colspan', 2) :attr('rowspan', rowspan) :done() cols = cols + 2 end if rounds > 1 then if has_seats and headings['sw'] then row :tag('th') :wikitext(args.firstround or 'First round') :attr('scope', 'col') :attr('colspan', 4) :done() :tag('th') :wikitext(args.secondround or 'Second round') :attr('scope', 'col') :attr('colspan', 4) :done() elseif has_seats then row :tag('th') :wikitext(args.firstround or 'First round') :attr('scope', 'col') :attr('colspan', 3) :done() :tag('th') :wikitext(args.secondround or 'Second round') :attr('scope', 'col') :attr('colspan', 3) :done() elseif has_votes then row :tag('th') :wikitext(args.firstround or 'First round') :attr('scope', 'col') :attr('colspan', 2) :done() :tag('th') :wikitext(args.secondround or 'Second round') :attr('scope', 'col') :attr('colspan', 2) :done() end secondrow = root:tag('tr') else secondrow = row end rowspan = (rounds > 1) and 1 or (rounds < 2 and headings['st1t']) and 2 or nil if has_seats and headings['sw'] then for k=1, rounds do secondrow :tag('th') :wikitext('Votes') :attr('scope', 'col') :attr('rowspan', rowspan) :done() :tag('th') :wikitext('%') :attr('scope', 'col') :attr('rowspan', rowspan) :done() :tag('th') :wikitext('+/–') :attr('scope', 'col') :attr('rowspan', rowspan) :done() :tag('th') :wikitext('Seats') :attr('scope', 'col') :attr('rowspan', rowspan) :done() cols = cols + 4 end end if has_seats and not headings['sw'] then for k=1, rounds do secondrow :tag('th') :wikitext('Votes') :attr('scope', 'col') :attr('rowspan', rowspan) :done() :tag('th') :wikitext('%') :attr('scope', 'col') :attr('rowspan', rowspan) :done() :tag('th') :wikitext('Seats') :attr('scope', 'col') :attr('rowspan', rowspan) :done() cols = cols + 3 end end if has_votes and not has_seats then for k=1, rounds do secondrow :tag('th') :wikitext('Votes') :attr('scope', 'col') :attr('rowspan', rowspan) :done() :tag('th') :wikitext('%') :attr('scope', 'col') :attr('rowspan', rowspan) :done() cols = cols + 2 end end if headings['sw'] and not has_seats then row :tag('th') :wikitext('+/–') :attr('scope', 'col') :attr('rowspan', rowspan) :done() cols = cols + 1 end rowspan = (rounds > 1) and 2 or nil if headings['seats'] and not has_seats then row :tag('th') :wikitext('Seats') :attr('scope', 'col') :attr('rowspan', rowspan) :done() cols = cols + 1 end if headings['totseats'] then row :tag('th') :wikitext(headings['totseats'] and 'Total<br>seats' or 'Totseats±') :attr('scope', 'col') :attr('rowspan', rowspan) :done() cols = cols + 1 end if headings['sc'] then row :tag('th') :wikitext(headings['seats'] and '+/–' or 'Seats±') :attr('scope', 'col') :attr('rowspan', rowspan) :done() cols = cols + 1 end if headings['st1t'] then row :tag('th') :wikitext('Seats') :attr('colspan', 5) :attr('scope', 'col') :done() if rounds < 2 then secondrow = root:tag('tr') end secondrow :tag('th') :wikitext(args.seattype1) :attr('scope', 'col') :done() cols = cols + 1 if headings['st2t'] then secondrow :tag('th') :wikitext(args.seattype2) :attr('scope', 'col') :done() cols = cols + 1 end if headings['st3t'] then secondrow :tag('th') :wikitext(args.seattype3) :attr('scope', 'col') :done() cols = cols + 1 end if headings['st4t'] then secondrow :tag('th') :wikitext(args.seattype4) :attr('scope', 'col') :done() cols = cols + 1 end if headings['st5t'] then secondrow :tag('th') :wikitext(args.seattype5) :attr('scope', 'col') :done() cols = cols + 1 end end if topcell then topcell:attr('colspan', cols) end local cs = cols - 2*rounds - (headings['sw'] and 1 or 0) - (headings['totseats'] and 1 or 0) - (headings['seats'] and 1 or 0) - (headings['sc'] and 1 or 0) - (headings['st1t'] and 1 or 0) - (headings['st2t'] and 1 or 0) - (headings['st3t'] and 1 or 0) - (headings['st4t'] and 1 or 0) - (headings['st5t'] and 1 or 0) - (has_seats and 1 or 0) - (has_sw and 1 or 0) + (has_votes and 0 or 2) - (seats_only and 2 or 0) local rsuff = (rounds > 1) and {'', '_2'} or {''} for i, v in ipairs(index) do row = root:tag('tr') :addClass(args['class' .. v]) :css('font-weight', args['font-weight' .. v]) -- determine the color local color = args['colour' .. v] or args['color' .. v] or nil if color == nil then local party = unlink(args['party' .. v]) or '' if party ~= '' and mw.title.new('Template:' .. party .. '/meta/color').exists then color = frame:expandTemplate{title = party .. '/meta/color'} end end if args['row' .. v] then row :css('background-color', args['acolor' .. v]) :tag('td') :wikitext(args['row' .. v]) :attr('colspan', cs) else -- create the empty color cell row :tag('td') :css('background-color', color) -- add the rest of the row if args['dsv'] then row :tag('td') :wikitext(args['party' .. v]) row :tag('td') :wikitext(args['cand' .. v]) end if headings['cand'] and not args['dsv'] then row :tag('td') :wikitext(args['cand' .. v]) if headings['vp'] then row :tag('td') :wikitext(args['vp' .. v]) end end if headings['party'] and not args['dsv'] then row :tag('td') :wikitext(args['party' .. v]) end end if args['votes' .. v] then row:tag('td') :css('text-align', 'right') :wikitext(fmt(args['votes' .. v])) row:tag('td') :css('text-align', 'right') :wikitext(pct(args['votes' .. v], valid[1])) elseif args['ivotes' .. v] or args ['ipct' .. v] then row:tag('td') :css('text-align', 'right') :css('font-style', 'italic') :wikitext(fmt(args['ivotes' .. v])) row:tag('td') :css('text-align', 'right') :css('font-style', 'italic') :wikitext(args['ipct' .. v]) elseif has_votes and not headings['sw'] and not has_seats or args['invalid'] and not headings['sw'] and not has_seats or args['totalvotes'] and not headings['sw'] and not has_seats or args['electorate'] and not headings['sw'] and not has_seats or args['turnout'] and not headings['sw'] and not has_seats or has_seats and args['seats' .. v] and not args['votes' .. v] and not args['ivotes' .. v] then row:tag('td') :attr('colspan', 2) elseif has_seats and not args['seats' .. v] and not headings['sw'] or has_votes and headings['sw'] and not has_seats then row:tag('td') :attr('colspan', 3) elseif has_seats and headings['sw'] then row:tag('td') :attr('colspan', 4) end if headings['sw'] and args['votes' .. v] or headings['sw'] and args['ivotes' .. v] then row :tag('td') :css('text-align', 'right') :wikitext(args['sw' .. v]) end if headings['seats'] and not args['dsv'] and not has_seats and rounds < 2 or has_seats and args['seats' .. v] or has_seats and args['votes' .. v] then if args['iseats' .. v] then row :tag('td') :css('font-style', 'italic') :css('text-align', 'right') :wikitext(args['iseats' .. v] or '–') else row :tag('td') :css('text-align', 'right') :wikitext(fmt(args['seats' .. v]) or '–') end end if args['votes' .. v .. '_2'] then row:tag('td') :css('text-align', 'right') :wikitext(fmt(args['votes' .. v .. '_2'])) row:tag('td') :css('text-align', 'right') :wikitext(pct(args['votes' .. v .. '_2'], valid[2])) elseif args['ivotes' .. v .. '_2'] or args ['ipct' .. v.. '_2'] then row:tag('td') :css('text-align', 'right') :css('font-style', 'italic') :wikitext(fmt(args['ivotes' .. v .. '_2'])) row:tag('td') :css('text-align', 'right') :css('font-style', 'italic') :wikitext(args['ipct' .. v .. '_2']) elseif args['invalid2'] and args['seats' .. v .. '_2'] or args['totalvotes2'] and args['seats' .. v .. '_2'] or args['electorate2'] and args['seats' .. v .. '_2'] or args['turnout2'] and args['seats' .. v .. '_2'] or has_votes and rounds > 1 and args['seats' .. v .. '_2'] or has_votes and rounds > 1 and not has_seats or has_seats and not args['votes' .. v .. '_2'] and args['seats' .. v .. '_2'] then row:tag('td') :attr('colspan', 2) elseif has_seats and not args['seats' .. v .. '_2'] and not headings['sw'] then row:tag('td') :attr('colspan', 3) elseif has_seats and headings['sw'] then row:tag('td') :attr('colspan', 4) end if headings['seats'] and args['dsv'] or headings['seats'] and rounds > 1 and not has_seats then row :tag('td') :css('text-align', 'right') :wikitext(fmt(args['seats' .. v]) or '–') end if has_sw and args['votes' .. v .. '_2'] then row :tag('td') :css('text-align', 'right') :wikitext(args['sw' .. v .. '_2']) end if args['seats' .. v .. '_2'] or has_seats and args['votes' .. v .. '_2'] then row :tag('td') :css('text-align', 'right') :wikitext(fmt(args['seats' .. v .. '_2']) or '–') end if headings['totseats'] and (args['totseats' .. v]) then row :tag('td') :css('text-align', 'right') :wikitext(fmt(args['totseats' .. v])) elseif headings['totseats'] then row :tag('td') :css('text-align', 'right') :css('font-style', 'italic') :wikitext(args['itotseats' .. v] or '–') end if headings['sc'] then row :tag('td') :css('text-align', 'right') :wikitext(args['sc' .. v] or '–') end if headings['st1t'] then row :tag('td') :css('text-align', 'right') :wikitext(args['st1t' .. v]) end if headings['st2t'] then row :tag('td') :css('text-align', 'right') :wikitext(args['st2t' .. v]) end if headings['st3t'] then row :tag('td') :css('text-align', 'right') :wikitext(args['st3t' .. v]) end if headings['st4t'] then row :tag('td') :css('text-align', 'right') :wikitext(args['st4t' .. v]) end if headings['st5t'] then row :tag('td') :css('text-align', 'right') :wikitext(args['st5t' .. v]) end end -- separating line row = root :tag('tr') :addClass('sortbottom') row :tag('td') :css('background', '#eaecf0') :attr('colspan', cols) -- valid votes if args['invalid'] or args['invalid2'] then row = root :tag('tr') :addClass('sortbottom') :css('text-align', 'right') row :tag('th') :wikitext('Valid votes') :attr('scope', 'row') :attr('colspan', cs) :css('text-align', 'left') :css('font-weight', 'normal') :css('background', 'inherit') if args['invalid'] then row :tag('td') :wikitext(fmt(ovalid[1])) :tag('td') :wikitext(pct(ovalid[1], ovalid[1] + invalid[1])) elseif not args['invalid'] then row :tag('td') :wikitext() :tag('td') :wikitext() end if has_seats and not headings['sw'] then row :tag('td') :wikitext() end if has_seats and headings['sw'] and args['validsw'] then row :tag('td') :wikitext(args['validsw']) :tag('td') :wikitext() end if has_seats and headings['sw'] and not args['validsw'] then row :tag('td') :attr('colspan', 2) :wikitext() end if rounds > 1 and args['invalid2'] then row :tag('td') :wikitext(fmt(ovalid[2])) :tag('td') :wikitext(pct(ovalid[2], ovalid[2] + invalid[2])) elseif rounds > 1 and not args['invalid2'] then row :tag('td') :wikitext() :tag('td') :wikitext() end if has_seats and not headings['sw'] then row :tag('td') :wikitext() end if has_seats and headings['sw'] and args['validsw2'] then row :tag('td') :wikitext(args['validsw2']) :tag('td') :wikitext() end if has_seats and headings['sw'] and not args['validsw2'] then row :tag('td') :attr('colspan', 2) :wikitext() end if args['invalidsw'] and not has_sw then row:tag('td') :wikitext(args['validsw']) local cspan = (headings['seats'] and 1 or 0) + (headings['sc'] and 1 or 0) + (headings['st1t'] and 1 or 0) + (headings['st2t'] and 1 or 0) + (headings['st3t'] and 1 or 0) + (headings['st4t'] and 1 or 0) + (headings['st5t'] and 1 or 0) if headings['seats'] or headings['sc'] then local cspan = (headings['seats'] and 1 or 0) + (headings['sc'] and 1 or 0) + (headings['st1t'] and 1 or 0) + (headings['st2t'] and 1 or 0) + (headings['st3t'] and 1 or 0) + (headings['st4t'] and 1 or 0) + (headings['st5t'] and 1 or 0) row :tag('td') :attr('colspan', cspan > 1 and cspan or nil) end elseif headings['sw'] or headings['seats'] or headings['sc'] or headings['st1t'] or headings['st2t'] or headings['st3t'] or headings['st4t'] or headings['ss51t'] then local cspan = (headings['sw'] and 1 or 0) + (headings['seats'] and 1 or 0) + (headings['sc'] and 1 or 0) + (headings['st1t'] and 1 or 0) + (headings['st2t'] and 1 or 0) + (headings['st3t'] and 1 or 0) + (headings['st4t'] and 1 or 0) + (headings['st5t'] and 1 or 0) row :tag('td') :attr('colspan', cspan > 1 and cspan or nil) end -- invalid votes row = root:tag('tr') :addClass('sortbottom') :css('text-align', 'right') if args['blank'] then row :tag('th') :wikitext('Invalid votes') :attr('scope', 'row') :attr('colspan', cs) :css('text-align', 'left') :css('font-weight', 'normal') :css('background', 'inherit') else row :tag('th') :wikitext('Invalid/blank votes') :attr('scope', 'row') :attr('colspan', cs) :css('text-align', 'left') :css('font-weight', 'normal') :css('background', 'inherit') end if args['invalid'] then row :tag('td') :wikitext(fmt(invalid[1])) :tag('td') :wikitext(pct(invalid[1], ovalid[1] + invalid[1])) elseif not args['invalid'] then row :tag('td') :wikitext() :tag('td') :wikitext() end if has_seats and not headings['sw'] then row :tag('td') :wikitext() end if has_seats and headings['sw'] and args['invalidsw'] then row :tag('td') :wikitext(args['invalidsw']) :tag('td') :wikitext() end if has_seats and headings['sw'] and not args['invalidsw'] then row :tag('td') :attr('colspan', 2) :wikitext() end if rounds > 1 and args['invalid2'] then row :tag('td') :wikitext(fmt(invalid[2])) :tag('td') :wikitext(pct(invalid[2], ovalid[2] + invalid[2])) elseif rounds > 1 and not args['invalid2'] then row :tag('td') :wikitext() :tag('td') :wikitext() end if has_seats and not headings['sw'] then row :tag('td') :wikitext() end if has_seats and headings['sw'] and args['invalidsw2'] then row :tag('td') :wikitext(args['invalidsw2']) :tag('td') :wikitext() end if has_seats and headings['sw'] and not args['invalidsw2'] then row :tag('td') :attr('colspan', 2) :wikitext() end if args['invalidsw'] and not has_sw then row:tag('td') :wikitext(args['invalidsw']) if headings['seats'] or headings['sc'] or headings['st1t'] or headings['st2t'] or headings['st3t'] or headings['st4t'] or headings['ss51t'] then local cspan = (headings['seats'] and 1 or 0) + (headings['sc'] and 1 or 0) row :tag('td') :attr('colspan', cspan > 1 and cspan or nil) end elseif headings['sw'] or headings['seats'] or headings['sc'] or headings['st1t'] or headings['st2t'] or headings['st3t'] or headings['st4t'] or headings['ss51t'] then local cspan = (headings['sw'] and 1 or 0) + (headings['seats'] and 1 or 0) + (headings['sc'] and 1 or 0) + (headings['st1t'] and 1 or 0) + (headings['st2t'] and 1 or 0) + (headings['st3t'] and 1 or 0) + (headings['st4t'] and 1 or 0) + (headings['st5t'] and 1 or 0) row :tag('td') :attr('colspan', cspan > 1 and cspan or nil) end end -- total if args['invalid'] or args['totalvotes'] or args['invalid2'] or args['totalvotes2'] then row = root:tag('tr') :addClass('sortbottom') :css('font-weight', 'bold') :css('text-align', 'right') row :tag('th') :wikitext('Total votes') :attr('scope', 'row') :attr('colspan', cs) :css('text-align', 'left') :css('background', 'inherit') if not args['totalvotes'] and args['invalid'] then row :tag('td') :wikitext(fmt(ovalid[1] + invalid[1])) :tag('td') :wikitext(pct(1, 1)) elseif args['totalvotes'] then row :tag('td') :wikitext(fmt(args.totalvotes)) :tag('td') :wikitext('–') elseif not args['invalid'] and not args['totalvotes'] then row :tag('td') :wikitext() :tag('td') :wikitext() end if has_seats and not headings['sw'] then row :tag('td') :wikitext() end if has_seats and headings['sw'] and args['invalidsw'] then row :tag('td') :wikitext('–') :tag('td') :wikitext() end if has_seats and headings['sw'] and not args['invalidsw'] then row :tag('td') :attr('colspan', 2) :wikitext() end if rounds > 1 and args['invalid2'] and not args['totalvotes2'] then row :tag('td') :wikitext(fmt(ovalid[2] + invalid[2])) :tag('td') :wikitext(pct(1, 1)) elseif rounds > 1 and args['totalvotes2'] then row :tag('td') :wikitext(fmt(args.totalvotes2)) :tag('td') :wikitext('–') elseif rounds > 1 and not args['invalid2'] or rounds > 1 and not args['totalvotes2'] then row :tag('td') :wikitext() :tag('td') :wikitext() end if has_seats and not headings['sw'] then row :tag('td') :wikitext() end if has_seats and headings['sw'] and args['invalidsw2'] then row :tag('td') :wikitext('–') :tag('td') :wikitext() end if has_seats and headings['sw'] and not args['invalidsw2'] then row :tag('td') :attr('colspan', 2) :wikitext() end if args['invalidsw'] and not has_sw then row:tag('td') :wikitext('–') if headings['seats'] or headings['sc'] or headings['st1t'] or headings['st2t'] or headings['st3t'] or headings['st4t'] or headings['st5t'] then local cspan = (headings['seats'] and 1 or 0) + (headings['sc'] and 1 or 0) + (headings['st1t'] and 1 or 0) + (headings['st2t'] and 1 or 0) + (headings['st3t'] and 1 or 0) + (headings['st4t'] and 1 or 0) + (headings['st5t'] and 1 or 0) row :tag('td') :attr('colspan', cspan > 1 and cspan or nil) end elseif headings['sw'] or headings['seats'] or headings['sc'] or headings['st1t'] or headings['st2t'] or headings['st3t'] or headings['st4t'] or headings['st5t'] then local cspan = (headings['sw'] and 1 or 0) + (headings['seats'] and 1 or 0) + (headings['sc'] and 1 or 0) + (headings['st1t'] and 1 or 0) + (headings['st2t'] and 1 or 0) + (headings['st3t'] and 1 or 0) + (headings['st4t'] and 1 or 0) + (headings['st5t'] and 1 or 0) row :tag('td') :attr('colspan', cspan > 1 and cspan or nil) end end -- registered if args['electorate'] or args['electorate2'] or args['turnout'] or args['turnout2'] then row = root:tag('tr') :addClass('sortbottom') :css('text-align', 'right') row :tag('th') :wikitext('Registered voters/turnout') :attr('scope', 'row') :attr('colspan', cs) :css('text-align', 'left') :css('font-weight', 'normal') :css('background', 'inherit') row :tag('td') :wikitext(fmt(electorate[1])) if args['invalid'] and args['electorate'] then row :tag('td') :wikitext(pct(ovalid[1] + invalid[1], electorate[1])) elseif args['totalvotes'] and args['electorate'] then row :tag('td') :wikitext(pct(totalvotes[1], electorate[1])) elseif args['electorate'] then row :tag('td') :wikitext(args.turnout or '–') else row :tag('td') :wikitext(args.turnout) end if has_seats and not headings['sw'] then row :tag('td') :wikitext() end if has_seats and headings['sw'] and args['turnoutsw'] then row :tag('td') :wikitext(args['turnoutsw']) :tag('td') :wikitext() end if has_seats and headings['sw'] and not args['turnoutsw'] then row :tag('td') :attr('colspan', 2) :wikitext() end if rounds > 1 then row :tag('td') :wikitext(fmt(electorate[2])) if args['invalid2'] and args['electorate2'] then row :tag('td') :wikitext(pct(ovalid[2] + invalid[2], electorate[2])) elseif args['totalvotes2'] and args['electorate2'] then row :tag('td') :wikitext(pct(totalvotes[2], electorate[2])) elseif args['electorate2'] then row :tag('td') :wikitext(args.turnout2 or '–') else row :tag('td') :wikitext(args.turnout2) end if has_seats and not headings['sw'] then row :tag('td') :wikitext() end if has_seats and headings['sw'] and args['turnoutsw2'] then row :tag('td') :wikitext(args['turnoutsw2']) :tag('td') :wikitext() end if has_seats and headings['sw'] and not args['turnoutsw2'] then row :tag('td') :attr('colspan', 2) :wikitext() end end if args['turnoutsw'] and not has_sw then row:tag('td') :wikitext(args['turnoutsw']) if headings['seats'] or headings['sc'] or headings['st1t'] or headings['st2t'] or headings['st3t'] or headings['st4t'] or headings['st5t'] then local cspan = (headings['seats'] and 1 or 0) + (headings['sc'] and 1 or 0) + (headings['st1t'] and 1 or 0) + (headings['st2t'] and 1 or 0) + (headings['st3t'] and 1 or 0) + (headings['st4t'] and 1 or 0) + (headings['st5t'] and 1 or 0) row :tag('td') :attr('colspan', cspan > 1 and cspan or nil) end elseif headings['sw'] or headings['seats'] or headings['sc'] or headings['st1t'] or headings['st2t'] or headings['st3t'] or headings['st4t'] or headings['st5t'] then local cspan = (headings['sw'] and 1 or 0) + (headings['seats'] and 1 or 0) + (headings['sc'] and 1 or 0) + (headings['st1t'] and 1 or 0) + (headings['st2t'] and 1 or 0) + (headings['st3t'] and 1 or 0) + (headings['st4t'] and 1 or 0) + (headings['st5t'] and 1 or 0) row :tag('td') :attr('colspan', cspan > 1 and cspan or nil) end end if args['majority'] then if args['invalid'] or args['electorate'] then row = root :tag('tr') :addClass('sortbottom') row :tag('td') :css('background', '#eaecf0') :attr('colspan', cols) end row = root :tag('tr') :addClass('sortbottom') :css('text-align', 'right') row :tag('th') :wikitext('Majority') :attr('scope', 'row') :attr('colspan', cs) :css('text-align', 'left') :css('font-weight', 'normal') :css('background', 'inherit') for k=1, rounds do row :tag('td') :wikitext(fmt(majority[k])) :tag('td') :wikitext(fmt(majoritypct[k])) end if args['majoritysw'] then row :tag('td') :wikitext(args['majoritysw']) end end if args['result'] then row = root:tag('tr') :addClass('sortbottom') -- determine the color local color = args['resultcolour'] or nil if color == nil then local result = unlink(args['result']) or '' if result ~= '' and mw.title.new('Template:' .. result .. '/meta/color').exists then color = frame:expandTemplate{title = result .. '/meta/color'} end end if args['resultsw'] then row :tag('td') :css('background-color', color) row :tag('td') :attr('colspan', 2) :wikitext(args['result']) row :tag('td') :attr('colspan', 2) :css('text-align', 'right') :wikitext('Swing') row :tag('td') :css('text-align', 'right') :wikitext(args['resultsw']) else row :tag('td') :css('background-color', color) row :tag('td') :attr('colspan', cols - 1) :wikitext(args['result']) end end if args['majority2'] then row = root :tag('tr') :addClass('sortbottom') :css('text-align', 'right') row :tag('th') :wikitext('Majority') :attr('scope', 'row') :attr('colspan', cs) :css('text-align', 'left') :css('font-weight', 'normal') :css('background', 'inherit') for k=1, rounds do row :tag('td') :wikitext(fmt(majority2[k])) :tag('td') :wikitext(fmt(majoritypct2[k])) end if args['majoritysw2'] then row :tag('td') :wikitext(args['majoritysw2']) end end if args['result2'] then row = root:tag('tr') :addClass('sortbottom') -- determine the color local color = args['resultcolour'] or nil if color == nil then local result = unlink(args['result2']) or '' if result ~= '' and mw.title.new('Template:' .. result .. '/meta/color').exists then color = frame:expandTemplate{title = result .. '/meta/color'} end end if args['resultsw2'] then row :tag('td') :css('background-color', color) row :tag('td') :attr('colspan', 2) :wikitext(args['result2']) row :tag('td') :attr('colspan', 2) :css('text-align', 'right') :wikitext('Swing') row :tag('td') :css('text-align', 'right') :wikitext(args['resultsw2']) else row :tag('td') :css('background-color', color) row :tag('td') :attr('colspan', cols - 1) :wikitext(args['result2']) end end if args['source'] then row = root:tag('tr') :addClass('sortbottom') :css('text-align', 'right') row:tag('td') :wikitext('Source: ', args.source) :attr('colspan', cols) :css('text-align', 'left') end return tostring(root) .. tracking end return p