Module:Conversion
Modèle de mise en forme de valeur numérique éventuellement accompagnée d'une unité de mesure.
Utilisation
modifierFonctions exportables vers un autre module
modifierfonction p.displayvalue(value, sourceunit, displayformat)
met en forme une valeur numérique éventuellement accompagné d'une unité de mesure
value
doit être un nombre, ou une chaîne pouvant être convertie en nombresourceunit
doit correspondre à une valeur acceptée sur Module:Conversion/Données.- la table
displayformat
contient les paramètres suivant :
showunit
showunit = true affiche l'unité de mesure, en utilisant l'abréviation donnée dans Module:Conversion/Données.showunit = long
utilise le format long ("mètres" à la place de "m").showlink =
affiche un lien vers l'article concernant l'unité de mesure (m -> m)rounding =
nombre de chiffres après la virgule
Fonctions exportables vers un modèle
modifierfonction p.display(frame)
: sert d'intermédiaire entre le wikicode et la fonction displayvalue. Arguments:
1 =
valeur numérique2 =
unité de mesure de la valeur d'origine3 =
unité de mesure de la valeur à retournershowunit =
mettre "true" pour afficher l'unité de mesurerounding =
nombre de chiffres après la virgule
Exemples
modifier{{#invoke:Conversion|display|25|foot|metre}}
7,62{{#invoke:Conversion|display|25|foot|metre|rounding=0|showunit = true}}
8 m
Modules externes et autres éléments dont ce module a besoin pour fonctionner
modifierlocal math_mod = require "Module:Math"
local formatnum = require "Module:Format".do_formatnum
local params = require "Module:Conversion/Données"
local linguistic = require "Module:Linguistique"
local defaultlang = 'fr'
local p = {}
local i18n = {
invalidunitcat = 'Page avec une unité de mesure non prise en charge',
invalidsourceunit = '$1 (unité non prise en charge)',
invalidtargetunit = 'unité cible non prise en charge $1',
typemismatch = 'impossible de convertir $1 en $2'
}
local function numString(val, rounding, displayformat) -- transforme un nombre en chaîne
if rounding then
val = math_mod._round( val, rounding )
end
val = formatnum({tostring(val)})
if displayformat and displayformat.suffix then
val = val .. suffix
end
return val
end
local function convert(value, sourceunitdata, targetunitdata) -- convertir une valeur numérique en son équivalent dans une autre unité de mesure
if not value then
return nil
end
if type(value) ~= 'number' then
return error("bad datatype: " .. type(value))
end
if (not sourceunitdata) or (not targetunitdata) then
return value
end
return value * sourceunitdata[2] / targetunitdata[2]
end
function p.displayvalue(val, sourceunit, displayformat, complement) -- affiche une valeur formatée)
-- préparation des paramètres
local numval = tonumber(val)
if not numval then -- si les données sont inhabituelles, on laisse la fonction appelante se débrouiller
return val
end
if not displayformat or type(displayformat) ~= 'table' then
displayformat = {}
end
local showunit, showlink, targetunit = displayformat.showunit, displayformat.showlink, displayformat.targetunit
local rounding = displayformat.rounding or 2
-- récupération des donnnées concernant les unités
if sourceunit and not targetunit then
targetunit = sourceunit
end
local sourceunitdata, targetunitdata = sourceunit, targetunit
if type(sourceunitdata) ~= 'table' then
sourceunitdata = params.units[sourceunit] or params.units[params.redirects[sourceunit]]
end
if type(targetunitdata) ~= 'table' then
targetunitdata = params.units[targetunit] or params.units[params.redirects[targetunit]]
end
local maintenancestr = ""
-- conversion
local function invalidsourcefallback(val, sourceunit) -- text to be shown when source unit is not supported
local str = tostring(val)
if sourceunit:match('Q%d+') or sourceunit:match('q%d+') then -- wikidata item
sourceunit = mw.wikibase.label(sourceunit)
end
return val .. ' ' .. i18n['invalidsourceunit']:gsub('$1', sourceunit) .. '[[Category:' .. i18n.invalidunitcat .. '|' .. sourceunit .. ']]'
end
-- escape if source unit is invalid
if (sourceunit and targetunit) and (targetunit~= sourceunit) and (not sourceunitdata or not sourceunitdata[1]) then
return invalidsourcefallback(val, sourceunit)
end
if sourceunit and (not sourceunitdata) then
local label = sourceunit
local item = sourceunit:match('q%d+') or sourceunit:match('Q%d+')
local link
local symbol
if item then
label = mw.wikibase.label(item)
link = mw.wikibase.sitelink(item)
if (displayformat.showunit) and (displayformat.showunit ~= 'long') then -- symbole retrieved only if needed (somewhat expensive)
for _,statement in pairs(mw.wikibase.getBestStatements(item, 'P5061')) do
if statement['mainsnak']['snaktype'] == 'value' and statement['mainsnak']['datavalue']['value']['language'] == 'fr' then
symbol = statement['mainsnak']['datavalue']['value']['text']
end
end
end
end
sourceunitdata = {nil, 1, symbol or label, item, link, label, label}
targetunit, targetunitdata = sourceunit, sourceunitdata
end
-- warn if targetunit is unknown
if targetunit and (not targetunitdata) then
targetunit, targetunitdata = sourceunit, sourceunitdata
maintenancestr = maintenancestr .. " " .. i18n['invalidtargetunit']:gsub('$1', targetunit) .. '[[Category:' .. i18n.invalidunitcat .. '|' .. targetunit .. ']]'
end
-- check for type mismatch
if (sourceunitdata and targetunitdata) and (targetunitdata[1] ~= sourceunitdata[1]) then
local errmsg = i18n.typemismatch
errmsg = errmsg:gsub('$1', sourceunit)
errmsg = errmsg:gsub('$2', targetunit)
maintenancestr = maintenancestr .. '(' .. errmsg .. ')'
targetunit, targetunitdata = sourceunit, sourceunitdata
end
-- convert if needed
if (sourceunit and targetunit) and (sourceunit ~= targetunit) then
numval = convert(numval, sourceunitdata, targetunitdata)
end
if displayformat.raw == true then -- nombre non formaté chaîne convertible en nombre sauf si catégorie de maintenance
return (tostring(numval) or "") .. maintenancestr
end
local numstr = numString(numval, rounding)
-- affichage de l'unité
local unitstr, link
if not targetunitdata then -- pour éviter les bugs
targetunitdata = {}
end
if showunit == 'long' then -- format long = montrer l'unité en entier
if (numval or 0) >= 2 then
unitstr = targetunitdata[7]
else
unitstr = targetunitdata[6]
end
if ((numval or 0) > 999999) and ( (numval or 0)% 1000000 == 0) then
unitstr = linguistic.of(unitstr) -- 10 000 000 "de" tonnes
end
elseif showunit and (showunit ~= '-') then
unitstr = targetunitdata[3]
end
-- showlink
local link
if (type(showlink) == 'string') and (showlink == '-') then
link = nil
elseif type(showlink) == 'string' then
link = showlink
elseif showlink then
link = targetunitdata[5]
end
if (unitstr and link) then
unitstr = '[[' .. link .. '|' .. unitstr .. ']]'
end
local str = numstr .. ' ' .. (unitstr or '') .. maintenancestr
if complement then
if sourceunit then
str = str .. " " .. linguistic.of(complement) -- "10 kg de bambous"
else
str = str .. " " .. complement -- "3000 véhicules"
end
end
return str
end
function p.display(frame)
local args = frame.args
local value, origunit, targetunit = args[1], args[2], args[3]
local rounding = args.rounding
local showlink, showunit = args.showlink, args.showunit
if showunit == 'true' then
showunit = true
end
if showlink == 'true' then
showlink = true
end
displayformat = {showunit = showunit, showlink = showlink, rounding = rounding, targetunit = targetunit}
return p.displayvalue(value, origunit, displayformat)
end
return p