Modul:Multilingual: Unterschied zwischen den Versionen
w>PerfektesChaos (update) |
w>PerfektesChaos (+ format|start=) |
||
Zeile 1: | Zeile 1: | ||
--[=[ 2014-10- | --[=[ 2014-10-16 | ||
Multilingual | Multilingual | ||
]=] | ]=] | ||
Zeile 91: | Zeile 91: | ||
Multilingual.format = function ( apply, alien, alter, active, alert, | Multilingual.format = function ( apply, alien, alter, active, alert, | ||
frame, assembly, adjacent ) | frame, assembly, adjacent, ahead ) | ||
-- Format one or more languages | -- Format one or more languages | ||
-- Precondition: | -- Precondition: | ||
Zeile 106: | Zeile 106: | ||
-- assembly -- string with split pattern, if list expected | -- assembly -- string with split pattern, if list expected | ||
-- adjacent -- string with list separator, else assembly | -- adjacent -- string with list separator, else assembly | ||
-- ahead -- string to prepend first element, if any | |||
-- Postcondition: | -- Postcondition: | ||
-- Returns string, or false | -- Returns string, or false | ||
Zeile 135: | Zeile 136: | ||
end | end | ||
end -- for k, v | end -- for k, v | ||
if r and ahead then | |||
r = ahead .. r | |||
end | |||
else | else | ||
local single = mw.text.trim( apply ) | local single = mw.text.trim( apply ) | ||
Zeile 382: | Zeile 386: | ||
-- split -- split pattern, if list expected | -- split -- split pattern, if list expected | ||
-- separator -- list separator, else assembly | -- separator -- list separator, else assembly | ||
-- start -- prepend first element, if any | |||
local r | local r | ||
local link | local link | ||
Zeile 394: | Zeile 399: | ||
frame, | frame, | ||
frame.args.split, | frame.args.split, | ||
frame.args.separator ) | frame.args.separator, | ||
frame.args.start ) | |||
return r or "" | return r or "" | ||
end -- p.format | end -- p.format |
Version vom 17. Oktober 2014, 10:54 Uhr
Utilities for multilingual texts and ISO 639 (BCP47) issues etc.
Verwendung in anderen Modulen
Dieses Modul ist notwendig für die Ausführung folgender Module. Bei Anpassungen sollte die Funktionstüchtigkeit der folgenden Module geprüft werden. Benutze dazu auch diese Tracking-Kategorie um Fehler zu finden, die sich dann auf Artikel auswirken:
- TemplateData
- Modul benötigt das Modul Multilingual – Wartungskategorie, in der nochmals alle Module gelistet sind, die von diesem Modul abhängig sind.|}}
--[=[ 2014-10-16 Multilingual ]=] local Multilingual = { } local Frame local Got = { } local SelfLang 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 Got[ access ] == false then elseif not Got[ access ] then local lucky, got = pcall( require, "Module:" .. access ) if lucky then if type( got ) == "table" then Got[ access ] = got if type( got[ access ] ) == "function" then Got[ access ] = got[ access ]() end end got = "Module" .. access .. " invalid" end if type( Got[ access ] ) ~= "table" then error( got, 0 ) end end return Got[ access ] end -- fetch() function isSupported( ask, accept ) -- Is ask to 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) 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 codes if not SelfLang then SelfLang = mw.language.getContentLanguage():getCode() end 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 -- for k, v 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 -- -- any valid code -- alter -- capitalize, if "c"; downcase, if "d" -- capitalize first item only, if "f" -- 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 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 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 slot = fetch( "WLink" ).getTarget( slot ) else lapsus = alert 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 ) end if slot then if r == slot then r = string.format( "[[%s]]", r ) else r = string.format( "[[%s|%s]]", slot, r ) end end if lapsus then r = string.format( "%s[[Category:%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 if slang then if slang == "*" then slang = nil elseif slang == "!" then if not SelfLang then SelfLang = mw.language.getContentLanguage():getCode() end slang = SelfLang else slang = slang:lower() end end r = mw.language.fetchLanguageName( ask, slang ) 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 frame = mw.getCurrentFrame() end slang = frame:callParserFunction( "int", "lang" ):lower() if type( accept ) == "string" then support = accept:lower() .. " " else support = mw.language.getContentLanguage():getCode() 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() 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