Modul:Gapnum

De la Wikipedia, enciclopedia liberă
Jump to navigation Jump to search

Acest modul este utilizat de {{val}}.

Utilizare în alte module[modificare sursă]

gaps[modificare sursă]

Funcția gaps poate fi utilă pentru formatarea în module care funcționează cu afișarea de numere mari.

local gaps = require('Module:Gapnum').gaps

În apelul funcției gaps, primul argument este numărul de formatat. Al doilea poate fi un tabel cu chei care spun modulului cum să formateze. Cheile ce se pot utiliza sunt:

  • gap - număr asociat unei unități CSS (px, em, en etc.) care definește dimensiunea spațiului între numere. Dacă este lăsat gol, modulul va folosi 0.25em.
  • prec - un număr ce determină precizia părții zecimale a numărului. Dacă precizia e mai mică decât numărul de cifre, cifrele suplimentare vor fi șterse fără rotunjire; dacă este mai mare, se vor adăuga zerouri la sfârșit pentru a obține precizia dorită. Dacă e lăsat gol, atunci modulul va folosi -1, ceea ce înseamnă că precizia va fi aceeași ca și numărul dat, fără adăugiri și eliminări de cifre.

Funcția întoarce un tabel, deci se pot adăuga stiluri și text în spanul conținător, dar aceasta înseamnă și că va fi nevoie să se apeleze tostring() din alte module.

local gaps = require('Module:Gapnum').gaps

function example()
	local n = 123456.78900011
	-- Example for just simple formatting of a number
	-- n_gaps will use the default, .25em gaps and no change in precision
	-- The result will have its gaps created with inline css
	-- But the result would look like:
	-- 123 456.789 000 11
	local n_gaps = gaps(n)

	-- Different gap size
	-- These will format n into the same groups as above
	-- But the spaces between the groups will be larger and smaller, respectively
	local n_big_gaps = gaps(n, {gap='1em'})
	local n_small_gaps = gaps(n, {gap='1px'})

	-- Different precision
	-- n_prec_5 will use the number 123456.78900
	-- The result would look like:
	-- 123 456.789 00
	local n_prec_5 = gaps(n, {prec=5})
	-- n_prec_10 will use the number 123456.7890001100
	-- The result would look like:
	-- 123 456.789 000 1100
	local n_prec_10 = gaps(n, {prec=10})

	-- Both different gaps and precision can be used:
	local n_big_5 = gaps(n, {gap='1em', prec=5})
	local n_small_10 = gaps(n, {gap='1px', prec=10})
end

groups[modificare sursă]

Funcția groups se poate utiliza în alte module pentru a separa numărul în grupuri, la fel ca gaps, dar în loc de string formatat, funcția întoarce tabele ale căror elemente sunt grupurile.

local groups = require('Module:Gapnum').groups

function example()
	-- This will return one table:
	-- {123,456}
	local n1 = groups(123456)

	-- This will return two tables, each assigned to a different variable:
	-- n2a will be:
	-- {1,234}
	-- n2b will be:
	-- {567,89}
	local n2a,n2b = groups(1234.56789)

	-- This will return two tables:
	-- An integer part is always returned, even if it is 0
	-- n3a will be:
	-- {0}
	-- n3b will be:
	-- {123,4567}
	local n3a,n3b = groups(0.1234567)

	-- Just like the other functions, a precision can be defined
	-- precision is simply the second parameter
	-- n4a will be:
	-- {123}
	-- n4b will be:
	-- {456,700,00}
	local n4a,n4b = groups(123.4567,8)
end

local p = {}

local getArgs

function p.main(frame)
	if not getArgs then
		getArgs = require('Module:Arguments').getArgs
	end

	local args = getArgs(frame, {wrappers = 'Template:Gapnum'})
	local n = args[1]

	if not n then
		error('Parameter 1 is required')
	elseif not tonumber(n) and not tonumber(n, 36) then -- Validates any number with base ≤ 36
		error('Unable to convert "' .. args[1] .. '" to a number')
	end

	local gap = args.gap
	local precision = tonumber(args.prec)

	return p.gaps(n,{gap=gap,prec=precision})
end

-- Not named p._main so that it has a better function name when required by Module:Val
function p.gaps(n,tbl)
	local nstr = tostring(n)
	if not tbl then
		tbl = {}
	end
	local gap = tbl.gap or '.25em'

	local int_part, frac_part = p.groups(n,tbl.prec)

	local ret = mw.html.create('span')
							:css('white-space','nowrap')
							-- No gap necessary on first group
							:wikitext(table.remove(int_part,1))

	-- Build int part
	for _, v in ipairs(int_part) do
		ret:tag('span')
				:css('margin-left',gap)
				:wikitext(v)
	end

	if frac_part then
		-- The first group after the decimal shouldn't have a gap
		ret:wikitext('.' .. table.remove(frac_part,1))
		-- Build frac part
		for _, v in ipairs(frac_part) do
			ret:tag('span')
					:css('margin-left',gap)
					:wikitext(v)
		end
	end

	return ret
end

-- Creates tables where each element is a different group of the number
function p.groups(num,precision)
	local nstr = tostring(num)
	if not precision then
		precision = -1
	end

	local decimalloc = nstr:find('.', 1, true)
	local int_part, frac_part
	if decimalloc == nil then
		int_part = nstr
	else
		int_part = nstr:sub(1, decimalloc-1)
		frac_part = nstr:sub(decimalloc + 1)
	end
	-- only define ret_i as an empty table, let ret_d stay nil
	local ret_i,ret_d = {}
	-- Loop to handle most of the groupings; from right to left, so that if a group has less than 3 members, it will be the first group
	while int_part:len() > 3 do
		-- Insert in first spot, since we're moving backwards
		table.insert(ret_i,1,int_part:sub(-3))
		int_part = int_part:sub(1,-4)
	end
	-- handle any left over numbers
	if int_part:len() > 0 then
		table.insert(ret_i,1,int_part)
	end

	if precision ~= 0 and frac_part then
		ret_d = {}
		if precision == -1 then
			precision = frac_part:len()
		end
		-- Reduce the length of the string if required precision is less than actual precision
		-- OR
		-- Increase it (by adding 0s) if the required precision is more than actual
		local offset = precision - frac_part:len()
		if offset < 0 then
			frac_part = frac_part:sub(1,precision)
		elseif offset > 0 then
			frac_part = frac_part .. string.rep('0', offset)
		end

		-- Allow groups of 3 or 2 (3 first)
		for v in string.gmatch(frac_part,'%d%d%d?') do
			table.insert(ret_d,v)
		end
		-- Preference for groups of 4 instead of groups of 1 at the end
		if #frac_part % 3 == 1 then
			if frac_part:len() == 1 then
				ret_d = {frac_part}
			else
				local last_g = ret_d[#ret_d] or ''
				last_g = last_g..frac_part:sub(-1)
				ret_d[#ret_d] = last_g
			end
		end
	end

	return ret_i,ret_d
end

return p