Module:Unité : Différence entre versions
(retouche de la modification précédente) |
(ajoute des infobulles avec le nom de l'unité.) |
||
Ligne 1 : | Ligne 1 : | ||
− | local p = { } | + | local p = {} |
+ | |||
+ | -- Chargement de la base de données des nom d'unités avec gestion d'erreur. | ||
+ | local moduleData = 'Module:Unité/Data' | ||
+ | local dataSuccess, Data = pcall ( mw.loadData, moduleData ) | ||
+ | if dataSuccess and type( Data ) == 'table' then | ||
+ | dataSuccess = type( Data.unit ) == 'table' | ||
+ | and type( Data.prefix ) == 'table' | ||
+ | and type( Data.exposant ) == 'table' | ||
+ | end | ||
--- Copie de Outils.trim acceptant les nombres. | --- Copie de Outils.trim acceptant les nombres. | ||
Ligne 10 : | Ligne 19 : | ||
elseif type( texte ) == 'number' then | elseif type( texte ) == 'number' then | ||
return tostring( texte ) | return tostring( texte ) | ||
+ | end | ||
+ | end | ||
+ | |||
+ | function p.sanitizeNum( nombre ) | ||
+ | if type( nombre ) == 'number' then | ||
+ | return tostring( nombre ) | ||
+ | elseif type( nombre ) == 'string' then | ||
+ | local result = nombre | ||
+ | -- trim | ||
+ | :gsub( '^%s*(.*)%f[%s]%s*$', '%1' ) | ||
+ | -- remplacement des signes moins ou demi-cadratin par un tiret | ||
+ | :gsub( '%−%f[%d]', '-') -- U+2212 | ||
+ | :gsub( '−%f[%d]', '-') -- html − | ||
+ | :gsub( '\226\128[\146\147]%f[%d]', '-') -- U+2212, U+2213 (tiret numérique et demi-cadratin) | ||
+ | -- remplacement des espaces insécable par des espace simple | ||
+ | :gsub( '\194\160', ' ' ) | ||
+ | return result | ||
+ | else | ||
+ | return '' | ||
end | end | ||
end | end | ||
--- | --- | ||
− | -- parseNum transforme si possible une chaine | + | -- parseNum transforme si possible une chaine formatée en un chaine interprétable par tonumber() |
-- retourne une chaine pour éviter les arrondi éventuels de lua. | -- retourne une chaine pour éviter les arrondi éventuels de lua. | ||
− | -- si nombre n'est pas un | + | -- si "nombre" est une chaine non reconnue comme un nombre par la fonction, retourne "nombre". |
− | + | -- si "nombre" n'est pas un number ou une chaine retourne une chaine vide. | |
function p.parseNombre( nombre ) | function p.parseNombre( nombre ) | ||
+ | local result | ||
if type( nombre ) == 'number' then | if type( nombre ) == 'number' then | ||
− | + | return tostring( nombre ) | |
− | + | else | |
− | + | -- remplacement des signes moins ou demi-cadratin par un tiret | |
+ | result = p.sanitizeNum( nombre ) | ||
+ | if result == '' then | ||
+ | return '' | ||
+ | elseif not result:match( '^%-?[%d., ]*%d$' ) then | ||
+ | return nombre | ||
+ | end | ||
end | end | ||
− | -- | + | -- suppression espaces |
− | + | result = result:gsub( ' ', '' ) | |
− | |||
− | |||
− | if | + | if result:match( '[.,]' ) then |
− | + | if result:match( '%d+,%d%d%d,%d%d%d%f[%D]' ) -- type 1,234,567 | |
− | + | or result:match( '%d+,%d%d%d%.%d+' ) -- type 1,234.5 | |
− | + | --or nombre:match( '%d+,%d00$' ) -- type 1,200 | |
− | if | + | then |
− | + | -- format anglo-saxon | |
− | + | result = result:gsub( ',', '' ) | |
− | + | elseif result:match( '%d+%.%d%d%d,%d' ) or result:match( '%d+%.%d%d%d%.%d%d%d%f[%D]' ) then | |
− | + | -- formant germanique type 1.234,5 | |
− | + | result = result:gsub( '%.', '' ):gsub( ',', '.' ) | |
− | + | else | |
− | + | result = result:gsub( ',', '.' ) | |
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
end | end | ||
− | return | + | return result |
end | end | ||
Ligne 59 : | Ligne 87 : | ||
if type( num ) == 'number' then | if type( num ) == 'number' then | ||
num = tostring( num ) | num = tostring( num ) | ||
− | elseif type( num ) ~= 'string' then | + | elseif type( num ) ~= 'string' or num == '' then |
return num | return num | ||
end | end | ||
− | local moins, entier, fraction = num:match( '^(%-?)(%d | + | local moins, entier, fraction = num:match( '^(%-?)(%d*)%.?(%d*)$' ) |
if not entier then | if not entier then | ||
return num | return num | ||
Ligne 72 : | Ligne 100 : | ||
end | end | ||
− | if entier:len() > 3 then | + | if entier == '' then |
− | local ini = math.fmod( entier:len(), 3 ) | + | entier = '0' |
+ | elseif entier:len() > 3 then | ||
+ | local ini = math.fmod( entier:len() - 1, 3 ) + 1 | ||
entier = ( entier:sub( 1, ini ) or '') .. entier:sub( ini + 1 ):gsub( '(%d%d%d)', '\194\160%1' ) | entier = ( entier:sub( 1, ini ) or '') .. entier:sub( ini + 1 ):gsub( '(%d%d%d)', '\194\160%1' ) | ||
end | end | ||
Ligne 84 : | Ligne 114 : | ||
--- | --- | ||
− | -- formatNum transforme les nombres d'une chaine en chaine formatée suivant les conventions du français | + | -- formatNum transforme les nombres d'une chaine en chaine formatée suivant les conventions du français. |
+ | -- Le nombre fourni doit un de type number ou chaine équivalente : | ||
+ | -- pas de séparateur de millier, point comme séparamèteur décimal, tiret comme signe moins. | ||
+ | -- Équivalent de FormatNum, mais avec vrai signe moins et séparateur de millier en partie décimale. | ||
function p.formatNum( num ) | function p.formatNum( num ) | ||
if type( num ) == 'number' then | if type( num ) == 'number' then | ||
Ligne 90 : | Ligne 123 : | ||
elseif type( num ) == 'string' then | elseif type( num ) == 'string' then | ||
return num:gsub( '%-?%d*%.?%d+', p.formatNombre ) | return num:gsub( '%-?%d*%.?%d+', p.formatNombre ) | ||
+ | else | ||
+ | return '' | ||
end | end | ||
end | end | ||
+ | --- | ||
+ | -- formatNombre transforme un nombre formaté ou non en chaine formatée suivant les convention du français. | ||
+ | -- si la chaine n'est pas reconnu comme un nombre, elle n'est pas modifiée. | ||
function p.formatNombre( nombre ) | function p.formatNombre( nombre ) | ||
return p._formatNum( p.parseNombre( nombre ) ) | return p._formatNum( p.parseNombre( nombre ) ) | ||
+ | end | ||
+ | |||
+ | --- formatNombres transforme tous les nombres d'une chaine en nombre formaté suivant les conventions du français. | ||
+ | function p.formatNombres( texte ) | ||
+ | if type( texte ) == 'number' then | ||
+ | return p.formatNum( texte ) | ||
+ | elseif type( texte ) == 'string' then | ||
+ | return texte:gsub( '%-?%f[%d.,][%d., ]+%f[%D]', p.formatNombre ) | ||
+ | else | ||
+ | return '' | ||
+ | end | ||
end | end | ||
function p.parseUnit( texte ) | function p.parseUnit( texte ) | ||
− | + | local toParse = p.sanitizeNum( texte ) | |
− | + | if toParse ~= '' then | |
local result | local result | ||
+ | local specificArgs = { ['à'] = 'à', et = 'et', ['–'] = '–', ['±'] = '±' } | ||
+ | |||
-- valeur numérique | -- valeur numérique | ||
− | local | + | local match, capture = toParse:match( '^((%-?%f[%d.,][%d., \194\160]*%d%f[%D])%s*)' ) |
− | if | + | if match then |
− | toParse = toParse:sub( | + | toParse = toParse:sub( match:len() + 1 ) |
end | end | ||
− | result = { | + | result = { capture or false } |
-- 10 exposant ( \195\151 = ×, signe multiplié) | -- 10 exposant ( \195\151 = ×, signe multiplié) | ||
− | + | match, capture = toParse:match( '^(%s*e(%-?%d+)%s*)' ) | |
+ | if not match then | ||
+ | match, capture = toParse:match( '^(%s*[x\195]\151?10e(%-?%d+)%s*)' ) | ||
+ | end | ||
if match then | if match then | ||
− | + | result.e = capture | |
− | |||
toParse = toParse:sub( match:len() + 1 ) | toParse = toParse:sub( match:len() + 1 ) | ||
end | end | ||
Ligne 118 : | Ligne 171 : | ||
-- unités | -- unités | ||
toParse = toParse:gsub( '⋅', '.' ) | toParse = toParse:gsub( '⋅', '.' ) | ||
− | local | + | local unit, exp |
+ | local unitRegex = '^(%.?(/?[%aà°±]+) ?(%-?[%d%.,]*)%s*)' | ||
+ | match, unit, exp = mw.ustring.match( toParse, unitRegex ) | ||
while match and unit:len() < 5 do | while match and unit:len() < 5 do | ||
− | table.insert( result, unit ) | + | if specificArgs[ unit ] then |
− | + | result[ specificArgs[ unit ] ] = exp | |
+ | else | ||
+ | table.insert( result, unit ) | ||
+ | table.insert( result, exp ) | ||
+ | end | ||
toParse = toParse:sub( match:len() + 1 ) | toParse = toParse:sub( match:len() + 1 ) | ||
− | match, unit, exp = mw.ustring.match( toParse, | + | match, unit, exp = mw.ustring.match( toParse, unitRegex ) |
end | end | ||
− | if | + | if toParse == '' then |
+ | return result | ||
+ | else | ||
-- une partie de la chaine n'a pas pu être décodée, on retourne la chaine originale | -- une partie de la chaine n'a pas pu être décodée, on retourne la chaine originale | ||
return { texte } | return { texte } | ||
− | + | end | |
− | |||
− | end | ||
else | else | ||
return { } | return { } | ||
+ | end | ||
+ | end | ||
+ | |||
+ | --- | ||
+ | -- nomUtnit retourne le nom français du code d'une unité et de son exposant. | ||
+ | -- si le code de l'unité n'est pas reconnu retourne 1 et false, de façon à ajouter false en première position d'une table. | ||
+ | function p.nomUnit( unit, exp ) | ||
+ | if not dataSuccess or type( unit ) ~= 'string' then | ||
+ | return 1, false | ||
+ | end | ||
+ | unit = unit:gsub( '^/' , '' ) | ||
+ | local unitTab = Data.unit[ unit ] | ||
+ | local unitPrefix = { nom = '' } | ||
+ | if not unitTab then | ||
+ | unitTab = Data.unit[ unit:sub( 2 ) ] | ||
+ | unitPrefix = Data.prefix[ unit:sub( 1, 1 ) ] | ||
+ | if not ( unitTab and unitPrefix ) then | ||
+ | unitTab = Data.unit[ unit:sub( 3 ) ] | ||
+ | unitPrefix = Data.prefix[ unit:sub( 1, 2 ) ] | ||
+ | if not ( unitTab and unitPrefix ) then | ||
+ | unitTab = false | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | if type( unitTab ) == 'table' and type( unitTab.nom ) == 'string' then | ||
+ | exp = tonumber( exp ) | ||
+ | exp = exp and math.abs( exp ) | ||
+ | local exposant = exp and Data.exposant[exp] or '' | ||
+ | return unitPrefix.nom .. unitTab.nom .. exposant | ||
+ | else | ||
+ | return 1, false | ||
end | end | ||
end | end | ||
function p._unite( args ) | function p._unite( args ) | ||
− | |||
local sep = '' | local sep = '' | ||
− | local nombre | + | local nombre, nbNombre, nombre2, nbNombre2 |
− | |||
− | |||
− | if nombre then | + | nombre = p.sanitizeNum( args[1] ) |
− | nombre = | + | if nombre == '' then |
− | -- | + | nombre = nil |
− | + | else | |
− | + | -- formatage du nombre | |
− | + | nombre, nbNombre = nombre:gsub( '%-?%f[%d.,][%d., ]+%f[%D]', p.formatNombre ) | |
− | |||
− | |||
end | end | ||
− | + | ||
− | + | -- et / à '–' | |
− | + | local intervalle = trim( args.et ) and ' et ' | |
− | + | or trim( args['à'] ) and ' à ' | |
− | + | or args['–'] and '–' | |
+ | if nombre and intervalle then | ||
+ | nombre2 = nombre2 or trim( args['à'] ) or trim( args.et ) or trim( args['–'] ) | ||
+ | if nombre2 then | ||
+ | nombre2 = p.sanitizeNum( nombre2 ) | ||
+ | nombre2, nbNombre2 = nombre2:gsub( '%-?%f[%d.,][%d., ]+%f[%D]', p.formatNombre ) | ||
+ | if intervalle == '–' and nombre:sub( 1, 2 ) == '−' then | ||
+ | intervalle = ' – ' | ||
+ | end | ||
+ | end | ||
end | end | ||
− | -- | + | -- ± |
− | if | + | local approximation |
− | + | if trim( args['±'] ) then | |
− | + | approximation = '±\194\160' .. p.formatNombre( args['±'] ) | |
− | |||
end | end | ||
-- puissance de 10 | -- puissance de 10 | ||
− | local | + | local exposant = trim( args.e ) |
− | + | if exposant then | |
− | + | if nombre then | |
− | + | exposant = '×\194\16010<sup>' .. exposant .. '</sup>' | |
− | |||
− | |||
− | if | ||
− | if | ||
− | |||
else | else | ||
− | + | exposant = '10<sup>' .. exposant .. '</sup>' | |
end | end | ||
− | |||
end | end | ||
− | -- unités | + | -- unités |
+ | local i = 1 | ||
+ | local unit = trim( args[ 2 * i ] ) | ||
+ | local units = '' | ||
+ | local nomUnits, par = {}, false | ||
while unit do | while unit do | ||
− | if | + | local exp = tonumber( p.parseNombre( args[ 2 * i + 1 ] ) ) |
− | + | local sep = '' | |
− | + | if units ~= '' then | |
− | + | if unit:sub( 1, 1 ) == '/' then | |
− | + | if not par then | |
− | + | par = true | |
− | + | table.insert( nomUnits, 'par' ) | |
− | + | end | |
+ | else | ||
+ | sep = '\194\160' -- point médian désactivé : '⋅\194\160' | ||
+ | if exp and not par and exp < 0 then | ||
+ | par = true | ||
+ | table.insert( nomUnits, 'par' ) | ||
+ | end | ||
+ | end | ||
end | end | ||
+ | local expUnit = exp and '<sup>' .. exp .. '</sup>' or '' | ||
+ | units = units .. sep .. unit .. expUnit | ||
+ | table.insert( nomUnits, p.nomUnit( unit, exp ) ) | ||
i = i + 1 | i = i + 1 | ||
unit = trim( args[ 2 * i ] ) | unit = trim( args[ 2 * i ] ) | ||
− | |||
end | end | ||
+ | |||
+ | if units == '°' then | ||
+ | nombre = nombre and nombre .. '°' | ||
+ | nombre2 = nombre2 and nombre2 .. '°' | ||
+ | approximation = approximation and approximation .. '°' | ||
+ | units = nil | ||
+ | end | ||
+ | if intervalle then | ||
+ | nombre = nombre .. intervalle .. nombre2 | ||
+ | end | ||
+ | |||
+ | local wiki = { nombre } | ||
+ | table.insert( wiki, approximation ) | ||
+ | table.insert( wiki, exposant ) | ||
+ | if nomUnits[1] then | ||
+ | units = string.format( '<abbr class=abbr title="%s">%s</abbr>', table.concat( nomUnits, ' ' ), units ) | ||
+ | end | ||
+ | table.insert( wiki, units ) | ||
if #wiki > 0 then | if #wiki > 0 then | ||
− | local result = table.concat( wiki ): | + | local result = table.concat( wiki, ' ' ) |
− | + | if result:match( ' ' ) then | |
+ | return '<span class="nowrap">' .. result .. '</span>' | ||
+ | else | ||
+ | return result | ||
+ | end | ||
end | end | ||
end | end | ||
Ligne 210 : | Ligne 332 : | ||
end | end | ||
if args then | if args then | ||
+ | if #args == 1 | ||
+ | and not ( args.e or args.et or args['à'] or args['±'] ) | ||
+ | and trim( args[1] ) | ||
+ | and args[1]:match('[^%d,. -]') | ||
+ | then | ||
+ | args = p.parseUnit( trim( args[1] ) ) | ||
+ | end | ||
return p._unite( args ) | return p._unite( args ) | ||
end | end |
Version du 30 avril 2015 à 14:25
La documentation pour ce module peut être créée à Module:Unité/doc
local p = {} -- Chargement de la base de données des nom d'unités avec gestion d'erreur. local moduleData = 'Module:Unité/Data' local dataSuccess, Data = pcall ( mw.loadData, moduleData ) if dataSuccess and type( Data ) == 'table' then dataSuccess = type( Data.unit ) == 'table' and type( Data.prefix ) == 'table' and type( Data.exposant ) == 'table' end --- Copie de Outils.trim acceptant les nombres. local function trim( texte ) if type( texte ) == 'string' then texte = texte:gsub( '^%s*(.*)%f[%s]%s*$', '%1' ) if texte ~= '' then return texte end elseif type( texte ) == 'number' then return tostring( texte ) end end function p.sanitizeNum( nombre ) if type( nombre ) == 'number' then return tostring( nombre ) elseif type( nombre ) == 'string' then local result = nombre -- trim :gsub( '^%s*(.*)%f[%s]%s*$', '%1' ) -- remplacement des signes moins ou demi-cadratin par un tiret :gsub( '%−%f[%d]', '-') -- U+2212 :gsub( '−%f[%d]', '-') -- html − :gsub( '\226\128[\146\147]%f[%d]', '-') -- U+2212, U+2213 (tiret numérique et demi-cadratin) -- remplacement des espaces insécable par des espace simple :gsub( '\194\160', ' ' ) return result else return '' end end --- -- parseNum transforme si possible une chaine formatée en un chaine interprétable par tonumber() -- retourne une chaine pour éviter les arrondi éventuels de lua. -- si "nombre" est une chaine non reconnue comme un nombre par la fonction, retourne "nombre". -- si "nombre" n'est pas un number ou une chaine retourne une chaine vide. function p.parseNombre( nombre ) local result if type( nombre ) == 'number' then return tostring( nombre ) else -- remplacement des signes moins ou demi-cadratin par un tiret result = p.sanitizeNum( nombre ) if result == '' then return '' elseif not result:match( '^%-?[%d., ]*%d$' ) then return nombre end end -- suppression espaces result = result:gsub( ' ', '' ) if result:match( '[.,]' ) then if result:match( '%d+,%d%d%d,%d%d%d%f[%D]' ) -- type 1,234,567 or result:match( '%d+,%d%d%d%.%d+' ) -- type 1,234.5 --or nombre:match( '%d+,%d00$' ) -- type 1,200 then -- format anglo-saxon result = result:gsub( ',', '' ) elseif result:match( '%d+%.%d%d%d,%d' ) or result:match( '%d+%.%d%d%d%.%d%d%d%f[%D]' ) then -- formant germanique type 1.234,5 result = result:gsub( '%.', '' ):gsub( ',', '.' ) else result = result:gsub( ',', '.' ) end end return result end --- -- _formantNum transforme un nombre ou une chaine représentant un nombre en chaine formatée suivant les conventions du français -- si le paramètre ne représente pas un nombre lua il est retourné sans modification function p._formatNum( num ) if type( num ) == 'number' then num = tostring( num ) elseif type( num ) ~= 'string' or num == '' then return num end local moins, entier, fraction = num:match( '^(%-?)(%d*)%.?(%d*)$' ) if not entier then return num end if moins == '-' then moins = '−' -- signe moins (U+2212) end if entier == '' then entier = '0' elseif entier:len() > 3 then local ini = math.fmod( entier:len() - 1, 3 ) + 1 entier = ( entier:sub( 1, ini ) or '') .. entier:sub( ini + 1 ):gsub( '(%d%d%d)', '\194\160%1' ) end if fraction ~= '' then fraction = ',' .. fraction:gsub( '(%d%d%d)', '%1\194\160' ):gsub( '\194\160$', '' ) end return moins .. entier .. fraction end --- -- formatNum transforme les nombres d'une chaine en chaine formatée suivant les conventions du français. -- Le nombre fourni doit un de type number ou chaine équivalente : -- pas de séparateur de millier, point comme séparamèteur décimal, tiret comme signe moins. -- Équivalent de FormatNum, mais avec vrai signe moins et séparateur de millier en partie décimale. function p.formatNum( num ) if type( num ) == 'number' then return p._formatNum( num ) elseif type( num ) == 'string' then return num:gsub( '%-?%d*%.?%d+', p.formatNombre ) else return '' end end --- -- formatNombre transforme un nombre formaté ou non en chaine formatée suivant les convention du français. -- si la chaine n'est pas reconnu comme un nombre, elle n'est pas modifiée. function p.formatNombre( nombre ) return p._formatNum( p.parseNombre( nombre ) ) end --- formatNombres transforme tous les nombres d'une chaine en nombre formaté suivant les conventions du français. function p.formatNombres( texte ) if type( texte ) == 'number' then return p.formatNum( texte ) elseif type( texte ) == 'string' then return texte:gsub( '%-?%f[%d.,][%d., ]+%f[%D]', p.formatNombre ) else return '' end end function p.parseUnit( texte ) local toParse = p.sanitizeNum( texte ) if toParse ~= '' then local result local specificArgs = { ['à'] = 'à', et = 'et', ['–'] = '–', ['±'] = '±' } -- valeur numérique local match, capture = toParse:match( '^((%-?%f[%d.,][%d., \194\160]*%d%f[%D])%s*)' ) if match then toParse = toParse:sub( match:len() + 1 ) end result = { capture or false } -- 10 exposant ( \195\151 = ×, signe multiplié) match, capture = toParse:match( '^(%s*e(%-?%d+)%s*)' ) if not match then match, capture = toParse:match( '^(%s*[x\195]\151?10e(%-?%d+)%s*)' ) end if match then result.e = capture toParse = toParse:sub( match:len() + 1 ) end -- unités toParse = toParse:gsub( '⋅', '.' ) local unit, exp local unitRegex = '^(%.?(/?[%aà°±]+) ?(%-?[%d%.,]*)%s*)' match, unit, exp = mw.ustring.match( toParse, unitRegex ) while match and unit:len() < 5 do if specificArgs[ unit ] then result[ specificArgs[ unit ] ] = exp else table.insert( result, unit ) table.insert( result, exp ) end toParse = toParse:sub( match:len() + 1 ) match, unit, exp = mw.ustring.match( toParse, unitRegex ) end if toParse == '' then return result else -- une partie de la chaine n'a pas pu être décodée, on retourne la chaine originale return { texte } end else return { } end end --- -- nomUtnit retourne le nom français du code d'une unité et de son exposant. -- si le code de l'unité n'est pas reconnu retourne 1 et false, de façon à ajouter false en première position d'une table. function p.nomUnit( unit, exp ) if not dataSuccess or type( unit ) ~= 'string' then return 1, false end unit = unit:gsub( '^/' , '' ) local unitTab = Data.unit[ unit ] local unitPrefix = { nom = '' } if not unitTab then unitTab = Data.unit[ unit:sub( 2 ) ] unitPrefix = Data.prefix[ unit:sub( 1, 1 ) ] if not ( unitTab and unitPrefix ) then unitTab = Data.unit[ unit:sub( 3 ) ] unitPrefix = Data.prefix[ unit:sub( 1, 2 ) ] if not ( unitTab and unitPrefix ) then unitTab = false end end end if type( unitTab ) == 'table' and type( unitTab.nom ) == 'string' then exp = tonumber( exp ) exp = exp and math.abs( exp ) local exposant = exp and Data.exposant[exp] or '' return unitPrefix.nom .. unitTab.nom .. exposant else return 1, false end end function p._unite( args ) local sep = '' local nombre, nbNombre, nombre2, nbNombre2 nombre = p.sanitizeNum( args[1] ) if nombre == '' then nombre = nil else -- formatage du nombre nombre, nbNombre = nombre:gsub( '%-?%f[%d.,][%d., ]+%f[%D]', p.formatNombre ) end -- et / à '–' local intervalle = trim( args.et ) and ' et ' or trim( args['à'] ) and ' à ' or args['–'] and '–' if nombre and intervalle then nombre2 = nombre2 or trim( args['à'] ) or trim( args.et ) or trim( args['–'] ) if nombre2 then nombre2 = p.sanitizeNum( nombre2 ) nombre2, nbNombre2 = nombre2:gsub( '%-?%f[%d.,][%d., ]+%f[%D]', p.formatNombre ) if intervalle == '–' and nombre:sub( 1, 2 ) == '−' then intervalle = ' – ' end end end -- ± local approximation if trim( args['±'] ) then approximation = '±\194\160' .. p.formatNombre( args['±'] ) end -- puissance de 10 local exposant = trim( args.e ) if exposant then if nombre then exposant = '×\194\16010<sup>' .. exposant .. '</sup>' else exposant = '10<sup>' .. exposant .. '</sup>' end end -- unités local i = 1 local unit = trim( args[ 2 * i ] ) local units = '' local nomUnits, par = {}, false while unit do local exp = tonumber( p.parseNombre( args[ 2 * i + 1 ] ) ) local sep = '' if units ~= '' then if unit:sub( 1, 1 ) == '/' then if not par then par = true table.insert( nomUnits, 'par' ) end else sep = '\194\160' -- point médian désactivé : '⋅\194\160' if exp and not par and exp < 0 then par = true table.insert( nomUnits, 'par' ) end end end local expUnit = exp and '<sup>' .. exp .. '</sup>' or '' units = units .. sep .. unit .. expUnit table.insert( nomUnits, p.nomUnit( unit, exp ) ) i = i + 1 unit = trim( args[ 2 * i ] ) end if units == '°' then nombre = nombre and nombre .. '°' nombre2 = nombre2 and nombre2 .. '°' approximation = approximation and approximation .. '°' units = nil end if intervalle then nombre = nombre .. intervalle .. nombre2 end local wiki = { nombre } table.insert( wiki, approximation ) table.insert( wiki, exposant ) if nomUnits[1] then units = string.format( '<abbr class=abbr title="%s">%s</abbr>', table.concat( nomUnits, ' ' ), units ) end table.insert( wiki, units ) if #wiki > 0 then local result = table.concat( wiki, ' ' ) if result:match( ' ' ) then return '<span class="nowrap">' .. result .. '</span>' else return result end end end function p.unite( frame ) local args if type( frame ) == 'table' and type( frame.getParent ) == 'function' then args = frame:getParent().args; end if args then if #args == 1 and not ( args.e or args.et or args['à'] or args['±'] ) and trim( args[1] ) and args[1]:match('[^%d,. -]') then args = p.parseUnit( trim( args[1] ) ) end return p._unite( args ) end end return p