Modul:Multilingual/maintain

aus Wikipedia, der freien Enzyklopädie
Zur Navigation springen Zur Suche springen
Vorlagenprogrammierung Diskussionen Lua Test Unterseiten
Modul Deutsch English

Modul: Dokumentation

Diese Seite enthält Code in der Programmiersprache Lua. Einbindungszahl Cirrus


local Multilingual = { suite  = "Multilingual",
                       sub    = "maintain",
                       serial = "2024-08-19",
                       item   = 0 }
--[=[
Multilingual data source maintainenance issues
]=]
local Failsafe   = Multilingual


local fill = function ( assembly, access, assign, adjust )
    -- Attach submodule
    -- Precondition:
    --     assembly  -- table
    --     access    -- submodule title
    --     assign    -- component name
    --     adjust    -- language code, or false
    -- Postcondition:
    --     Returns  table with additional components
    --     Throws error, if not available
    local lucky, got = pcall( require,
                              "Module:Multilingual/" .. access )
    local r = assembly
    local elem, part
    if type( got ) == "table" then
        for series, collection in pairs( got ) do
            if adjust  and  series ~= adjust then
            elseif type( series ) == "string" then
                if type( collection ) == "table" then
                    series = series:lower()
                    part = r[ series ]
                    if type( part ) ~= "table" then
                         r[ series ] = { }
                         part        = r[ series ]
                    end
                    for k, v in pairs( collection ) do
                        k = k:lower()
                        elem = part[ k ]
                        if type( elem ) ~= "table" then
                            part[ k ] = { }
                            elem      = part[ k ]
                        end
                        elem[ assign ] = v
                    end -- for k, v
                elseif series:sub( 1, 1 ) ~= "#" then
                    got = string.format( "Multilingual/%s invalid at %s",
                                         access, series )
                    error( got, 0 )
                end
            else
                got = string.format( "Multilingual/%s bad key type %s",
                                     access, type( series ) )
                error( got, 0 )
            end
        end -- for in, collection
    end
    return r
end -- fill()



local first = function ( a1, a2 )
    -- Sort obeying hyphen
    -- Precondition:
    --     a1  -- first string
    --     a2  -- second string
    -- Postcondition:
    --     Returns true when a1 is less than a2
    local n1 = a1:find( "-", 1, true )
    local n2 = a2:find( "-", 1, true )
    local r
    if n1 then
        if n2 then
            local s1 = a1:sub( 1, n1 )
            local s2 = a2:sub( 1, n2 )
            if s1 == s2 then
                r = ( a1:sub( n1 )  <  a2:sub( n2 ) )
            else
                r = ( s1 < s2 )
            end
        else
            r = ( a1:sub( 1, n1 )  <  a2 )
        end
    elseif n2 then
        r = ( a1  <  a2:sub( 1, n2 ) )
    else
        r = ( a1 < a2 )
    end
    return  r
end -- first()



Multilingual.fetchLanguageNames = function ( ask, amount )
    -- Make wikitable of language names in a certain language
    -- Precondition:
    --     ask     -- code of requested language
    --                -- nil, "native", "*", string
    --     amount  -- kind of extension
    --                -- nil, "all", "*", "mw", "mw", "#"
    -- Postcondition:
    --     Returns wikitext string, or number
    local codes      = { }
    local collection, n, r, scope, slang
    if not ask  or  ask == "*" then
        slang = "native"
    else
        slang = ask
    end
    if not amount  or  amount == "mw" then
        scope = "mw"
    elseif amount == "mwfile" then
        scope = "mwfile"
    else
        scope = "all"
    end
    collection = mw.language.fetchLanguageNames( slang, scope )
    for k, v in pairs( collection ) do
        table.insert( codes, k )
    end -- for k, v
    n = #codes
    if amount == "#" then
       r = n
    else
       local mwdef, s
       table.sort( codes, first )
       if scope == "all" then
           local mwfile = mw.language.fetchLanguageNames( slang,
                                                          "mwfile" )
           mwdef = mw.language.fetchLanguageNames( slang, "mw" )
           for k, v in pairs( mwdef ) do
               if mwfile[ k ] then
                   s = "mw file"
               else
                   s = "mw"
               end
               mwdef[ k ] = s
           end -- for k, v
       end
       r = "{| class='wikitable sortable'\n" ..
           string.format( "|+ '''<code>%s</code>''' (%s)\n",
                          slang, scope ) ..
           "|-\n" ..
           "! Code !! Name\n"
           if mwdef then
               r = r .. "! Scope\n"
           end
       for i = 1, n do
           s = codes[ i ]
           r = string.format( "%s|-\n|<code>%s</code>||%s\n",
                              r, s, collection[ s ] )
           if mwdef then
               s = mwdef[ s ]
               if s then
                   r = string.format( "%s| %s\n", r, s )
               end
           end
       end -- for i
       r = string.format( "%s|}\n%d items\n\n",
                          r, n )
    end
    return r
