Module:Conversion
La documentation pour ce module peut être créée à Module:Conversion/doc
local math_mod = require "Module:Math"
local params = mw.loadData("Module:Conversion/Données")
local linguistic = require "Module:Linguistique"
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 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
if showlink == 'true' then
showlink = true
end
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 suffix = {'', '', ''}
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 showunit and (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'] == 'ht' or statement['mainsnak']['datavalue']['value']['language'] == 'mul') 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 rounding then
numval = math_mod._round( numval, rounding )
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
if not displayformat.rounding then
if (math.abs(numval) > 1E9) then
numval = math_mod._round( numval / 1E9, 1 )
suffix = {"milya ", "<abbr title=\"milya\">G</abbr> "}
elseif (math.abs(numval) > 1E6) then
numval = math_mod._round( numval / 1E6, 1 )
suffix = {"milyon ", "<abbr title=\"milyon\">M</abbr> "}
end
end
local numstr = mw.getContentLanguage():formatNum(numval)
-- showlink
if not targetunitdata then -- pour éviter les bugs
targetunitdata = {}
end
local link
if showlink == '-' then
link = nil
elseif type(showlink) == 'string' then
link = showlink
elseif showlink then
link = targetunitdata[5]
end
-- affichage de l'unité
local unitstr, suffixstr
if showunit == 'long' then -- format long = montrer l'unité en entier
if math.abs(numval or 0) >= 2 then
unitstr = targetunitdata[7]
else
unitstr = targetunitdata[6]
end
if ((unitstr ~= '') and link) then
unitstr = '[[' .. link .. '|' .. unitstr .. ']]'
end
if (unitstr ~= '') and ((suffix[1] ~= '') or (((numval or 0) > 999999) and ( (numval or 0)% 1000000 == 0))) then
unitstr = linguistic.of(unitstr) -- 10 000 000 "de" tonnes
end
if math.abs(numval or 0) >= 2 then
suffixstr = suffix[2]
else
suffixstr = suffix[1]
end
elseif showunit and (showunit ~= '-') then
unitstr = targetunitdata[3]
if string.find(unitstr, "^%a") then -- 8 G$ mais 8 G CHF
suffixstr = suffix[3]
else
suffixstr = mw.text.trim(suffix[3])
end
if ((unitstr ~= '') and link) then
unitstr = '[[' .. link .. '|' .. unitstr .. ']]'
end
else
suffixstr = suffix[3]
end
local str = numstr .. ' ' .. (suffixstr or '') .. (unitstr or '')
str = mw.text.trim(str) .. 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
displayformat = {showunit = showunit, showlink = showlink, rounding = rounding, targetunit = targetunit}
return p.displayvalue(value, origunit, displayformat)
end
return p