Module:Nombre2texte
Ce module contient différentes fonction pratiques.
1 Résumé des fonctions
Fonctions exportables :
ordinal( nombre, feminin )
– retourne un ordinal abrégé comme {{1er}}, {{2e}}… à partir d’un nombre ou d’une chaîne contenant uniquement des chiffres. Si le deuxième paramètre est défini, retourne 1re au lieu de 1er.nombre2texte_reel(pnombre, plangue, ptype, porthographe, pgenre, pmajuscule)
– transforme un nombre en texte (5 → cinq ou cinquième). Gère la langue (fr, be, ch), l’orthographe pré ou post 1990, le genre ainsi que les variantes locales des nombres.nombre2texte(frame)
– similaire à nombre2texte_reel mais pour un appel depuis un modèle.
Modules externes et autres éléments dont ce module a besoin pour fonctionner :
Module:Nombre2texte/Data
– pour les conversions nombre → texte.
2 Détail par fonction
2.1 nombre2texte_reel
2.1.1 Syntaxe
Nombre2texte.nombre2texte_reel( pnombre, plangue, ptype, porthographe, pgenre, pmajuscule )
Retourne la forme textuelle du nombre passé en paramètre. Supporte l’orthographe pré/post 1990, la création d’ordinaux ou de cardinaux et les variantes de certains nombres (septante, nonante, huitante…).
2.1.2 Contraintes
- Ne traite que les nombres entre -999999999999 et 999999999999 (inclus).
- Ne gère pas les nombres à point flottant (avec une virgule) — la partie décimale est ignorée, et seule la partie entière est traitée.
- Pour les ordinaux, seuls les nombres positifs sont traités (un nombre négatif est accepté mais son signe est ignoré).
2.1.3 Paramètres
pnombre
– doit être une chaîne de caractères. Le nombre à convertir.plangue
– langue utilisée. Valeurs possibles : "fr" (soixante-dix, quatre-vingts, quatre-vingt-dix) ; "be" (septante, quatre-vingts, nonante) ; "ch" (septante, huitante, nonante) ; "ch2" (septante, octante, nonante). Une valeur vide correspond à "fr".ptype
– le type de sortie. Seules valeurs possibles : nil ou "ordinal". Si "ordinal" l’ordinal correspondant au nombre est généré (exemple : 12 → "douzième") sinon un cardinal est généré (exemple : 12 → "douze"). nil correspond à un cardinal.porthographe
– le type d’orthographe suivi. Valeurs possibles : nil ou "réformée". Si “réformée”, l’orthographe post-1990 est utilisée (tirets entre chaque termes) sinon c’est l’orthographe « historique » qui est suivie.pgenre
– le genre du nombre. Valeurs possibles : nil ou "féminin". Si “féminin”, la seule différence est pour les ordinaux (« premier » devient « première »); aucun changement dans les autres cas.pmajuscule
– mettre une majuscule à la première lettre. Valeurs possibles : nil ou “oui”. Si « oui », la première lettre du résultat est mise en majuscule, sinon elle reste en minuscule.
2.1.4 Exemples
Voir ci-dessous.
2.2 nombre2texte
Même fonction que ci-dessus mais pour un appel depuis un article (via un modèle).
2.2.1 Paramètres
Voir ci-dessus pour les détails.
- Premier paramètre non nommé – le nombre à convertir (format numérique).
langue=
– la langue utilisée (vide ou "fr" (équivalents), "be", "ch" ou "ch2").orthographe=
– l’orthographe suivie (vide ou "réformée").genre=
– le genre du résultat (vide ou "féminin").majuscule=
– mettre une majuscule à la première lettre (vide ou “oui”).type
– générer un cardinal ou un ordinal (absent ou “ordinal”).
2.2.2 Exemples
Appel de base : {{#invoke:Nombre2texte|nombre2texte|132}}
→ cent trente-deux
Ordinal : {{#invoke:Nombre2texte|nombre2texte|132|type=ordinal}}
→ cent trente-deuxième
Majuscule : {{#invoke:Nombre2texte|nombre2texte|132|majuscule=oui}}
→ Cent trente-deux
Langue : {{#invoke:Nombre2texte|nombre2texte|198|langue=be}}
→ cent nonante huit
Genre : {{#invoke:Nombre2texte|nombre2texte|1|genre=féminin|type=ordinal}}
→ première
Orthographe : {{#invoke:Nombre2texte|nombre2texte|1927|orthographe=réformée}}
→ mille-neuf-cent-vingt-sept
local p = { }
--[[
ordinal renvoie une chaine correspondant à l'abréviation de l'adjectif ordinal du nombre.
Paramètres :
1 = nombre (string ou number)
2 = true pour avoir première au lieu de premier su nombre = 1
--]]
function p.ordinal( nombre, feminin )
local num = tonumber( nombre )
if num == nil then
return mw.text.trim( tostring( nombre ) or '' )
else
local nom = p.nombre2texte_reel( nombre, nil, 'ordinal', 'réformée', feminin and 'féminin' )
local exposant
if num == 1 then
exposant = (feminin and 're' or 'er')
else
exposant = 'e'
end
return '<abbr class="abbr" title="' .. nom .. '">' .. num .. '<sup>' .. exposant .. '</sup></abbr>'
end
end
--[[
Fonction de traitement d'une "tranche" de nombres entre 0 et 999.
Retourne la forme texturelle (5 → cinq, 46 → quarante six, 432 → quatre cent trente deux…)
Les paramètres sont les chiffres, du plus grand au plus petit (centaine, dizaine, unité).
La valeur nil signifie "0" (pour n'importe lequel des paramètres)
La fonction retourne le texte ou 'nil' si la valeur est zéro (pour gérer les 0 millier…)
Le paramètre 'langue' indique la variante de langue (fr, be, ch ou ch2).
Data est la table des données (issue de loadData())
--]]
function p.traite_tranche(_c1, _c2, _c3, langue, Data)
local c1, c2, c3
if (_c1 == nil) then c1 = 0 else c1 = tonumber(_c1) or 0 end
if (_c2 == nil) then c2 = 0 else c2 = tonumber(_c2) or 0 end
if (_c3 == nil) then c3 = 0 else c3 = tonumber(_c3) or 0 end
if (c1 == 0 and c2 == 0 and c3 == 0) then
return nil -- sil signifie "zéro" (mais à traiter spécialement quand entouré)
end
local resu = ""
-- on calcule la valeur restante (sans les centaines)
local val = 10*c2 + c3
-- présence d'une centaine ?
if (c1 ~= 0) then
if (c1 == 1) then
resu = "cent " -- séparateur
else
-- plusieurs centaines : on ajoute l'unité
resu = Data.infcent[c1] .. " cent"
-- si pas d'unité 100 prend un 's'
if (val == 0) then
resu = resu .. "s "
else
resu = resu .. " "
end
end
end
-- reste = 0 ?
if (val == 0) then
-- on retourne directement la centaine
return resu
end
-- c'est forcément un nombre pré-défini
local vvv
if (langue == "fr") then
vvv = Data.infcent[val]
elseif (langue == "be") then
vvv = Data.infcent_be[val] or Data.infcent[val]
elseif (langue == "ch") then
vvv = Data.infcent_ch[val] or Data.infcent_be[val] or Data.infcent[val]
else
vvv = Data.infcent_ch2[val] or Data.infcent_be[val] or Data.infcent[val]
end
return resu .. vvv .. " "
-- note : cette fonction retourne *toujours* un " " à la fin du terme
end
--[[
Fonction principale
Reçoit en paramètre (premier non nommé) le nombre à traiter.
Retourne la forme textuelle de ce nombre.
--]]
function p.nombre2texte_reel(pnombre, plangue, ptype, porthographe, pgenre, pmajuscule, pordinal)
-- le nombre à convertir (vient toujours du modèle)
local valeur = pnombre
if (valeur == nil) then
return '<span class="error">Il faut un paramètre non nommé numérique.</span>'
elseif type(valeur) == "sting" then
-- s'il y a une virgule, on l'ignore
local bla = mw.ustring.find(valeur, "[.,]")
if (bla ~= nil) then
-- extraction de la partie avant la virgule
valeur = mw.ustring.match(mw.text.trim(valeur), "^[-]?[0-9]*")
end
elseif type(valeur) == "number" then
valeur = math.floor(valeur)
end
local nvaleur = tonumber(valeur)
if (type(nvaleur) ~= "number") then
return '<span class="error">Le paramètre doit être un nombre.</span>'
end
-- limites
if (nvaleur < -999999999999 or nvaleur > 999999999999) then
return '<span class="error">Nombre trop grand ou trop petit.</span>'
end
-- note : ici il faudrait s'assurer que le nombre est un entier !
-- on extrait le moins si présent
local signe = false
if (nvaleur < 0) then
nvaleur = -nvaleur
signe = true
end
-- option : choix de la langue
local langue = plangue
if (langue == nil) then
langue = "fr"
else
langue = mw.text.trim(langue)
end
-- validation des valeurs permises
if (langue ~= "fr" and langue ~= "be" and langue ~= "ch" and langue ~= "ch2") then
return '<span class="error">Paramètre langue non reconnu (fr, be, ch ou ch2).</span>'
end
-- type de résultat : seule valeur autorisée : 'ordinal'
local style = ptype
if (style ~= nil and style ~= "ordinal") then
style = nil
end
-- type d'orthographe
local ortho = porthographe
if (ortho ~= nil and ortho ~= "réformée") then
ortho = nil
end
-- genre : uniquement pour l'ordinal "premier / première"
local genre = pgenre
if (genre ~= nil and genre ~= "féminin") then
genre = nil
end
-- majuscule : mettre une majuscule au premier mot
local maj = pmajuscule
if (maj ~= nil and maj ~= "oui") then
maj = nil
end
-- cas (très) simple : 0
if (nvaleur == 0) then
if (style == "ordinal") then
if (maj) then
return "Zéroième"
else
return "zéroième"
end
else
if (maj) then
return "Zéro"
else
return "zéro"
end
end
end
-- on charge les données
local Data = mw.loadData( 'Module:Nombre2texte/Data' )
-- on traite les autres cas simples : le nombre est pré-codé
local val
if (langue == "fr") then
val = Data.infcent[nvaleur]
elseif (langue == "be") then
val = Data.infcent_be[nvaleur] or Data.infcent[nvaleur]
elseif (langue == "ch") then
val = Data.infcent_ch[nvaleur] or Data.infcent_be[nvaleur] or Data.infcent[nvaleur]
else
val = Data.infcent_ch2[nvaleur] or Data.infcent_be[nvaleur] or Data.infcent[nvaleur]
end
local res = val or ""
if (val == nil) then
-- pas de résultat, on fait le "calcul"
-- on l'éclate en une table des différents caractères
local tvaleur = mw.text.split(valeur, "")
local nb = #tvaleur -- nombre d'éléments
-- on boucle sur les triplets de chiffres et on stocke le résultat dans une table
local tbl = {}
while (true) do
-- on prend les 3 valeurs concernées
local p1 = tvaleur[nb-2]
local p2 = tvaleur[nb-1]
local p3 = tvaleur[nb]
-- si les 3 sont 'nil' on a terminé
if (p1 == nil and p2 == nil and p3 == nil) then
break
end
-- on calcule la valeur du bloc concerné (rangé dans la table)
local tmp = mw.text.trim(p.traite_tranche(p1, p2, p3, langue, Data) or "zéro")
table.insert(tbl, tmp)
-- décalage
nb = nb - 3
end
-- on construit le résultat final en combinant les éléments
-- et en ajoutant les milliers/millions/...
local pos = 1
while (tbl[pos] ~= nil) do
local el = ""
-- on l'ajoute, s'il existe
if (tbl[pos] ~= "zéro " and tbl[pos] ~= "zéro") then
if (pos == 1) then
-- rang "1", on ajoute simplement la valeur
el = tbl[pos] .. " "
else
-- si la valeur est "un" on ajoute seulement le rang
if (tbl[pos] == "un " or tbl[pos] == "un") then
el = Data.sup[pos] .. " "
else
-- on ajoute X + rang
el = tbl[pos] .. " " .. Data.sup[pos]
-- le pluriel, sauf pour 1000, et le séparateur
if (pos ~= 2) then
el = el .. "s "
else
el = el .. " "
end
end
end
end
-- on insert
res = el .. res
-- on passe au suivant
pos = pos + 1
end
-- suppression espaces
res = mw.text.trim(res)
end -- fin (si on n'avait pas trouvé en pré-défini)
if (style ~= nil) then
-- ordinal : on cherche la fin du nombre pour ajouter le "ième" qui convient
if (res == "zéro") then
res = "zéroième" -- eurk!
elseif (res == "un") then
if (genre == nil) then
res = "premier"
else
res = "première"
end
else
-- on récupère le dernier mot
local fin = mw.ustring.match(res, "%a*$")
-- on récupère le reste (début)
local debut = mw.ustring.gsub(res, "%a*$", "")
-- on génère la fin en ordinal
local nfin = Data.iemes[fin]
if (nfin == nil) then
nfin = '<span class="error">erreur interne d\'ordinal.</span>'
end
res = debut .. nfin
end
end
-- si orthographe réformée on remplace les espaces par des tirets
if (ortho == "réformée") then
res = mw.ustring.gsub(res, "[ ]", "-")
else
-- sinon on remplace les espaces par des insécables
res = mw.ustring.gsub(res, "[ ]", " ")
end
if (style == nil) then
-- traitement de signe éventuel (sauf ordinaux)
if (signe) then
res = "moins " .. res
end
end
-- si demandé on passe la première lettre en majuscule
if (maj) then
local langage = mw.getContentLanguage()
res = langage:ucfirst(res)
end
-- on retourne
return res
end
--[[
Fonction principale
Reçoit en paramètre (premier non nommé) le nombre à traiter.
Retourne la forme textuelle de ce nombre.
--]]
function p.nombre2texte(frame)
local pframe = frame:getParent()
return p.nombre2texte_reel(
pframe.args[1] or frame.args[1], -- pas obligé. Pour permettre des exemples, avec priorité au modèle
frame.args["langue"] or pframe.args["langue"],
frame.args["type"] or pframe.args["type"],
frame.args["orthographe"] or pframe.args["orthographe"],
frame.args["genre"] or pframe.args["genre"],
frame.args["majuscule"] or pframe.args["majuscule"],
frame.args["ordinal"] or pframe.args["ordinal"]);
end
return p