Aller au contenu

Module:Nom dynastique

Cette page fait l’objet d’une mesure de semi-protection étendue.
Une page de Wikipédia, l'encyclopédie libre.
Ceci est une version archivée de cette page, en date du 8 octobre 2017 à 11:31 et modifiée en dernier par Rehtse (discuter | contributions) (nettoyage). Elle peut contenir des erreurs, des inexactitudes ou des contenus vandalisés non présents dans la version actuelle.

 Documentation[voir] [modifier] [historique] [purger]

Ce module est utilisé par les modèles {{Souverain2}}, {{Souverain3}} et {{Souverain-}}.

Utilisation

Fonctions exportables :

  • fonction(frame) – description (courte description de fonction(frame) et autres informations pertinentes).
  • fonction2() – description2 (courte description de fonction2() et autres informations pertinentes).

Autres fonctions :

  • fonction() – description2 (courte description de fonction() et autres informations pertinentes).

Modules externes et autres éléments dont ce module a besoin pour fonctionner :

  • mw.title – description (courte description expliquant la dépendance de ce module externe).

Exemples

Pour des exemples, voir la page de test permettant de tester diverses modifications apportées.



local p = {}

local Outils = require( 'Module:Outils' )
local trim = Outils.trim

--  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

-- Gestion des erreurs
local erreur = ""

-- Types de chaînes
local typenom = "[a-zA-ZÇÉÈŒéèàùâêîôûëïöüçæœ%'%-]+"
local typeromains = "[IVXLCDMer]+"
local typecomplement = "[a-zA-ZÇÉÈŒéèàùâêîôûëïöüçæœ%'%- ]+"

-- Variables
local niveau_par_chiffre = { ['I']={1, false},
	['IV'] = {4, false},
	['V'] = {5, false},
	['IX'] = {9, false},
	['X'] = {10, false},
	['XL'] = {40, false},
	['L'] = {50, false},
	['XC'] = {90, false},
	['C'] = {100, false},
	['CD'] = {400, false},
	['D'] = {500, false},
	['CM'] = {900, false},
	['M'] = {1000, false}
	}
		
local lien = ""
local complement = ""
local nom = ""
local quantieme = ""
local quantiemeaffiche = ""
local extension

-- Restitution de la valeur d'une suite de chiffres romains identiques : XXX..., III..
-- On récupère le chiffre romain composant cette séquence, le nombre d'occurrence et la chaîne de départ tronquée de la séquence traitée
function p.niveau(romains)
	local longueur_chaine = string.len(romains)
	local valeur = 0
	local rang = string.sub(romains, 1, 1)
	local caractere = rang		
	while (valeur < longueur_chaine) and (caractere == rang) do
		valeur = valeur + 1
		romains = string.sub(romains, 2)
		caractere = string.sub(romains, 1, 1)
	end
	return romains, rang, valeur
end

-- Fonction destinée à gérer les séquences particulières (IV, IX, XL, XC, CD, CM), avec test de cohérence
function p.uniques (depart, romains, chaine)
	local nb = 0
	local resultat = 0
	local test = true
	
	romains, nb = string.gsub(romains, chaine, '')
	if nb > 1 then
		test = false
		message = Outils.erreur('Nombre romain incorrect, répétition de séquence incohérente ('..nb..' '..chaine..')')
	else
		if nb == 1 then
			resultat = niveau_par_chiffre[chaine][1]
		end
	end
	return test, message, resultat, romains
end

-- Conversion d'un nombre romain et entier du système décimal, avec tests de cohérence
function p.conversion (romains)
	local message = ''
	local resultat, valeur = 0, 0
	local rang = ''
	local depart = romains
	local niveau = 10000
-- Cas des valeurs obtenues par soustraction du chiffre placé à gauche du chiffre significatif, séquences qui doivent être uniques
-- A/  Unités : IV et IX
	if string.match(romains, 'IX') then
		test, message, resultat, romains = p.uniques (depart, romains, 'IX')
		if not test then return test, message, resultat end
	else
		if string.match(romains, 'IV') then
			test, message, resultat, romains = p.uniques (depart, romains, 'IV')
			if not test then return test, message, resultat end
			niveau_par_chiffre['V'][2] = true
		end
	end

-- B  Dizaines : XL et XC
	if string.match(romains, 'XL') then
		test, message, valeur, romains = p.uniques (depart, romains, 'XL')
		if not test then return test, message, resultat end
		niveau_par_chiffre['L'][2] = true
	else
		if string.match(romains, 'XC') then
			test, message, valeur, romains = p.uniques (depart, romains, 'XC')
			if not test then return test, message, resultat end
		end
	end
	resultat = resultat + valeur
	
