Aller au contenu

Module:Unité

Cette page est protégée.
Une page de Wikipédia, l'encyclopédie libre.
Ceci est une version archivée de cette page, en date du 16 avril 2015 à 09:59 et modifiée en dernier par Zebulon84 (discuter | contributions) (Nouvelle page : local p = { } --- Copie de Outils.trim acceptant les nombres. local function trim( texte ) if type( texte ) == 'string' then texte = texte:gsub( '^%s*(.*)%f[%s]%s*$', '%1' )...). Elle peut contenir des erreurs, des inexactitudes ou des contenus vandalisés non présents dans la version actuelle.
(diff) ← Version précédente | Version actuelle (diff) | Version suivante → (diff)

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

Ce module est principalement destiné à implémenter le modèle {{Unité}}.

Utilisation

Fonctions exportables

  • unite( frame ) – implémente le modèle unité. Les paramètres sont pris soit au niveau du modèle appelant le module via #invoke, soit directement dans la table fournie lorsque la fonction est appelée depuis un autre module. Essaye de parser les deux premiers paramètres pour facilité la saisie (par exemple fonction avec p.unite{ '1.23 ±0.05 e5 m/s-2' }) ;
  • _unite( args ) – affiche l'unité à partir des paramètres classiques du modèle Unité (exemple p._unite{ '1.23', 'm', '/s', '-2', ['±'] = '0.05', e='5' }) ;
  • formatNombres( texte ) – formate tous les nombres de la chaine fournie suivant les conventions du français ;
  • formatNombre( nombre ) – transforme un nombre formaté ou non en chaine formatée suivant les conventions du français ; si la chaine n'est pas reconnue comme un nombre, elle n'est pas modifiée ;
  • _formatNum( num ) – transforme un number, ou une chaine correspondant à un number en chaine formatée suivant les conventions du français ; si le paramètre ne représente pas un number lua il est retourné sans modification ;
  • parseNombre( nombre ) – transforme si possible une chaine formatée en un chaine interprétable par tonumber() (retourne une chaine pour éviter les arrondis éventuels de lua) ; les chaines non reconnues sont retournées sans modification.

Autres fonctions

  • sanitizeNum( nombre ) – transforme les signes moins en tiret, les espaces insécables en espace simple (simplifie les pattern ultérieures) ;
  • parseUnit( texte ) – essaye de séparer une chaine en différents paramètres du modèle unité ;
  • nomUnit( unit, exposant ) – retourne si possible le nom de l'unité et son exposant en toute lettre.

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

  • Module:Unité/Data – Liste d'unités et de multiples, avec leur abréviation et leur nom en toute lettre.
  • Module:Delink – Utilisé pour supprimer les liens des unités pour essayer de les reconnaitre.

Exemples

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

Voir aussi : les tests unitaires et ceux du bac à sable.

local p = { }

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

---
-- parseNum transforme si possible une chaine formater en un chaine interprétable par tonumber()
-- retourne une chaine pour éviter les arrondi éventuels de lua.
-- si nombre n'est pas un nombre ou une chaine retourne une chaine vide.
-- 
function p.parseNombre( nombre )
	if type( nombre ) == 'number' then
		nombre = tostring( nombre )
	elseif type( nombre ) ~= 'string' then
		return ''
	elseif nombre == '' or not nombre:match( '^[-\226]?[\128\136]?[\146-\148]?[%d., \194\160]+$' ) then
		return nombre
	end
	
	if nombre:match( '^-?[\146-\148]?[%d., \194\160]+$' ) or 
		nombre:match( '^\226[\128\136][\146-\148][%d., \194\160]+$' ) or
		nombre:match( '^−[%d., \194\160]+$' )
	then
		-- suppression espaces et remplacement minus, ensp et emsp par un tiret (utilisé par lua)
		-- Utilise string pour être plus rapide.
		nombre = nombre:gsub( ' ', '' ):gsub( '\194\160', '' )
			:gsub( '^\226\128[\146-\148]', '-' )	-- U+2012 à U+2014 (voir [[Tiret]])
			:gsub( '^−', '-' ) -- U+2212
			:gsub( '^&minus', '-' ) -- code html du signe moins
		
		if nombre:match( '[.,]' ) then
			if nombre:match( '%d+,%d%d%d,%d%d%d%f[%D]' ) -- type 1,234,567 
				or nombre:match( '%d+,%d%d%d%.%d+' )  -- type 1,234.5
				--or nombre:match( '%d+,%d00$' )  -- type 1,200
			then
				-- format anglo-saxon
				nombre = nombre:gsub( ',', '' )
			elseif nombre:match( '%d+%.%d%d%d,%d' ) or nombre:match( '%d+%.%d%d%d.%d%d%d%f[%D]' ) then
				-- formant germanique type 1.234,5
				nombre = nombre:gsub( '%.', '' ):gsub( ',', '.' )
			else
				nombre = nombre:gsub( ',', '.' )
			end
		end
	end
	
	return nombre
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' 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:len() > 3 then
		local ini = math.fmod( entier:len(), 3 )
		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 nombre d'une chaine
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 )
	end
end

function p.formatNombre( nombre )
	return p._formatNum( p.parseNombre( nombre ) )
end


function p._unite( args )
	local wiki = { }
	local sep = ''
	local nombre = trim( args[1] )
	if nombre then
		nombre = nombre:gsub( '[-−–—]?%f[%d][%d., \194\160]+%f[%D]', p.formatNombre )
		table.insert( wiki, nombre )
		sep = '\194\160'
	end
	
	local i = 1
	local unit = trim( args[2] )
	if unit == 10 then
		args.e = args[3]
		i = 2
		unit = trim( args[4] )
	end
	local exp = trim( args.e )
	if exp then
		if #wiki > 0 then
			table.insert( wiki, '×10<sup>' .. exp .. '</sup>' )
		else
			table.insert( wiki, '10<sup>' .. exp .. '</sup>' )
		end
		sep = '\194\160'
	end
	
	while unit do
		table.insert( wiki, sep )
		table.insert( wiki, unit )
		exp = trim( args[ 2 * i + 1 ] )
		if exp then
			table.insert( wiki, '<sup>' .. exp:gsub( '-', '−' ) .. '</sup>' )
		end
		i = i + 1
		unit = trim( args[ 2 * i ] )
		sep = '⋅'
	end
	
	if #wiki > 0 then
		return '<span class="nowrap">' .. table.concat( wiki ) .. '</span>'
	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
		return p._unite( args )
	end
end

return p