Aller au contenu

Module:Nom dynastique

Depi Wikipedya, ansiklopedi lib

La documentation pour ce module peut être créée à Module:Nom dynastique/doc

local p = {}

local Outils = require( 'Module:Outils' )
local trim = Outils.trim
local Romains = require('Module:Chif women yo')
local conversion = Romains.conversion

-- Ce booléen permet d'indiquer si on doit prendre le complément du lien pour l'afficher (exemple : "Louis Ier d'Italie"); c'est le cas
-- de l'appel par le modèle Souverain3
local afficher_le_complement = false

local typenom = '[%C]+'

local function trouveRomain(chaine)
	local test = ' ' .. chaine .. ' '
	local positionDebut, _, quantieme = string.find(test, ' ([IVXLCDM]+),? ')
	if not positionDebut then
		positionDebut, _, quantieme = string.find(test, ' (Ier),? ')
	end
	if not positionDebut then
		positionDebut, _, quantieme = string.find(test, ' (Ire),? ')
	end
	if positionDebut then
		return positionDebut, positionDebut + string.len(quantieme) - 1, quantieme
	else
		return nil, nil, nil
	end
end

-- Extraction d'une chaîne, on recherche si c'est de la forme : "nom" "chiffres romains" "complément"
-- En retour, le premier paramètre indique s'il y a présence d'un nombre en chiffres romains
function p.chaine(chaine)
	local function extraction_elements(chaine)
		local positionDebut, positionFin, quantieme = trouveRomain(chaine)
		if not positionDebut then
			return false, '', '', ''
		end
		local nom = string.sub(chaine, 1, positionDebut - 2)
		local complement = ''
		if positionFin < string.len(chaine) then
			complement = trim(string.sub(chaine, positionFin + 1))
		end
		return true, nom, quantieme, complement
	end

	-- Si le paramètre passé n'existe pas, retour
	if not chaine or chaine == '' then
		return false, '<span class="error">Aucun paramètre</span>'
	end

	local presence_romain, nom, quantieme, complement = extraction_elements(chaine)

	return true, '', presence_romain, nom, quantieme, complement
end

function p.surnom(chaine)
	local presence_italiques, presence_guillemets, presence_dit, presence_virgule = false, false, false, false
	if mw.ustring.match(chaine, "''") then
		presence_italiques = true
		chaine = mw.ustring.gsub(chaine, "''", "")
	end
	if mw.ustring.match(chaine, '«') then
		presence_guillemets = true
		chaine = mw.ustring.gsub(chaine, '« ', '')
		chaine = mw.ustring.gsub(chaine, '«', '')
	end
	if mw.ustring.match(chaine, '»') then
		presence_guillemets = true
		chaine = mw.ustring.gsub(chaine, ' »', '')
		chaine = mw.ustring.gsub(chaine, '»', '')
	end
	if mw.ustring.match(chaine, ' dite? ') or (mw.ustring.sub(chaine, 1, 4) == 'dit ') or (mw.ustring.sub(chaine, 1, 5) == 'dite ') then
		presence_dit = true
		chaine = mw.ustring.gsub(chaine, 'dit ', '')
		chaine = mw.ustring.gsub(chaine, 'dite ', '')
	end
	if presence_italiques or presence_guillemets or presence_dit then
		if mw.ustring.match(chaine, ', ') then
			presence_virgule = true
			chaine = mw.ustring.gsub(chaine, ', ', ' ')
		end
	end

	return chaine, presence_italiques, presence_guillemets, presence_dit, presence_virgule
end

function p.nettoyage(chaine)
	-- remplacement des espaces insécables
	if chaine then
		chaine = chaine
			-- nbsp
			:gsub( '\194\160', ' ' )
			:gsub( '&nbsp;', ' ' )
			:gsub( '&#160;', ' ' )
			-- narrow nbsp
			:gsub( '\226\128\175', ' ' )
			:gsub( '&#8239;', ' ' )
			-- thin space
			:gsub( '\226\128\137', ' ' )
			:gsub( '&thinsp;', ' ' )
			:gsub( '&#8201;', ' ' )
			-- simple space
			:gsub( '&#32;', ' ' )
	end
	return chaine
end

