Modulo Lua per implementare le funzioni dei template {{Nomelingua}}, {{Lingue}} e templati ad essi collegati e per offrire le medesime funzionalità ad altri moduli Lua senza dover dipendere da chiamate ai medesimi template.

Funzioni

Per moduli Lua

Il modulo rende disponibili alcune funzioni per altri moduli Lua, per utilizzarle occorre prima caricare il modulo con l'istruzione: local lg = require( "Modulo:Lingue" );

Le funzioni saranno disponibili come lg.nomefunzione (lg è solo un nome di esempio, si può scegliere quello che si preferisce purché si richiamino coerentemente le funzioni, per esempio si può usare local lingue = require( "Modulo:Lingue" );, in questo caso le funzioni andranno richiamate come lingua.nomefunzione

esiste(code)
ritorna true se code corrisponde a una lingua, altrimenti false
get_nome(code, maiuscolo, default)
ritorna la coppia nome della lingua corrispondente a code e code normalizzato (per esempio se code è "inglese" ritorna (lingua inglese, en). Se maiuscolo è vero la prima lettera del nome ritornato è maiuscola. Se non trova una lingua corrispondente a code ritorna il valore default se questo è definito, altrimenti ritorna stringa nulla '' e il valore di code originariamente passato.
get_voce(code)
ritorna il nome della voce dedicata alla lingua corrispondente a code. Se il modulo non trova la voce ritorna stringa nulla ''
lingue(lista_di_lingue)
ritorna le lingue corrispondenti a lista_di_lingue formattate come da template {{lingue}}. Se si deve passare una stringa piuttosto che una lista trasformarla in lista, per esempio chiamando la funzione racchiudendo la stringa tra parentesi graffe: lg.lingue( {stringa} )

Per i template

Il modulo comprende anche funzioni per implementare direttamente alcuni template, a cui si rimanda per la sintassi d'uso:

lingue(frame)
oltre a fare da interfaccia diretta per altri moduli Lua implementa anche il modulo {{Lingue}}
nomecompleto(frame)
implementa le funzionalità di {{nomelingua}}
nome(frame)
implementa le funzionalità di {{nomelingua/nome}}
voce(frame)
implementa le funzionalità di {{nomelingua/voce}}

Di documentazione

tabella
richiamata da una pagina wiki con {{#Invoke:Lingue|tabella}} ritorna una tabella di tutti i codici e dei nomi e collegamenti alle pagine delle lingue riconosciute.

Note tecniche

I dati utilizzati sono caricati nel modulo modulo:Lingue/Configurazione, che contiene due tabelle, la prima di alias di lingue che associa ad ogni codice riconosciuto per una lingua un codice standard (generalmente il codice ISO_639-3 della lingua). La seconda che associa a ogni codice standard il nome per la lingua e la sua pagina su it.wiki.

Per aggiungere un nuovo alias per una lingua già riconosciuta dal modulo basta aggiungere alla tabella language_config.alias una riga nel formato

    ["alias"] = "codice_standard"',

dove alias è l'alias da inserire e codice_standard è il codice standard che deve essere già inserito nella tabella language_config.codici.

Per inserire una nuova lingua basta aggiungere alla tabella language_config.codici una riga nel formato:

    [ "codice_standard"] = { "nome_lingua", "articolo" },

dove codice_standard è il codice standard usato dal programma (usare in ordine di preferenza codice ISO 639-1 (due lettere) altrimenti il ISO 639-2 (tre lettere), se nessuno dei due esiste usare un altro codice, purchè non sia un codice ISO 639-1 o ISO 639-2 dedicato ad altra lingua), nome lingua il nome della lingua come dev'essere visualizzato a video e articolo il nome dell'articolo di wikipedia dedicato alla lingua. Per inserire codici alternativi per la lingua vedi istruzioni del paragrafo sopra.

Nota bene: i codici e gli alias delle lingue devono essere inseriti in lettere minuscole o non verranno riconosciuti.


local language = {}
local getArgs = require('Module:Arguments').getArgs

-- File di configurazione contenente due tabelle:
-- lg.alias: per normalizzare gli alias a un codice unico
-- lg.codici: che dato un codice restituisce un array contente
-- nome della lingua e collegamento all'articolo su it.wiki dedicato alla lingua
local lg = mw.loadData('Modulo:Lingue/Configurazione');

-- ritorna il nome della voce corrispondente a "code". Se "code" non corrisponde a nessuna
-- lingua inserita in tabella ritorna una stringa nulla
function language.get_voce(code)
	if code == nil then return '' end
	local code = mw.ustring.lower(code)
	if lg.alias[code] then code = lg.alias[code] end
	local lingua = lg.codici[code]
	if lingua then
		return lingua[2]
	end
	return ''
end

-- ritorna vero se "code" corrisponde a una lingua, falso altrimenti
function language.esiste(code)
	if code == nil or code=='' then return false end
	if lg.alias[code] then code= lg.alias[code] end
	if lg.codici[code] then return true end
	return false
end

-- Restituisce il nome standard della lingua corrispondente a "code" e il codice normalizzato
-- a quella della tabella codici.
-- Se "code" non corrisponde a nessuna lingua inserita in tabella, restituisce il valore di default
-- o stringa nulla se questo non è indicato e il codice richiesto. Se maiuscolo è vero il
-- nome viene restituito con la prima lettera maiuscola.
function language.get_nome(code, maiuscolo, default)
	local nome = default or ''
	if code ~= nil and code ~= '' then
		-- prova a cercare la lingua fra gli alias
		if lg.alias[code] then
			code = lg.alias[code]
		-- altrimenti converte il testo in minuscolo e prova sia a ricercare
		-- fra gli alias sia a estrarre la prima parte di codici come it-IT
		else
			code = mw.ustring.lower(code)
			code = lg.alias[code] or mw.ustring.gsub(code, '(%l+)%-.*', '%1')
		end
		local lingua = lg.codici[code]
		if lingua then nome = lingua[1] end
	end
	if maiuscolo then
		nome = mw.ustring.gsub(nome, '^%l', mw.ustring.upper)
	end
	return nome, code
end

-- funzione di interfaccia per template:Nomelingua/voce
function language.voce(frame)
	local code = frame.args[1]
	if code == nil or code == '' then
		return ''
	end
	return language.get_voce(code)
end

-- funzione di interfaccia per template:Nomelingua/nome
function language.nome(frame)
	local maiuscolo = false
	local code = frame.args[1] or ''
	local default = (frame.args[2] == 'v' and '') or code
	if frame.args['M']~=nil and frame.args['M']~='' then
		maiuscolo = true
	end
	return language.get_nome(code, maiuscolo, default), _

end

--funzione di interfaccia per template:Nomelingua
function language.nomecompleto(frame)
	local code = frame.args[1]
	if code == nil or code == '' then
		return ''
	end
	local maiuscolo = false
	if frame.args['M']~=nil and frame.args['M']~='' then
		maiuscolo = true
	end
	local voce = language.get_voce(code)
	local nome = language.get_nome(code, maiuscolo, code)
	if nome == "" and voce ~="" then
		if maiuscolo then
			nome = mw.ustring.gsub(voce, '^%l', mw.ustring.upper)
		else
			nome = voce
		end
	end
	if voce == "" then
		return nome
	else
		return table.concat({'[[', voce, "|", nome, "]]"})
	end
end

--funzione di interfaccia per template:Lingue, se viene passato anche il parametro
--usa_codice (qualunque sia il suo valore), allora il testo mostrato tra parentesi
--viene normalizzato a quello standard della lingua, piuttosto che essere quello
--passato
--In aggiunta può ricevere se il parametro return_error è vero ritorna in caso di
--codici lingua non ritrovati in tabella una tabella aggiuntiva con i codici errati
--return_error viene controllato solo se la funzione è richiamata da un modulo Lua
--se è richiamata da un template è sempre falsa
function language.lingue(frame)
	local lingue_list = { }
	-- Se chiamata mediante  #invoke, usa gli argomenti passati al template invocante.
	-- Altrimenti a scopo di test assume che gli argomenti siano passati direttamente
	local args
	local return_error = false
	local error_list = {}
	if frame == mw.getCurrentFrame() then
		args = frame:getParent().args
	else
		args = frame
		return_error = args['return_error'] or false
	end
	local lingua, codice_normalizzato, code_to_show

	local yet_processed = {}
	for _,code in ipairs(args) do
		lingua, codice_normalizzato = language.get_nome(code)
		codice_normalizzato = mw.ustring.upper(codice_normalizzato)
		if not yet_processed[ codice_normalizzato ] then
			if lingua ~= "" then
				lingue_list[#lingue_list+1] = '<abbr title="' .. lingua .. '">' ..codice_normalizzato .. "</abbr>"
				yet_processed[ codice_normalizzato ] = true
			else
				lingue_list[#lingue_list+1] = code
				if return_error then error_list[#error_list+1] = code end
			end
		end
	end
	local reply
	if #lingue_list > 0 then
		reply = '(<span style="font-weight:bolder; font-size:80%">' .. table.concat(lingue_list, ",&nbsp;") .. "</span>)"
	else
		reply = ''
	end
	reply = reply
	if #error_list>0 then
		return reply, error_list
	else
		return reply
	end
end

-- ========================================================
-- Ritorna la stringa txt inserita in un tag <span> con indicato
-- il codice lingua del testo (language_code) e il senso
-- di lettura (sinistro o destro).
-- Il parametro "corsivo" permette di indicare se il testo
-- deve essere messo in corsivo, ha tre valori:
-- -- d: consulta le tabelle di configurazione per la lingua
-- -- s: forza corsivo attivo
-- -- n: forza corsivo disattivo (è il valore di default)
-- ========================================================
function language._lang_testo(args)
	local txt = args.txt or args[2]
	if not txt then return '' end
	local language_code = args.lang or args[1]
	local direction = "ltr"
	if language_code then
		language_code = mw.ustring.lower(language_code)
		language_code = lg.alias[language_code] or language_code
		local writing = lg.scrittura[language_code]
		if writing then
			direction = writing[1]
			if #writing > 1 then language_code = writing[2] end
		end
	end
	local set_italic = args.corsivo or "n"
	if set_italic ~= "n" then
		local italic = false
		if set_italic:lower() == 's' then
			italic = true
		elseif language_code and lg.codici[language_code] then
			italic = not lg.codici[language_code][3]
		else
			italic = true
		end	  
		if italic then
			if txt[1]=="'" then txt = "<nowiki />" .. txt end
			if txt[#txt] =="'" then txt = txt .. "<nowiwiki />" end
			txt = mw.ustring.format("''%s''", txt)
		end
	end
	local span = mw.html.create('span'):wikitext(txt):addClass(args.class)
	if lg.codici[language_code] then
		span
			:attr('dir', direction)
			:attr('lang', language_code)
			:attr('xml:lang', language_code)
	end			
	return tostring(span)
end

-- ========================================================
-- Funzione di interfaccia per _lang_testo
-- richiamabile nei template
-- ========================================================
function language.lang_testo(frame)
	local args = getArgs(frame)
	return language._lang_testo(args)
end

-- Restituisce una tabella con tutti i codici riconosciuti dal modulo
function language.tabella(frame)

	-- genera una tabella codici -> lista alias e una di codici per ordinarla
	local alias_table = {}
	local codici_sorted = {}
	for code, _ in pairs(lg.codici) do
		alias_table[code] = {"'''" .. code .. "'''"}
		codici_sorted[#codici_sorted+1] = code
	end
	for alias, code in pairs(lg.alias) do
		if alias_table[code] then table.insert(alias_table[code], alias) end
	end
	table.sort(codici_sorted)

	local root = mw.html.create('table')
	root
		:addClass('wikitable sortable')
		:tag('tr')
			:tag('th'):wikitext('Codici'):done()
			:tag('th'):wikitext('[[template:Nomelingua/nome]]'):done()
			:tag('th'):wikitext('[[template:Nomelingua/voce]]'):done()
			:tag('th'):wikitext('[[template:Lingue]]')

	for _,code in ipairs(codici_sorted) do
		local code_string = table.concat(alias_table[code], ", ")
		local nome, voce = language.get_nome(code), language.get_voce(code)
		if voce ~= '' then voce = '[[' .. voce .. ']]' end
		root
			:tag('tr')
				:tag('td'):wikitext(code_string):done()
				:tag('td'):wikitext(nome):done()
				:tag('td'):wikitext(voce):done()
				:tag('td'):css('text-align', 'center'):wikitext(language.lingue({code}))
	end
	return tostring(root)
end

-- Restituisce una tabella degli alias in formato alias;codice
function language.tabella_alias(frame)

	local root = mw.html.create('table')
	root
		:addClass('wikitable sortable')
		:tag('tr')
			:tag('th'):wikitext('Alias'):done()
			:tag('th'):wikitext('codice'):done()
	for alias, code in pairs(lg.alias) do
		root
			:tag('tr')
				:tag('td'):wikitext(alias):done()
				:tag('td'):wikitext(code)
	end
	return tostring(root)
end

-- Restituisce una tabella dei codici in formato codice;nome;voce
function language.tabella_codici(frame)

	local root = mw.html.create('table')
	root
		:addClass('wikitable sortable')
		:tag('tr')
			:tag('th'):wikitext('Codice'):done()
			:tag('th'):wikitext('Nome'):done()
			:tag('th'):wikitext('Voce'):done()
	for code, valore in pairs(lg.codici) do
		root
			:tag('tr')
				:tag('td'):wikitext(code):done()
				:tag('td'):wikitext(valore[1]):done()
				:tag('td'):wikitext(valore[2])
	end
	return tostring(root)
end

-- ritorna una whitelist di tutti i codici riconosciuti ad uso bot in python
function language.whitelist(frame)
	local rows = { 'WHITELIST_LINGUE = set( [' }
	-- genera una tabella codici -> lista alias e una di codici per ordinarla
	local codici = {}
	for code, _ in pairs(lg.codici) do
		codici[#codici+1] = code
	end
	for alias, _ in pairs(lg.alias) do
		codici[#alias+1] = alias
	end
	table.sort(codici)
	for _, codice in ipairs(codici) do
		rows[#rows+1] = "	'" .. codice .."',"
	end
	rows[#rows+1] = "])"
	return table.concat(rows, '\n')
end

return language