Modul:Linguistic

Dari Wikipedia bahasa Indonesia, ensiklopedia bebas

--[[
Modul ini disalin dari modul dengan nama yang sama di Wikimedia Commons.

Simple internationalization functions that can be called by other modules.
This Module was copied from Wikimedia Commons, so please request changes there.

Maintainers:
* Zolo - original version
* Jarekt

Dependencies:
- Module uses c:data:I18n/Or.tab
]]
require('strict')

-- ==================================================
-- === Internal functions ===========================
-- ==================================================

local function langSwitch(list,lang)
	local langList = mw.language.getFallbacksFor(lang)
	table.insert(langList,1,lang)
	for i,language in ipairs(langList) do
		if list[language] then
			return list[language]
		end
	end
	return nil
end

------------------------------------------------------------------------------
-- read Commons Data:SOMENAME.tab dataset and look for message identified by a 
-- "key" in a language "lang". See editAtWikidata as an example.
local function formatMessage(dataset, key, lang)
	for _, row in pairs(mw.ext.data.get(dataset, lang).data) do
		local id, msg = unpack(row)
		if id == key then
			return mw.message.newRawMessage(msg):plain()
		end
	end
	error('Invalid message key "' .. key .. '"')
end

------------------------------------------------------------------------------
local function nowiki(str) -- remove all the links
	if not str then
		return str
	end
	str = mw.ustring.gsub(str, "<[^>]*>", "")    -- remove all html tags from str
	str = mw.ustring.gsub(str, "'''", "")        -- remove bold 
	str = mw.ustring.gsub(str, "''", "")         -- remove italics
	str = mw.ustring.gsub(str, "%[%[[Ff]ile:[^%]]+%]%]", "") -- remove file icons
	str = mw.ustring.gsub(str, "%[%[[^|]*|", "") -- remove piped links, like "[[:en:test|"
	str = mw.ustring.gsub(str, "%[[^ ]+ ", "")   -- remove URL links, like "[https://www.wikidata.org/wiki/Q2706250 "
	str = mw.ustring.gsub(str, "%[%[", "" )      -- remove piped links, like "[["
	str = mw.ustring.gsub(str, "%]", "" )        -- remove piped links, like "]" or "]]"
	return str
end

------------------------------------------------------------------------------
-- Function allowing for consistent treatment of boolean-like wikitext input.
-- It works similarly to Module:Yesno
local function yesno(val, default)
	if type(val) == 'boolean' then
		return val
	elseif type(val) == 'number' then
		if val==1 then 
			return true
		elseif val==0 then
			return false
		end
	elseif type(val) == 'string' then
	    val = mw.ustring.lower(val)  -- put in lower case
	    if val == 'no'  or val == 'n' or val == 'false' or val == '0' then
	        return false
	    elseif val == 'yes' or val == 'y' or val == 'true'  or val == '1' then
	        return true
	    end
    end
    return default
end

-- ==================================================
-- === External functions ===========================
-- ==================================================
local p = {}

-- ===========================================================================
-- === Version of the function to be called from other LUA codes
-- ===========================================================================

------------------------------------------------------------------------------------------
function p.vowelfirst (str)
	if str then 
		local vowels = 'aeiouyąăẵằẳặȃắâẫấầẩậãäǟāáàȁǎảẚåǻḁạǡæǣǽĕȇêễếềểệḙẽḛëēḕéḗèȅěẻẹęȩḝǝĭȋîĩḭï'..
			'ḯīíìȉǐỉịįıŏȏôỗốồổộõṏṍöōṑóṓòȍǒỏọǫǭơỡớờởợøǿŭȗûṷũṻṹṵüǖǘǜǚṳūúùȕǔủůụųưữứừửựŷỹÿȳýỳỷẙỵ'
		str = mw.ustring.lower(mw.ustring.sub(str,1,1))
		return mw.ustring.find(vowels, str, 1, true ) 
	end
end

------------------------------------------------------------------------------------------
function p.inparentheses(str)
	if (not str) or (str == "") then
		return nil
	end
	local str2 = mw.message.new('parentheses', str):inLanguage(lang):plain()
	return (str2~=nil and str2) or ('('..str..')') -- in case this module is moved to a project where {{int:parenthesis}} is not set
end

