Module:Gapnum

From Zoophilia Wiki
Revision as of 18:58, 5 July 2014 by meta>The Mol Man (I forgot about rounding... Let's see if we can get away with not converting)
Jump to navigationJump to search

Documentation for this module may be created at Module:Gapnum/doc

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 gap =  args.gap or '0.25em'

	local ret_string = '<span style="white-space:nowrap">'

	local n = args[1]
	
	if not tonumber(n) then
		if not args[1] then
			error('Nil value in parameter 1')
		else
			error('Unable to convert "' .. args[1] .. '" to a number')
		end
	end
	
	local nstr = tostring(n)
	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
	
	local int_string = ''
	-- 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
		int_string = '<span style="margin-left:'..gap..';">'..int_part:sub(-3)..'</span>'..int_string
		int_part = int_part:sub(1,-4)
	end
	
	-- handle any left over numbers
	int_string = int_part..int_string
	
	ret_string = ret_string..int_string
	
	local precision = tonumber(args.prec) or -1
	if precision ~= 0 and frac_part then
		local frac_string = '.'
		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
		
		-- The first group after the decimal shouldn't have a gap between the decimal
		if frac_part:len() >= 3 then
			frac_string = frac_string..frac_part:sub(1,3)
			frac_part = frac_part:sub(4)
		else
			frac_string = frac_string..frac_part
			frac_part = ''
		end
		
	-- Loop to handle most of the groupings; from left to right, so that if a group has
	-- less than 3 members, it will be the last group
		while frac_part:len() >= 3 do
			frac_string = frac_string..'<span style="margin-left:'..gap..';">'..frac_part:sub(1,3)..'</span>'
			frac_part = frac_part:sub(4)
		end
	
		-- Handle any left over numbers
		if frac_part:len() > 0 then
			frac_string = frac_string..'<span style="margin-left:'..gap..';">'..frac_part..'</span>'
		end
		
		if frac_string:len() > 1 then
			ret_string = ret_string..frac_string
		end
	end
	
	-- Closing span tag
	ret_string = ret_string..'</span>'

	return ret_string
end

return p