<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="vi">
	<id>https://bktt.vn/index.php?action=history&amp;feed=atom&amp;title=M%C3%B4_%C4%91un%3A%C4%90V</id>
	<title>Mô đun:ĐV - Lịch sử thay đổi</title>
	<link rel="self" type="application/atom+xml" href="https://bktt.vn/index.php?action=history&amp;feed=atom&amp;title=M%C3%B4_%C4%91un%3A%C4%90V"/>
	<link rel="alternate" type="text/html" href="https://bktt.vn/index.php?title=M%C3%B4_%C4%91un:%C4%90V&amp;action=history"/>
	<updated>2026-04-03T20:52:06Z</updated>
	<subtitle>Lịch sử thay đổi của trang này ở wiki</subtitle>
	<generator>MediaWiki 1.35.0</generator>
	<entry>
		<id>https://bktt.vn/index.php?title=M%C3%B4_%C4%91un:%C4%90V&amp;diff=11379&amp;oldid=prev</id>
		<title>Tttrung: Tạo trang mới với nội dung “local p = {}  local moduleData = 'Module:ĐV/Data' local dataSuccess, Data = pcall ( mw.loadData, moduleData ) if dataSuccess and type( Data ) == 'table'…”</title>
		<link rel="alternate" type="text/html" href="https://bktt.vn/index.php?title=M%C3%B4_%C4%91un:%C4%90V&amp;diff=11379&amp;oldid=prev"/>
		<updated>2021-01-09T08:56:52Z</updated>

		<summary type="html">&lt;p&gt;Tạo trang mới với nội dung “local p = {}  local moduleData = &amp;#039;Module:ĐV/Data&amp;#039; local dataSuccess, Data = pcall ( mw.loadData, moduleData ) if dataSuccess and type( Data ) == &amp;#039;table&amp;#039;…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Trang mới&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local moduleData = 'Module:ĐV/Data'&lt;br /&gt;
local dataSuccess, Data = pcall ( mw.loadData, moduleData )&lt;br /&gt;
if dataSuccess and type( Data ) == 'table' then&lt;br /&gt;
	dataSuccess = type( Data.unit ) == 'table'&lt;br /&gt;
		and type( Data.prefix ) == 'table'&lt;br /&gt;
		and type( Data.exposant ) == 'table'&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local errorCat = '[[Thể loại:Có lỗi phát sinh khi dùng Mô đun:ĐV]]'&lt;br /&gt;
local addErrorCat = false&lt;br /&gt;
&lt;br /&gt;
local supUnicode = { ['0'] = '⁰', ['1'] = '¹', ['2'] = '²', ['3'] = '³', ['4'] = '⁴', ['5'] = '⁵', ['6'] = '⁶', ['7'] = '⁷', ['8'] = '⁸', ['9'] = '⁹',&lt;br /&gt;
	['+'] = '⁺', ['-'] = '⁻', ['='] = '⁼', ['('] = '⁽', [')'] = '⁾', ['n'] = 'ⁿ' }&lt;br /&gt;
local subUnicode = { ['0'] = '₀', ['1'] = '₁', ['2'] = '₂', ['3'] = '₃', ['4'] = '₄', ['5'] = '₅', ['6'] = '₆', ['7'] = '₇', ['8'] = '₈', ['9'] = '₉',&lt;br /&gt;
	['+'] = '₊', ['-'] = '₋', ['='] = '₌', ['('] = '₍', [')'] = '₎',&lt;br /&gt;
	['a'] = 'ₐ', ['e'] = 'ₑ', ['o'] = 'ₒ', ['x'] = 'ₓ', ['h'] = 'ₕ', ['k'] = 'ₖ', ['l'] = 'ₗ',&lt;br /&gt;
	['m'] = 'ₘ', ['n'] = 'ₙ', ['p'] = 'ₚ', ['s'] = 'ₛ', ['t'] = 'ₜ',&lt;br /&gt;
	}&lt;br /&gt;
--- Copie de Outils.trim acceptant les nombres.&lt;br /&gt;
local function trim( texte )&lt;br /&gt;
	if type( texte ) == 'string' then&lt;br /&gt;
		texte = texte:gsub( '^%s*(%S?.-)%s*$', '%1' )&lt;br /&gt;
		if texte ~= '' then&lt;br /&gt;
			return texte&lt;br /&gt;
		end&lt;br /&gt;
	elseif type( texte ) == 'number' then&lt;br /&gt;
		return tostring( texte )&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.sanitizeNum( nombre )&lt;br /&gt;
	if type( nombre ) == 'number' then&lt;br /&gt;
		return tostring( nombre )&lt;br /&gt;
	elseif type( nombre ) == 'string' then&lt;br /&gt;
		if nombre:match( '^%-?[%d.,]+$' ) then&lt;br /&gt;
			return nombre&lt;br /&gt;
		end&lt;br /&gt;
		local result = nombre&lt;br /&gt;
			-- remplacement des signes moins ou demi-cadratin par un tiret&lt;br /&gt;
			:gsub( '%−%f[%d]', '-')  -- U+2212&lt;br /&gt;
			:gsub( '&amp;amp;minus;%f[%d]', '-')  -- html &amp;amp;minus;&lt;br /&gt;
			:gsub( '\226\128[\146\147]%f[%d]', '-') -- U+2212, U+2213 (tiret numérique et demi-cadratin)&lt;br /&gt;
			-- remplacement des espaces insécable par des espace simple&lt;br /&gt;
			:gsub( '\194\160', ' ' )&lt;br /&gt;
			:gsub( '&amp;amp;nbsp;', ' ' )&lt;br /&gt;
			:gsub( '\226\128[\128-\138\175]', ' ' ) -- U+2002 à U+200A et U+202F&lt;br /&gt;
			-- trim&lt;br /&gt;
			:gsub( '^%s*(%S?.-)%s*$', '%1' )&lt;br /&gt;
		return result&lt;br /&gt;
	else&lt;br /&gt;
		return ''&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
