|
|
Zeile 1: |
Zeile 1: |
| local Multilingual = { suite = "Multilingual",
| | --[=[ 2014-10-16 |
| serial = "2020-12-10",
| | Multilingual |
| item = 47541920,
| |
| 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
| |
|
| |
|
|
| |
|
|
| |
|
| Multilingual.exotic = { simple = true, | | local Multilingual = { } |
| no = true }
| | local Frame |
| Multilingual.prefer = { cs = true,
| | local Got = { } |
| de = true,
| | local SelfLang |
| en = true,
| |
| es = true,
| |
| fr = true,
| |
| it = true,
| |
| nl = true,
| |
| pt = true,
| |
| ru = true,
| |
| sv = true }
| |
|
| |
|
|
| |
|
|
| |
|
| local foreignModule = function ( access, advanced, append, alt, alert )
| | local fetch = function ( access, allow ) |
| -- 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:
| |
| -- Returns table with sequence of preferred languages
| |
| -- * ahead elements
| |
| -- * user (not yet accessible)
| |
| -- * 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
| |
| return r
| |
| end -- favorites()
| |
| | |
| | |
| | |
| local feasible = function ( ask, accept )
| |
| -- Is ask to be supported by application?
| |
| -- Precondition:
| |
| -- ask -- lowercase code
| |
| -- accept -- sequence table, with offered lowercase codes
| |
| -- Postcondition:
| |
| -- nil, or true
| |
| local r
| |
| for i = 1, #accept do
| |
| if accept[ i ] == ask then
| |
| r = true
| |
| break -- for i
| |
| end
| |
| end -- for i
| |
| return r
| |
| end -- feasible()
| |
| | |
| | |
| | |
| local fetch = function ( access, append ) | |
| -- Attach config or library module | | -- Attach config or library module |
| -- Precondition: | | -- Precondition: |
| -- access -- module title | | -- access -- module title |
| -- append -- string, with subpage part of this; or false | | -- allow -- permit non-existence |
| -- Postcondition: | | -- Postcondition: |
| -- Returns: table, with library, or false | | -- Returns table or false, with library |
| local got, sign | | -- Throws error, if not available |
| if append then | | if Got[ access ] == false then |
| sign = string.format( "%s/%s", access, append )
| | elseif not Got[ access ] then |
| else
| | local lucky, got = pcall( require, "Module:" .. access ) |
| sign = access
| | if lucky then |
| end
| | if type( got ) == "table" then |
| if type( Multilingual.ext ) ~= "table" then
| | Got[ access ] = got |
| Multilingual.ext = { }
| | if type( got[ access ] ) == "function" then |
| end
| | Got[ access ] = got[ access ]() |
| got = Multilingual.ext[ sign ]
| |
| if not got and got ~= false then | |
| local global = Multilingual.globals[ access ]
| |
| local lib = ( not append or append == "config" ) | |
| got = foreignModule( access, lib, append, global ) | |
| if type( got ) == "table" then
| |
| if lib then
| |
| local startup = got[ access ] | |
| if type( startup ) == "function" then | |
| got = startup() | |
| end | | end |
| end | | end |
| else | | got = "Module" .. access .. " invalid" |
| got = false | | end |
| | if type( Got[ access ] ) ~= "table" then |
| | error( got, 0 ) |
| end | | end |
| Multilingual.ext[ sign ] = got
| |
| end | | end |
| return got | | return Got[ access ] |
| end -- fetch() | | end -- fetch() |
|
| |
|
|
| |
|
|
| |
|
| local fetchISO639 = function ( access )
| | function isSupported( ask, accept ) |
| -- Retrieve table from commons:Data:ISO639/***.tab | | -- Is ask to supported by application? |
| -- Precondition: | | -- Precondition: |
| -- access -- string, with subpage identification | | -- ask -- lowercase code |
| -- Postcondition:
| | -- accept -- space separated/terminated list of lowercase codes |
| -- 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()
| |
| | |
| | |
| | |
| 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
| |
| return r
| |
| end -- fill()
| |
| | |
| | |
| | |
| local find = function ( ask, alien )
| |
| -- Derive language code from name | |
| -- Precondition:
| |
| -- ask -- language name, downcased
| |
| -- alien -- language code of ask | |
| -- Postcondition:
| |
| -- nil, or string
| |
| local codes = mw.language.fetchLanguageNames( alien, "all" )
| |
| local r
| |
| for k, v in pairs( codes ) do
| |
| if mw.ustring.lower( v ) == ask then
| |
| r = k
| |
| break -- for k, v
| |
| end
| |
| end -- for k, v
| |
| if not r then
| |
| r = Multilingual.fair( ask )
| |
| end
| |
| return r
| |
| end -- find()
| |
| | |
| | |
| | |
| local fold = function ( frame )
| |
| -- Merge template and #invoke arglist
| |
| -- Precondition:
| |
| -- frame -- template frame
| |
| -- Postcondition: | | -- Postcondition: |
| -- table, with combined arglist | | -- nil, or else |
| local r = { }
| | local seek = string.format( " %s ", ask ) |
| local f = function ( apply ) | | local supported = string.format( " %s", accept ) |
| if type( apply ) == "table" and
| | return supported:find( seek, 1, true ) |
| type( apply.args ) == "table" then
| | end -- isSupported() |
| 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()
| |
| | |
| | |
| | |
| User.favorize = function ( accept, frame )
| |
| -- Guess user language
| |
| -- Precondition:
| |
| -- accept -- sequence table, with offered ISO 639 etc. codes
| |
| -- frame -- frame, if available
| |
| -- Postcondition:
| |
| -- Returns string with best code, or nil
| |
| if not ( User.self or User.langs ) then
| |
| if not User.trials then
| |
| User.tell = mw.message.new( User.sniffer )
| |
| if User.tell:exists() then
| |
| User.trials = { }
| |
| if not Multilingual.frame then
| |
| if frame then
| |
| Multilingual.frame = frame
| |
| else
| |
| Multilingual.frame = mw.getCurrentFrame()
| |
| end
| |
| end
| |
| User.sin = Multilingual.frame:callParserFunction( "int",
| |
| User.sniffer )
| |
| else
| |
| User.langs = true
| |
| end
| |
| end
| |
| if User.sin then
| |
| local order = { }
| |
| local post = { }
| |
| local three = { }
| |
| local unfold = { }
| |
| local s, sin
| |
| for i = 1, #accept do
| |
| s = accept[ i ]
| |
| if not User.trials[ s ] then
| |
| if #s > 2 then
| |
| if s:find( "-", 3, true ) then
| |
| table.insert( unfold, s )
| |
| else
| |
| table.insert( three, s )
| |
| end
| |
| else
| |
| if Multilingual.prefer[ s ] then
| |
| table.insert( order, s )
| |
| else
| |
| table.insert( post, s )
| |
| 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 -- for i
| |
| end
| |
| end
| |
| return User.self
| |
| end -- User.favorize()
| |
| | |
| | |
| | |
| Multilingual.fair = function ( ask )
| |
| -- Format language specification according to RFC 5646 etc.
| |
| -- Precondition:
| |
| -- ask -- string or table, as created by .getLang()
| |
| -- Postcondition:
| |
| -- Returns string, or false
| |
| local s = type( ask )
| |
| local q, r | |
| if s == "table" then
| |
| q = ask
| |
| elseif s == "string" then
| |
| q = Multilingual.getLang( ask )
| |
| end
| |
| if q and
| |
| q.legal and
| |
| mw.language.isKnownLanguageTag( q.base ) then
| |
| r = q.base
| |
| if q.n > 1 then
| |
| local order = { "extlang",
| |
| "script",
| |
| "region",
| |
| "other",
| |
| "extension" }
| |
| for i = 1, #order do
| |
| s = q[ order[ i ] ]
| |
| if s then
| |
| r = string.format( "%s-%s", r, s )
| |
| end
| |
| end -- for i
| |
| end
| |
| end
| |
| return r or false | |
| end -- Multilingual.fair()
| |
| | |
| | |
| | |
| Multilingual.fallback = function ( able, another )
| |
| -- Is another language suitable as replacement?
| |
| -- Precondition:
| |
| -- able -- language version specifier to be supported
| |
| -- another -- language specifier of a possible replacement,
| |
| -- or not to retrieve a fallback table
| |
| -- Postcondition:
| |
| -- Returns boolean, or table with fallback codes
| |
| local r
| |
| if type( able ) == "string" and #able > 0 then
| |
| if type( another ) == "string" and #another > 0 then
| |
| if able == another then
| |
| 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
| |
| local s = Multilingual.getBase( able )
| |
| if s then
| |
| r = mw.language.getFallbacksFor( s )
| |
| if r[ 1 ] == "en" then
| |
| local d = fetchISO639( "fallback" )
| |
| 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
| |
| return r or false
| |
| end -- Multilingual.fallback() | |
|
| |
|
|
| |
|
|
| |
|
| Multilingual.findCode = function ( ask ) | | Multilingual.findCode = function ( ask ) |
| -- Retrieve code of local (current project or English) language name | | -- Retrieve code of local (current project) language name |
| -- Precondition: | | -- Precondition: |
| -- ask -- string, with presumable language name | | -- ask -- string, with presumable language name |
Zeile 573: |
Zeile 66: |
| if #seek > 1 then | | if #seek > 1 then |
| if seek:find( "[", 1, true ) then | | if seek:find( "[", 1, true ) then |
| local wlink = fetch( "WLink" ) | | seek = fetch( "WLink" ).getPlain( seek ) |
| 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 ) |
| if Multilingual.isLang( seek ) then | | if Multilingual.isLang( seek ) then |
| r = Multilingual.fair( seek ) | | r = seek |
| else | | else |
| local collection = favorites() | | local codes |
| for i = 1, #collection do | | if not SelfLang then |
| r = find( seek, collection[ i ] ) | | SelfLang = mw.language.getContentLanguage():getCode() |
| if r then
| | end |
| break -- for i | | codes = mw.language.fetchLanguageNames( SelfLang, "all" ) |
| | for k, v in pairs( codes ) do |
| | if mw.ustring.lower( v ) == seek then |
| | r = k |
| | break -- for k, v |
| end | | end |
| end -- for i | | end -- for k, v |
| 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 617: |
Zeile 98: |
| -- -- nil, false, "*": native | | -- -- nil, false, "*": native |
| -- -- "!": current project | | -- -- "!": current project |
| -- -- "#": code, downcased, space separated
| |
| -- -- "-": code, mixcase, space separated
| |
| -- -- any valid code | | -- -- any valid code |
| -- alter -- capitalize, if "c"; downcase all, if "d" | | -- alter -- capitalize, if "c"; downcase, if "d" |
| -- capitalize first item only, if "f" | | -- capitalize first item only, if "f" |
| -- downcase every first word only, if "m"
| |
| -- active -- link items, if true | | -- active -- link items, if true |
| -- alert -- string with category title in case of error | | -- alert -- string with category title in case of error |
Zeile 630: |
Zeile 108: |
| -- ahead -- string to prepend first element, if any | | -- ahead -- string to prepend first element, if any |
| -- Postcondition: | | -- Postcondition: |
| -- Returns string, or false if apply empty | | -- Returns string, or false |
| local r = false | | local r = false |
| if apply then | | if apply then |
Zeile 640: |
Zeile 118: |
| if adjacent then | | if adjacent then |
| separator = adjacent | | separator = adjacent |
| elseif alien == "#" or alien == "-" then
| |
| separator = " "
| |
| else | | else |
| separator = assembly | | separator = assembly |
Zeile 671: |
Zeile 147: |
| slang = Multilingual.findCode( single ) | | slang = Multilingual.findCode( single ) |
| if slang then | | if slang then |
| if alien == "-" then | | r = Multilingual.getName( slang, alien ) |
| r = slang
| | if active then |
| elseif alien == "#" then | | local cnf = fetch( "Multilingual/config", true ) |
| r = slang:lower() | | if cnf then |
| else
| | if not frame then |
| r = Multilingual.getName( slang, alien )
| | if not Frame then |
| if active then
| | Frame = mw.getCurrentFrame() |
| slot = fill( slang, false, frame ) | | end |
| | frame = Frame |
| | end |
| | slot = cnf.getLink( slang, frame ) |
| if slot then | | if slot then |
| local wlink = fetch( "WLink" ) | | slot = fetch( "WLink" ).getTarget( slot ) |
| if wlink and
| |
| type( wlink.getTarget )
| |
| == "function" then
| |
| slot = wlink.getTarget( slot )
| |
| end
| |
| else | | else |
| lapsus = alert | | lapsus = alert |
Zeile 701: |
Zeile 175: |
| lapsus = alert | | lapsus = alert |
| end | | end |
| if not r then | | if alter == "c" or alter == "f" then |
| r = single
| |
| elseif alter == "c" or alter == "f" then
| |
| r = mw.ustring.upper( mw.ustring.sub( r, 1, 1 ) ) | | r = mw.ustring.upper( mw.ustring.sub( r, 1, 1 ) ) |
| .. mw.ustring.sub( r, 2 ) | | .. mw.ustring.sub( r, 2 ) |
| elseif alter == "d" then | | elseif alter == "d" then |
| if Multilingual.isMinusculable( slang, r ) then | | r = mw.ustring.lower( r ) |
| r = mw.ustring.lower( r )
| |
| end
| |
| elseif alter == "m" then
| |
| if Multilingual.isMinusculable( slang, r ) then
| |
| r = mw.ustring.lower( mw.ustring.sub( r, 1, 1 ) )
| |
| .. mw.ustring.sub( r, 2 )
| |
| end
| |
| end | | end |
| if slot then | | if slot then |
Zeile 723: |
Zeile 188: |
| end | | end |
| end | | end |
| if lapsus and alert then | | if lapsus then |
| r = string.format( "%s[[Category:%s]]", r, alert ) | | r = string.format( "%s[[Category:%s]]", r, alert ) |
| end | | end |
Zeile 753: |
Zeile 218: |
| return r | | return r |
| end -- Multilingual.getBase() | | end -- Multilingual.getBase() |
|
| |
|
| |
|
| |
| Multilingual.getLang = function ( ask )
| |
| -- Retrieve components of a RFC 5646 language code
| |
| -- Precondition:
| |
| -- ask -- language code with subtags
| |
| -- Postcondition:
| |
| -- Returns table with formatted subtags
| |
| -- .base
| |
| -- .region
| |
| -- .script
| |
| -- .suggest
| |
| -- .year
| |
| -- .extension
| |
| -- .other
| |
| -- .n
| |
| local tags = mw.text.split( ask, "-" )
| |
| local s = tags[ 1 ]
| |
| local r
| |
| if s:match( "^%a%a%a?$" ) then
| |
| r = { base = s:lower(),
| |
| legal = true,
| |
| n = #tags }
| |
| for i = 2, r.n do
| |
| s = tags[ i ]
| |
| if #s == 2 then
| |
| if r.region or not s:match( "%a%a" ) then
| |
| r.legal = false
| |
| else
| |
| r.region = s:upper()
| |
| end
| |
| elseif #s == 4 then
| |
| if s:match( "%a%a%a%a" ) then
| |
| r.legal = ( not r.script )
| |
| r.script = s:sub( 1, 1 ):upper() ..
| |
| s:sub( 2 ):lower()
| |
| elseif s:match( "20%d%d" ) or
| |
| s:match( "1%d%d%d" ) then
| |
| r.legal = ( not r.year )
| |
| r.year = s
| |
| else
| |
| r.legal = false
| |
| end
| |
| elseif #s == 3 then
| |
| if r.extlang or not s:match( "%a%a%a" ) then
| |
| r.legal = false
| |
| else
| |
| r.extlang = s:lower()
| |
| end
| |
| elseif #s == 1 then
| |
| s = s:lower()
| |
| if s:match( "[tux]" ) then
| |
| r.extension = s
| |
| for k = i + 1, r.n do
| |
| s = tags[ k ]
| |
| if s:match( "^%w+$" ) then
| |
| r.extension = string.format( "%s-%s",
| |
| r.extension, s )
| |
| else
| |
| r.legal = false
| |
| end
| |
| end -- for k
| |
| else
| |
| r.legal = false
| |
| end
| |
| break -- for i
| |
| else
| |
| r.legal = ( not r.other ) and
| |
| s:match( "%a%a%a" )
| |
| r.other = s:lower()
| |
| end
| |
| if not r.legal then
| |
| break -- for i
| |
| end
| |
| end -- for i
| |
| if r.legal then
| |
| r.suggest = Multilingual.fix( r.base )
| |
| if r.suggest then
| |
| r.legal = false
| |
| end
| |
| end
| |
| else
| |
| 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
| |
| return r
| |
| end -- Multilingual.getLang()
| |
|
| |
|
|
| |
|
Zeile 861: |
Zeile 233: |
| local r | | local r |
| if ask then | | if ask then |
| local slang = alien | | local slang = alien |
| local tLang
| |
| if slang then | | if slang then |
| if slang == "*" then | | if slang == "*" then |
| slang = Multilingual.fair( ask ) | | slang = nil |
| elseif slang == "!" then | | elseif slang == "!" then |
| slang = favorites()[ 1 ] | | if not SelfLang then |
| | SelfLang = mw.language.getContentLanguage():getCode() |
| | end |
| | slang = SelfLang |
| else | | else |
| slang = Multilingual.fair( slang ) | | slang = slang:lower() |
| end
| |
| else
| |
| slang = Multilingual.fair( ask )
| |
| end
| |
| if not slang then
| |
| slang = ask or "?????"
| |
| end
| |
| slang = slang:lower()
| |
| tLang = fetch( "Multilingual", "names" )
| |
| if tLang then
| |
| tLang = tLang[ slang ]
| |
| if tLang then
| |
| r = tLang[ ask ]
| |
| end
| |
| end
| |
| if not r then
| |
| if not Multilingual.ext.tMW then
| |
| Multilingual.ext.tMW = { }
| |
| end
| |
| tLang = Multilingual.ext.tMW[ slang ]
| |
| if tLang == nil then
| |
| tLang = mw.language.fetchLanguageNames( slang )
| |
| if tLang then
| |
| Multilingual.ext.tMW[ slang ] = tLang
| |
| else
| |
| Multilingual.ext.tMW[ slang ] = false
| |
| end
| |
| end
| |
| if tLang then
| |
| r = tLang[ ask ]
| |
| end
| |
| end
| |
| if not r then
| |
| r = mw.language.fetchLanguageName( ask:lower(), slang )
| |
| if r == "" then
| |
| r = false
| |
| end | | end |
| end | | end |
| | r = mw.language.fetchLanguageName( ask, slang ) |
| else | | else |
| r = false | | r = false |
Zeile 916: |
Zeile 255: |
|
| |
|
|
| |
|
| Multilingual.i18n = function ( available, alt, frame )
| | Multilingual.isLang = function ( ask ) |
| -- 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()
| |
| | |
| | |
| | |
| Multilingual.int = function ( access, alien, apply )
| |
| -- Translated system message
| |
| -- Precondition:
| |
| -- access -- message ID
| |
| -- alien -- language code
| |
| -- apply -- nil, or sequence table with parameters $1, $2, ...
| |
| -- Postcondition:
| |
| -- Returns string, or false
| |
| local o = mw.message.new( access )
| |
| local r
| |
| if o:exists() then
| |
| if type( alien ) == "string" then
| |
| o:inLanguage( alien:lower() )
| |
| end
| |
| if type( apply ) == "table" then
| |
| o:params( apply )
| |
| end
| |
| r = o:plain()
| |
| end
| |
| return r or false
| |
| end -- Multilingual.int()
| |
| | |
| | |
| | |
| Multilingual.isLang = function ( ask, additional ) | |
| -- Could this be an ISO language code? | | -- Could this be an ISO language code? |
| -- Precondition: | | -- Precondition: |
| -- ask -- language code | | -- ask -- language code |
| -- additional -- true, if Wiki codes like "simple" permitted
| |
| -- Postcondition: | | -- Postcondition: |
| -- Returns boolean | | -- Returns boolean |
| local r, s | | local r |
| if additional then
| | local s = Multilingual.getBase( ask ) |
| s = ask
| |
| else | |
| s = Multilingual.getBase( ask )
| |
| end
| |
| if s then | | if s then |
| r = mw.language.isKnownLanguageTag( s ) | | r = mw.language.isKnownLanguageTag( s ) |
| if r then
| |
| r = not Multilingual.fix( s )
| |
| elseif additional then
| |
| r = Multilingual.exotic[ s ] or false
| |
| end
| |
| else | | else |
| r = false | | r = false |
Zeile 1.020: |
Zeile 282: |
| local s = Multilingual.getBase( ask ) | | local s = Multilingual.getBase( ask ) |
| if s then | | if s then |
| r = mw.language.isSupportedLanguage( s ) or | | r = mw.language.isSupportedLanguage( s ) |
| Multilingual.exotic[ ask ]
| |
| else | | else |
| r = false | | r = false |
Zeile 1.030: |
Zeile 291: |
|
| |
|
|
| |
|
| Multilingual.isMinusculable = function ( ask, assigned ) | | Multilingual.kannDeutsch = function ( ask ) |
| -- Could this language name become downcased? | | -- Kann man mit diesem Sprachcode deutsch verstehen? |
| -- Precondition: | | -- Precondition: |
| -- ask -- language code, or nil | | -- ask -- language version specifier |
| -- assigned -- language name, or nil
| |
| -- Postcondition: | | -- Postcondition: |
| -- Returns boolean | | -- Returns boolean |
| local r = true
| |
| if ask then
| |
| local cnf = fetch( "Multilingual", "config" )
| |
| if cnf then
| |
| local s = string.format( " %s ", ask:lower() )
| |
| if type( cnf.stopMinusculization ) == "string"
| |
| and cnf.stopMinusculization:find( s, 1, true ) then
| |
| r = false
| |
| end
| |
| if r and assigned
| |
| and type( cnf.seekMinusculization ) == "string"
| |
| and cnf.seekMinusculization:find( s, 1, true )
| |
| and type( cnf.scanMinusculization ) == "string" then
| |
| local scan = assigned:gsub( "[%(%)]", " " ) .. " "
| |
| if not scan:find( cnf.scanMinusculization ) then
| |
| r = false
| |
| end
| |
| end
| |
| end
| |
| end
| |
| return r
| |
| 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 | | local r |
| Multilingual.rtl = Multilingual.rtl or { } | | local s = Multilingual.getBase( ask ) |
| r = Multilingual.rtl[ ask ]
| | if s then |
| if type( r ) ~= "boolean" then | | local support = [=[ de als bar dsb frr gsw hsb ksh | |
| local bib = fetch( "ISO15924" ) | | lb nds pdc pdt pfl sli stq vmf ]=] |
| if type( bib ) == "table" and | | if support:find( string.format( " %s ", s ), 1, true ) then |
| type( bib.isRTL ) == "function" then
| | r = true |
| r = bib.isRTL( ask ) | |
| else | | else |
| r = mw.language.new( ask ):isRTL() | | r = false |
| end | | end |
| Multilingual.rtl[ ask ] = r | | else |
| | r = false |
| end | | end |
| return r | | return r |
| end -- Multilingual.isRTL() | | end -- Multilingual.kannDeutsch() |
| | |
| | |
| | |
| 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 1.236: |
Zeile 318: |
| -- Try to support user language by application | | -- Try to support user language by application |
| -- Precondition: | | -- Precondition: |
| -- accept -- string or table | | -- accept -- space separated list of available ISO 639 codes |
| -- 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 |
| -- Postcondition: | | -- Postcondition: |
| -- Returns string with appropriate code | | -- Returns string with appropriate code |
| local s = type( accept ) | | local r, slang, support |
| local codes, r, slang
| | if not frame then |
| if s == "string" then | | frame = mw.getCurrentFrame() |
| codes = mw.text.split( accept:lower(), "%s+" ) | | end |
| elseif s == "table" then | | slang = frame:callParserFunction( "int", "lang" ):lower() |
| codes = { } | | if type( accept ) == "string" then |
| for i = 1, #accept do | | support = accept:lower() .. " " |
| s = accept[ i ]
| | else |
| if type( s ) == "string" and
| | support = mw.language.getContentLanguage():getCode() |
| s ~= "" then
| | if mw.language.isKnownLanguageTag( support ) then |
| table.insert( codes, s:lower() )
| | support = string.format( "%s en ", support ) |
| end | | else |
| end -- for i | | support = "en " |
| | end |
| end | | end |
| slang = User.favorize( codes, frame ) | | if isSupported( slang, support ) then |
| if slang then
| | r = slang |
| if feasible( slang, codes ) then | | elseif slang:find( "-", 1, true ) then |
| | slang = Multilingual.getBase() |
| | if isSupported( slang, support ) 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 back = favorites() | | if Multilingual.kannDeutsch( slang ) and |
| for i = 1, #back do
| | isSupported( "de", support ) then |
| slang = back[ i ]
| | r = "de" |
| if feasible( slang, codes ) then
| |
| r = slang
| |
| break -- for i
| |
| end
| |
| end -- for i
| |
| if not r and codes[ 1 ] then
| |
| r = codes[ 1 ] | |
| end | | end |
| end
| | if not r then |
| return r or favorites()[ 1 ]
| | r = support:match( "^(%S+) " ) |
| end -- Multilingual.userLang()
| |
| | |
| | |
| | |
| Multilingual.userLangCode = function ()
| |
| -- Guess a user language code
| |
| -- Postcondition:
| |
| -- Returns code of current best guess
| |
| return User.self or favorites()[ 1 ]
| |
| end -- Multilingual.userLangCode()
| |
| | |
| | |
| | |
| 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
| |
| -- Precondition:
| |
| -- atleast -- string, with required version
| |
| -- or wikidata|item|~|@ or false
| |
| -- Postcondition:
| |
| -- Returns string -- with queried version/item, also if problem
| |
| -- false -- if appropriate
| |
| -- 2020-08-17
| |
| 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
| |
| end
| |
| end
| |
| if type( r ) == "nil" then
| |
| if not since or since <= Failsafe.serial then
| |
| r = Failsafe.serial
| |
| else
| |
| r = false
| |
| end | | end |
| end | | end |
| return r | | return r |
| end -- Failsafe.failsafe() | | end -- Multilingual.userLang() |
|
| |
|
|
| |
|
Zeile 1.410: |
Zeile 362: |
| -- Export | | -- Export |
| local p = { } | | local p = { } |
|
| |
|
| |
|
| |
| p.fair = function ( frame )
| |
| -- Format language code
| |
| -- 1 -- language code
| |
| local s = mw.text.trim( frame.args[ 1 ] or "" )
| |
| return Multilingual.fair( s ) or ""
| |
| end -- p.fair
| |
|
| |
|
| |
|
| |
| p.fallback = function ( frame )
| |
| -- Is another language suitable as replacement?
| |
| -- 1 -- language version specifier to be supported
| |
| -- 2 -- language specifier of a possible replacement
| |
| local s1 = mw.text.trim( frame.args[ 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
| |
|
| |
|
|
| |
|
Zeile 1.442: |
Zeile 368: |
| -- Retrieve language code from language name | | -- Retrieve language code from language name |
| -- 1 -- name in current project language | | -- 1 -- name in current project language |
| local s = mw.text.trim( frame.args[ 1 ] or "" ) | | return Multilingual.findCode( 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 1.470: |
Zeile 385: |
| -- scream -- category title in case of error | | -- scream -- category title in case of error |
| -- split -- split pattern, if list expected | | -- split -- split pattern, if list expected |
| -- separator -- list separator, else split | | -- separator -- list separator, else assembly |
| -- start -- prepend first element, if any | | -- start -- prepend first element, if any |
| local r | | local r |
Zeile 1.494: |
Zeile 409: |
| -- Retrieve base language from possibly combined ISO language code | | -- Retrieve base language from possibly combined ISO language code |
| -- 1 -- code | | -- 1 -- code |
| local s = mw.text.trim( frame.args[ 1 ] or "" ) | | return Multilingual.getBase( frame.args[ 1 ] ) or "" |
| return Multilingual.getBase( s ) or ""
| |
| end -- p.getBase | | end -- p.getBase |
|
| |
|
Zeile 1.507: |
Zeile 421: |
| -- * -- 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( s, slang ) | | r = Multilingual.getName( frame.args[ 1 ], slang ) |
| return r or "" | | return r or "" |
| end -- p.getName | | end -- p.getName |
|
| |
|
| |
|
| |
| p.int = function ( frame )
| |
| -- Translated system message
| |
| -- 1 -- message ID
| |
| -- lang -- language code
| |
| -- $1, $2, ... -- parameters
| |
| local sysMsg = frame.args[ 1 ]
| |
| local r
| |
| if sysMsg then
| |
| sysMsg = mw.text.trim( sysMsg )
| |
| if sysMsg ~= "" then
| |
| local n = 0
| |
| local slang = frame.args.lang
| |
| local i, params, s
| |
| if slang == "" then
| |
| slang = false
| |
| end
| |
| for k, v in pairs( frame.args ) do
| |
| if type( k ) == "string" then
| |
| s = k:match( "^%$(%d+)$" )
| |
| if s then
| |
| i = tonumber( s )
| |
| if i > n then
| |
| n = i
| |
| end
| |
| end
| |
| end
| |
| end -- for k, v
| |
| if n > 0 then
| |
| local s
| |
| params = { }
| |
| for i = 1, n do
| |
| s = frame.args[ "$" .. tostring( i ) ] or ""
| |
| table.insert( params, s )
| |
| end -- for i
| |
| end
| |
| r = Multilingual.int( sysMsg, slang, params )
| |
| end
| |
| end
| |
| return r or ""
| |
| end -- p.int
| |
|
| |
|
|
| |
|
Zeile 1.566: |
Zeile 435: |
| -- Could this be an ISO language code? | | -- Could this be an ISO language code? |
| -- 1 -- code | | -- 1 -- code |
| local s = mw.text.trim( frame.args[ 1 ] or "" )
| | local lucky, r = pcall( Multilingual.isLang, |
| local lucky, r = pcall( Multilingual.isLang, s ) | | frame.args[ 1 ] ) |
| return r and "1" or "" | | return r and "1" or "" |
| end -- p.isLang | | end -- p.isLang |
Zeile 1.576: |
Zeile 445: |
| -- 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 lucky, r = pcall( Multilingual.isLangWiki, |
| local s = mw.text.trim( frame.args[ 1 ] or "" )
| | frame.args[ 1 ] ) |
| local lucky, r = pcall( Multilingual.isLangWiki, s ) | |
| return r and "1" or "" | | return r and "1" or "" |
| end -- p.isLangWiki | | end -- p.isLangWiki |
Zeile 1.584: |
Zeile 452: |
|
| |
|
|
| |
|
| p.isRTL = function ( frame ) | | p.kannDeutsch = function ( frame ) |
| -- Check whether language is written right-to-left | | -- Kann man mit diesem Sprachcode deutsch verstehen? |
| -- 1 -- string, with language code | | -- 1 -- code |
| -- Returns non-empty, if right-to-left
| | local r = Multilingual.kannDeutsch( frame.args[ 1 ] ) |
| local s = mw.text.trim( frame.args[ 1 ] or "" ) | | return r and "1" or "" |
| return Multilingual.isRTL( s ) and "1" or "" | | end -- p.kannDeutsch |
| 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 1.636: |
Zeile 464: |
| -- 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 |
| local s = mw.text.trim( frame.args[ 1 ] or "" )
| | return Multilingual.userLang( frame.args[ 1 ], frame ) |
| 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
| |
|
| |
|
| |
|
| |
| 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()
| |
|
| |
|
|
| |
|