Modul:Multilingual: Unterschied zwischen den Versionen
te>PerfektesChaos (update) |
te>PerfektesChaos (2015-06-19) |
||
Zeile 1: | Zeile 1: | ||
− | + | local Multilingual = { suite = "Multilingual", | |
− | Multilingual | + | serial = "2015-06-19" }; |
− | |||
− | local | + | -- local globals |
local Frame | local Frame | ||
− | local | + | |
− | + | ||
+ | |||
+ | local favorite = function () | ||
+ | -- Postcondition: | ||
+ | -- Returns code of curent project language | ||
+ | if not Multilingual.self then | ||
+ | Multilingual.self = mw.language.getContentLanguage():getCode() | ||
+ | :lower() | ||
+ | end | ||
+ | return Multilingual.self | ||
+ | end -- favorite() | ||
Zeile 20: | Zeile 29: | ||
-- Returns table or false, with library | -- Returns table or false, with library | ||
-- Throws error, if not available | -- Throws error, if not available | ||
− | if | + | if type( Multilingual.ext ) ~= "table" then |
− | elseif not | + | Multilingual.ext = { } |
+ | end | ||
+ | if Multilingual.ext[ access ] == false then | ||
+ | elseif not Multilingual.ext[ access ] then | ||
local lucky, got = pcall( require, "Module:" .. access ) | local lucky, got = pcall( require, "Module:" .. access ) | ||
if lucky then | if lucky then | ||
if type( got ) == "table" then | if type( got ) == "table" then | ||
− | + | Multilingual.ext[ access ] = got | |
if type( got[ access ] ) == "function" then | if type( got[ access ] ) == "function" then | ||
− | + | Multilingual.ext[ access ] = got[ access ]() | |
end | end | ||
end | end | ||
− | |||
end | end | ||
− | if type( | + | if type( Multilingual.ext[ access ] ) ~= "table" then |
− | error( got, 0 ) | + | if allow then |
+ | Multilingual.ext[ access ] = false | ||
+ | else | ||
+ | got = string.format( "Module:%s invalid", access ) | ||
+ | error( got, 0 ) | ||
+ | end | ||
end | end | ||
end | end | ||
− | return | + | return Multilingual.ext[ access ] |
end -- fetch() | end -- fetch() | ||
+ | |||
+ | |||
+ | |||
+ | function find( ask, alien ) | ||
+ | -- Derive language code from name | ||
+ | -- Precondition: | ||
+ | -- ask -- language name, downcased | ||
+ | -- alien -- language code of ask | ||
+ | -- Postcondition: | ||
+ | -- nil, or | ||
+ | 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 | ||
+ | return r | ||
+ | end -- find() | ||
function isSupported( ask, accept ) | function isSupported( ask, accept ) | ||
− | -- Is ask to supported by application? | + | -- Is ask to be supported by application? |
-- Precondition: | -- Precondition: | ||
-- ask -- lowercase code | -- ask -- lowercase code | ||
Zeile 56: | Zeile 92: | ||
Multilingual.findCode = function ( ask ) | Multilingual.findCode = function ( ask ) | ||
− | -- Retrieve code of local (current project) language name | + | -- Retrieve code of local (current project or English) language name |
-- Precondition: | -- Precondition: | ||
-- ask -- string, with presumable language name | -- ask -- string, with presumable language name | ||
Zeile 72: | Zeile 108: | ||
r = seek | r = seek | ||
else | else | ||
− | local | + | local slang = favorite() |
− | if not | + | r = find( seek, slang ) |
− | + | if not r and slang ~= "en" then | |
+ | r = find( seek, "en" ) | ||
end | end | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
end | end | ||
Zeile 98: | Zeile 128: | ||
-- -- nil, false, "*": native | -- -- nil, false, "*": native | ||
-- -- "!": current project | -- -- "!": current project | ||
+ | -- -- "#": code, downcased, space separated | ||
-- -- any valid code | -- -- any valid code | ||
-- alter -- capitalize, if "c"; downcase all, if "d" | -- alter -- capitalize, if "c"; downcase all, if "d" | ||
Zeile 119: | Zeile 150: | ||
if adjacent then | if adjacent then | ||
separator = adjacent | separator = adjacent | ||
+ | elseif alien == "#" then | ||
+ | separator = " " | ||
else | else | ||
separator = assembly | separator = assembly | ||
Zeile 148: | Zeile 181: | ||
slang = Multilingual.findCode( single ) | slang = Multilingual.findCode( single ) | ||
if slang then | if slang then | ||
− | r = Multilingual.getName( slang, alien ) | + | if alien == "#" then |
− | + | r = slang | |
− | + | else | |
− | + | r = Multilingual.getName( slang, alien ) | |
− | + | if active then | |
− | + | local cnf = fetch( "Multilingual/config", | |
− | + | true ) | |
+ | if cnf then | ||
+ | if not frame then | ||
+ | if not Frame then | ||
+ | Frame = mw.getCurrentFrame() | ||
+ | end | ||
+ | frame = Frame | ||
+ | end | ||
+ | slot = cnf.getLink( slang, frame ) | ||
+ | if slot then | ||
+ | local wlink = fetch( "WLink" ) | ||
+ | slot = wlink.getTarget( slot ) | ||
+ | else | ||
+ | lapsus = alert | ||
end | end | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
end | end | ||
Zeile 237: | Zeile 276: | ||
local r | local r | ||
if ask then | if ask then | ||
− | local slang = alien | + | local slang = alien |
+ | local support = "Multilingual/names" | ||
+ | local tLang | ||
if slang then | if slang then | ||
if slang == "*" then | if slang == "*" then | ||
− | slang = | + | slang = ask:lower() |
elseif slang == "!" then | elseif slang == "!" then | ||
− | + | slang = favorite() | |
− | |||
− | |||
− | |||
else | else | ||
slang = slang:lower() | slang = slang:lower() | ||
+ | end | ||
+ | else | ||
+ | slang = ask:lower() | ||
+ | end | ||
+ | fetch( support, true ) | ||
+ | tLang = Multilingual.ext.tNames | ||
+ | if tLang then | ||
+ | tLang = tLang[ slang ] | ||
+ | if tLang then | ||
+ | r = tLang[ ask ] | ||
end | end | ||
end | end | ||
− | r = mw.language.fetchLanguageName( ask, slang ) | + | 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, slang ) | ||
+ | end | ||
else | else | ||
r = false | r = false | ||
Zeile 329: | Zeile 396: | ||
local r, slang, support | local r, slang, support | ||
if not frame then | if not frame then | ||
− | + | if not Frame then | |
+ | Frame = mw.getCurrentFrame() | ||
+ | end | ||
+ | frame = Frame | ||
end | end | ||
slang = frame:callParserFunction( "int", "lang" ):lower() | slang = frame:callParserFunction( "int", "lang" ):lower() | ||
Zeile 335: | Zeile 405: | ||
support = accept:lower() .. " " | support = accept:lower() .. " " | ||
else | else | ||
− | support = | + | support = favorite() |
if mw.language.isKnownLanguageTag( support ) then | if mw.language.isKnownLanguageTag( support ) then | ||
support = string.format( "%s en ", support ) | support = string.format( "%s en ", support ) | ||
Zeile 345: | Zeile 415: | ||
r = slang | r = slang | ||
elseif slang:find( "-", 1, true ) then | elseif slang:find( "-", 1, true ) then | ||
− | slang = Multilingual.getBase() | + | slang = Multilingual.getBase( slang ) |
if isSupported( slang, support ) then | if isSupported( slang, support ) then | ||
r = slang | r = slang |
Version vom 24. Juni 2015, 21:53 Uhr
local Multilingual = { suite = "Multilingual",
serial = "2015-06-19" };
-- local globals local Frame
local favorite = function ()
-- Postcondition: -- Returns code of curent project language if not Multilingual.self then Multilingual.self = mw.language.getContentLanguage():getCode() :lower() end return Multilingual.self
end -- favorite()
local fetch = function ( access, allow )
-- Attach config or library module -- Precondition: -- access -- module title -- allow -- permit non-existence -- Postcondition: -- Returns table or false, with library -- Throws error, if not available if type( Multilingual.ext ) ~= "table" then Multilingual.ext = { } end if Multilingual.ext[ access ] == false then elseif not Multilingual.ext[ access ] then local lucky, got = pcall( require, "Module:" .. access ) if lucky then if type( got ) == "table" then Multilingual.ext[ access ] = got if type( got[ access ] ) == "function" then Multilingual.ext[ access ] = got[ access ]() end end end if type( Multilingual.ext[ access ] ) ~= "table" then if allow then Multilingual.ext[ access ] = false else got = string.format( "Module:%s invalid", access ) error( got, 0 ) end end end return Multilingual.ext[ access ]
end -- fetch()
function find( ask, alien )
-- Derive language code from name -- Precondition: -- ask -- language name, downcased -- alien -- language code of ask -- Postcondition: -- nil, or 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 return r
end -- find()
function isSupported( ask, accept )
-- Is ask to be supported by application? -- Precondition: -- ask -- lowercase code -- accept -- space separated/terminated list of lowercase codes -- Postcondition: -- nil, or else local seek = string.format( " %s ", ask ) local supported = string.format( " %s", accept ) return supported:find( seek, 1, true )
end -- isSupported()
Multilingual.findCode = function ( ask )
-- Retrieve code of local (current project or English) language name -- Precondition: -- ask -- string, with presumable language name -- A code itself will be identified, too. -- Postcondition: -- Returns string, or false local seek = mw.text.trim( ask ) local r = false if #seek > 1 then if seek:find( "[", 1, true ) then seek = fetch( "WLink" ).getPlain( seek ) end seek = mw.ustring.lower( seek ) if Multilingual.isLang( seek ) then r = seek else local slang = favorite() r = find( seek, slang ) if not r and slang ~= "en" then r = find( seek, "en" ) end end end return r
end -- Multilingual.findCode()
Multilingual.format = function ( apply, alien, alter, active, alert,
frame, assembly, adjacent, ahead ) -- Format one or more languages -- Precondition: -- apply -- string with language list or item -- alien -- language of the answer -- -- nil, false, "*": native -- -- "!": current project -- -- "#": code, downcased, space separated -- -- any valid code -- alter -- capitalize, if "c"; downcase all, if "d" -- capitalize first item only, if "f" -- downcase every first word only, if "m" -- active -- link items, if true -- alert -- string with category title in case of error -- frame -- if available -- assembly -- string with split pattern, if list expected -- adjacent -- string with list separator, else assembly -- ahead -- string to prepend first element, if any -- Postcondition: -- Returns string, or false local r = false if apply then local slang if assembly then local bucket = mw.text.split( apply, assembly ) local shift = alter local separator if adjacent then separator = adjacent elseif alien == "#" then separator = " " else separator = assembly end for k, v in pairs( bucket ) do slang = Multilingual.format( v, alien, shift, active, alert ) if slang then if r then r = string.format( "%s%s%s", r, separator, slang ) else r = slang if shift == "f" then shift = "d" end end end end -- for k, v if r and ahead then r = ahead .. r end else local single = mw.text.trim( apply ) if single == "" then r = false else local lapsus, slot slang = Multilingual.findCode( single ) if slang then if alien == "#" then r = slang else r = Multilingual.getName( slang, alien ) if active then local cnf = fetch( "Multilingual/config", true ) if cnf then if not frame then if not Frame then Frame = mw.getCurrentFrame() end frame = Frame end slot = cnf.getLink( slang, frame ) if slot then local wlink = fetch( "WLink" ) slot = wlink.getTarget( slot ) else lapsus = alert end end end end else r = single if active then local title = mw.title.makeTitle( 0, single ) if title.exists then slot = single end end lapsus = alert end if alter == "c" or alter == "f" then r = mw.ustring.upper( mw.ustring.sub( r, 1, 1 ) ) .. mw.ustring.sub( r, 2 ) elseif alter == "d" then r = mw.ustring.lower( r ) elseif alter == "m" then r = mw.ustring.lower( mw.ustring.sub( r, 1, 1 ) ) .. mw.ustring.sub( r, 2 ) end if slot then if r == slot then r = string.format( "%s", r ) else r = string.format( "%s", slot, r ) end end if lapsus then r = string.format( "%s", r, alert ) end end end end return r
end -- Multilingual.format()
Multilingual.getBase = function ( ask )
-- Retrieve base language from possibly combined ISO language code -- Precondition: -- ask -- language code -- Postcondition: -- Returns string, or false local r if ask then local slang = ask:match( "^%s*(%a%a%a?)-?%a*%s*$" ) if slang then r = slang:lower() else r = false end else r = false end return r
end -- Multilingual.getBase()
Multilingual.getName = function ( ask, alien )
-- Which name is assigned to this language code? -- Precondition: -- ask -- language code -- alien -- language of the answer -- -- nil, false, "*": native -- -- "!": current project -- -- any valid code -- Postcondition: -- Returns string, or false local r if ask then local slang = alien local support = "Multilingual/names" local tLang if slang then if slang == "*" then slang = ask:lower() elseif slang == "!" then slang = favorite() else slang = slang:lower() end else slang = ask:lower() end fetch( support, true ) tLang = Multilingual.ext.tNames 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, slang ) end else r = false end return r
end -- Multilingual.getName()
Multilingual.isLang = function ( ask )
-- Could this be an ISO language code? -- Precondition: -- ask -- language code -- Postcondition: -- Returns boolean local r local s = Multilingual.getBase( ask ) if s then r = mw.language.isKnownLanguageTag( s ) else r = false end return r
end -- Multilingual.isLang()
Multilingual.isLangWiki = function ( ask )
-- Could this be a Wiki language version? -- Precondition: -- ask -- language version specifier -- Postcondition: -- Returns boolean local r local s = Multilingual.getBase( ask ) if s then r = mw.language.isSupportedLanguage( s ) else r = false end return r
end -- Multilingual.isLangWiki()
Multilingual.kannDeutsch = function ( ask )
-- Kann man mit diesem Sprachcode deutsch verstehen? -- Precondition: -- ask -- language version specifier -- Postcondition: -- Returns boolean local r local s = Multilingual.getBase( ask ) if s then local support = [=[ de als bar dsb frr gsw hsb ksh | lb nds pdc pdt pfl sli stq vmf ]=] if support:find( string.format( " %s ", s ), 1, true ) then r = true else r = false end else r = false end return r
end -- Multilingual.kannDeutsch()
Multilingual.userLang = function ( accept, frame )
-- Try to support user language by application -- Precondition: -- accept -- space separated list of available ISO 639 codes -- Default: project language, or English -- frame -- frame, if available -- Postcondition: -- Returns string with appropriate code local r, slang, support if not frame then if not Frame then Frame = mw.getCurrentFrame() end frame = Frame end slang = frame:callParserFunction( "int", "lang" ):lower() if type( accept ) == "string" then support = accept:lower() .. " " else support = favorite() if mw.language.isKnownLanguageTag( support ) then support = string.format( "%s en ", support ) else support = "en " end end if isSupported( slang, support ) then r = slang elseif slang:find( "-", 1, true ) then slang = Multilingual.getBase( slang ) if isSupported( slang, support ) then r = slang end end if not r then if Multilingual.kannDeutsch( slang ) and isSupported( "de", support ) then r = "de" end if not r then r = support:match( "^(%S+) " ) end end return r
end -- Multilingual.userLang()
-- Export local p = { }
p.findCode = function ( frame )
-- Retrieve language code from language name -- 1 -- name in current project language return Multilingual.findCode( frame.args[ 1 ] ) or ""
end -- p.findCode
p.format = function ( frame )
-- Format one or more languages -- 1 -- language list or item -- slang -- language of the answer, if not native -- * -- native -- ! -- current project -- any valid code -- shift -- capitalize, if "c"; downcase, if "d" -- capitalize first item only, if "f" -- link -- 1 -- link items -- scream -- category title in case of error -- split -- split pattern, if list expected -- separator -- list separator, else assembly -- start -- prepend first element, if any local r local link if frame.args.link == "1" then link = true end r = Multilingual.format( frame.args[ 1 ], frame.args.slang, frame.args.shift, link, frame.args.scream, frame, frame.args.split, frame.args.separator, frame.args.start ) return r or ""
end -- p.format
p.getBase = function ( frame )
-- Retrieve base language from possibly combined ISO language code -- 1 -- code return Multilingual.getBase( frame.args[ 1 ] ) or ""
end -- p.getBase
p.getName = function ( frame )
-- Retrieve language name from ISO language code -- 1 -- code -- 2 -- language to be used for the answer, if not native -- ! -- current project -- * -- native -- any valid code local slang = frame.args[ 2 ] local r if slang then slang = mw.text.trim( slang ) end r = Multilingual.getName( frame.args[ 1 ], slang ) return r or ""
end -- p.getName
p.isLang = function ( frame )
-- Could this be an ISO language code? -- 1 -- code local lucky, r = pcall( Multilingual.isLang, frame.args[ 1 ] ) return r and "1" or ""
end -- p.isLang
p.isLangWiki = function ( frame )
-- Could this be a Wiki language version? -- 1 -- code local lucky, r = pcall( Multilingual.isLangWiki, frame.args[ 1 ] ) return r and "1" or ""
end -- p.isLangWiki
p.kannDeutsch = function ( frame )
-- Kann man mit diesem Sprachcode deutsch verstehen? -- 1 -- code local r = Multilingual.kannDeutsch( frame.args[ 1 ] ) return r and "1" or ""
end -- p.kannDeutsch
p.userLang = function ( frame )
-- Which language does the current user prefer? -- 1 -- space separated list of available ISO 639 codes return Multilingual.userLang( frame.args[ 1 ], frame )
end -- p.userLang
p.Multilingual = function ()
return Multilingual
end -- p.Multilingual
return p