Sari la conținut

Modul:InLang

Permanently protected module
De la Wikipedia, enciclopedia liberă

local getArgs = require('Modul:Arguments').getArgs
local illWd = require('Modul:Ill-wd')
local StringUtils = require('Modul:StringUtils')
local wikidata = require('Modul:Wikidata')
local lang = require('Modul:Lang')
local mYesNo = require('Modul:Yesno')
local mTransliteration = require('Modul:Transliteration')
local langData = nil
local p = {}

local function lazyLoadData(data, dataSource)
	return data or mw.loadData(dataSource)
end

local function is_set(var)
	return not (var == nil or var == '');
end

local function parseIETF (source)
	if not is_set (source) then
		return nil;
	end

	local pattern = {															-- table of tables holding acceptibe ietf tag patterns and short names of the ietf part captured by the pattern
		{'^(%a%a%a?)%-(%a%a%a%a)%-(%a%a)%-(%d%d%d%d)$', 's', 'r', 'v'}, 				-- 1 -  ll-Ssss-RR-variant (where variant is 4 digits)
		{'^(%a%a%a?)%-(%a%a%a%a)%-(%d%d%d)%-(%d%d%d%d)$', 's', 'r', 'v'},				-- 2 -  ll-Ssss-DDD-variant (where region is 3 digits; variant is 4 digits)
		{'^(%a%a%a?)%-(%a%a%a%a)%-(%a%a)%-(%w%w%w%w%w%w?%w?%w?)$', 's', 'r', 'v'},		-- 3 -  ll-Ssss-RR-variant (where variant is 5-8 alnum characters)
		{'^(%a%a%a?)%-(%a%a%a%a)%-(%d%d%d)%-(%w%w%w%w%w%w?%w?%w?)$', 's', 'r', 'v'},	-- 4 -  ll-Ssss-DDD-variant (where region is 3 digits; variant is 5-8 alnum characters)
		
		{'^(%a%a%a?)%-(%a%a%a%a)%-(%d%d%d%d)$', 's', 'v'},						-- 5 -  ll-Ssss-variant (where variant is 4 digits)
		{'^(%a%a%a?)%-(%a%a%a%a)%-(%w%w%w%w%w%w?%w?%w?)$', 's', 'v'},			-- 6 -  ll-Ssss-variant (where variant is 5-8 alnum characters)
		
		{'^(%a%a%a?)%-(%a%a)%-(%d%d%d%d)$', 'r', 'v'},							-- 7 -  ll-RR-variant (where variant is 4 digits)
		{'^(%a%a%a?)%-(%d%d%d)%-(%d%d%d%d)$', 'r', 'v'},						-- 8 -  ll-DDD-variant (where region is 3 digits; variant is 4 digits)
		{'^(%a%a%a?)%-(%a%a)%-(%w%w%w%w%w%w?%w?%w?)$', 'r', 'v'},				-- 9 -  ll-RR-variant (where variant is 5-8 alnum characters)
		{'^(%a%a%a?)%-(%d%d%d)%-(%w%w%w%w%w%w?%w?%w?)$', 'r', 'v'},				-- 10 - ll-DDD-variant (where region is 3 digits; variant is 5-8 alnum characters)
		
		{'^(%a%a%a?)%-(%d%d%d%d)$', 'v'},										-- 11 - ll-variant (where variant is 4 digits)
		{'^(%a%a%a?)%-(%w%w%w%w%w%w?%w?%w?)$', 'v'},							-- 12 - ll-variant (where variant is 5-8 alnum characters)
		
		{'^(%a%a%a?)%-(%a%a%a%a)%-(%a%a)$', 's', 'r'},							-- 13 - ll-Ssss-RR
		{'^(%a%a%a?)%-(%a%a%a%a)%-(%d%d%d)$', 's', 'r'},						-- 14 - ll-Ssss-DDD (region is 3 digits)
		
		{'^(%a%a%a?)%-(%a%a%a%a)$', 's'},										-- 15 - ll-Ssss
		
		{'^(%a%a%a?)%-(%a%a)$', 'r'},											-- 16 - ll-RR
		{'^(%a%a%a?)%-(%d%d%d)$', 'r'},											-- 17 - ll-DDD (region is 3 digits)
		
		{'^(%a%a%a?)$'},														-- 18 - ll
		
		{'^(%a%a%a?)%-x%-(%w%w?%w?%w?%w?%w?%w?%w?)$', 'p'},						-- 19 - ll-x-pppppppp (private is 1-8 alnum characters)
		}

	local t = {};																-- table of captures; serves as a translator between captured ietf tag parts and named variables

	for i, v in ipairs (pattern) do												-- spin through the pattern table looking for a match
		local c1, c2, c3, c4;													-- captures in the 'pattern' from the pattern table go here
	
		c1, c2, c3, c4 = mw.ustring.match(source, pattern[i][1]);				-- one or more captures set if source matches pattern[i])
		if c1 then																-- c1 always set on match
			t = {
				l = c1,
				[pattern[i][2] or 'x'] = c2,									-- fill the table of captures with the rest of the captures
				[pattern[i][3] or 'x'] = c3,									-- take index names from pattern table and assign sequential captures
				[pattern[i][4] or 'x'] = c4,									-- index name may be nil in pattern[i] table so "or 'x'" spoofs a name for this index in this table
				};
			return t															-- and done
		end
	end
