Nicht angemeldeter Benutzer - Bearbeiten von Seiten ist nur als angemeldeter Benutzer möglich.
Änderungen
Zur Navigation springen
Zur Suche springen
Modul:Multilingual (Quelltext anzeigen)
Version vom 4. Oktober 2014, 14:52 Uhr
, 14:52, 4. Okt. 2014Setup
--[=[ 2014-10-04
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 )
-- 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
-- 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
else
local single = mw.text.trim( apply )
if single == "" then
r = false
else
local 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 )
end
end
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
elseif alert then
r = string.format( "%s[[Category:%s]]",
single, alert )
else
r = single
if active then
local title = mw.title.makeTitle( 0, single )
if title.exists then
slot = single
end
end
end
if slot then
if r == slot then
r = string.format( "[[%s]]", r )
else
r = string.format( "[[%s|%s]]", slot, r )
end
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
-- 1=Leerzeichen-getrennte Liste von ISO639-Codes
-- Default: project language, or English
-- Vorgabe: Projektsprache Englisch
-- 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
-- Wenn die aktuelle Benutzersprache nicht Element der Liste
-- ist, wird auf das erste Element zurückgefallen.
-- Wenn die aktuelle Benutzersprache eine Variante ist wie
-- de-AT
-- oder
-- de-CH
-- und diese nicht explizit in der Liste genannt wird,
-- wird ersatzweise die Basissprache
-- (hier
-- de
-- ) versucht.
-- Wenn alles nicht passt, ist die Ausgabe
-- en
-- für Englisch.
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 -- string with 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 -- string with category title in case of error
-- split -- string with split pattern, if list expected
-- separator -- string with list separator, else assembly
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 )
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
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 )
-- 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
-- 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
else
local single = mw.text.trim( apply )
if single == "" then
r = false
else
local 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 )
end
end
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
elseif alert then
r = string.format( "%s[[Category:%s]]",
single, alert )
else
r = single
if active then
local title = mw.title.makeTitle( 0, single )
if title.exists then
slot = single
end
end
end
if slot then
if r == slot then
r = string.format( "[[%s]]", r )
else
r = string.format( "[[%s|%s]]", slot, r )
end
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
-- 1=Leerzeichen-getrennte Liste von ISO639-Codes
-- Default: project language, or English
-- Vorgabe: Projektsprache Englisch
-- 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
-- Wenn die aktuelle Benutzersprache nicht Element der Liste
-- ist, wird auf das erste Element zurückgefallen.
-- Wenn die aktuelle Benutzersprache eine Variante ist wie
-- de-AT
-- oder
-- de-CH
-- und diese nicht explizit in der Liste genannt wird,
-- wird ersatzweise die Basissprache
-- (hier
-- de
-- ) versucht.
-- Wenn alles nicht passt, ist die Ausgabe
-- en
-- für Englisch.
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 -- string with 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 -- string with category title in case of error
-- split -- string with split pattern, if list expected
-- separator -- string with list separator, else assembly
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 )
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