La documentazione per questo modulo può essere creata in Modulo:Lingua/man

--modulo contenente funzioni di tipo linguistico (grammatica e ortografia italiana), da usare altrove
local p = {}
local c = require('Modulo:Common')

local vocali = {'A', 'E', 'I', 'O', 'U'}

-- true se è una vocale
function p.isVocale(lettera)
	 lettera = c.stripAccents( (lettera or ''):sub(1, 1) ):upper()
	 return c.contains(vocali, lettera)
end

function p.artDet(frame)
	return p.articoloDeterminativo(frame.args[1], frame.args[2], frame.args[3])
end

--ritorna la parola data preceduta dal corretto articolo
function p.articoloDeterminativo(parola, genere, numero)
	local art = p.determinaArticolo(parola, genere, numero)
	if art == 'l\'' then return art .. parola
	else return art .. ' ' .. parola end
end
	
--data una parola, ritorna il corretto articolo determinativo
function p.determinaArticolo(parola, genere, numero)
	genere = (genere or 'M'):upper()
	numero = (numero or 'S'):upper()
	local prima  = c.stripAccents(parola:sub(1, 1)):upper()
	local seconda= c.stripAccents(parola:sub(2, 2)):upper()
	
	if tonumber(parola) ~= nil then
		if genere == 'M' and numero == 'S' then
			if parola == '8' or parola == '11' then
				return 'l\''
			end
		end
	end
	
	if p.isVocale(prima) and not p.isVocale(seconda) then
		if numero == 'S' then
			return 'l\''
		else
			if genere == 'M' then return 'gli' end
		end
		
	elseif genere == 'M' and (
		(p.isVocale(prima) and p.isVocale(seconda))
		or prima..seconda == 'GN' or prima..seconda == 'PS' or prima..seconda == 'PN'
		or prima == 'Z' or prima == 'X' or prima == 'Y' or (prima == 'S' and not p.isVocale(seconda) ) ) then
			
			if numero == 'S' then return 'lo'
			else return 'gli' end
	end
	
	if genere == 'M' then
		if numero == 'S' then return 'il'
		else return 'gli' end
	else
		if numero == 'S' then return 'la'
		else return 'le' end
	end
end

--ritorna il genere (maschile/femminile) di una parola, sulla base di una lista di parole femminili
local paroleFemminili = {'lingua'}
function p.determinaGenere(parola)
	if c.contains(paroleFemminili, parola) then
		return 'F'
	else
		return 'M'
	end
end

function p.spezzaParole(stringa)
	local parole = {}
	for word in string.gmatch(stringa, "%w+") do
		table.insert(parole, word)
	end
	return parole
end

--ritorna la parola data, preceduta dalla preposizione (di a da in su) nella forma corretta
function p.prepArt(prep, parola, genere, numero)
	if prep == 'di' then prep = 'de' end
	if prep == 'in' then prep = 'ne' end
	
	local art = p.determinaArticolo(parola, genere, numero)
	if art == 'il' then return prep .. 'l ' .. parola
	elseif art == 'l\'' then return prep .. 'll\'' .. parola
	elseif art == 'lo' or art == 'la' or art == 'le' then return prep .. 'l' .. art .. ' ' .. parola
	else return prep .. art .. ' ' .. parola end
end


--metodo esposto al template PrepArt
function p.preposizioneArticolata(frame)
	local prep = frame.args[1]
	local parola = frame.args[2]
	local genere = p.determinaGenere(c.first(p.spezzaParole(parola)))
	local numero = 'S'
	if frame.args[3] and frame.args[3]:upper() == 'F' then genere = 'F' end
	if frame.args[4] and frame.args[4]:upper() == 'P' then numero = 'P' end
	return p.prepArt(prep, parola, genere, numero)
end

--ritorna la prima lettera del titolo fornito, ma escludendo gli eventuali articoli iniziale (IL, LO, LA, UN...)
function p.primaLetteraEsclusoArticolo(titolo)
	if not titolo or titolo == '' then return '' end
	titolo = titolo:gsub("^Il ", ''):gsub("^Il ", ''):gsub("^L'", ''):gsub("^Lo ", ''):gsub("^La ", ''):gsub("^Un ", ''):gsub("^Un'", ''):gsub("^Uno ", ''):gsub("^Una ", '')
		:gsub("^'", ''):gsub("^‛", ''):gsub("^’", ''):gsub("^ʿ", '')
	return titolo:sub(1, 1):upper()
end

--ritorna la prima lettera del titolo esclusi gli apostrofi e convertendo le lettere accentate o con diacritici nella corrispondente lettera base
function p.primaLettera(frame)
	titolo = frame.args[1] or ''
	titolo = titolo:gsub("^[. ]*", ''):gsub("^'", ''):gsub("^'", ''):gsub("^‛", ''):gsub("^’", ''):gsub("^ʼ", ''):gsub("^ʿ", '')
		:gsub("\"", ''):gsub("«", ''):gsub("%[", ''):upper()
		:gsub("^Æ", 'A'):gsub("^À", 'A'):gsub("^Á", 'A')
		:gsub("^Ć", 'C'):gsub("^Ç", 'C')
		:gsub("^È", 'E'):gsub("^É", 'E'):gsub("^Ë", 'E'):gsub("^ε", 'E')
		:gsub("^Ì", 'I'):gsub("^Í", 'I')
		:gsub("^Ò", 'O'):gsub("^Ó", 'O'):gsub("^Œ", 'O'):gsub("^Ø", 'O'):gsub("^Ö", 'O'):gsub("^Ô", 'O')
		:gsub("^Ù", 'U'):gsub("^Ú", 'U'):gsub("^Ü", 'U'):gsub("^Û", 'U')
		:gsub("^Ś", 'S'):gsub("^Ṡ", 'S'):gsub("Ž", 'Z')
	return titolo:sub(1, 1)
end

return p