end

p.getLangLabel = function(q)
	local lbl = wikidata.findLabel(q)
	lbl = StringUtils._removeStart(lbl, 'Limba ')
	lbl = StringUtils._removeStart(lbl, 'limba ')
	return lbl
end

p.getLangLink = function(q)
	return illWd.fromArgs(q, p.getLangLabel(q), nil)
end

p.getLangQId = function(code)
	langData = lazyLoadData(langData, 'Modul:InLang/data')
	return langData.languageCodes[code]
end

local function getAlphabetCode(alphabetQID)
	return wikidata.findOneValueNoRef('P506', alphabetQID)
end

local function getLanguageDir(alphabetQID)
	if not mw.ustring.match(alphabetQID, 'Q?%d+') then return nil end -- TODO implement something to identify direction if alphabet is specified as IETF fragment
	local languageDirectionalities = wikidata.getBestEntityIdsList(alphabetQID, 'P1406')
	local languageDir
	if languageDirectionalities and languageDirectionalities[1] then
		languageDir = (languageDirectionalities[1] == 7333457) and 'rtl' or nil
	end
	return languageDir
end

p.fromArgs = function(langId, langText, alternateSpellings, defaultAlphabet, italics, langLit, autoTransl)
	local languageLink
	if mw.ustring.match(langId, 'Q?%d+') then
		languageLink = p.getLangLink(langId)
		local langISOcode = wikidata.findOneValueNoRef('P218', langId) or wikidata.findOneValueNoRef('P219', langId) or wikidata.findOneValueNoRef('P305', langId)
		local languageDir = nil
		local defaultAlphabetCode
		if not defaultAlphabet then
			local languageAlphabets = wikidata.getBestEntityIdsList(langId, 'P282')
			if languageAlphabets and languageAlphabets[1] then
				defaultAlphabet = languageAlphabets[1]
			end
		elseif mw.ustring.match(defaultAlphabet, 'Q%d+') then -- must be on an 'else' here because we need an explicit alphabet code only if more are possible (so only if a default is specified)
			defaultAlphabetCode = getAlphabetCode(defaultAlphabet)
		end
		if defaultAlphabet then
			languageDir = getLanguageDir(defaultAlphabet)
		end
		local out = languageLink .. ' '
		if langText then
			if langISOcode then
				local htmlText = lang.fromArgs(defaultAlphabetCode and (langISOcode .. '-' .. defaultAlphabetCode) or langISOcode, languageDir, langText, italics)
				out = out .. htmlText
			else
				out = out .. '\'\'' .. langText .. '\'\''
			end
		end
		local spellingsTexts = {}
		if alternateSpellings and #alternateSpellings > 0 then
			for _,eachSpelling in ipairs(alternateSpellings) do
				local crtAlphabet = eachSpelling.alphabet
				local crtAlphabetDir = nil
				local crtSpellingText = ''
				local crtAlphabetCode = 'Latn'

				if mw.ustring.match(crtAlphabet, 'Q%d+') then
					crtAlphabetDir = getLanguageDir(crtAlphabet)
					crtAlphabetCode = getAlphabetCode(crtAlphabet)
					crtSpellingText = 'cu ' .. wikidata.findLinkToItem(crtAlphabet)
				else
					crtSpellingText = crtAlphabet
				end
				if langISOcode then
					local htmlText = lang.fromArgs(crtAlphabetCode and (langISOcode .. '-' .. crtAlphabetCode) or langISOcode, crtAlphabetDir, eachSpelling.spelling, italics)
					crtSpellingText = crtSpellingText .. ': ' .. htmlText
				else
					crtSpellingText = crtSpellingText .. ': \'\'' .. eachSpelling.spelling .. '\'\''
				end
				table.insert(spellingsTexts, crtSpellingText)
			end
		elseif autoTransl and langISOcode and mTransliteration.isTransliterationSupported(langISOcode) then
			table.insert(spellingsTexts, 'transliterat: ' .. lang.fromArgs(langISOcode .. '-Latn', nil, mTransliteration.transliterate(langText, langISOcode)))
		end
		if #spellingsTexts > 0 then
			out = out .. ', ' .. table.concat(spellingsTexts, ', ')
		end
		if langLit then
			out = out .. ', lit. ' .. langLit
		end
		return out
	else 
		languageLink = '[[Limba ' .. langId .. '|' .. langId .. ']]'
		local langTranslit = alternateSpellings and alternateSpellings[1] and alternateSpellings[1].spelling or nil
		local latinVariantName = alternateSpellings and alternateSpellings[1] and alternateSpellings[1].alphabet or 'transliterat'
		return languageLink .. ' ' .. (langText and ((italics and '\'\'' or '') .. langText .. (italics and '\'\'' or '')) or '') .. (langTranslit and (', ' .. latinVariantName .. ' ' .. '\'\'' .. langTranslit .. '\'\'') or '') .. (langLit and (', lit. ' .. langLit) or '')
	end