-- parseNum transforme si possible une chaine formatée en un chaine interprétable par tonumber()&lt;br /&gt;
-- retourne une chaine pour éviter les arrondi éventuels de lua.&lt;br /&gt;
-- si &amp;quot;nombre&amp;quot; est une chaine non reconnue comme un nombre par la fonction, retourne &amp;quot;nombre&amp;quot;.&lt;br /&gt;
-- si &amp;quot;nombre&amp;quot; n'est pas un number ou une chaine retourne une chaine vide.&lt;br /&gt;
function p.parseNombre( nombre )&lt;br /&gt;
	local result&lt;br /&gt;
	if type( nombre ) == 'number' then&lt;br /&gt;
		return tostring( nombre )&lt;br /&gt;
	else&lt;br /&gt;
		-- remplacement des signes moins ou demi-cadratin par un tiret&lt;br /&gt;
		result = p.sanitizeNum( nombre )&lt;br /&gt;
		if result == '' then&lt;br /&gt;
			return ''&lt;br /&gt;
		elseif not result:match( '^%-?[%d., ]*%d$' ) then&lt;br /&gt;
			return nombre&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- suppression espaces&lt;br /&gt;
	result = result:gsub( ' ', '' )&lt;br /&gt;
&lt;br /&gt;
	-- gestion des points et des virgules&lt;br /&gt;
	if result:match( '[.,]' ) then&lt;br /&gt;
		if result:match( '%d%.%d%d%d%.%d' ) then&lt;br /&gt;
			-- type 12.345.678&lt;br /&gt;
			result = result:gsub( '%.', '' ):gsub( ',', '.' )&lt;br /&gt;
		elseif result:match( '%d,%d%d%d,%d' ) -- type 1,234,567 ou 1.234,567,8&lt;br /&gt;
			or result:match( '%d,%d%d%d%.%d' )  -- format anglo-saxon type 1,234.5&lt;br /&gt;
			or result:match( '%d%.%d%d%d,%d' ) -- type 1.123,56 (utilisé en exemple pour sépararer les décimales avec l'ancien modèle unité ou formatnum)&lt;br /&gt;
		then&lt;br /&gt;
			result = result:gsub( ',', '' )&lt;br /&gt;
		else&lt;br /&gt;
			result = result:gsub( ',', '.' )&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
-- _formantNum transforme un nombre ou une chaine représentant un nombre en chaine formatée suivant les conventions du français&lt;br /&gt;
-- si le paramètre ne représente pas un nombre lua il est retourné sans modification&lt;br /&gt;
-- Le paramètre peut être transmis sous forme de table pour ajouter des options :&lt;br /&gt;
-- * round : arrondi à n chiffre après la virgule (peut être négatif)&lt;br /&gt;
-- * decimals : nombre de décimales affichées (peut être négatif, dans ce cas équivalent à round)&lt;br /&gt;
-- * noHtml : n'utilise pas de balise HTML pour affiché les puissance de 10 (pour pouvoir être utilisé en title)&lt;br /&gt;
function p.formatNum( num )&lt;br /&gt;
	local params = {}&lt;br /&gt;
	if type( num ) == 'table' then&lt;br /&gt;
		params = num&lt;br /&gt;
		num = params[1]&lt;br /&gt;
	end&lt;br /&gt;
	if type( num ) == 'number' then&lt;br /&gt;
		num = tostring( num )&lt;br /&gt;
	elseif type( num ) ~= 'string' or num == '' then&lt;br /&gt;
		return num&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- séparation exposant&lt;br /&gt;
	local n, exponent = num:match( '^([-%d.]+)[eE]([+-]?%d+)$' )&lt;br /&gt;
	if exponent then&lt;br /&gt;
		num = n&lt;br /&gt;
		if params.noHtml then&lt;br /&gt;
			exponent = exponent:gsub('+?%f[%d]0', '' )&lt;br /&gt;
				:gsub( '[%d-]', supUnicode )&lt;br /&gt;
		else&lt;br /&gt;
			exponent = '&amp;lt;sup&amp;gt;' .. exponent:gsub('^%+?(%-?)0?', { ['-'] = '−', [''] = '' } ) .. '&amp;lt;/sup&amp;gt;'&lt;br /&gt;
		end&lt;br /&gt;
		exponent = ' ×10' .. exponent&lt;br /&gt;
	else&lt;br /&gt;
		exponent = ''&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- arrondi&lt;br /&gt;
	local decimals = tonumber( params.decimals )&lt;br /&gt;
	local round = tonumber( params.round ) or decimals&lt;br /&gt;
	if round and tonumber( num ) then&lt;br /&gt;
		local mult = 10 ^ round&lt;br /&gt;
		num = tostring( math.floor( num * mult + 0.5 ) / mult )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local moins, entier, fraction = num:match( '^(%-?)(%d*)%.?(%d*)$' )&lt;br /&gt;
	if not entier then&lt;br /&gt;
		return num&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if moins == '-' then&lt;br /&gt;
		moins = '−' -- signe moins (U+2212)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if entier == '' then&lt;br /&gt;
		entier = '0'&lt;br /&gt;
	elseif entier:len() &amp;gt; 3 then&lt;br /&gt;
		local ini = math.fmod( entier:len() - 1, 3 ) + 1&lt;br /&gt;
		entier = ( entier:sub( 1, ini ) or '') .. entier:sub( ini + 1 ):gsub( '(%d%d%d)', '\194\160%1' )&lt;br /&gt;
	end&lt;br /&gt;
	if fraction ~= '' or ( decimals and decimals &amp;gt; 0 ) then&lt;br /&gt;
		if decimals and decimals &amp;gt; #fraction then&lt;br /&gt;
			fraction = fraction .. string.rep( '0', decimals - #fraction )&lt;br /&gt;
		end&lt;br /&gt;
		if #fraction &amp;gt; 3 then&lt;br /&gt;
			fraction = ',' .. fraction:gsub( '(%d%d%d)', '%1\194\160' ):gsub( '\194\160$', '' )&lt;br /&gt;
		else&lt;br /&gt;
			fraction = ',' .. fraction&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return moins .. entier .. fraction .. exponent&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
-- formatNombre transforme un nombre formaté ou non en chaine formatée suivant les convention du français.&lt;br /&gt;
-- si la chaine n'est pas reconnu comme un nombre, elle n'est pas modifiée.&lt;br /&gt;
function p.formatNombre( num, round, decimals )&lt;br /&gt;
	return p.formatNum{ p.parseNombre( num ), round = round, decimals = decimals }&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--- formatNombres transforme tous les nombres d'une chaine en nombre formaté suivant les conventions du français.&lt;br /&gt;
function p.formatNombres( nombres, round, decimals )&lt;br /&gt;
	if type( nombres ) == 'number' then&lt;br /&gt;
		return p.formatNum( nombres, round, decimals )&lt;br /&gt;
	elseif type( nombres ) == 'string' then&lt;br /&gt;
		-- retire les chiffres des strip marker&lt;br /&gt;
		local strip, i = {}, 0&lt;br /&gt;
		nombres = nombres:gsub(&lt;br /&gt;
			'UNIQ%-%-%a+%-%x%x%x%x%x%x%x%x%-QINU',&lt;br /&gt;
			function ( marker )&lt;br /&gt;
				i = i + 1&lt;br /&gt;
				strip[ tostring( i ) ] = marker&lt;br /&gt;
				return 'UNIQ^' .. i .. '¤QINU'&lt;br /&gt;
			end&lt;br /&gt;
		)&lt;br /&gt;
		--  formatage proprement dit&lt;br /&gt;
		nombres = p.sanitizeNum( nombres )&lt;br /&gt;
		local formatN = function ( n )&lt;br /&gt;
			return p.formatNombre( n, round, decimals )&lt;br /&gt;
		end&lt;br /&gt;
		nombres = nombres&lt;br /&gt;
			:gsub( '%-?%f[%d.,][%d., ]*%de[+-]?%d+', formatN )&lt;br /&gt;
			:gsub( '%-?%f[%d.,][%d., ]*%d', formatN )&lt;br /&gt;
&lt;br /&gt;
		-- réintroduction des strip marker&lt;br /&gt;
		nombres = nombres:gsub( 'UNIQ^(%d+)¤QINU', strip )&lt;br /&gt;
		return nombres&lt;br /&gt;
	else&lt;br /&gt;
		return ''&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.parseUnit( texte )&lt;br /&gt;
	local toParse = p.sanitizeNum( texte )&lt;br /&gt;
	if toParse ~= '' then&lt;br /&gt;
		local result&lt;br /&gt;
		local specificArgs = {&lt;br /&gt;
			['à'] = 'à',&lt;br /&gt;
			et = 'et',&lt;br /&gt;
			ou = 'ou',&lt;br /&gt;
			['/'] = '/',&lt;br /&gt;
			['–'] = '–', ['-'] = '–', -- demi cadratin et tiret&lt;br /&gt;
			['±'] = '±', ['+-'] = '±', ['+/-'] = '±',&lt;br /&gt;
			['+'] = '+',&lt;br /&gt;
			['−'] = '−', -- signe moins&lt;br /&gt;
			['×'] = '×', x = '×', ['*'] = '×',&lt;br /&gt;
			['××'] = '××', xx = '××', ['**'] = '××',&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		-- valeur numérique&lt;br /&gt;
		local match, capture = toParse:match( '^(([%d., ]+%f[^d%(])%s*)' )&lt;br /&gt;
		local prefix&lt;br /&gt;
		if not match then&lt;br /&gt;
			-- cas ou le nombre est remplcé par un ou plusieurs points d'interrogation&lt;br /&gt;
			match, prefix = toParse:match( '^((%?+)%s*)' )&lt;br /&gt;
		end&lt;br /&gt;
		if not match then&lt;br /&gt;
			-- cas ou un mot type &amp;quot;vers&amp;quot;, &amp;quot;environ&amp;quot; précède le nombre (mot simple, sans accent pour ne pas complexifier pour des cas minoritaires)&lt;br /&gt;
			match, prefix, capture = toParse:match( '^(([%a]+[.,]?[: ]* )([+-]?%f[%d.,][%d., ]*%d%f[%D])%s*)' )&lt;br /&gt;
		end&lt;br /&gt;
		if not match then&lt;br /&gt;
			-- cas ou le nombre est précédé par un signe, un symbole ASCII, ou suivit d'une incerititude entre parenthèse&lt;br /&gt;
			match, prefix, capture = toParse:match( '^(([(&amp;lt;&amp;gt;=~ ]*)([+-]?%f[%d.,][%d., ]*%d%(?%d*%)?)%s*)' )&lt;br /&gt;
		end&lt;br /&gt;
		if not match then&lt;br /&gt;
			-- cas ou le nombre est précédé par un symbole ≤, ≥ ou ≈&lt;br /&gt;
			match, prefix, capture = toParse:match( '^((\226\137[\164\165\136] ?)([+-]?%f[%d.,][%d., ]*%d%f[%D])%s*)' )&lt;br /&gt;
		end&lt;br /&gt;
		result = { capture or false, prefix = prefix }&lt;br /&gt;
		if match then&lt;br /&gt;
			toParse = toParse:sub( match:len() + 1 )&lt;br /&gt;
&lt;br /&gt;
			-- point de suspensions (ex π = 3.14159...)&lt;br /&gt;
			match = toParse:match( '^…%s*' )&lt;br /&gt;
			if not match then&lt;br /&gt;
				match, capture = toParse:match( '^%.%.%.%s*' )&lt;br /&gt;
			end&lt;br /&gt;
			if match then&lt;br /&gt;
				result[1] = result[1] .. '…'&lt;br /&gt;
				toParse = toParse:sub( match:len() + 1 )&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			-- fraction&lt;br /&gt;
			match, capture = toParse:match( '^((%d*/%d+)%s*)' )&lt;br /&gt;
			if not match then&lt;br /&gt;
				match, capture = toParse:match( '^((\194[\188-\190])%s*)' ) -- ¼ à ¾&lt;br /&gt;
			end&lt;br /&gt;
			if not match then&lt;br /&gt;
				match, capture = toParse:match( '^((\226\133[\144-\158])%s*)' ) -- ⅐ à ⅞&lt;br /&gt;
			end&lt;br /&gt;
			if match then&lt;br /&gt;
				if capture:match( '^/' ) then&lt;br /&gt;
					local n = result[1]:match( ' %d+$' ) or result[1]:match( '^%d+$' )  or ''&lt;br /&gt;
					result[1] = result[1]:sub( 1, -1 - #n )&lt;br /&gt;
					result.fraction = n:gsub( '^ ', '' ) .. capture&lt;br /&gt;
				else&lt;br /&gt;
					result.fraction = capture&lt;br /&gt;
				end&lt;br /&gt;
				toParse = toParse:sub( match:len() + 1 )&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			-- lien avec un deuxième nombre&lt;br /&gt;
			local match2, conj, num = mw.ustring.match( toParse, '^(([àetouM+/−x*×±–-]+) ?(%-?%f[%d.,][%d., ]*%d%f[%D]%)?)%s*)' )&lt;br /&gt;
			if match2 and specificArgs[ conj ]&lt;br /&gt;
				and not ( specificArgs[ conj ] == '×' and mw.ustring.match( toParse, '^[×x] ?10 ?e') ) then&lt;br /&gt;
				result[ specificArgs[ conj ] ] = num&lt;br /&gt;
				toParse = toParse:sub( match2:len() + 1 )&lt;br /&gt;
			end&lt;br /&gt;
			if result['+'] or result['×'] then&lt;br /&gt;
				match2, conj, num = mw.ustring.match( toParse, '^(([x*×−-]) ?(%-?%f[%d.,][%d., ]*%d%f[%D])%s*)' )&lt;br /&gt;
				if match2 then&lt;br /&gt;
					if specificArgs[ conj ] == '×' then&lt;br /&gt;
						result['××'] = num&lt;br /&gt;
					else&lt;br /&gt;
						result['−'] = num&lt;br /&gt;
					end&lt;br /&gt;
					toParse = toParse:sub( match2:len() + 1 )&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- 10 exposant   ( \195\151 = ×, signe multiplié)&lt;br /&gt;
		match, capture = toParse:match( '^(%s*e(%-?%d+)%s*)' )&lt;br /&gt;
		if not match then&lt;br /&gt;
			match, capture = toParse:match( '^(%s*[x\195]\151?10e(%-?%d+)%s*)' )&lt;br /&gt;
		end&lt;br /&gt;
		if match then&lt;br /&gt;
			result.e = capture&lt;br /&gt;
			toParse = toParse:sub( match:len() + 1 )&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- unités&lt;br /&gt;
		if Data.unit[ toParse ] or mw.ustring.match( toParse, '^%a+$' ) or toParse:match( '%b&amp;lt;&amp;gt;' ) then&lt;br /&gt;
			table.insert( result, toParse )&lt;br /&gt;
			toParse = ''&lt;br /&gt;
		elseif toParse ~= '' then&lt;br /&gt;
			local unit, exp&lt;br /&gt;
			toParse = toParse:gsub( '²', '2' ):gsub( '³', '3' )&lt;br /&gt;
			repeat&lt;br /&gt;
				-- unité contenant un lien&lt;br /&gt;
				match, unit, exp = mw.ustring.match( toParse, '^((/?[^%s%d/%[%]]*%b[][^%s%d/]*) ?(%-?%d*)%s*)' )&lt;br /&gt;
				if not match then&lt;br /&gt;
					-- unité ne contenant pas de lien&lt;br /&gt;
					match, unit, exp = mw.ustring.match( toParse, '^((/?[^%s%d/]+) ?(%-?%d*)%s*)' )&lt;br /&gt;
				end&lt;br /&gt;
				if not match then&lt;br /&gt;
					-- l/100 km&lt;br /&gt;
					match, unit, exp = mw.ustring.match( toParse, '^((/100 ?[^%s%d/]+) ?(%-?%d*)%s*)' )&lt;br /&gt;
				end&lt;br /&gt;
				if match then&lt;br /&gt;
					if unit:match( '%-$' ) and exp ~= '' then&lt;br /&gt;
						unit = unit:gsub( '%-$', '' )&lt;br /&gt;
						exp = '-' .. exp&lt;br /&gt;
					elseif exp == '-' then&lt;br /&gt;
						unit = match&lt;br /&gt;
						exp = ''&lt;br /&gt;
					end&lt;br /&gt;
					if Data.unit[ unit ] or mw.ustring.match( unit, '[%a€£$«»]' ) then&lt;br /&gt;
						table.insert( result, unit )&lt;br /&gt;
						table.insert( result, exp )&lt;br /&gt;
						toParse = toParse:sub( match:len() + 1 )&lt;br /&gt;
					else&lt;br /&gt;
						break&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			until toParse == '' or not match&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if toParse == '' then&lt;br /&gt;
			if #result &amp;gt; 1 and result[ #result ] == '' then&lt;br /&gt;
				result[ #result ] = nil&lt;br /&gt;
			end&lt;br /&gt;
			return result&lt;br /&gt;
		else&lt;br /&gt;
			-- une partie de la chaine n'a pas pu être décodée, on retourne la chaine originale&lt;br /&gt;
			addErrorCat = true&lt;br /&gt;
			return { texte }&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		return { }&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
-- nomUtnit retourne le nom français du code d'une unité et de son exposant.&lt;br /&gt;
-- 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.&lt;br /&gt;
function p.nomUnit( unit, exposant )&lt;br /&gt;
	if not dataSuccess or type( unit ) ~= 'string' then&lt;br /&gt;
		return 1, false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- nettoyage des liens et balise HTML&lt;br /&gt;
	unit = unit:gsub( '^/' , '' )&lt;br /&gt;
	if unit:match( '%[' ) then&lt;br /&gt;
		local Delink = require( 'Module:Delink' )&lt;br /&gt;
		unit = Delink._delink{ unit }&lt;br /&gt;
	end&lt;br /&gt;
	if unit:match( '&amp;lt;' ) then&lt;br /&gt;
		unit = unit:gsub( '%b&amp;lt;&amp;gt;', '' )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- récupère le nom de l'unité&lt;br /&gt;
	local unitTab = Data.unit[ unit ]&lt;br /&gt;
	local unitPrefix = { nom = '' }&lt;br /&gt;
	if not unitTab then&lt;br /&gt;
		unitTab = Data.unit[ unit:sub( 2 ) ]&lt;br /&gt;
		unitPrefix = Data.prefix[ unit:sub( 1, 1 ) ]&lt;br /&gt;
		if not ( unitTab and unitPrefix ) then&lt;br /&gt;
			-- pour µ, Ki, Mi, Gi... qui sont codé sur deux octets&lt;br /&gt;
			unitTab = Data.unit[ unit:sub( 3 ) ]&lt;br /&gt;
			unitPrefix = Data.prefix[ unit:sub( 1, 2 ) ]&lt;br /&gt;
			if not ( unitTab and unitPrefix ) then&lt;br /&gt;
				unitTab = false&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- récupère le nom de l'exposant&lt;br /&gt;
	if trim( exposant ) then&lt;br /&gt;
		local exp = tonumber( exposant )&lt;br /&gt;
		exp = exp and Data.exposant[ math.abs( exp ) ]&lt;br /&gt;
		exposant = exp or ' puissance ' .. exposant&lt;br /&gt;
	else&lt;br /&gt;
		exposant = ''&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- assemble les deux partie&lt;br /&gt;
	if type( unitTab ) == 'table' and type( unitTab.nom ) == 'string' then&lt;br /&gt;
		return unitPrefix.nom .. unitTab.nom .. exposant&lt;br /&gt;
	elseif unit:match( '[/%d]' ) then&lt;br /&gt;
		-- ce n'est pas du texte simple, on anule l'infobule&lt;br /&gt;
		return 1, false&lt;br /&gt;
	else&lt;br /&gt;
		return unit .. exposant&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._unite( args )&lt;br /&gt;
	-- remplacement de certains caractères, pour simplifier les pattern&lt;br /&gt;
	local nombre = p.sanitizeNum( args[1] )&lt;br /&gt;
	if nombre == '' then&lt;br /&gt;
		nombre = nil&lt;br /&gt;
	else&lt;br /&gt;
		-- formatage du nombre&lt;br /&gt;
		nombre = p.formatNombres( nombre, args.arrondi, args['décimales'] )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local wiki = { args.prefix or '', nombre }   -- prefix est un paramètre interne défini par p.parseUnit, utile notamment lorsque {{unité}} est utilisé dans les infobox&lt;br /&gt;
&lt;br /&gt;
	-- fraction&lt;br /&gt;
	if args.fraction then&lt;br /&gt;
		local nom, den = args.fraction:match( '^(.-)/(.+)$' )&lt;br /&gt;
		if nom then&lt;br /&gt;
			if nom:match( '^[ %dn()=+-]+$' ) and den:match( '^[ %daeoxhklmnpst()=+-]$' ) then&lt;br /&gt;
				nom = nom:gsub( '[%dn()=+-]', supUnicode )&lt;br /&gt;
				den = den:gsub( '[%daeoxhklmnpst()=+-]', subUnicode )&lt;br /&gt;
			else&lt;br /&gt;
				nom = '&amp;lt;sup style=&amp;quot;font-size: 70%; vertical-align: 0.4em;&amp;quot;&amp;gt;' .. nom .. '&amp;lt;/sup&amp;gt;'&lt;br /&gt;
				den = '&amp;lt;sub style=&amp;quot;font-size: 70%; vertical-align: 0em;&amp;quot;&amp;gt;' .. den .. '&amp;lt;/sub&amp;gt;'&lt;br /&gt;
			end&lt;br /&gt;
			args.fraction = nom .. '⁄' .. den&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if nombre then&lt;br /&gt;
			table.insert( wiki, '\194\160' )&lt;br /&gt;
		end&lt;br /&gt;
		table.insert( wiki, args.fraction )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- à, et, ou, ×, – (tiret cadratin)&lt;br /&gt;
	local specificArgs = { '–', 'à', 'et', 'ou', '/', '×', '××', '±'	}&lt;br /&gt;
	for _, name in ipairs( specificArgs ) do&lt;br /&gt;
		local v = trim( args[ name ] )&lt;br /&gt;
		if v then&lt;br /&gt;
			v = p.formatNombres( v )&lt;br /&gt;
			if name == '–' and nombre and nombre:match( '^[^−]' ) and v:match( '^[^−]' ) then&lt;br /&gt;
				-- pas d'espace pour le tiret cadratin entre deux nombres positifs&lt;br /&gt;
				table.insert( wiki, '–' )&lt;br /&gt;
			elseif name == '/' then&lt;br /&gt;
				-- espace demi-cadratin (U+2002 ou &amp;amp;ensp;) avec /&lt;br /&gt;
				table.insert( wiki, ' / ' )&lt;br /&gt;
			elseif name == '××' then&lt;br /&gt;
				table.insert( wiki, '\194\160×\194\160' )&lt;br /&gt;
			elseif name == '×' or name == '±' then&lt;br /&gt;
				table.insert( wiki, '\194\160' .. name .. '\194\160' )&lt;br /&gt;
			else&lt;br /&gt;
				table.insert( wiki, ' ' .. name .. ' ' )&lt;br /&gt;
			end&lt;br /&gt;
			table.insert( wiki, v )&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- analyse de l'unité pour la conversion (mais ne sera affiché qu'après l'incertitude + et - séparé&lt;br /&gt;
	local i = 1&lt;br /&gt;
	local unit = trim( args[ 2 * i ] )&lt;br /&gt;
	local units = ''&lt;br /&gt;
	local nomUnits, par = {}, false&lt;br /&gt;
	while unit do&lt;br /&gt;
		local exp = p.parseNombre( args[ 2 * i + 1 ] )&lt;br /&gt;
		local sep = ''&lt;br /&gt;
		-- gestion des exposants&lt;br /&gt;
		local expUnit = ''&lt;br /&gt;
		if exp == '' then&lt;br /&gt;
			if unit:sub( -2 ) == '²' then&lt;br /&gt;
				exp = '2'&lt;br /&gt;
				unit = unit:sub( 1, -3 )&lt;br /&gt;
			elseif unit:sub( -2 ) == '³' then&lt;br /&gt;
				exp = '3'&lt;br /&gt;
				unit = unit:sub( 1, -3 )&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if #exp &amp;gt; 0 then&lt;br /&gt;
			expUnit = '&amp;lt;sup&amp;gt;' .. exp:gsub( '^-', '−') .. '&amp;lt;/sup&amp;gt;'  -- remplace le tiret par un vrai signe moins&lt;br /&gt;
		end&lt;br /&gt;
		-- gestion de la séparation des unités et des unités en dénominateur&lt;br /&gt;
		if units ~= '' then&lt;br /&gt;
			if unit:sub( 1, 1 ) == '/' then&lt;br /&gt;
				sep = '/'&lt;br /&gt;
				unit = unit:sub( 2 )&lt;br /&gt;
				if not par then&lt;br /&gt;
					par = true&lt;br /&gt;
					table.insert( nomUnits, 'par' )&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				sep = '\194\160'  -- point médian désactivé : '⋅\194\160'&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if exp:match( '^-' ) and not par then&lt;br /&gt;
			par = true&lt;br /&gt;
			table.insert( nomUnits, 'par' )&lt;br /&gt;
		end&lt;br /&gt;
		-- remplacement de l'unité par son symbole&lt;br /&gt;
		if Data.unit[ unit ] then&lt;br /&gt;
			-- unit = Data.unit[ unit ].symbole&lt;br /&gt;
			-- désactivé car ne gère pas les multiple tel mL&lt;br /&gt;
		end&lt;br /&gt;
		units = units .. sep .. unit .. expUnit&lt;br /&gt;
		table.insert( nomUnits, p.nomUnit( unit, exp ) )&lt;br /&gt;
		i = i + 1&lt;br /&gt;
		unit = trim( args[ 2 * i ] )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- conversion&lt;br /&gt;
	local unitNameString = nomUnits[1] and table.concat( nomUnits, ' ' ) or ''&lt;br /&gt;
	unitNameString = mw.ustring.gsub( unitNameString, '(%a)s%f[%A]', '%1' )&lt;br /&gt;
	local multiple = 1&lt;br /&gt;
	local convertTable = Data.convert[ unitNameString ]&lt;br /&gt;
	if not convertTable and #unitNameString &amp;gt; 5 then&lt;br /&gt;
		-- gesion des multiples (Kilo, méga, mili...)&lt;br /&gt;
		local prefix = Data.prefix[ unitNameString:sub( 1, 4 ) ] or Data.prefix[ unitNameString:sub( 1, 5 ) ]&lt;br /&gt;
		local _, par = unitNameString:find( ' par ' )&lt;br /&gt;
		local prefix2&lt;br /&gt;
		if par then&lt;br /&gt;
			prefix2 = Data.prefix[ unitNameString:sub( par + 1, 4 ) ] or Data.prefix[ unitNameString:sub( par + 1, 5 ) ]&lt;br /&gt;
		end&lt;br /&gt;
		if prefix and Data.convert[ unitNameString:gsub( '^' .. prefix.nom, '' ) ] then&lt;br /&gt;
			convertTable = Data.convert[ unitNameString:gsub( '^' .. prefix.nom, '' ) ]&lt;br /&gt;
			multiple = 10 ^ prefix.puissance&lt;br /&gt;
		elseif prefix2 and  Data.convert[ unitNameString:gsub( ' par ' .. prefix2.nom, '' ) ] then&lt;br /&gt;
			convertTable = Data.convert[ unitNameString:gsub( ' par ' .. prefix2.nom, '' ) ]&lt;br /&gt;
			multiple = 1 / 10 ^ prefix2.puissance&lt;br /&gt;
		elseif prefix and prefix2 and Data.convert[ unitNameString:gsub( '^' .. prefix.nom, '' ):gsub( ' par ' .. prefix2.nom, '' ) ] then&lt;br /&gt;
			convertTable = Data.convert[ unitNameString:gsub( '^' .. prefix.nom, '' ):gsub( ' par ' .. prefix2.nom, '' ) ]&lt;br /&gt;
			multiple = 10 ^ prefix.puissance / 10 ^ prefix2.puissance&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if convertTable then&lt;br /&gt;
		if type( convertTable[1] ) ~= 'table' then&lt;br /&gt;
			convertTable = { convertTable }&lt;br /&gt;
		end&lt;br /&gt;
		for i, v in ipairs( wiki ) do&lt;br /&gt;
			local n = tonumber( p.parseNombre( v ) )&lt;br /&gt;
			if n then&lt;br /&gt;
				n = n * 10 ^ ( tonumber( p.parseNombre( args.e ) ) or 0 )&lt;br /&gt;
				local converted = {}&lt;br /&gt;
				for _, c in ipairs( convertTable ) do&lt;br /&gt;
					local nConverted = n&lt;br /&gt;
					if c.inverse then&lt;br /&gt;
						nConverted = 1 / n&lt;br /&gt;
					end&lt;br /&gt;
					if c.M then&lt;br /&gt;
						-- M = masse molaire&lt;br /&gt;
						local M = tonumber( args.M )&lt;br /&gt;
						if not M then&lt;br /&gt;
							break&lt;br /&gt;
						end&lt;br /&gt;
						if c.M == '*' then&lt;br /&gt;
							nConverted = nConverted * M&lt;br /&gt;
						elseif c.M == '/' then&lt;br /&gt;
							nConverted = nConverted / M&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
					nConverted = nConverted * multiple * c[2] + ( c[3] or 0 )&lt;br /&gt;
					-- format&lt;br /&gt;
					nConverted = p.formatNum{ nConverted, round = c.round or 6, noHtml = true }&lt;br /&gt;
					local sep = ' '&lt;br /&gt;
					if mw.ustring.sub( c[1], 1, 1 ) == '°' then&lt;br /&gt;
						sep = ''&lt;br /&gt;
					end&lt;br /&gt;
					mw.log( c[1], mw.ustring.codepoint( sep, 1, 1))&lt;br /&gt;
					table.insert( converted, nConverted .. sep.. c[1] )&lt;br /&gt;
				end&lt;br /&gt;
				wiki[ i ] = '&amp;lt;span title=&amp;quot;' .. table.concat( converted, ' ou ' ) ..'&amp;quot;&amp;gt;' .. v ..'&amp;lt;/span&amp;gt;'&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- incertitude avec + et − séparés&lt;br /&gt;
	if trim( args['+'] ) then&lt;br /&gt;
		local approximation = '+' .. p.formatNombre( args['+'] ) .. ''&lt;br /&gt;
		if trim( args['−'] ) then&lt;br /&gt;
			approximation = approximation .. '&amp;lt;br&amp;gt; −' .. p.formatNombre( args['−'] )&lt;br /&gt;
		end&lt;br /&gt;
		table.insert( wiki, '&amp;lt;span class=&amp;quot;nowrap&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;display:inline-block; padding-left:0.2em; vertical-align:top; line-height:1em; font-size:80%; text-align:left;&amp;quot;&amp;gt;' )&lt;br /&gt;
		table.insert( wiki, approximation .. '&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;' )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- puissance de 10&lt;br /&gt;
	local exposant = trim( args.e )&lt;br /&gt;
	if exposant then&lt;br /&gt;
		exposant = p.formatNombre( exposant )&lt;br /&gt;
		if nombre then&lt;br /&gt;
			if trim( args['±'] ) and not nombre:match( '^%(' ) then&lt;br /&gt;
				table.insert( wiki, 1, '(' )&lt;br /&gt;
				table.insert( wiki, ')' )&lt;br /&gt;
			end&lt;br /&gt;
			table.insert( wiki, '\194\160× 10&amp;lt;sup&amp;gt;' .. exposant .. '&amp;lt;/sup&amp;gt;' )&lt;br /&gt;
		else&lt;br /&gt;
			table.insert( wiki, '10&amp;lt;sup&amp;gt;' .. exposant .. '&amp;lt;/sup&amp;gt;' )&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if units ~= '' then&lt;br /&gt;
		local sep = '\194\160'&lt;br /&gt;
		if not ( nombre or args.fraction or exposant ) then&lt;br /&gt;
			sep = ''&lt;br /&gt;
		else&lt;br /&gt;
			local symbole = Data.unit[ units ] and Data.unit[ units ].symbole&lt;br /&gt;
			if symbole == '°' or symbole == '′' or symbole == '″' then&lt;br /&gt;
				sep = ''&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		-- ajoute une abréviation si le nom de l'unité est différent de l'unité (en retirant les espaces qui peuvent être devenus insécables)&lt;br /&gt;
		if nomUnits[1] and table.concat( nomUnits ):gsub( ' ', '' ):gsub( '\194\160', '' ) ~= units:gsub( ' ', '' ):gsub( '\194\160', '' ) then&lt;br /&gt;
			units = string.format( '&amp;lt;abbr class=abbr title=&amp;quot;%s&amp;quot;&amp;gt;%s&amp;lt;/abbr&amp;gt;', table.concat( nomUnits, ' ' ), units )&lt;br /&gt;
		end&lt;br /&gt;
		table.insert( wiki, sep .. units )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if #wiki &amp;gt; 0 then&lt;br /&gt;
		return table.concat( wiki )&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.unite( frame )&lt;br /&gt;
	local args&lt;br /&gt;
	if type( frame ) == 'table' then&lt;br /&gt;
		if type( frame.getParent ) == 'function' then&lt;br /&gt;
			args = frame:getParent().args;&lt;br /&gt;
		else&lt;br /&gt;
			args = frame&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if args then&lt;br /&gt;
		args[1] = trim( args[1] ) or false&lt;br /&gt;
		if args[1] then&lt;br /&gt;
			if args[1]:match('[^%d,. -]') then&lt;br /&gt;
				local tempArgs = p.parseUnit( args[1] )&lt;br /&gt;
				if not ( args[2] and tempArgs[2] ) then&lt;br /&gt;
					for k, v in pairs( tempArgs ) do&lt;br /&gt;
						args[k] = v&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			args[2] = trim( args[2] ) or false&lt;br /&gt;
			if args[2] and not args[3] and args[2]:match('/') then&lt;br /&gt;
				local tempArgs = p.parseUnit( args[2] )&lt;br /&gt;
				args[2] = false&lt;br /&gt;
				if tempArgs[1] ~= false then&lt;br /&gt;
					table.insert( tempArgs, 1, false )&lt;br /&gt;
				end&lt;br /&gt;
				for k, v in pairs( tempArgs ) do&lt;br /&gt;
					if args[k] and v then&lt;br /&gt;
						addErrorCat = true&lt;br /&gt;
					end&lt;br /&gt;
					args[k] = args[k] or v&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		-- args alias&lt;br /&gt;
		args['×'] = args['×'] or args['x']  -- lettre x → signe multiplié&lt;br /&gt;
		args['±'] = args['±'] or args['+-'] or args['+/-']&lt;br /&gt;
		if args['+'] then&lt;br /&gt;
			args['−'] = args['−'] or args['-'] -- tiret → signe moins&lt;br /&gt;
		else&lt;br /&gt;
			args['–'] = args['–'] or args['-'] -- tiret → demi-cadratin&lt;br /&gt;
		end&lt;br /&gt;
		local cat = ''&lt;br /&gt;
		if addErrorCat then&lt;br /&gt;
			cat = errorCat&lt;br /&gt;
		end&lt;br /&gt;
		return p._unite( args ) .. cat&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Tttrung</name></author>
	</entry>
</feed>