Modul:ISO15924/table

aus Wikipedia, der freien Enzyklopädie
local ISO15924 = { suite  = "ISO15924",
                   sub    = "table",
                   serial = "2019-10-22",
                   item   = 71970561,
                   main   = 71584769,
                   iso639 = { suite = "Multilingual",
                              item  = 47541920 }
                 }
--[=[
Generate ISO 15924 table with names and languages
]=]
local Failsafe  = ISO15924
local GlobalMod = ISO15924



local foreignModule = function ( access, advanced, append, alt, alert )
    -- Fetch global module
    -- Precondition:
    --     access    -- string, with name of base module
    --     advanced  -- true, for require(); else mw.loadData()
    --     append    -- string, with subpage part, if any; or false
    --     alt       -- number, of wikidata item of root; or false
    --     alert     -- true, for throwing error on data problem
    -- Postcondition:
    --     Returns whatever, probably table
    -- 2019-10-20
    local storage = access
    local fun, lucky, r
    if advanced then
        fun = require
    else
        fun = mw.loadData
    end
    if append then
        storage = string.format( "%s/%s", storage, append )
    end
    lucky, r = pcall( fun,  "Module:" .. storage )
    if not lucky then
        local suited
        GlobalMod.globalModules = GlobalMod.globalModules or { }
        suited = GlobalMod.globalModules[ access ]
        if not suited  and
           type( alt ) == "number"  and
           alt > 0 then
            suited = string.format( "Q%d", alt )
            suited = mw.wikibase.getSitelink( suited )
            GlobalMod.globalModules[ access ] = suited or true
        end
        if type( suited ) == "string" then
            storage = suited
            if append then
                storage = string.format( "%s/%s", storage, append )
            end
            lucky, r = pcall( fun, storage )
        end
        if not lucky and alert then
            error( "Missing or invalid page: " .. storage, 0 )
        end
    end
    return r
end -- foreignModule()



local function fill( access, alien )
    -- Expand language name template
    --     access  -- string, with language code
    --     alien   -- language code for which to be generated
    -- Returns string
    local config = foreignModule( ISO15924.suite,
                                  false,
                                  "config",
                                  ISO15924.main )
    local r
    if type( config ) == "table" then
        local template = config.tmplLang
        if type( template ) == "table" then
            local s = template.title
            local p = { }
            if type( s ) == "string" then
                if type( template.param ) == "string" then
                    p[ template.param ] = access
                end
            else
                if type( template.namePat ) == "string"  and
                   template.namePat:find( "%s", 1, true ) then
                    s = string.format( template.namePat, access )
                end
            end
            if type( s ) == "string" then
                local lucky
                lucky, s = pcall( function ()
                                    return ISO15924.frame:expandTemplate{
                                                               title = s,
                                                               args = p }
                                  end )
                if lucky then
                    r = s
                end
            end
        end
    end
    if not r  and  ISO15924.iso639.bib then
        r = ISO15924.iso639.bib.getName( access, alien )
    end
    if not r then
        local e = mw.html.create( "code" ):wikitext( access )
        r = tostring( e )
    end
    return r
end -- fill()



ISO15924.fiat = function ( access, assigned, adjust, alien,
                           accessed, align, alien2, access2 )
    -- Create table row of scripting code, names, and perhaps languages
    --     access    -- string, with scripting code
    --     assigned  -- table, with translate text
    --     adjust    -- function
    --     alien     -- language code for which to be generated
    --     accessed  -- table, with languages, or nil
    --     align     -- number of columns
    --     alien2    -- code of second language, or nil
    --     access2   -- table, with translate text of second language, or nil
    local e = assigned[ access ]
    local r = "\n|-"
    if accessed then
        r = string.format( "%s id='%s'", r, access )
    end
    r = string.format( "%s\n|style='font-family:monospace'| %s ||",
                       r, access )
    local s = type( e )
    if accessed then
        local cl = { }
        if s == "table" then
            s = e[ 1 ]
        else
            s = e
        end
        if type( s ) == "string" then
            r = string.format( "%s %s || ", r, adjust( access ) )
        else
            r = r .. "   || "
        end
        if type( alien2 ) == "string" then
            if type( access2 ) == "table" then
                r = string.format( "%s %s || ",
                                   r,  access2[ access ] )
            else
                r = r .. "   || "
            end
        end
        for k, v in pairs( accessed ) do
            if type( v ) == "table" then
                for kk, vv in pairs( v ) do
                    if vv == access then
                        table.insert( cl, k )
                        break -- for kk, vv
                    end
                end -- for kk, vv
            elseif v == access then
                table.insert( cl, k )
            end
        end -- for k, v
        table.sort( cl )
        s = ""
        for i = 1, #cl do
            r = string.format( "%s%s%s",
                               r,  s,  fill( cl[ i ], alien ) )
            s = ", "
        end -- for i
    else
        local n
        if s == "table" then
            n = 0
            s = e[ 1 ]
            for k, v in pairs( e ) do
                n = n + 1
            end -- for k, v
        else
            s = e
            n = 1
        end
        if n == 1  and  align > 1 then
            r = string.format( "%scolspan='%d'|", r, align )
        end
        r = string.format( "%s %s", r, adjust( access ) )
        if n > 1 then
            for i = 2, n do
                r = string.format( "%s || %s",
                                   r,  adjust( access, false, i ) )
                if i >= align then
                    break -- for i
                end
            end -- for i
        end
    end
    return r