end

p.fromArray = function(args)
	local languageId = args[1]
	local languageText = args[2]
	local languageTranslit = args[3]
	local latinVariantName = args[4] or 'transliterat'
	local defaultAlphabet = args['default_alphabet']
	local alternateSpellings = {}
	if languageTranslit then
		table.insert(alternateSpellings, {spelling = languageTranslit, alphabet = latinVariantName})
	end
	local crtArgIndex = 5
	while args[crtArgIndex + 1] do
		if args[crtArgIndex] then
			table.insert(alternateSpellings, {spelling = args[crtArgIndex], alphabet = args[crtArgIndex + 1]})
		end
		crtArgIndex = crtArgIndex + 2
	end
	local italics = mYesNo(args['italics'] or '', true)
	local autoTransl = mYesNo(args['auto-transl'] or '', false)
	local languageLit = args.lit
	return p.fromArgs(languageId, languageText, alternateSpellings, defaultAlphabet, italics, languageLit, autoTransl)
end

p.fromFrame = function(frame)
	argsOptions = {frameOnly = false, parentOnly = false}
	if frame.args['args'] then
		argsOptions.frameOnly = (frame.args['args'] == 'frameOnly')
		argsOptions.parentOnly = (frame.args['args'] == 'parentOnly')
	end
	local args = getArgs(frame, argsOptions)
	return p.fromArray(args)
end

p.langXFromArray = function(args)
	local languageId = args[1]
	local languageText = args[2] or args.text
	local languageTranslitText = args[3] or args.translit
	local languageLit = args.lit or args.translation
	local autoTransl = mYesNo(args['auto-transl'] or '', false)
	
	local ietfParts = parseIETF(languageId)
	if ietfParts and ietfParts.l then
		local alphabet = is_set(ietfParts.s) and ietfParts.s or nil
		local languageQ = p.getLangQId(ietfParts.l)
		return p.fromArgs(languageQ or ietfParts.l or languageId, languageText, {{ spelling=languageTranslitText, alphabet='transliterat'}}, alphabet, mYesNo(args['italics'] or '', true), languageLit, autoTransl)
	end
end

p.langX = function(frame)
	local args = getArgs(frame)
	return p.langXFromArray(args)
end

return p