Modul:Multilingual: Unterschied zwischen den Versionen

K
43 Versionen von wikivoyage:Modul:Multilingual importiert
w>PerfektesChaos
(2019-11-01)
K (43 Versionen von wikivoyage:Modul:Multilingual importiert)
 
(10 dazwischenliegende Versionen von 4 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
local Multilingual = { suite  = "Multilingual",
local Multilingual = { suite  = "Multilingual",
                       serial  = "2019-11-01",
                       serial  = "2020-12-10",
                       item    = 47541920,
                       item    = 47541920,
                       globals = { ISO15924 = 71584769,
                       globals = { ISO15924 = 71584769,
                                   WLink    = 19363224 }
                                   WLink    = 19363224 }
                     }
                     }
local Failsafe  = Multilingual
--[=[
local GlobalMod = Multilingual
Utilities for multilingual texts and ISO 639 (BCP47) issues etc.
local User     = { sniffer = "showpreview" }
* 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
Multilingual.globals.Multilingual = Multilingual.item






Multilingual.correction = { -- Frequently mistaken language code
      aze      = "az",
      cz        = "cs",
      deu      = "de",
      dk        = "da",
      ["en-UK"] = "en-GB",
      ["en-uk"] = "en-GB",
      eng      = "en",
      ger      = "de",
      gr        = "el",
      ["in"]    = "id",
      iw        = "he",
      jp        = "ja",
      lat      = "la",
      se        = "sv",
      tj        = "tg"
    }
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 }




Zeile 44: Zeile 63:
     -- Postcondition:
     -- Postcondition:
     --    Returns whatever, probably table
     --    Returns whatever, probably table
     -- 2019-10-29
     -- 2020-01-01
     local storage = access
     local storage = access
     local finer = function ()
     local finer = function ()
Zeile 79: Zeile 98:
         end
         end
         if not lucky and alert then
         if not lucky and alert then
             error( "Missing or invalid page: " .. storage, 0 )
             error( "Missing or invalid page: " .. storage )
         end
         end
     end
     end
     return r
     return r
end -- foreignModule()
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()




Zeile 98: Zeile 187:
     --    * en
     --    * en
     local r = Multilingual.polyglott
     local r = Multilingual.polyglott
    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
     if not r then
     if not r then
         local self = mw.language.getContentLanguage():getCode():lower()
         local self = mw.language.getContentLanguage():getCode():lower()
         local sub  = mw.title.getCurrentTitle().subpageText
         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 = { }
         r = { }
         if sub:find( "/", 2, true ) then
         if sub:find( "/", 2, true ) then
Zeile 119: Zeile 208:
                 table.insert( r, sub )
                 table.insert( r, sub )
             end
             end
        elseif sub:find( "^%l%l%l?%-?%a?%a?%a?%a?$" )  and
              mw.language.isSupportedLanguage( sub ) then
            table.insert( r, sub )
         end
         end
         f( self )
         f( self )
Zeile 167: Zeile 259:
     if not got  and  got ~= false then
     if not got  and  got ~= false then
         local global = Multilingual.globals[ access ]
         local global = Multilingual.globals[ access ]
         got = foreignModule( access, not append, append, global )
        local lib    = ( not append  or  append == "config" )
         got = foreignModule( access, lib, append, global )
         if type( got ) == "table" then
         if type( got ) == "table" then
             if not append then
             if lib then
                 local startup = got[ access ]
                 local startup = got[ access ]
                 if type( startup ) == "function" then
                 if type( startup ) == "function" then
Zeile 182: Zeile 275:
     return got
     return got
end -- fetch()
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
        Multilingual.iso639[ access ] = r
    end
    return r or { }
end -- fetchISO639()




Zeile 205: Zeile 334:
         local f, lucky, s
         local f, lucky, s
         Multilingual.tmplLang = template
         Multilingual.tmplLang = template
         if type( source ) ~= "string" then
         if type( source ) ~= "string" and
            if type( template.namePat ) == "string"  and
          type( template.namePat ) == "string"  and
              template.namePat:find( "%s", 1, true ) then
          template.namePat:find( "%s", 1, true ) then
                source = string.format( template.namePat, access )
            source = string.format( template.namePat, access )
            end
         end
         end
         if type( source ) == "string" then
         if type( source ) == "string" then
Zeile 307: 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 367: 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 431: Zeile 603:
     -- Postcondition:
     -- Postcondition:
     --    Returns string with correction, or false if no problem known
     --    Returns string with correction, or false if no problem known
     return Multilingual.correction[ attempt:lower() ] or false
     local r = fetchISO639( "correction" )[ attempt:lower() ]
    return r or false
end -- Multilingual.fix()
end -- Multilingual.fix()


Zeile 740: Zeile 913:
     return r
     return r
end -- Multilingual.getName()
end -- Multilingual.getName()
Multilingual.getScriptName = function ( assigned, alien, add )
    -- Retrieve script name, hopefully linked
    -- Precondition:
    --    assigned  -- string, with ISO 15924 script code
    --    alien    -- string, with ISO language code, or not
    --    add      -- arbitrary additional information
    -- Postcondition:
    --    Returns string
    local bib = fetch( "ISO15924" )
    local r
    if bib  and
      type( bib.getScriptName ) == "function" then
        r = bib.getScriptName( assigned, alien, add )
    end
    return r or ""
end -- Multilingual.getScriptName()




Zeile 766: Zeile 920:
     -- Precondition:
     -- Precondition:
     --    available  -- table, with mapping language code ./. text
     --    available  -- table, with mapping language code ./. text
     --    alt        -- string|nil|false, with fallback
     --    alt        -- string|nil|false, with fallback text
     --    frame      -- frame, if available
     --    frame      -- frame, if available
     --    Returns
     --    Returns
Zeile 883: 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" )
         local cnf = fetch( "Multilingual", "config" )
Zeile 908: Zeile 1.062:




Multilingual.isTrans = function ( ask, assign, about )
Multilingual.isRTL = function ( ask )
     -- Check whether valid transcription for context
     -- Check whether language is written right-to-left
     -- Precondition:
     -- Precondition:
     --    ask     -- string, with transcription key
     --    ask  -- string, with language (or script) code
    --    assign -- string, with language or scripting code
     -- Returns true, if right-to-left
     --     about  -- string or nil, with site scripting code
    -- Postcondition:
    --     Returns boolean
    local bib = fetch( "ISO15924" )
     local r
     local r
     if type( bib ) == "table"  and
    Multilingual.rtl = Multilingual.rtl or { }
      type( bib.isTrans ) == "function" then
    r = Multilingual.rtl[ ask ]
         r = bib.isTrans( ask, assign, about )
     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
     end
     return r or false
     return r
end -- Multilingual.isTrans()
end -- Multilingual.isRTL()




Zeile 937: Zeile 1.095:
     if type( arglist ) == "table" then
     if type( arglist ) == "table" then
         local t = { }
         local t = { }
         local m, p
         local m, p, save
         for k, v in pairs( arglist ) do
         for k, v in pairs( arglist ) do
             if type( k ) == "string"  and
             if type( k ) == "string"  and
Zeile 956: Zeile 1.114:
             end
             end
         end -- for k, v
         end -- for k, v
         r = Multilingual.i18n( t, nil, frame )
        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
         if p  and  r  and  r:find( "$", 1, true ) then
             t = { }
             t = { }
Zeile 1.011: Zeile 1.172:
     return r  or  ""
     return r  or  ""
end -- Multilingual.sitelink()
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 1.093: Zeile 1.312:
     --    frame    -- frame, if available
     --    frame    -- frame, if available
     -- Postcondition:
     -- Postcondition:
     --    Returns string with appropriate code
     --    Returns
    --        1. string, with selected message
    --        2. string, with language code, or not
     local s = type( all )
     local s = type( all )
     local object, r
     local object, r, r2
     if s == "table" then
     if s == "table" then
         object = all
         object = all
Zeile 1.102: Zeile 1.323:
     end
     end
     if type( object ) == "table" then
     if type( object ) == "table" then
         if about then
         if about and  about ~= "labels" then
             s = "descriptions"
             s = "descriptions"
         else
         else
Zeile 1.110: Zeile 1.331:
         if type( object ) == "table" then
         if type( object ) == "table" then
             if object[ attempt ] then
             if object[ attempt ] then
                 r = object[ attempt ].value
                 r = object[ attempt ].value
                r2 = attempt
             else
             else
                 local poly
                 local poly
Zeile 1.118: Zeile 1.340:
                 end -- for k, v
                 end -- for k, v
                 if poly then
                 if poly then
                     r = Multilingual.i18n( poly, nil, frame )
                     r, r2 = Multilingual.i18n( poly, nil, frame )
                 end
                 end
             end
             end
         end
         end
     end
     end
     return r  or  ""
     return r  or  "",  r2
end -- Multilingual.wikibase()
end -- Multilingual.wikibase()


Zeile 1.131: Zeile 1.353:
     -- Retrieve versioning and check for compliance
     -- Retrieve versioning and check for compliance
     -- Precondition:
     -- Precondition:
     --    atleast  -- string, with required version or "wikidata" or "~"
     --    atleast  -- string, with required version
     --                 or false
     --                         or wikidata|item|~|@ or false
     -- Postcondition:
     -- Postcondition:
     --    Returns  string  -- with queried version, also if problem
     --    Returns  string  -- with queried version/item, also if problem
     --              false  -- if appropriate
     --              false  -- if appropriate
     -- 2019-10-15
     -- 2020-08-17
    local last  = ( atleast == "~" )
     local since = atleast
     local since = atleast
    local last    = ( since == "~" )
    local linked  = ( since == "@" )
    local link    = ( since == "item" )
     local r
     local r
     if last  or  since == "wikidata" then
     if last or  link  or  linked or  since == "wikidata" then
         local item = Failsafe.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 seek = Failsafe.serialProperty or "P348"
            else
                local vsn  = entity:formatPropertyValues( seek )
                local entity = mw.wikibase.getEntity( suited )
                if type( vsn ) == "table"  and
                if type( entity ) == "table" then
                  type( vsn.value ) == "string"  and
                    local seek = Failsafe.serialProperty or "P348"
                  vsn.value ~= "" then
                    local vsn  = entity:formatPropertyValues( seek )
                    if last  and  vsn.value == Failsafe.serial then
                    if type( vsn ) == "table"  and
                         r = false
                      type( vsn.value ) == "string"  and
                    else
                      vsn.value ~= "" then
                         r = vsn.value
                        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
Zeile 1.191: 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 s1   = mw.text.trim( frame.args[ 1 ]  or  "" )
     local s1 = mw.text.trim( frame.args[ 1 ]  or  "" )
     local s2   = mw.text.trim( frame.args[ 2 ]  or  "" )
     local s2 = mw.text.trim( frame.args[ 2 ]  or  "" )
     return Multilingual.fallback( s1, s2 )  and  "1"  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 1.276: Zeile 1.517:
     return r or ""
     return r or ""
end -- p.getName
end -- p.getName
p.getScriptName = function ( frame )
    -- OBSOLETE
    -- Retrieve script name from ISO 15924 script code, hopefully linked
    --    1  -- code
    --    2  -- optional additional key
    local s1 = mw.text.trim( frame.args[ 1 ]  or  "????" )
    local s2 = frame.args[ 2 ]
    if s2 then
        s2 = mw.text.trim( s2 )
    end
    return Multilingual.getScriptName( s1, false, s2 )
end -- p.getScriptName




Zeile 1.350: Zeile 1.576:
     -- Could this be a Wiki language version?
     -- Could this be a Wiki language version?
     --    1  -- code
     --    1  -- code
    -- Returns non-empty, if possibly language version
     local s = mw.text.trim( frame.args[ 1 ]  or  "" )
     local s = mw.text.trim( frame.args[ 1 ]  or  "" )
     local lucky, r = pcall( Multilingual.isLangWiki, s )
     local lucky, r = pcall( Multilingual.isLangWiki, s )
Zeile 1.357: Zeile 1.584:




p.isTrans = function ( frame )
p.isRTL = function ( frame )
    -- OBSOLETE
     -- Check whether language is written right-to-left
     -- Check whether valid transcription for context
     --    -- string, with language code
    --     1    -- string, with transcription key
     -- Returns non-empty, if right-to-left
     --    2    -- string, with language or scripting code
     local s = mw.text.trim( frame.args[ 1 ]  or  "" )
     --     site  -- string or nil, with site scripting code
     return Multilingual.isRTL( s ) and "1" or ""
     local s1  = mw.text.trim( frame.args[ 1 ] or  "" )
end -- p.isRTL()
    local s2  = mw.text.trim( frame.args[ 2 ]  or  "" )
    local site = mw.text.trim( frame.args.site or  "" )
     return Multilingual.isTrans( s1, s2, site ) and "1"   or   ""
end -- p.isTrans




Zeile 1.393: Zeile 1.616:
     return r or s
     return r or s
end -- p.sitelink
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 1.408: Zeile 1.645:
     -- Optimal translation of wikibase component
     -- Optimal translation of wikibase component
     --    1  -- object ID
     --    1  -- object ID
     --    2  -- either "descriptions" or "labels"
     --    2  -- 1 for "descriptions", 0 for "labels".
    --          or either "descriptions" or "labels"
     local r
     local r
     local s = mw.text.trim( frame.args[ 1 ]  or  "" )
     local s = mw.text.trim( frame.args[ 1 ]  or  "" )