Module:OpinionPollDenmark

-- Module:OpinionPoll
local p = {}
local partyModule = require("Module:Political party")

-- Hent farve fra Template:Party shading/<Partinavn>
local function getPartyColor(partyName)
    local title = mw.title.new("Template:Party shading/" .. partyName)
    if title and title.exists then
        local content = title:getContent()
        if content then
            local color = content:match("#[%x]+") -- find første hexkode
            return color or "#FFFFFF"
        end
    end
    return "#FFFFFF" -- fallback hvis intet findes
end

-- Hjælpefunktion: find partinavn og evt. alias fra [[Link|Alias]] eller [url tekst]
local function parseLink(text)
    if not text then return text end
    text = mw.text.trim(text)

    -- Eksternt link som [https://dr.dk Epinion] eller [Epinion dr.dk]
    local label, url = text:match("^%[([^%s%]]+)%s+([^%]]+)%]$")
    if label and url then
        -- Hvis label ligner et domæne og url ikke gør, bytter vi
        if label:find("%.") and not url:find("%.") then
            label, url = url, label
        end
        -- Hvis der ikke er http, tilføj det
        if not url:match("^https?://") then
            url = "https://" .. url
        end
        return string.format("[%s %s]", url, label)
    end

    -- Intern wikilink [[Artikel|Alias]]
    local link, alias = text:match("^%[%[([^|%]]+)|([^%]]+)%]%]$")
    if link then
        return string.format("[[%s|%s]]", link, alias)
    end

    -- Simpel [[Artikel]]
    local linkOnly = text:match("^%[%[([^%]]+)%]%]$")
    if linkOnly then
        return string.format("[[%s]]", linkOnly)
    end

    -- Ellers, returnér teksten som den er
    return text
end

-- Hjælpefunktion: find største og næststørste tal
local function topTwo(values)
    local nums = {}
    for _, v in ipairs(values) do
        if v.num then table.insert(nums, v.num) end
    end
    table.sort(nums, function(a, b) return a > b end)
    return nums[1], nums[2]
end

-- Hjælpefunktion: find partinavn og evt. alias fra [[Link|Alias]]
local function parsePartyInput(text)
    if not text then return nil, nil end
    text = mw.text.trim(text)

    -- [[Artikel|Alias]]
    local link, alias = text:match("^%[%[([^|%]]+)|([^%]]+)%]%]$")
    if link then
        return link, alias
    end

    -- [[Artikel]]
    local linkOnly = text:match("^%[%[([^%]]+)%]%]$")
    if linkOnly then
        return linkOnly, nil
    end

    -- Alm. tekst
    return text, nil
end

-- Generér én tabelrække
local function makePollRow(args, parties, prefix, includeOthers, isBasePoll)
    local wikitext = ""

    -- Separator kun for basepoll
    if isBasePoll then
        wikitext = wikitext .. '\n|-\n| colspan="22" style="background:#636161" |\n'
    end

    -- Grunddata
    local firm = args[prefix .. "_election"] or args[prefix .. "_firm"] or ""
    local date = args[prefix .. "_date"] or args[prefix .. "_fw"] or ""
    local sample = args[prefix .. "_sample"] or ""

    -- Behandl eventuelle links i firm
    firm = parseLink(firm)

    -- Valgresultat?
    local isElection = args[prefix .. "_electionpoll"] == "y"

    if isBasePoll or isElection then
        -- Grå baggrund
        wikitext = wikitext ..
            string.format('|- style="background:#E9E9E9;"\n| %s || %s || %s', firm, date, sample)
    else
        -- Normal baggrund
        wikitext = wikitext ..
            string.format("|-\n| %s || %s || %s", firm, date, sample)
    end

    -- Saml værdier
    local values = {}
    for _, pinfo in ipairs(parties) do
        local raw = args[prefix .. "_" .. pinfo.idx]
        local num = nil
        if raw and raw ~= "" then
            local percent, mandate = raw:match("^(%d+%.?%d*)%s*%((%d+)%)$")
            if percent and mandate then
                raw = percent .. '<br/><span style="font-size:85%;">(' .. mandate .. ')</span>'
                num = tonumber(percent)
            else
                num = tonumber(raw:match("[%d%.]+"))
            end
        end
        if not raw or raw == "" then raw = "–" end
        table.insert(values, { raw = raw, num = num })
    end

    -- Største & næststørste
    local max1, max2 = topTwo(values)

    -- Find alle vindere (alle partier med max1)
    local winningParties = {}
    for idx, v in ipairs(values) do
        if v.num and v.num == max1 then
            winningParties[idx] = parties[idx].name
        end
    end

    -- Udskriv værdier (vindere med deres egen farve + fed skrift)
    for idx, v in ipairs(values) do
        if v.num and winningParties[idx] then
            local color = getPartyColor(winningParties[idx]) or "#FFD700"
            wikitext = wikitext .. string.format(" || style=\"background:%s;\" | '''%s'''", color, v.raw)
        else
            wikitext = wikitext .. string.format(" || %s", v.raw)
        end
    end

    -- Others
    if includeOthers then
        local oth = args[prefix .. "_oth"] or "–"
        local percent, mandate = oth:match("^(%d+%.?%d*)%s*%((%d+)%)$")
        if percent and mandate then
            oth = percent .. '<br/><span style="font-size:85%;">(' .. mandate .. ')</span>'
        end
        wikitext = wikitext .. " || " .. oth
    end

-- Lead
local lead = "–"
if max1 and max2 then
    lead = string.format("%.1f", max1 - max2)
end

-- Tæl antal vindere
local winnersCount = 0
local firstIdx = nil
for idx in pairs(winningParties) do
    winnersCount = winnersCount + 1
    if not firstIdx then firstIdx = idx end
end

if winnersCount == 1 and firstIdx then
    -- Kun én vinder → brug partiets farve
    local color = getPartyColor(winningParties[firstIdx]) or "#FFD700"
    wikitext = wikitext .. string.format(" || style=\"background:%s;\" | '''%s'''", color, lead)
else
    -- Flere vindere → neutralt lead
    wikitext = wikitext .. string.format(" || '''%s'''", lead)
end

wikitext = wikitext .. "\n"


    return wikitext
end

-- Hovedfunktion
function p.renderPoll(frame)
    local args = frame:getParent().args
    local includeOthers = args["Others"] and mw.text.trim(args["Others"]) == "y"
    local wikitext = '{| class="wikitable sortable mw-datatable" style="text-align:center;font-size:90%;line-height:14px;"\n'

    ---------------------------------------------------------------------
    -- Partier
    ---------------------------------------------------------------------
    local parties = {}
    for i = 1, 20 do
        local raw = args["Party" .. i]
        if raw and raw ~= "" then
            local pname, alias = parsePartyInput(raw)
            table.insert(parties, { name = pname, customAbbrev = alias, idx = i })
        end
    end

    ---------------------------------------------------------------------
    -- HEADER
    ---------------------------------------------------------------------
    wikitext = wikitext ..
        "|-\n" ..
        '! rowspan="2"| Polling<br/>firm ' ..
        '|| rowspan="2"| Fieldwork<br/>date ' ..
        '|| rowspan="2"| Sample<br/>size '

    for _, pinfo in ipairs(parties) do
        local abbrev = pinfo.customAbbrev or partyModule._fetch({ pinfo.name, "abbrev" }) or "?"
        wikitext = wikitext ..
            string.format('|| class="unsortable" style="width:40px;"| [[%s|%s]] ', pinfo.name, abbrev)
    end

    if includeOthers then
        wikitext = wikitext .. '|| class="unsortable" style="width:40px;" rowspan="2"| Others '
    end

    wikitext = wikitext .. '|| rowspan="2"| Lead\n'

    ---------------------------------------------------------------------
    -- FARVER (øverste farvebar)
    ---------------------------------------------------------------------
    wikitext = wikitext .. "|-\n!! "
    for _, pinfo in ipairs(parties) do
        local color = partyModule._fetch({ pinfo.name, "color" }) or "#FFFFFF"
        color = string.gsub(color, "#", "&#35;")
        wikitext = wikitext ..
            string.format('! data-sort-type="number" style="background:%s !important;" | \n', color)
    end

    ---------------------------------------------------------------------
    -- POLLS: poll2–poll99 (øverst til nederst)
    ---------------------------------------------------------------------
    local pollRows = {}
    for i = 2, 99 do
        if args["poll" .. i .. "_firm"] or args["poll" .. i .. "_election"] then
            table.insert(pollRows, { index = i })
        end
    end

    -- Udskriv polls i omvendt rækkefølge (højeste nummer øverst)
    for j = #pollRows, 1, -1 do
        local i = pollRows[j].index
        wikitext = wikitext .. makePollRow(args, parties, "poll" .. i, includeOthers, false)
    end

    -- Til sidst basepoll nederst
    if args["bpoll_election"] or args["bpoll_date"] or args["bpoll_sample"] then
        wikitext = wikitext .. makePollRow(args, parties, "bpoll", includeOthers, true)
    end

    ---------------------------------------------------------------------
    -- Luk tabel
    ---------------------------------------------------------------------
    wikitext = wikitext .. "\n|}"

    return wikitext
end

return p

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.