end -- ISO15924.fiat()



ISO15924.fire = function ( all, alien, add, alien2 )
    -- Create table body of scripting codes, names, and perhaps languages
    -- Precondition:
    --     all     -- true, if all known languages to be added
    --                otherwise linguistic variations
    --     alien   -- code of language in which to be generated, or nil
    --     add     -- arbitrary additional information
    --     alien2  -- code of second language, or nil
    -- Postcondition:
    --     Returns  string in table syntax
    local texts = foreignModule( ISO15924.suite,
                                 false,
                                 "translate",
                                 ISO15924.main )
    local slang = alien
    local r = ""
    if not slang then
        slang = mw.language.getContentLanguage():getCode():lower()
    end
    if type( texts.translate ) == "table"  and
       type( texts.translate[ slang ] ) == "table" then
        local trsl = texts.translate[ slang ]
        if type( trsl ) == "table" then
            local max   = trsl.maxElem or 0
            local order = { }
            local s
            for k, v in pairs( trsl ) do
                s = type( v )
                if s == "table" then
                    m = max
                elseif s == "string" then
                    m = 1
                else
                    m = false
                end
                if m then
                    table.insert( order, k )
                    if m > max then
                        max = m
                    end
                end
            end -- for k, v
            if max > 0 then
                local resi
                local fmtr = function( a, another, add )
                                 return resi.Text.scriptName( a,
                                                              another or
                                                                   slang,
                                                              add )
                             end
                local data, trsl2
                if not ISO15924.frame then
                    ISO15924.frame = mw.getCurrentFrame()
                end
                table.sort( order )
                if all then
                    data = foreignModule( ISO15924.suite,
                                          false,
                                          "commons",
                                          ISO15924.main )
                    if not data then
                        data = foreignModule( ISO15924.suite,
                                              false,
                                              "codes",
                                              ISO15924.main )
                    end
                    if type( data.iso639script ) == "table" then
                        local iso639
                        data = data.iso639script
                        resi = foreignModule( ISO15924.suite,
                                              true,
                                              false,
                                              ISO15924.main )
                        if type( resi ) == "table" then
                            resi          = resi[ ISO15924.suite ]()
                            ISO15924.base = resi
                        end
                        iso639 = foreignModule( ISO15924.iso639.suite,
                                                true,
                                                false,
                                                ISO15924.iso639.item )
                        if type( iso639 ) == "table" then
                            ISO15924.iso639.bib =
                                        iso639[ ISO15924.iso639.suite ]()
                        end
                    else
                        data = false
                    end
                end
                if resi then
                    if type( alien2 ) == "string" then
                        trsl2 = texts.translate[ alien2 ]
                    end
                    for i = 1, #order do
                        r = r .. ISO15924.fiat( order[ i ],
                                                trsl,
                                                fmtr,
                                                slang,
                                                data,
                                                max,
                                                alien2,
                                                trsl2 )
                    end -- for i
                end
            end
        end
    end
    r = r .. "\n|}"
    return r
end -- ISO15924.fire()



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
    -- 2019-10-15
    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 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
                    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 = { }

p.f = function ( frame )
    ISO15924.frame = frame
    return ISO15924.fire( frame.args.languages == "1",
                          frame.args.lang,
                          frame.args.add,
                          frame.args.lang2 )
end -- p.f

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

return p