Modul:Multilingual: Unterschied zwischen den Versionen

23.214 Bytes hinzugefügt ,  18. Dezember 2020
2020-12-10
(Die Seite wurde neu angelegt: „local Multilingual = { suite = "Multilingual", serial = "2018-04-16", item = 47541920 } local User = { sniffer…“)
 
(2020-12-10)
Zeile 1: Zeile 1:
local Multilingual = { suite = "Multilingual",
local Multilingual = { suite   = "Multilingual",
                       serial = "2018-04-16",
                       serial = "2020-12-10",
                       item   = 47541920 }
                       item   = 47541920,
local User = { sniffer = "publishchanges" }
                      globals = { ISO15924 = 71584769,
                                  WLink    = 19363224 }
                    }
--[=[
Utilities for multilingual texts and ISO 639 (BCP47) issues etc.
* fair()
* fallback()
* findCode()
* fix()
* format()
* getBase()
* getLang()
* getName()
* i18n()
* int()
* isLang()
* isLangWiki()
* isMinusculable()
* isRTL()
* message()
* sitelink()
* tabData()
* userLang()
* userLangCode()
* wikibase()
* failsafe()
loadData: Multilingual/config Multilingual/names
]=]
local Failsafe  = Multilingual
local GlobalMod  = Multilingual
local GlobalData = Multilingual
local User       = { sniffer = "showpreview" }
Multilingual.globals.Multilingual = Multilingual.item




Zeile 8: Zeile 40:
Multilingual.exotic = { simple = true,
Multilingual.exotic = { simple = true,
                         no    = true }
                         no    = true }
Multilingual.prefer = { cs = true,
                        de = true,
                        en = true,
                        es = true,
                        fr = true,
                        it = true,
                        nl = true,
                        pt = true,
                        ru = true,
                        sv = true }






local favorite = function ()
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
    -- 2020-01-01
    local storage = access
    local finer = function ()
                      if append then
                          storage = string.format( "%s/%s",
                                                  storage,
                                                  append )
                      end
                  end
    local fun, lucky, r, suited
    if advanced then
        fun = require
    else
        fun = mw.loadData
    end
    GlobalMod.globalModules = GlobalMod.globalModules or { }
    suited = GlobalMod.globalModules[ access ]
    if not suited then
        finer()
        lucky, r = pcall( fun,  "Module:" .. storage )
    end
    if not lucky then
        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
            finer()
            lucky, r = pcall( fun, storage )
        end
        if not lucky and alert then
            error( "Missing or invalid page: " .. storage )
        end
    end
    return r
end -- foreignModule()
 
 
 
local fetchData = function ( access )
    -- Retrieve translated keyword from commons:Data:****.tab
    -- Precondition:
    --    access  -- string, with page identification on Commons
    --    Returns table, with data, or string, with error message
    -- 2019-12-05
    local storage = access
    local r
    if type( storage ) == "string" then
        local s
        storage = mw.text.trim( storage )
        s = storage:lower()
        if s:sub( 1, 2 ) == "c:" then
            storage = mw.text.trim( storage:sub( 3 ) )
            s      = storage:lower()
        elseif s:sub( 1, 8 ) == "commons:" then
            storage = mw.text.trim( storage:sub( 9 ) )
            s      = storage:lower()
        end
        if s:sub( 1, 5 ) == "data:" then
            storage = mw.text.trim( storage:sub( 6 ) )
            s      = storage:lower()
        end
        if s == ""  or  s == ".tab" then
            storage = false
        elseif s:sub( -4 ) == ".tab" then
            storage = storage:sub( 1, -5 ) .. ".tab"
        else
            storage = storage .. ".tab"
        end
    end
    if type( storage ) == "string" then
        local data
        if type( GlobalData.TabDATA ) ~= "table" then
            GlobalData.TabDATA = { }
        end
        data = GlobalData.TabDATA[ storage ]
        if data then
            r = data
        else
            local lucky
            lucky, data = pcall( mw.ext.data.get, storage, "_" )
            if type( data ) == "table" then
                data = data.data
                if type( data ) == "table" then
                    GlobalData.TabDATA[ storage ] = data
                else
                    r = string.format( "%s [[%s%s]]",
                                      "INVALID Data:*.tab",
                                      "commons:Data:",
                                      storage )
                end
            else
                r = "BAD PAGE Data:*.tab – commons:" .. storage
            end
            if r then
                GlobalData.TabDATA[ storage ] = r
                data = false
            else
                r = data
            end
        end
    else
        r = "BAD PAGE commons:Data:*.tab"
    end
    return r
end -- fetchData()
 
 
 
local favorites = function ()
    -- Provide fallback codes
     -- Postcondition:
     -- Postcondition:
     --    Returns code of current project language
     --    Returns table with sequence of preferred languages
     if not Multilingual.self then
    --    * ahead elements
         Multilingual.self = mw.language.getContentLanguage():getCode()
    --    * user (not yet accessible)
                                                            :lower()
    --    * page content language (not yet accessible)
    --    * page name subpage
    --    * project
    --    * en
    local r = Multilingual.polyglott
     if not r then
         local self = mw.language.getContentLanguage():getCode():lower()
        local sub  = mw.title.getCurrentTitle().subpageText
        local f    = function ( add )
                        local s = add
                        for i = 1, #r do
                            if r[ i ] == s then
                                s = false
                                break -- for i
                            end
                        end -- for i
                        if s then
                            table.insert( r, s )
                        end
                    end
        r = { }
        if sub:find( "/", 2, true ) then
            sub = sub:match( "/(%l%l%l?)$" )
            if sub then
                table.insert( r, sub )
            end
        elseif sub:find( "^%l%l%l?%-?%a?%a?%a?%a?$" )  and
              mw.language.isSupportedLanguage( sub ) then
            table.insert( r, sub )
        end
        f( self )
        f( "en" )
        Multilingual.polyglott = r
     end
     end
     return Multilingual.self
     return r
end -- favorite()
end -- favorites()






function feasible( ask, accept )
local feasible = function ( ask, accept )
     -- Is ask to be supported by application?
     -- Is ask to be supported by application?
     -- Precondition:
     -- Precondition:
Zeile 42: Zeile 240:




local fetch = function ( access, allow )
local fetch = function ( access, append )
     -- Attach config or library module
     -- Attach config or library module
     -- Precondition:
     -- Precondition:
     --    access  -- module title
     --    access  -- module title
     --    allow  -- permit non-existence
     --    append  -- string, with subpage part of this; or false
     -- Postcondition:
     -- Postcondition:
     --    Returns  table or false, with library
     --    Returns: table, with library, or false
     --     Throws error, if not available
     local got, sign
     if append then
        sign = string.format( "%s/%s", access, append )
    else
        sign = access
    end
     if type( Multilingual.ext ) ~= "table" then
     if type( Multilingual.ext ) ~= "table" then
         Multilingual.ext = { }
         Multilingual.ext = { }
     end
     end
     if Multilingual.ext[ access ] == false then
     got = Multilingual.ext[ sign ]
    elseif not Multilingual.ext[ access ] then
    if not got  and  got ~= false then
         local lucky, got = pcall( require, "Module:" .. access )
        local global = Multilingual.globals[ access ]
         if lucky then
         local lib    = ( not append  or  append == "config" )
            if type( got ) == "table" then
        got = foreignModule( access, lib, append, global )
                 Multilingual.ext[ access ] = got
         if type( got ) == "table" then
                 if type( got[ access ] ) == "function" then
            if lib then
                     Multilingual.ext[ access ] = got[ access ]()
                 local startup = got[ access ]
                 if type( startup ) == "function" then
                     got = startup()
                 end
                 end
             end
             end
        else
            got = false
        end
        Multilingual.ext[ sign ] = got
    end
    return got
end -- fetch()
local fetchISO639 = function ( access )
    -- Retrieve table from commons:Data:ISO639/***.tab
    -- Precondition:
    --    access  -- string, with subpage identification
    -- Postcondition:
    --    Returns table, with data, even empty
    local r
    if type( Multilingual.iso639 ) ~= "table" then
        Multilingual.iso639 = { }
    end
    r = Multilingual.iso639[ access ]
    if type( r ) == "nil" then
        local raw = fetchData( "ISO639/" .. access )
        if type( raw ) == "table" then
            local t
            r = { }
            for i = 1, #raw do
                t = raw[ i ]
                if type( t ) == "table"  and
                  type( t[ 1 ] ) == "string"  and
                  type( t[ 2 ] ) == "string" then
                    r[ t[ 1 ] ] =  t[ 2 ]
                else
                    break -- for i
                end
            end -- for i
        else
            r = false
         end
         end
         if type( Multilingual.ext[ access ] ) ~= "table" then
         Multilingual.iso639[ access ] = r
             if allow then
    end
                Multilingual.ext[ access ] = false
    return r or { }
            else
end -- fetchISO639()
                got = string.format( "Module:%s invalid", access )
 
                 error( got, 0 )
 
 
local fill = function ( access, alien, frame )
    -- Expand language name template
    -- Precondition:
    --    access  -- string, with language code
    --    alien  -- language code for which to be generated
    --    frame  -- frame, if available
    -- Postcondition:
    --    Returns string
    local template = Multilingual.tmplLang
    local r
    if type( template ) ~= "table" then
        local cnf = fetch( "Multilingual", "config" )
        if cnf then
             template = cnf.tmplLang
        end
    end
    if type( template ) == "table" then
        local source = template.title
        local f, lucky, s
        Multilingual.tmplLang = template
        if type( source ) ~= "string"  and
          type( template.namePat ) == "string"  and
          template.namePat:find( "%s", 1, true ) then
            source = string.format( template.namePat, access )
        end
        if type( source ) == "string" then
            if not Multilingual.frame then
                 if frame then
                    Multilingual.frame = frame
                else
                    Multilingual.frame = mw.getCurrentFrame()
                end
            end
            f = function ( a )
                    return Multilingual.frame:expandTemplate{ title = a }
                end
            lucky, s = pcall( f, source )
            if lucky then
                r = s
             end
             end
         end
         end
     end
     end
     return Multilingual.ext[ access ]
     return r
end -- fetch()
end -- fill()






function find( ask, alien )
local find = function ( ask, alien )
     -- Derive language code from name
     -- Derive language code from name
     -- Precondition:
     -- Precondition:
Zeile 98: Zeile 381:
     return r
     return r
end -- find()
end -- find()
local fold = function ( frame )
    -- Merge template and #invoke arglist
    -- Precondition:
    --    frame  -- template frame
    -- Postcondition:
    --    table, with combined arglist
    local r = { }
    local f = function ( apply )
                  if type( apply ) == "table"  and
                    type( apply.args ) == "table" then
                      for k, v in pairs( apply.args ) do
                          v = mw.text.trim( v )
                          if v ~= "" then
                              r[ tostring( k ) ] = v
                          end
                      end -- for k, v
                  end
              end -- f()
    f( frame:getParent() )
    f( frame )
    return r
end -- fold()




Zeile 127: Zeile 435:
         end
         end
         if User.sin then
         if User.sin then
            local order  = { }
            local post  = { }
            local three  = { }
            local unfold = { }
             local s, sin
             local s, sin
             for i = 1, #accept do
             for i = 1, #accept do
                 s = accept[ i ]
                 s = accept[ i ]
                 if not User.trials[ s ] then
                 if not User.trials[ s ] then
                     sin = User.tell:inLanguage( s ):plain()
                     if #s > 2 then
                    if sin == User.sin then
                        if s:find( "-", 3, true ) then
                         User.self = s
                            table.insert( unfold, s )
                         break -- for i
                         else
                            table.insert( three, s )
                         end
                     else
                     else
                         User.trials[ s ] = true
                         if Multilingual.prefer[ s ] then
                            table.insert( order, s )
                        else
                            table.insert( post, s )
                        end
                     end
                     end
                end
            end -- for i
            for i = 1, #post do
                table.insert( order, post[ i ] )
            end -- for i
            for i = 1, #three do
                table.insert( order, three[ i ] )
            end -- for i
            for i = 1, #unfold do
                table.insert( order, unfold[ i ] )
            end -- for i
            for i = 1, #order do
                s = order[ i ]
                sin = User.tell:inLanguage( s ):plain()
                if sin == User.sin then
                    User.self = s
                    break -- for i
                else
                    User.trials[ s ] = true
                 end
                 end
             end -- for i
             end -- for i
Zeile 187: Zeile 524:
     -- Precondition:
     -- Precondition:
     --    able    -- language version specifier to be supported
     --    able    -- language version specifier to be supported
     --    another  -- language specifier of a possible replacement
     --    another  -- language specifier of a possible replacement,
    --                or not to retrieve a fallback table
     -- Postcondition:
     -- Postcondition:
     --    Returns boolean
     --    Returns boolean, or table with fallback codes
     local r
     local r
     if type( able ) == "string"  and
     if type( able ) == "string"  and #able > 0 then
      type( another ) == "string" then
        if type( another ) == "string" and  #another > 0 then
        if able == another then
            if able == another then
             r = true
                r = true
             else
                local s = Multilingual.getBase( able )
                if s == another then
                    r = true
                else
                    local others = mw.language.getFallbacksFor( s )
                    r = feasible( another, others )
                end
            end
         else
         else
             local s = Multilingual.getBase( able )
             local s = Multilingual.getBase( able )
             if s == another then
             if s then
                 r = true
                 r = mw.language.getFallbacksFor( s )
            else
                 if r[ 1 ] == "en" then
                local others = mw.language.getFallbacksFor( s )
                    local d = fetchISO639( "fallback" )
                 r = feasible( another, others )
                    if type( d ) == "table"  and
                      type( d[ s ] ) == "string" then
                        r = mw.text.split( d[ s ], "|" )
                        table.insert( r, "en" )
                    end
                end
             end
             end
         end
         end
Zeile 221: Zeile 573:
     if #seek > 1 then
     if #seek > 1 then
         if seek:find( "[", 1, true ) then
         if seek:find( "[", 1, true ) then
             seek = fetch( "WLink" ).getPlain( seek )
             local wlink = fetch( "WLink" )
            if wlink  and
              type( wlink.getPlain ) == "function" then
                seek = wlink.getPlain( seek )
            end
         end
         end
         seek = mw.ustring.lower( seek )
         seek = mw.ustring.lower( seek )
Zeile 227: Zeile 583:
             r = Multilingual.fair( seek )
             r = Multilingual.fair( seek )
         else
         else
             local slang = favorite()
             local collection = favorites()
             r = find( seek, slang )
             for i = 1, #collection do
            if not r and  slang ~= "en" then
                r = find( seek, collection[ i ] )
                 r = find( seek, "en" )
                if r then
             end
                    break -- for i
                 end
             end -- for i
         end
         end
     end
     end
     return r
     return r
end -- Multilingual.findCode()
end -- Multilingual.findCode()
Multilingual.fix = function ( attempt )
    -- Fix frequently mistaken language code
    -- Precondition:
    --    attempt  -- string, with presumable language code
    -- Postcondition:
    --    Returns string with correction, or false if no problem known
    local r = fetchISO639( "correction" )[ attempt:lower() ]
    return r or false
end -- Multilingual.fix()




Zeile 308: Zeile 678:
                         r = Multilingual.getName( slang, alien )
                         r = Multilingual.getName( slang, alien )
                         if active then
                         if active then
                             local cnf = fetch( "Multilingual/config",
                             slot = fill( slang, false, frame )
                                              true )
                             if slot then
                             if cnf  and
                                 local wlink = fetch( "WLink" )
                              type( cnf.getLink ) == "function" then
                                 if wlink  and
                                 if not Multilingual.frame then
                                  type( wlink.getTarget )
                                    if frame then
                                                      == "function" then
                                        Multilingual.frame = frame
                                    else
                                        Multilingual.frame
                                                  = mw.getCurrentFrame()
                                    end
                                 end
                                slot = cnf.getLink( slang,
                                                    Multilingual.frame )
                                if slot then
                                    local wlink = fetch( "WLink" )
                                     slot = wlink.getTarget( slot )
                                     slot = wlink.getTarget( slot )
                                else
                                    lapsus = alert
                                 end
                                 end
                            else
                                lapsus = alert
                             end
                             end
                         end
                         end
Zeile 405: Zeile 765:
     --            .region
     --            .region
     --            .script
     --            .script
    --            .suggest
     --            .year
     --            .year
     --            .extension
     --            .extension
Zeile 468: Zeile 829:
             end
             end
         end -- for i
         end -- for i
        if r.legal then
            r.suggest = Multilingual.fix( r.base )
            if r.suggest then
                r.legal = false
            end
        end
     else
     else
         r = { legal = false }
         r = { legal = false }
    end
    if not r.legal then
        local cnf = fetch( "Multilingual", "config" )
        if cnf  and  type( cnf.scream ) == "string" then
            r.scream = cnf.scream
        end
     end
     end
     return r
     return r
Zeile 489: Zeile 862:
     if ask then
     if ask then
         local slang  = alien
         local slang  = alien
        local support = "Multilingual/names"
         local tLang
         local tLang
         if slang then
         if slang then
Zeile 495: Zeile 867:
                 slang = Multilingual.fair( ask )
                 slang = Multilingual.fair( ask )
             elseif slang == "!" then
             elseif slang == "!" then
                 slang = favorite()
                 slang = favorites()[ 1 ]
             else
             else
                 slang = Multilingual.fair( slang )
                 slang = Multilingual.fair( slang )
Zeile 506: Zeile 878:
         end
         end
         slang = slang:lower()
         slang = slang:lower()
         tLang = fetch( support, true )
         tLang = fetch( "Multilingual", "names" )
         if tLang then
         if tLang then
             tLang = tLang[ slang ]
             tLang = tLang[ slang ]
Zeile 541: Zeile 913:
     return r
     return r
end -- Multilingual.getName()
end -- Multilingual.getName()
Multilingual.i18n = function ( available, alt, frame )
    -- Select translatable message
    -- Precondition:
    --    available  -- table, with mapping language code ./. text
    --    alt        -- string|nil|false, with fallback text
    --    frame      -- frame, if available
    --    Returns
    --        1. string|nil|false, with selected message
    --        2. string|nil|false, with language code
    local r1, r2
    if type( available ) == "table" then
        local codes = { }
        local trsl  = { }
        local slang
        for k, v in pairs( available ) do
            if type( k ) == "string"  and
              type( v ) == "string" then
                slang = mw.text.trim( k:lower() )
                table.insert( codes, slang )
                trsl[ slang ] = v
            end
        end -- for k, v
        slang = Multilingual.userLang( codes, frame )
        if slang  and  trsl[ slang ] then
            r1 = mw.text.trim( trsl[ slang ] )
            if r1 == "" then
                r1 = false
            else
                r2 = slang
            end
        end
    end
    if not r1  and  type( alt ) == "string" then
        r1 = mw.text.trim( alt )
        if r1 == "" then
            r1 = false
        end
    end
    return r1, r2
end -- Multilingual.i18n()




Zeile 583: Zeile 998:
     if s then
     if s then
         r = mw.language.isKnownLanguageTag( s )
         r = mw.language.isKnownLanguageTag( s )
         if not r  and  additional then
         if r then
            r = not Multilingual.fix( s )
        elseif additional then
             r = Multilingual.exotic[ s ] or false
             r = Multilingual.exotic[ s ] or false
         end
         end
Zeile 620: Zeile 1.037:
     -- Postcondition:
     -- Postcondition:
     --    Returns boolean
     --    Returns boolean
     local r   = true
     local r = true
     if ask then
     if ask then
         local cnf = fetch( "Multilingual/config", true )
         local cnf = fetch( "Multilingual", "config" )
         if cnf then
         if cnf then
             local s = string.format( " %s ", ask:lower() )
             local s = string.format( " %s ", ask:lower() )
Zeile 642: Zeile 1.059:
     return r
     return r
end -- Multilingual.isMinusculable()
end -- Multilingual.isMinusculable()
Multilingual.isRTL = function ( ask )
    -- Check whether language is written right-to-left
    -- Precondition:
    --    ask  -- string, with language (or script) code
    -- Returns true, if right-to-left
    local r
    Multilingual.rtl = Multilingual.rtl or { }
    r = Multilingual.rtl[ ask ]
    if type( r ) ~= "boolean" then
        local bib = fetch( "ISO15924" )
        if type( bib ) == "table"  and
          type( bib.isRTL ) == "function" then
            r = bib.isRTL( ask )
        else
            r = mw.language.new( ask ):isRTL()
        end
        Multilingual.rtl[ ask ] = r
    end
    return r
end -- Multilingual.isRTL()
Multilingual.message = function ( arglist, frame )
    -- Show text in best match of user language like system message
    -- Precondition:
    --    arglist  -- template arguments
    --    frame    -- frame, if available
    -- Postcondition:
    --    Returns string with appropriate text
    local r
    if type( arglist ) == "table" then
        local t = { }
        local m, p, save
        for k, v in pairs( arglist ) do
            if type( k ) == "string"  and
              type( v ) == "string" then
                v = mw.text.trim( v )
                if v ~= "" then
                    if k:match( "^%l%l" ) then
                        t[ k ] = v
                    elseif k:match( "^%$%d$" )  and  k ~= "$0" then
                        p = p or { }
                        k = tonumber( k:match( "^%$(%d)$" ) )
                        p[ k ] = v
                        if not m  or  k > m then
                            m = k
                        end
                    end
                end
            end
        end -- for k, v
        if type( arglist[ "-" ] ) == "string" then
            save = arglist[ arglist[ "-" ] ]
        end
        r = Multilingual.i18n( t, save, frame )
        if p  and  r  and  r:find( "$", 1, true ) then
            t = { }
            for i = 1, m do
                t[ i ] = p[ i ]  or  ""
            end -- for i
            r = mw.message.newRawMessage( r, t ):plain()
        end
    end
    return r  or  ""
end -- Multilingual.message()
Multilingual.sitelink = function ( all, frame )
    -- Make link at local or other site with optimal linktext translation
    -- Precondition:
    --    all    -- string or table or number, item ID or entity
    --    frame  -- frame, if available
    -- Postcondition:
    --    Returns string with any helpful internal link, or plain text
    local s = type( all )
    local object, r
    if s == "table" then
        object = all
    elseif s == "string" then
        object = mw.wikibase.getEntity( all )
    elseif s == "number" then
        object = mw.wikibase.getEntity( string.format( "Q%d", all ) )
    end
    if type( object ) == "table" then
        local collection = object.sitelinks
        local entry
        s = false
        if type( collection ) == "table" then
            Multilingual.site = Multilingual.site  or
                                mw.wikibase.getGlobalSiteId()
            entry = collection[ Multilingual.site ]
            if entry then
                s = ":" .. entry.title
            elseif collection.enwiki then
                s = "w:en:" .. collection.enwiki.title
            end
        end
        r = Multilingual.wikibase( object, "labels", frame )
        if s then
            if s == ":" .. r then
                r = string.format( "[[%s]]", s )
            else
                r = string.format( "[[%s|%s]]", s, r )
            end
        end
    end
    return r  or  ""
end -- Multilingual.sitelink()
Multilingual.tabData = function ( access, at, alt, frame )
    -- Retrieve translated keyword from commons:Data:****.tab
    -- Precondition:
    --    access  -- string, with page identification on Commons
    --    at      -- string, with keyword
    --    alt    -- string|nil|false, with fallback text
    --    frame  -- frame, if available
    --    Returns
    --        1. string|nil|false, with selected message
    --        2. language code, or "error"
    local data = fetchData( access )
    local r1, r2
    if  type( data ) == "table" then
        if type( at ) == "string" then
            local seek = mw.text.trim( at )
            if seek == "" then
                r1 = "EMPTY Multilingual.tabData key"
            else
                local e, poly
                for i = 1, #data do
                    e = data[ i ]
                    if type( e ) == "table" then
                        if e[ 1 ] == seek then
                            if type( e[ 2 ] ) == "table" then
                                poly = e[ 2 ]
                            else
                                r1 = "INVALID Multilingual.tabData bad #"
                                                        .. tostring( i )
                            end
                            break  -- for i
                        end
                    else
                        break  -- for i
                    end
                end  -- for i
                if poly then
                    data = poly
                else
                    r1 = "UNKNOWN Multilingual.tabData key: " .. seek
                end
            end
        else
            r1 = "INVALID Multilingual.tabData key"
        end
    else
        r1 = data
    end
    if r1 then
        r2 = "error"
    elseif data then
        r1, r2 = Multilingual.i18n( data, alt, frame )
        r2 = r2 or "error"
    end
    return r1, r2
end -- Multilingual.tabData()




Zeile 648: Zeile 1.236:
     -- Try to support user language by application
     -- Try to support user language by application
     -- Precondition:
     -- Precondition:
     --    accept  -- space separated list of available ISO 639 codes
     --    accept  -- string or table
    --                space separated list of available ISO 639 codes
     --                Default: project language, or English
     --                Default: project language, or English
     --    frame  -- frame, if available
     --    frame  -- frame, if available
Zeile 656: Zeile 1.245:
     local codes, r, slang
     local codes, r, slang
     if s == "string" then
     if s == "string" then
         codes = mw.text.split( accept:lower(), " " )
         codes = mw.text.split( accept:lower(), "%s+" )
     elseif s == "table" then
     elseif s == "table" then
         codes = { }
         codes = { }
         for i = 1, #accept do
         for i = 1, #accept do
             s = accept[ i ]
             s = accept[ i ]
             if type( s ) == "string"  then
             if type( s ) == "string"  and
              s ~= "" then
                 table.insert( codes, s:lower() )
                 table.insert( codes, s:lower() )
             end
             end
         end -- for i
         end -- for i
    else
        codes = { }
        slang = favorite()
        if mw.language.isKnownLanguageTag( slang ) then
            table.insert( codes, slang )
        end
     end
     end
     slang = User.favorize( codes, frame )
     slang = User.favorize( codes, frame )
     if not slang then
     if slang then
        slang = favorite()  or  "en"
    end
    if feasible( slang, codes ) then
        r = slang
    elseif slang:find( "-", 1, true ) then
        slang = Multilingual.getBase( slang )
         if feasible( slang, codes ) then
         if feasible( slang, codes ) then
             r = slang
             r = slang
        elseif slang:find( "-", 1, true ) then
            slang = Multilingual.getBase( slang )
            if feasible( slang, codes ) then
                r = slang
            end
        end
        if not r then
            local others = mw.language.getFallbacksFor( slang )
            for i = 1, #others do
                slang = others[ i ]
                if feasible( slang, codes ) then
                    r = slang
                    break -- for i
                end
            end -- for i
         end
         end
     end
     end
     if not r then
     if not r then
         local others = mw.language.getFallbacksFor( slang )
         local back = favorites()
         for i = 1, #others do
         for i = 1, #back do
             slang = others[ i ]
             slang = back[ i ]
             if feasible( slang, codes ) then
             if feasible( slang, codes ) then
                 r = slang
                 r = slang
Zeile 693: Zeile 1.286:
             end
             end
         end -- for i
         end -- for i
         if not r then
         if not r and  codes[ 1 ] then
            if feasible( "en", codes ) then
             r = codes[ 1 ]
                r = "en"
             else
                r = codes[ 1 ]
            end
         end
         end
     end
     end
     return r
     return r or  favorites()[ 1 ]
end -- Multilingual.userLang()
end -- Multilingual.userLang()


Zeile 710: Zeile 1.299:
     -- Postcondition:
     -- Postcondition:
     --    Returns code of current best guess
     --    Returns code of current best guess
     return User.self  or  favorite() or  "en"
     return User.self  or  favorites()[ 1 ]
end -- Multilingual.userLangCode()
end -- Multilingual.userLangCode()






Multilingual.failsafe = function ( assert )
Multilingual.wikibase = function ( all, about, attempt, frame )
    -- Optimal translation of wikibase component
    -- Precondition:
    --    all      -- string or table, object ID or entity
    --    about    -- boolean, true "descriptions" or false "labels"
    --    attempt  -- string or not, code of preferred language
    --    frame    -- frame, if available
    -- Postcondition:
    --    Returns
    --        1. string, with selected message
    --        2. string, with language code, or not
    local s = type( all )
    local object, r, r2
    if s == "table" then
        object = all
    elseif s == "string" then
        object = mw.wikibase.getEntity( all )
    end
    if type( object ) == "table" then
        if about  and  about ~= "labels" then
            s = "descriptions"
        else
            s = "labels"
        end
        object = object[ s ]
        if type( object ) == "table" then
            if object[ attempt ] then
                r  = object[ attempt ].value
                r2 = attempt
            else
                local poly
                for k, v in pairs( object ) do
                    poly = poly or { }
                    poly[ k ] = v.value
                end -- for k, v
                if poly then
                    r, r2 = Multilingual.i18n( poly, nil, frame )
                end
            end
        end
    end
    return r  or  "",  r2
end -- Multilingual.wikibase()
 
 
 
Failsafe.failsafe = function ( atleast )
     -- Retrieve versioning and check for compliance
     -- Retrieve versioning and check for compliance
     -- Precondition:
     -- Precondition:
     --    assert -- string, with required version or "wikidata",
     --    atleast -- string, with required version
     --               or false
     --                         or wikidata|item|~|@ or false
     -- Postcondition:
     -- Postcondition:
     --    Returns  string with appropriate version, or false
     --    Returns  string -- with queried version/item, also if problem
     local since = assert
    --              false   -- if appropriate
    -- 2020-08-17
    local since = atleast
     local last    = ( since == "~" )
    local linked  = ( since == "@" )
    local link    = ( since == "item" )
     local r
     local r
     if since == "wikidata" then
     if last  or  link  or  linked  or  since == "wikidata" then
         local item = Multilingual.item
         local item = Failsafe.item
         since = false
         since = false
         if type( item ) == "number"  and  item > 0 then
         if type( item ) == "number"  and  item > 0 then
             local entity = mw.wikibase.getEntity( string.format( "Q%d",
             local suited = string.format( "Q%d", item )
                                                                item ) )
            if link then
            if type( entity ) == "table" then
                r = suited
                local vsn = entity:formatPropertyValues( "P348" )
            else
                if type( vsn ) == "table"  and
                local entity = mw.wikibase.getEntity( suited )
                  type( vsn.value) == "string" and
                if type( entity ) == "table" then
                  vsn.value ~= "" then
                    local seek = Failsafe.serialProperty or "P348"
                    r = vsn.value
                    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
             end
             end
         end
         end
     end
     end
     if not r then
     if type( r ) == "nil" then
         if not since  or  since <= Multilingual.serial then
         if not since  or  since <= Failsafe.serial then
             r = Multilingual.serial
             r = Failsafe.serial
         else
         else
             r = false
             r = false
Zeile 748: Zeile 1.404:
     end
     end
     return r
     return r
end -- Multilingual.failsafe()
end -- Failsafe.failsafe()




Zeile 760: Zeile 1.416:
     -- Format language code
     -- Format language code
     --    1  -- language code
     --    1  -- language code
     return Multilingual.fair( frame.args[ 1 ] )  or  ""
     local s = mw.text.trim( frame.args[ 1 ] or  "" )
    return Multilingual.fair( s )  or  ""
end -- p.fair
end -- p.fair


Zeile 769: Zeile 1.426:
     --    1  -- language version specifier to be supported
     --    1  -- language version specifier to be supported
     --    2  -- language specifier of a possible replacement
     --    2  -- language specifier of a possible replacement
     local r = Multilingual.fallback( frame.args[ 1 ], frame.args[ 2 ]  )
     local s1 = mw.text.trim( frame.args[ 1 ] or  "" )
     return r and "1" or ""
    local s2 = mw.text.trim( frame.args[ 2 ]  or  "" )
    local r  = Multilingual.fallback( s1, s2 )
    if type( r ) == "table" then
        r = r[ 1 ]
     else
        r = r and "1"   or   ""
    end
    return r
end -- p.fallback
end -- p.fallback


Zeile 778: Zeile 1.442:
     -- Retrieve language code from language name
     -- Retrieve language code from language name
     --    1  -- name in current project language
     --    1  -- name in current project language
     return Multilingual.findCode( frame.args[ 1 ] )  or  ""
     local s = mw.text.trim( frame.args[ 1 ] or  "" )
    return Multilingual.findCode( s )  or  ""
end -- p.findCode
end -- p.findCode
p.fix = function ( frame )
    local r = frame.args[ 1 ]
    if r then
        r = Multilingual.fix( mw.text.trim( r ) )
    end
    return r or ""
end -- p.fix




Zeile 819: Zeile 1.494:
     -- Retrieve base language from possibly combined ISO language code
     -- Retrieve base language from possibly combined ISO language code
     --    1  -- code
     --    1  -- code
     return Multilingual.getBase( frame.args[ 1 ] )  or  ""
     local s = mw.text.trim( frame.args[ 1 ] or  "" )
    return Multilingual.getBase( s )  or  ""
end -- p.getBase
end -- p.getBase


Zeile 831: Zeile 1.507:
     --          * -- native
     --          * -- native
     --          any valid code
     --          any valid code
    local s    = mw.text.trim( frame.args[ 1 ]  or  "" )
     local slang = frame.args[ 2 ]
     local slang = frame.args[ 2 ]
     local r
     local r
    Multilingual.frame = frame
     if slang then
     if slang then
         slang = mw.text.trim( slang )
         slang = mw.text.trim( slang )
     end
     end
     r = Multilingual.getName( frame.args[ 1 ], slang )
     r = Multilingual.getName( s, slang )
     return r or ""
     return r or ""
end -- p.getName
end -- p.getName
Zeile 888: Zeile 1.566:
     -- Could this be an ISO language code?
     -- Could this be an ISO language code?
     --    1  -- code
     --    1  -- code
     local lucky, r = pcall( Multilingual.isLang,
    local s = mw.text.trim( frame.args[ 1 ]  or  "" )
                            frame.args[ 1 ] )
     local lucky, r = pcall( Multilingual.isLang, s )
     return r and "1" or ""
     return r and "1" or ""
end -- p.isLang
end -- p.isLang
Zeile 898: Zeile 1.576:
     -- Could this be a Wiki language version?
     -- Could this be a Wiki language version?
     --    1  -- code
     --    1  -- code
     local lucky, r = pcall( Multilingual.isLangWiki,
    -- Returns non-empty, if possibly language version
                            frame.args[ 1 ] )
    local s = mw.text.trim( frame.args[ 1 ]  or  "" )
     local lucky, r = pcall( Multilingual.isLangWiki, s )
     return r and "1" or ""
     return r and "1" or ""
end -- p.isLangWiki
end -- p.isLangWiki
Zeile 905: Zeile 1.584:




p.kannDeutsch = function ( frame )
p.isRTL = function ( frame )
     -- Kann man mit diesem Sprachcode deutsch verstehen?
     -- Check whether language is written right-to-left
     --    1  -- code
     --    1  -- string, with language code
     local r = Multilingual.fallback( frame.args[ 1 ], "de" )
    -- Returns non-empty, if right-to-left
     return r and "1" or ""
     local s = mw.text.trim( frame.args[ 1 ] or  "" )
end -- p.kannDeutsch
     return Multilingual.isRTL( s ) and "1" or ""
end -- p.isRTL()
 
 
 
p.message = function ( frame )
    -- Translation of text element
    return Multilingual.message( fold( frame ), frame )
end -- p.message
 
 
 
p.sitelink = function ( frame )
    -- Make link at local or other site with optimal linktext translation
    --    1  -- item ID
    local s = mw.text.trim( frame.args[ 1 ]  or  "" )
    local r
    if s:match( "^%d+$") then
        r = tonumber( s )
    elseif s:match( "^Q%d+$") then
        r = s
    end
    if r then
        r = Multilingual.sitelink( r, frame )
    end
    return r or s
end -- p.sitelink
 
 
 
p.tabData = function ( frame )
    -- Retrieve best message text from Commons Data
    --    1    -- page identification on Commons
    --    2    -- keyword
    --    alt  -- fallback text
    local suite = frame.args[ 1 ]
    local seek  = frame.args[ 2 ]
    local salt  = frame.args.alt
    local r    = Multilingual.tabData( suite, seek, salt, frame )
    return r
end -- p.tabData




Zeile 917: Zeile 1.636:
     -- Which language does the current user prefer?
     -- Which language does the current user prefer?
     --    1  -- space separated list of available ISO 639 codes
     --    1  -- space separated list of available ISO 639 codes
  return Multilingual.userLang( frame.args[ 1 ], frame )
    local s = mw.text.trim( frame.args[ 1 ] or  "" )
    return Multilingual.userLang( s, frame )
end -- p.userLang
end -- p.userLang
p.wikibase = function ( frame )
    -- Optimal translation of wikibase component
    --    1  -- object ID
    --    2  -- 1 for "descriptions", 0 for "labels".
    --          or either "descriptions" or "labels"
    local r
    local s = mw.text.trim( frame.args[ 1 ]  or  "" )
    if s ~= "" then
        local s2    = mw.text.trim( frame.args[ 2 ]  or  "0" )
        local slang = mw.text.trim( frame.args.lang  or  "" )
        local large = ( s2 ~= ""  and  s2 ~= "0" )
        if slang == "" then
            slang = false
        end
        r = Multilingual.wikibase( s, large, slang, frame )
    end
    return r or ""
end -- p.wikibase




Zeile 937: Zeile 1.678:
         end
         end
     end
     end
     return Multilingual.failsafe( since )  or  ""
     return Failsafe.failsafe( since )  or  ""
end -- p.failsafe()
end -- p.failsafe()


Anonymer Benutzer