------------------------------------------------------------------------------------------
function p.of(word, lang, raw, gender, number, determiner) -- rough translation of "of" in various languages
-- note that the cases when on "of" is employed varies a lot among languages, so it is more prudent to call this from lang specific function only
	if not raw or mw.text.trim(raw) == "" then 
		raw = mw.ustring.lower(nowiki(word))
	end

	-- raw is the string without the Wikiformatting so that it correctly analyses the string that is [[:fr:Italie|Italie]] -> 'italie'
	-- any way to automate this ?
	
	if lang == 'fr' then 
		determiner = yesno(determiner,false)

		if determiner then
			if string.sub(number or '',1,1)=='p' then -- number == 'plural'
				return 'des&#32;' .. word
			elseif p.vowelfirst(raw) then
				return 'de l’' .. word
			elseif string.sub(gender or '',1,1)=='f' then -- gender == 'feminine'
				return 'de la&#32;' .. word
			else
				return 'du&#32;' .. word
			end
		else
			if p.vowelfirst(raw) then
				return 'd’' .. word
			else
				return 'de&#32;' .. word
			end
		end
	elseif lang == 'ca' then
		-- implement [[Template:Of/ca]] or  https://ca.wikipedia.org/wiki/Plantilla:Deod%27/base for case where "{{{context}}}" is "en" (default on Commons)
		if ( p.vowelfirst(raw) and not mw.ustring.find( 'ia|ià|ie|io|iu|ua|ue|ui|uí|uï|uo|ya|ye|yi|yo|yu|', mw.ustring.sub(raw,1,2) .. '|')) then
			return 'd\'' .. word
		else
			return 'de ' .. word
		end
	end	
end

------------------------------------------------------------------------------------------
function p.noungroup(noun, adj, lang)
	if not noun or noun == '' then 
		return nil -- not '' so that it is not counted as a string by mw.listToText
	end
	if not adj or adj == ''
		then return noun
	end
	
	local wordsep = mw.message.new( "Word-separator" ):inLanguage(lang):plain()
	-- Assign order of words per language: 1 means adjective before the noun and 2 means adjective after the noun
	-- original source for many: language subpages of [[Template:Technique]]
	-- corrections to that using https://wals.info/feature/87A, still different:
	-- * vi: WALS says 2
	-- * gl isn't consistent in [[Template:Technique/gl]], but seems to be 2
	local LUT = {ar=2, ca=2, cs=1, da=1, de=1, el=1, en=1, es=2, et=1, fi=1, fr=2, 
		gl=2, he=2, hu=1, it=2, ja=1, la=2, mk=1, nds=1, nb=1, nl=1, no=1, pl=1, pt=2, 
		ro=2, ru=1, scn=2, sk=1, sl=1, sr=1, sv=1, sw=1, tr=1, vec=1, vi=1, zh=1}
	local primaryLangSubtag = mw.text.split(lang, '-', true)[1]
	local case = LUT[lang] or LUT[primaryLangSubtag]
	if case==1 then     -- adjective before the noun
		return adj .. wordsep .. noun
	elseif case==2 then -- adjective after the noun
		return noun .. wordsep .. adj
	else                -- order unknown
		return noun .. ' (' .. adj .. ')'
	end
end

------------------------------------------------------------------------------------------
function p.conj(args, lang, conjtype)
	local comma    = mw.message.new( "comma-separator"):inLanguage(lang):plain()
	local wordsep  = mw.message.new( "Word-separator" ):inLanguage(lang):plain()
	local andtable = { ar=' و', he=' ו', ja='および', pl=' i '} -- languages with a problem with the MediaWiki:And
	local sep1, sep2 = comma, nil
	if conjtype == 'comma' then
		sep2 = comma
	elseif conjtype == 'or' or conjtype == 'explicit or' then 
		local wordor = formatMessage('I18n/Or.tab', 'or', lang) -- get translated "or"
		sep2 = wordsep .. wordor  .. wordsep -- pad it with spaces (if needed)
		sep1 = (conjtype == 'explicit or' and sep2) or comma -- adds "or" betwen all words when the context can be confusing
	elseif conjtype and conjtype ~= 'and' and conjtype ~= '' then
		sep1, sep2 = conjtype, conjtype
	elseif andtable[lang] then 
		sep2 = andtable[lang]
	else
		sep2 = mw.message.new( "and" ):inLanguage(lang):plain() .. wordsep
	end
	return mw.text.listToText(args, sep1, sep2)

end

-- ===========================================================================
-- === Version of the functions to be called from template namespace
-- ===========================================================================

------------------------------------------------------------------------------------------
function p.offromwiki(frame)
	local args = frame.args
	return p.of(args.word, args.lang, args.raw, args.gender, args.number, args.determiner)
end

------------------------------------------------------------------------------------------
function p.conjfromWiki(frame)
	local args = frame.args
	if not args or not args[1] then
		args = frame:getParent().args
	end
	local lang = args.lang
	if not lang or mw.text.trim(lang) == '' then
		lang = frame:callParserFunction( "int", "lang" )
	end
	local newargs = {}  -- transform args metatable into a table so it can be concetenated
	for i, j in pairs(args) do
			if type(i) == 'number' then
				j = mw.text.trim(j)
				if j ~= '' then
					table.insert(newargs, j)
				end
			else 
				if i ~= 'type' and i ~= 'lang' then 
					return 'error: bad parameter in template:Conj: ' .. i .. '[[Category:Pages with incorrect template usage/Conj|A]]'
				end
			end
	end
	return p.conj(newargs, lang, args.type)
end

return p