-- Mise en forme, traitement des donneés
function p.traitement(a1, a2, a3, a4)
	local test = true
	local message = ''
	local lien = ''
	local nom = ''
	local quantieme = ''
	local complement = ''
	local nom_affiche = ''
	local quantieme_affiche = ''
	local complement_affiche = ''

	local presence_romains, presence_italiques, presence_guillemets

	a1 = p.nettoyage(a1)
	a2 = p.nettoyage(a2)
	a3 = p.nettoyage(a3)
	a4 = p.nettoyage(a4)

	-- Si le premier paramètre n'existe pas, retour
	if (a1 == '') and (a2 == '') then
		return false, '<span class="error">Paramètres absents</span>'
	end

	-- Test de présence d'un deuxième paramètre
	if a2 and a2 ~= '' then
		-- Cas où il y a au moins deux paramètres
		if string.match(a2, '^[IVXLCDM]+$') or a2 == 'Ier' or a2 == 'Ire' then
			-- Si le deuxième paramètre est un nombre en chiffres romains, on est dans le cas de :
			--{{Souverain|Louis|XIV|(roi de France)|, le Roi Soleil}} et similaires
			nom = a1
			nom_affiche = a1
			quantieme = a2
			test, message, quantieme_affiche = p.typo(quantieme)
			if not test then return test, message end
			lien = nom..' '..quantieme
			complement = ''
			if a3 then
				complement = a3
				if string.len(complement) > 0 then
					lien = lien..' '..p.surnom(complement)
				end
			end
			if not a4 then a4 ='' end
			if a4 == '' then
				if a3 and afficher_le_complement then
					complement_affiche = a3
				end
			else
				complement_affiche = a4
			end
		else
			-- Si le deuxième paramètre n'est pas un nombre en chiffres romains, soit il y a une erreur,
			-- soit on est dans le cas de :
			--{{Souverain|Louis XIV (roi de France)|, le Roi Soleil}} et similaires
			--ou {{Souverain|René II d'Anjou|René III de Poitiers}}
			--Il faut qu'il y ait un nombre romain dans au moins un des deux
			lien = a1
			-- On vérifie d'abord si complément contient un texte à mettre en forme, auquel cas il s'impose sur le libellé du lien
			test, message, presence_romains, nom, quantieme, complement = p.chaine(a2)
			if not test then return test, message end
			if presence_romains then
				test, message, quantieme_affiche = p.typo(quantieme)
				if not test then return test, message end
				nom_affiche = nom
				if complement then
					complement_affiche = complement
				end
			else
				test, message, presence_romains, nom, quantieme, complement = p.chaine(a1)
				if not test then return test, message end
				nom_affiche = nom
				if presence_romains then
					test, message, quantieme_affiche = p.typo(quantieme)
					if not test then return test, message end
					complement_affiche = a2
				else
					test = false
					message = '<span class="error">Un nombre en chiffres romains est requis</span>'
				end
			end
		end
	else
		-- Si le deuxième paramètre n'existe pas, on est dans le cas de : {{Souverain|Louis XIV de France}} et similaires
		test, message, presence_romains, nom, quantieme, complement = p.chaine(a1)
		if not test then return test, message end
		lien = a1
		if presence_romains then
			nom_affiche = nom
			test, message, quantieme_affiche = p.typo(quantieme)
			if not test then return test, message end
		end
		lien, presence_italiques, presence_guillemets = p.surnom(lien)
		if afficher_le_complement == true then
			if trim(complement) then
				complement_affiche = trim(complement)
			else
				if (presence_italiques or presence_guillemets) and not presence_romains then
					complement_affiche = a1
				else
					afficher_le_complement = false
				end
			end
		end
	end
	return test, message, lien, nom_affiche, quantieme_affiche, complement_affiche
end

function p.typo(quantieme)
	local test = true
	local message = ''
	-- Mise en forme typographique : éventuelle infobulle et éventuel exposant à partir du chiffre romain envoyé
	-- On obtient le "quantième affiché"

	-- On teste d'abord si on a une chaine de la forme "Ier" ou "Ire"
	local test1 = 'non'
	if string.len(quantieme) > 2 then
		test1 = string.sub(quantieme, -2)
	end

	-- émulation des modèles {{Ire}}, {{III}}
	local infobulle = ''
	local exposant = 'non'
	local numero = ''
	local fin = ''
	local quantieme_affiche = ''
	if (test1 == 're') or (test1 == 'er') then
		if test1 == 're' then
			exposant = '<sup>re</sup>'
			infobulle = 'première'
		else
			exposant = '<sup>er</sup>'
			infobulle = "premier"
		end
		quantieme = 'I'..test1
		numero = 'I'
		fin = '</span>'..exposant..'</abbr>'
	else
		quantieme = string.upper(quantieme)
		test, message, infobulle = conversion(quantieme)
		if not test then return test, message, '' end
		numero = quantieme
		fin = '</span></abbr>'
	end
	if infobulle == ''	then
		infobulle = 'inconnu'
	end
	quantieme_affiche = '<abbr class="abbr" title="'..infobulle..'" ><span class="romain" style="text-transform:uppercase">'..numero..fin
	return test, message, quantieme_affiche
end

function p.typo_complement(chaine)
	if chaine then
		if string.len(chaine) > 0 then
-- si le complement affiché (", le Roi Soleil" dans le cas de Louis XIV) commence par une virgule, on ne met pas d'espace avant,
-- mais on vérifie qu'il y a bien une espace entre la virgule et le mot suivant
			if not (string.sub(chaine, 1, 1) == ',') then
				chaine = ' '..chaine
			end
-- S'il y a des guillemets, on compense le bug qui empêche la gestion correcte des insécables dans un lien wiki
			if mw.ustring.match(chaine, '« '..typenom..' »') then
				chaine = mw.ustring.gsub(chaine, '« ', '«&#160;')
				chaine = mw.ustring.gsub(chaine, ' »', '&#160;»')
			end
		end
	end
	return true, '', chaine
end

-- Fonction de mise en forme du lien à afficher
-- de la forme [[lien | "nom affiché"&nbsp;"quantième affiché" "complément affiché" ]], les éléments de la partie droite sont optionnels
function p.ecriture_avec_lien(lien, nom_affiche, quantieme_affiche, complement_affiche)
	local test = true
	local texte1 = ''

	local test, message, complement_affiche2 = p.typo_complement(complement_affiche)

	texte1 = '[['..lien
	if nom_affiche then
		if string.len(nom_affiche) > 0 then
			if string.len(quantieme_affiche) > 0 then
				-- S'il y a un nombre, ajout d'un "nowrap" pour l'espace insécable
				texte1 = texte1..'|<span class="nowrap">'..nom_affiche..' '..quantieme_affiche..'</span>'
				if complement_affiche2
				then
					if string.len(complement_affiche2) > 0 then
						texte1 = texte1..complement_affiche2
					end
				end
			else
				texte1 = texte1..'|'..nom_affiche
				if string.len(complement_affiche2) > 0 then
					texte1 = texte1..complement_affiche2
				end
			end
		end
	else
		if complement_affiche2 then
			if string.len(complement_affiche2) > 0 then
				texte1 = texte1..'|'..trim(complement_affiche2)
			end
		end
	end
	texte1 = texte1.."]]"
	return test, message, texte1
end

function p.ecriture_sans_lien(lien, nom_affiche, quantieme_affiche, complement_affiche)
	local test = true
	local message = ''
	local texte1 = ''

	local test, message, complement_affiche2 = p.typo_complement(complement_affiche)

	if quantieme_affiche and nom_affiche then
		if (string.len(nom_affiche) > 0) then
			if string.len(quantieme_affiche) > 0 then
				-- S'il y a un nombre, ajout d'un "nowrap" pour l'espace insécable
				texte1 = texte1..'<span class="nowrap">'..nom_affiche..' '..quantieme_affiche..'</span>'
				if complement_affiche2 then
					texte1 = texte1..complement_affiche2
				end
			else
				if complement_affiche2 then
					texte1 = texte1..nom_affiche..complement_affiche2
				end
			end
		else
			texte1 = texte1..quantieme_affiche
			if complement_affiche2 then
				texte1 = texte1..complement_affiche2
			end
		end
	else
		if complement_affiche2 then
			if string.len(complement_affiche2) > 0 then
				texte1 = texte1..trim(complement_affiche2)
			end
		end
	end
	if texte1 == '' then
		texte1 = lien
	end
	return test, message, texte1
end

-- Affichage dans le cas général (émule le modèle Souverain2)
function p.Souverain2(frame)
	local args = Outils.extractArgs( frame )
	local arg1 = trim(args[1]) or ''
	local arg2 = trim(args[2]) or ''
	local arg3 = trim(args[3]) or ''
	local arg4 = trim(args[4]) or ''

	local test, message, t1, t2, t3, t4 = p.traitement(arg1, arg2, arg3, arg4)
	if not test then
		return message
	end

	local test, message, texte = p.ecriture_avec_lien(t1, t2, t3, t4)
	if not test then
		return message
	else
		return texte
	end
end

-- Affichage dans le cas où le lien est de la forme [[Charles V le Sage|{{nobr|Charles V}} le Sage]]
-- correspond au modèle Souverain3, ce qui permet d'écrire :
-- {{Souverain3|Charles V le Sage}}
-- plutôt que :
-- {{Souverain2|Charles V le Sage|le Sage}}
-- (émule le modèle Souverain3)
function p.Souverain3(frame)
	local args = Outils.extractArgs( frame )
	local a1 = trim(args[1]) or ''
	local a2 = trim(args[2]) or ''
	local a3 = trim(args[3]) or ''
	local a4 = trim(args[4]) or ''

	afficher_le_complement = true
	local test, message, t1, t2, t3, t4 = p.traitement(a1, a2, a3)
	if not test then
		return message
	end

	local test, message, texte = p.ecriture_avec_lien(t1, t2, t3, t4)
	if not test then
		return message
	else
		return texte
	end
end

-- Affichage dans le cas où on veut une mise en forme correspndant à {{nobr|Charles {{V}}}} ou {{nobr|Louis {{Ier}}}}
-- Aucune mise en forme s'il n'y a pas un nombre en chiffres romains
-- (correspond au modèle Souverain-)
function p.Souverain_sans_lien(frame)
	local args = Outils.extractArgs( frame )
	local a1 = trim(args[1]) or ''
	local a2 = trim(args[2]) or ''
	local a3 = trim(args[3]) or ''
	local a4 = trim(args[4]) or ''

	afficher_le_complement = false
	local test, message, t1, t2, t3, t4 = p.traitement(a1, a2, a3, a4)
	if not test then
		return message
	end

	local test, message, texte = p.ecriture_sans_lien(t1, t2, t3, t4)
	if not test then
		return message
	else
		return texte
	end
end

return p