Modul:ISO3166/maintain

aus Wikipedia, der freien Enzyklopädie

Die Dokumentation für dieses Modul kann unter Modul:ISO3166/maintain/Doku erstellt werden

local ISO3166 = { suite    = "ISO3166",
                  sub      = "maintain",
                  serial   = "2019-10-14",
                  item     = 0 }
--[=[
Maintain ISO 3166 data and create reverse map
require()
{{#invoke:ISO3166/maintain|factory}}
]=]
local Failsafe = ISO3166



ISO3166.factory = function ()
    -- Create reverse map
    -- Postcondition:
    --     Returns  string  -- with JSON code
    local frame = mw.getCurrentFrame()
    local self  = frame:getTitle()
    local suite = self:match( "^(.+)/%l+$" )
    local lucky, base = pcall( require, suite )
    local order   = { }
    local ordered = { }
    local source  = "codes"
    local toA2    = { }
    local start   = [===[{
        "license": "CC0-1.0",
        "description": { "en": "ISO 3166 code mapping to A2 (reverse)" },
        "sources": "%s",
        "schema": {
            "fields": [
                { "name": "seek",
                  "type": "string",
                  "title": { "en": "access key (A2 A3 NUM A4)" } },
                { "name": "shift",
                  "type": "string",
                  "title": { "en": "A2 key" } }
                      ]
                  },
        "data": [
]===]
    local codes, entry, r, s, sign
    if type( base ) == "table" then
       base = base.ISO3166()
       if type( base ) == "table" then
           base.fetch( true )
           if type( base.codes ) == "table" then
               codes = base.codes
           end
       end
    end
    if codes then
        for k, v in pairs( codes ) do
            table.insert( order, k )
        end -- for k, v
        table.sort( order )
        for i = 1, #order do
            sign  = order[ i ]
            entry = mw.text.split( codes[ sign ],  "%s+" )
            if not toA2[ sign ] then
                table.insert( ordered, sign )
            end
            toA2[ sign ] = sign
            for j = 1, #entry do
                s = entry[ j ]
                if toA2[ s ] then
                    if j > 1 then
                        s = string.format( "Duplicated: %s (%s)",
                                           s, sign )
                        error( s, 0 )
                    end
                else
                    toA2[ s ] = sign
                    table.insert( ordered, s )
                end
            end -- for j
        end -- for i
    end
    for i = 1, #ordered do
        s = ordered[ i ]
        if r then
            r = r .. ",\n"
        else
            r = ""
        end
        r = string.format( "%s[\"%s\",\"%s\"]", r, s, toA2[ s ] )
    end -- for i
    source = string.format( "commons:Data:ISO3166/%s.tab", source )
    s      = frame:callParserFunction( "#timel", "c" )
    source = string.format( "%s %s", source, s )
    start  = string.format( start, source )
    r      = r or ""
    r      = string.format( "%s%s\n                ]\n}", start, r )
    return r
end -- ISO3166.factory()



Failsafe.failsafe = function ( atleast )
    -- Retrieve versioning and check for compliance
    -- Precondition:
    --     atleast  -- string, with required version or "wikidata" or "~"
    --                 or false
    -- Postcondition:
    --     Returns  string  -- with queried version, also if problem
    --              false   -- if appropriate
    local last  = ( atleast == "~" )
    local since = atleast
    local r
    if last  or  since == "wikidata" then
        local item = Failsafe.item
        since = false
        if type( item ) == "number"  and  item > 0 then
            local entity = mw.wikibase.getEntity( string.format( "Q%d",
                                                                 item ) )
            if type( entity ) == "table" then
                local vsn = entity:formatPropertyValues( "P348" )
                if type( vsn ) == "table"  and
                   type( vsn.value ) == "string"  and
                   vsn.value ~= "" then
                    if last  and  vsn.value == Failsafe.serial then
                        r = false
                    else
                        r = vsn.value
                    end
                end
            end
        end
    end
    if type( r ) == "nil" then
        if not since  or  since <= Failsafe.serial then
            r = Failsafe.serial
        else
            r = false
        end
    end
    return r
end -- Failsafe.failsafe()



-- Export
local p = { }

function p.factory()
    return ISO3166.factory()
end -- p.factory

p.failsafe = function ( frame )
    -- Versioning interface
    local s = type( frame )
    local since
    if s == "table" then
        since = frame.args[ 1 ]
    elseif s == "string" then
        since = frame
    end
    if since then
        since = mw.text.trim( since )
        if since == "" then
            since = false
        end
    end
    return Failsafe.failsafe( since )  or  ""
end -- p.failsafe



p.ISO3166 = function ()
    return ISO3166
end -- p.ISO3166()

return p