end -- Multilingual.fetchLanguageNames()



Multilingual.forward = function ( args )
    -- Make wikitable of maintainenance issues
    -- Precondition:
    --    args   -- table of options
    --              lack    -- show missing CLDR definitions
    --              leap    -- show open issues only
    --              learnt  -- show superfluous local entries only
    --              slang   -- limit to particular language
    -- Postcondition:
    --     Returns wikitext string
    local codes  = { }
    local pars   = args or { }
    local leap   = ( pars.leap    and  pars.leap   ~= "0" )
    local learnt = ( pars.learnt  and  pars.learnt ~= "0" )
    local slang  = ( pars.slang   and  pars.slang ~= "" )
    local slice  = "%s|-\n" ..
                   "|<code>%s</code>||<code>%s</code>||%s||%s||%s||%s\n"
    local r      = "{| class='wikitable sortable'\n" ..
                   "|-\n" ..
                   "! In !! For !! Suggested !! @MW !! @CLDR !! ToDo\n"
    local data = fill( { }, "names", "shift", slang )
    local elem, series, server, shift, single, state, super, tupel
    data = fill( data, "cldr", "super", slang )
    for series, collection in pairs( data ) do
        part = data[ series ]
        for k, v in pairs( collection ) do
            table.insert( codes,
                          string.format( "%s %s", series, k ) )
            v.server = mw.language.fetchLanguageName( k, series )
        end -- for k, v
    end -- for in, collection
    table.sort( codes, first )
    for i = 1, #codes do
        tupel  = mw.text.split( codes[ i ], " ", true )
        series = tupel[ 1 ]
        single = tupel[ 2 ]
        elem   = data[ series ][ single ]
        shift  = elem.shift  or ""
        server = elem.server or ""
        super  = elem.super  or ""
        if not elem.super then
            if shift == server then
                state = "Upstream"
            else
                state = "Learn"
            end
        elseif server ~= super then
            if shift == super then
                state = "CLDR"
            elseif elem.shift then
                state = "Proposal"
            elseif series == "en" then
                state = "Conflict"
            else
                state = mw.language.fetchLanguageName( single, "en" )
                if server == state then
                    state = false
                else
                    state = "Conflict"
                end
            end
        elseif elem.shift then
            if shift == server then
                state = "Discard"
            else
                state = "Proposal"
            end
        else
            state = false
        end
        if state then
            r = string.format( slice,
                               r,
                               series, single, shift, server, super,
                               state )
        end
    end -- for i
    r = r .. "|}\n\n"
    return r
end -- Multilingual.forward()



Failsafe.failsafe = function ( atleast )
    -- Retrieve versioning and check for compliance
    -- Precondition:
    --     atleast  -- string, with required version
    --                         or wikidata|item|~|@ or false
    -- Postcondition:
    --     Returns  string  -- with queried version/item, also if problem
    --              false   -- if appropriate
    -- 2024-03-01
    local since  = atleast
    local last   = ( since == "~" )
    local linked = ( since == "@" )
    local link   = ( since == "item" )
    local r
    if last  or  link  or  linked  or  since == "wikidata" then
        local item = Failsafe.item
        since = false
        if type( item ) == "number"  and  item > 0 then
            local suited = string.format( "Q%d", item )
            if link then
                r = suited
            else
                local entity = mw.wikibase.getEntity( suited )
                if type( entity ) == "table" then
                    local seek = Failsafe.serialProperty or "P348"
                    local vsn  = entity:formatPropertyValues( seek )
                    if type( vsn ) == "table"  and
                       type( vsn.value ) == "string"  and
                       vsn.value ~= "" then
                        if last  and  vsn.value == Failsafe.serial then
                            r = false
                        elseif linked then
                            if mw.title.getCurrentTitle().prefixedText
                               ==  mw.wikibase.getSitelink( suited ) then
                                r = false
                            else
                                r = suited
                            end
                        else
                            r = vsn.value
                        end
                    end
                end
            end
        elseif link then
            r = false
        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 = { }

p.fetchLanguageNames = function ( frame )
    -- Make wikitable of language names in a certain language
    --     1  -- code of requested language
    --     2  -- kind of extension
    return Multilingual.fetchLanguageNames( frame.args[ 1 ],
                                            frame.args[ 2 ] )
end -- p.fetchLanguageNames

p.forward = function ( frame )
    -- Make wikitable of maintainenance issues
    --    leap    -- show open issues only
    --    learnt  -- show superfluous local entries only
    --    slang   -- limit to particular language
    return Multilingual.forward( frame.args )
end -- p.forward

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.MLM = function ()
    return Failsafe
end -- p.MLM

setmetatable( p,  { __call = function ( func, ... )
                                 setmetatable( p, nil )
                                 return Failsafe
                             end } )

return p