-- C/  centaines : CD et CM
	valeur = 0
	if string.match(romains, 'CD') then
		test, message, valeur, romains = p.uniques (depart, romains, 'CD')
		if not test then return test, message, resultat end
		niveau_par_chiffre['D'][2] = true
	else
		if string.match(romains, 'CM') then
			test, message, valeur, romains = p.uniques (depart, romains, 'CM')
			if not test then return test, message, resultat end
		end
	end
	resultat = resultat + valeur
	
-- Une fois les cas particuliers traités, la chaine ne contient plus que des séquences" de chiffres identiques
-- Ces séquences sont limitées à 4 occurrences (écriture simplifiée), sauf pour les milliers
-- Contrôle de l'unicité de présence des chiffres V, L et D
-- Contrôle de cohérence (on ne peut pas avoir une séquence du chiffre n si une séquence de chiffres d'un' niveau inférieur à n a déjà été traitée)
	valeur = 0
	test = true

	while not(romains=='') and test do
		romains, rang, valeur = p.niveau (romains)
		if not string.match(rang, typeromains) then
			test = false
			message = Outils.erreur('Chiffre romain incorrect ('..rang..')')
		else
			if ((valeur > 4) and not (rang == 'M'))
			or niveau_par_chiffre[rang][2]
			or (((rang == 'V') or (rang == 'L') or (rang == 'D')) and (valeur > 1)) then
				test = false
				message = Outils.erreur('Nombre romain incorrect, répétiion de chiffre ('..rang..')')
			else
				if niveau_par_chiffre[rang][1] > niveau then
					test = false
					message = Outils.erreur('Nombre romain incorrect, séquence incohérente ('..depart..')')
				else
					niveau_par_chiffre[rang][2] = true
					niveau = niveau_par_chiffre[rang][1]
					resultat = resultat + valeur*niveau
				end
			end
		end
	end
	return test, message, resultat
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 nom = ""
	local quantieme = ""
	local complement = ""
	local type_romain = false
	-- Si le paramètre passé n'existe pas, retour
	if not chaine
	then
		erreur = 'Lien absent'
		return
	else
		if string.len(chaine) == 0
		then
			erreur = 'Lien vide'
			return
		end
	end
	local nom = string.match( chaine, typenom, 1)
	-- Si le nom contient des caractères non prévus, retour
	if not nom
	then
		erreur = 'Lien incorrect'
		return
	end
	local format_nom_romain_complement = false
	local format_nom_romain = false
	local format_nom_complement = false

	local presence_romain = false
	if chaine:match (typenom..' '..typeromains..' ') then format_nom_romain_complement = true end
	if chaine:match (typenom..' '..typeromains) then format_nom_romain = true end

	if format_nom_romain_complement or format_nom_romain then presence_romain = true end
		
	if presence_romain
	then
		quantieme = string.match(chaine, typeromains, string.len(nom)+2)
 		if format_nom_romain_complement
		then
			complement = string.sub(chaine, string.len(nom..quantieme)+2)
			complement = trim(complement)
		else
			if string.len(nom..' '..quantieme) < string.len(chaine) then
				quantieme = string.sub(chaine, string.len(nom)+2)
			end
		end
	end
	
	return presence_romain, nom, quantieme, complement
end

