Anonymous
×
Create a new article
Write your page title here:
We currently have 15 articles on TwistedFates Database. Type your article name above or click on one of the titles below and start writing!



    TwistedFates Database
    15Articles

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