Módulo:Storm categories/demo

Origem: Wikipédia, a enciclopédia livre.
--
-- This module handles demonstration and list of possible values for all storm
-- category templates! Please test this module on [[Module:Storm categories/demo/doc]]
-- before publishing to avoid errros. Thank you!
--
local colorRatio = require("Module:Color contrast")._ratio
local TableTools = require("Module:TableTools")
local stormcats = require("Module:Storm categories")
local cats = require("Module:Storm categories/categories").cats
local colors = require("Module:Storm categories/colors").colors
local icons = require("Module:Storm categories/icons").icons
local p = {}

local customKeys = {}
for k, v in pairs(colors) do
    table.insert(customKeys, k)
end
for k, v in pairs(icons) do
    table.insert(customKeys, k)
end
TableTools.removeDuplicates(customKeys)

function tableEmpty(_table)
    for k, v in pairs(_table) do
        return false
    end
    return true
end

--- Generates and renderds the demo table.
-- @param frame The Scribunto frame.
function p.demo(frame)
    local plain = (frame.args["plain"] or frame:getParent().args["plain"] or "") ~= ""
    local verbose = (frame.args["verbose"] or frame:getParent().args["verbose"] or "") ~= ""
    
    local legend = setmetatable({}, { refgroupname = "" })
    local errors = setmetatable({}, { refgroupname = "E" })
    local warnings = setmetatable({}, { refgroupname = "W" })
    
    --- Builds the entire reflist
    -- @param _group The group to build for. Uses `legend` by default.
    function buildReflist(_group)
        group = _group or legend
        return frame:expandTemplate{ title = 'reflist', args = {
            group = getmetatable(group)["refgroupname"]
        } }
    end
    
    --- Returns a single <ref> tag containing the legend provided and
    -- attaches the note definition to the list of notes.
    -- @param details The details of the legend.
    -- @param _group The group to write in. Uses `legend` by default.
    function createLegend(details, _group)
        hash = string.sub(mw.hash.hashValue("md5", details), 0, 8)
        group = _group or legend
        if group[hash] == nil then
            group[hash] = plain and "" or frame:extensionTag{
                -- <ref name="hash">details</ref>
                name = 'ref',
                content = mw.ustring.gsub(details, "%[%[File:([^%|]+)[^%]]*%]%]", "[[:File:%1]]"),
                args = {
                    name = hash,
                    group = getmetatable(group)["refgroupname"]
                }
            }
        end
        
        -- <ref name="hash"/>
        return plain and "" or frame:extensionTag{ name = 'ref', args = {
            name = hash,
            group = getmetatable(group)["refgroupname"]
        } }
    end
    
    --- Checks for color contrast issues and tags accordingly.
    -- Returns the refernce tag, so this should be used in conjunction with an
    -- HTML node's :wikitext function.
    function contrastCheck(color)
        local catColorBlackRatio = colorRatio({ "#" .. color, "black" })
        local catColorLinkRatio = colorRatio({ "#" .. color, "#0645ad" })
        local catColorVisitedLinkRatio = colorRatio({ "#" .. color, "#0b0080" })
        
        local finalWikitext = ""
        if catColorBlackRatio == "?" or catColorLinkRatio == "?" or catColorVisitedLinkRatio == "?" then
            finalWikitext = finalWikitext ..
                createLegend("This color must be a hexadecimal color.", errors)
        else
            if catColorBlackRatio < 4.5 then
                finalWikitext = finalWikitext ..
                    createLegend("This color has [[MOS:COLOR|contrast issues]] with black (not WCAG 2.0 AA-compatible). It will be unusable on all infoboxes and storm season summaries.", errors)
            end
            if catColorLinkRatio < 4.5 then
                finalWikitext = finalWikitext ..
                    createLegend("This color has [[MOS:COLOR|contrast issues]] with links (not WCAG 2.0 AA-compatible). It should not be used in conjunction with a link.", warnings)
            end
            if catColorVisitedLinkRatio < 4.5 then
                finalWikitext = finalWikitext ..
                    createLegend("This color has [[MOS:COLOR|contrast issues]] with visited links (not WCAG 2.0 AA-compatible with #0b0080). It should not be used in conjunction with a visited link.", warnings)
            end
            if actualCat == "c0c0c0" and cat[sortkey] ~= 0 then
                finalWikitext = finalWikitext ..
                    createLegend("This category is using a color reserved specifically for the \"unknown\" category.", warnings)
            end
        end
        return finalWikitext
    end
    
    function colorInfo(color, verbose, extra)
        local catColorBlackRatio = colorRatio({ "#" .. color, "black" })
        local catColorLinkRatio = colorRatio({ "#" .. color, "#0645ad" })
        local catColorVisitedLinkRatio = colorRatio({ "#" .. color, "#0b0080" })
        
        local nc = tostring(mw.html.create("abbr")
            :wikitext("NC")
            :attr("title", "Does not satisfy the minimum WCAG 2.1 compliance level for color contrast (AA)")
        );
        local aa = tostring(mw.html.create("abbr")
            :wikitext("AA")
            :attr("title", "WCAG 2.1 Level AA: Acceptable compliance")
        );
        local aaa = tostring(mw.html.create("abbr")
            :wikitext("AAA")
            :attr("title", "WCAG 2.1 Level AAA: Optimal compliance")
        );
        
        function contrastLevel(contrast)
            return contrast >= 7 and aaa or (contrast >= 4.5 and aa or nc)
        end
        
        return mw.html.create("td")
            :attr("data-sort-value", math.min(catColorBlackRatio))
            :wikitext(
                "#" .. color .. (extra or "") .. contrastCheck(color) .. (verbose and ("<br/>"
                .. tostring(
                    mw.html.create("abbr")
                        :attr("title", "Contrast to black")
                        :wikitext("CTB")
                ) .. ": " .. string.format("%.2f", catColorBlackRatio) .. " (" .. contrastLevel(catColorBlackRatio) .. ")<br/>"
                .. tostring(
                    mw.html.create("abbr")
                        :attr("title", "Contrast to links")
                        :wikitext("CTL")
                ) .. ": " .. string.format("%.2f", catColorLinkRatio) .. " (" .. contrastLevel(catColorLinkRatio) .. ")<br/>"
                .. tostring(
                    mw.html.create("abbr")
                        :attr("title", "Contrast to visited links")
                        :wikitext("CTVL")
                ) .. ": " .. string.format("%.2f", catColorVisitedLinkRatio) .. " (" .. contrastLevel(catColorVisitedLinkRatio) .. ")") or "")
            )
    end
    
    local categoryTable = mw.html.create("table")
        :addClass("wikitable")
        :addClass("sortable")
        :attr("style", "width: 100%")
        
    categoryTable
        :node(
            mw.html.create("tr")
                :node(mw.html.create("th"):wikitext("Icon")
                    :attr("class", "unsortable")
                    :attr("rowspan", "2")
                    :css("width", "0"))
                :node(mw.html.create("th"):wikitext("ID")
                    :attr("rowspan", "2"))
                :node(mw.html.create("th"):wikitext("Name")
                    :attr("colspan", "2"))
                :node(mw.html.create("th"):wikitext("Color")
                    :attr("rowspan", "2")
                    :attr("colspan", "2"))
                :node(mw.html.create("th"):wikitext("Sortkey")
                    :attr("colspan", "2"))
        ):node(
            mw.html.create("tr")
                :node(mw.html.create("th"):wikitext("Basin"))
                :node(mw.html.create("th"):wikitext("Name"))
                :node(mw.html.create("th"):wikitext("Basin"))
                :node(mw.html.create("th"):wikitext("Sortkey")
                    :attr("data-sort-type", "number"))
        )
    
    for name, cat in TableTools.sortedPairs(cats) do
        local rows = { mw.html.create("tr") }
        local row = rows[1]
        
        local actualIcon = stormcats._icon(name)
        local icon = mw.html.create("td")
            :wikitext(actualIcon)
        if cat["icon"] ~= nil and actualIcon ~= cat["icon"] then
            icon:wikitext(
                createLegend("Overriden from original icon (" .. cat["icon"] .. ")")
            )
        end
            
        local id = mw.html.create("td")
            :wikitext(name)
        local actualColor = stormcats._color(name)
        local colorPreview = mw.html.create("td")
            :attr("style", "background-color: #" .. actualColor .. "; padding: 0; width: 1.8em")
        local color = colorInfo(
            actualColor,
            verbose,
            actualColor ~= cat["color"] and createLegend(
                "Overriden from original color ({{color box|#"
                .. cat["color"]
                .. "}} #"
                .. cat["color"]
                .. ")"
            ) or ""
        ):css("width", "0"):css("white-space", "nowrap")
        
        local sortkeyCategory = mw.html.create("td")
            :attr("data-sort-value", cat["sortkey"])
        local sortkey = mw.html.create("td")
            :attr("data-sort-value", cat["sortkey"])
            :wikitext(cat["sortkey"])
            
        if cat["sortkey"] < 0 then
            sortkeyCategory:wikitext("Invalid")
        elseif cat["sortkey"] < 20000 then
            sortkeyCategory:wikitext("Global")
        elseif cat["sortkey"] < 30000 then
            sortkeyCategory:wikitext("Historical")
        elseif cat["sortkey"] < 40000 then
            sortkeyCategory:wikitext("SWIO")
        elseif cat["sortkey"] < 50000 then
            sortkeyCategory:wikitext("Aus/Fiji")
        elseif cat["sortkey"] < 60000 then
            sortkeyCategory:wikitext("NIO")
        elseif cat["sortkey"] < 80000 then
            sortkeyCategory:wikitext("WPAC")
        elseif cat["sortkey"] < 90000 then
            sortkeyCategory:wikitext("Atl/EPac/SAtl")
        elseif cat["sortkey"] < 100000 then
            sortkeyCategory:attr("style", "color: gray")
            sortkeyCategory:wikitext("''Global''")
        else
            sortkeyCategory:wikitext("Invalid")
        end
        
        if type(cat["name"]) == "string" then
            local name = mw.html.create("td")
                :attr("colspan", "2")
                :wikitext(cat["name"])
            row:node(icon)
            row:node(id)
            row:node(name)
        else
            local nameTableLength = TableTools.size(cat["name"])
            icon:attr("rowspan", nameTableLength)
            id:attr("rowspan", nameTableLength)
            colorPreview:attr("rowspan", nameTableLength)
            color:attr("rowspan", nameTableLength)
            sortkeyCategory:attr("rowspan", nameTableLength)
            sortkey:attr("rowspan", nameTableLength)
            
            row:node(icon)
            row:node(id)
            local firstDone = false
            for key, basinName in TableTools.sortedPairs(cat["name"]) do
                if firstDone then
                    local nameRow = mw.html.create("tr")
                    
                    nameRow
                        :node(mw.html.create("td"):wikitext(key))
                        :node(mw.html.create("td"):wikitext(basinName))
                        
                    table.insert(rows, nameRow)    
                else
                    firstDone = true
                    row
                        :node(mw.html.create("td"):wikitext(key))
                        :node(mw.html.create("td"):wikitext(basinName))
                end
            end
        end
        
        row:node(colorPreview)
        row:node(color)
        row:node(sortkeyCategory)
        row:node(sortkey)
        
        for _, _row in TableTools.sortedPairs(rows) do
            categoryTable:node(_row)
        end
    end
    
    for name, _ in TableTools.sortedPairs(TableTools.listToSet(customKeys)) do
        if cats[name] == nil then
            local row = mw.html.create("tr")
            
            local icon = stormcats._icon(name, true)
            row
                :node(mw.html.create("td")
                    :wikitext(
                        icon ~= nil
                        and icon
                        or "''<span style=\"color:gray\">N/A</span>''"
                    ))
                :node(mw.html.create("td"):wikitext(name))
            
            local color = stormcats._color(name, true)
            -- Add more conditions eventually
            if color ~= nil then
                row
                    :node(mw.html.create("td")
                        :attr("colspan", "2")
                        :wikitext("''<span style=\"color:gray\">not available</span>''"))
                    :node(mw.html.create("td")
                        :attr("style", "background-color: #" .. color .. "; padding: 0; width: 1.8em"))
                    :node(colorInfo(color, verbose))
                        :css("width", "0")
                        :css("white-space", "nowrap")
                    :node(mw.html.create("td")
                        :attr("colspan", "2")
                        :wikitext("''<span style=\"color:gray\">not available</span>''"))
            else
                row
                    :node(mw.html.create("td")
                        :attr("colspan", "6")
                        :wikitext("''<span style=\"color:gray\">not available</span>''"))
            end
            categoryTable:node(row)
        end
    end
    
    out = ""
    if not plain and not tableEmpty(errors) then
        out = out
            .. tostring(mw.html.create("h4"):wikitext("Error"))
            .. tostring(mw.html.create("p"):wikitext("This table contains errors than need to be addressed immediately, as it may cause errors on a large amount of pages."))
            .. buildReflist(errors)
    end
    if not plain and not tableEmpty(legend) then
        out = out
            .. tostring(mw.html.create("h4"):wikitext("Legend"))
            .. buildReflist(legend)
    end
    out = out .. tostring(categoryTable)
    if not plain and not tableEmpty(warnings) then
        out = out
            .. tostring(mw.html.create("h4"):wikitext("Warnings"))
            .. tostring(mw.html.create("p"):wikitext("This table contains warnings than should be addressed. Please note that some warnings cannot be fully addressed without changes that would require consensus."))
            .. buildReflist(warnings)
    end
    
    return mw.text.trim(out)
end

return p