-- Mise en forme, traitement des donneés
function p.traitement (a1, a2, a3, a4)
	local lien = ""
	local nom = ""
	local quantieme = ""
	local complement = ""
	local nom_affiche = ""
	local quantieme_affiche = ""
	local complement_affiche = ""
	-- Si le premier paramètre n'existe pas, retour
	if not a1 then
		erreur = 'lien absent'
		return
	end
	
	-- Test de présence d'un deuxième paramètre
	local parametre2 = false
	if a2 then
		if string.len(a2) > 0 then
			parametre2 = true
		end
	end
	if parametre2 then
		-- Ca où il y a au moins deux paramètres
		if a2 == string.match(a2, typeromains) 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
		    quantieme_affiche = p.typo(quantieme)
		    lien = nom..' '..quantieme
		    local parametre3 = false
		    if a3 then
		    	if string.len(a3) > 0 then
			    	complement = a3
			    	lien = lien..' '..complement
			    end
		    end
		    if afficher_le_complement == true then
		    	complement_affiche = a3
		    else
		    	if a4 then
			    	if string.len(a4) > 0 then
				    	complement_affiche = a4
				    end
				end
			end
		else
			-- Si le deuxième paramètre n'est pas un nombre en chiffres romains, on est dans le cas de :
			--{{Souverain|Louis XIV (roi de France)|, le Roi Soleil}} et similaires
			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
			c1, c2, c3, c4 = p.chaine (a2)
			if c1 == true then
				quantieme_affiche = p.typo(c3)
				nom_affiche = c2
				if c4 then
					if string.len(c4) > 0 then
						complement_affiche = c4
					end
				end
			else
				c1, c2, c3, c4 = p.chaine (a1)
				nom_affiche = c2
				quantieme_affiche = p.typo(c3)
				complement_affiche = a2
			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
		c1, c2, c3, c4 = p.chaine (a1)
		lien = a1
		if c1 then
			nom_affiche = c2
			quantieme_affiche = p.typo(c3)
		end
		if afficher_le_complement == true then
			if trim(c4) then
				complement_affiche = trim(c4)
			else
				afficher_le_complement = false
			end
		end
	end
	return lien, nom_affiche, quantieme_affiche, complement_affiche
end

function p.typo(quantieme)
	-- 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.reverse(quantieme)
		test1 = string.sub(test1, 1, 2)
		test1 = string.reverse(test1)
	end
	
	-- émulation des modèles {{Ire}}, {{III}}
	local infobulle = ""
	local abbr = ""
	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 = p.conversion (quantieme)
		if not test then
			return message
		end
 		numero = quantieme
		fin = '</span></abbr>'
	end
	if infobulle == nil	then
		infobulle = "inconnu"
	end
	quantieme_affiche = '<abbr class="abbr" title="'..infobulle..'" ><span class="romain" style="text-transform:uppercase">'..numero..fin
	return quantieme_affiche
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 texte1 = ""
	local complement_affiche2 = complement_affiche
	-- 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 complement_affiche then
		if string.len(complement_affiche) > 0 then
			if string.sub(complement_affiche, 1, 1) == "," then
				if string.sub(complement_affiche, 2, 1) ~= " " then
					complement_affiche2 = ", "..string.sub(complement_affiche, 2)
				end
			end
		end
	end
	texte1 = '[['..lien
	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
	else
		if complement_affiche2 then
			if string.len(complement_affiche2) > 0 then
				texte1 = texte1..'|'..complement_affiche2
			end
		end
	end
 	texte1 = texte1.."]]"
	return texte1
end

function p.ecriture_sans_lien (lien, nom_affiche, quantieme_affiche, complement_affiche)
	local texte1 = ""
	local complement_affiche2 = complement_affiche
	-- 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 complement_affiche then
		if string.len(complement_affiche) > 0 then
			if string.sub(complement_affiche, 1, 1) == "," then
				if string.sub(complement_affiche, 2, 1) ~= " " then
					complement_affiche2 = ", "..string.sub(complement_affiche, 2)
				end
			end
		end
	end
	if quantieme_affiche and (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
	else
		if complement_affiche2 then
			if string.len(complement_affiche2) > 0 then
				texte1 = texte1..complement_affiche2
			end
		end
		if texte1 == "" then
			texte1 = lien
		end
	end
	return 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, arg2, arg3, arg4 = args[1] or "", args[2] or "", args[3] or "", args[4] or ""
	
	local t1, t2, t3, t4 = p.traitement(arg1, arg2, arg3, arg4)
	if string.len(erreur) > 0 then
		return erreur
	end
	
    local texte = p.ecriture_avec_lien (t1, t2, t3, t4)
   	if string.len(erreur) > 0 then
		return erreur
	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, a2, a3 = args[1] or "", args[2] or "", args[3] or ""
	
    afficher_le_complement = true
	local t1, t2, t3, t4 = p.traitement(a1, a2, a3)
   	if string.len(erreur) > 0 then
		return erreur
	end
	
    local texte = p.ecriture_avec_lien (t1, t2, t3, t4)
   	if string.len(erreur) > 0 then
		return erreur
	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, a2, a3, a4 = args[1] or "", args[2] or "", args[3] or "", args[4] or ""
	
    afficher_le_complement = true
	local t1, t2, t3, t4 = p.traitement(a1, a2, a3, a4)
   	if string.len(erreur) > 0 then
		return erreur
	end
	
    local texte = p.ecriture_sans_lien (t1, t2, t3, t4)
   	if string.len(erreur) > 0 then
		return erreur
	else
    	return texte
    end
end

return p