Module:Shorten

From Pandorabox
Jump to navigation Jump to search

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

local module = {}

--- this is copied straight from technic/technic/helpers.lua
local prefixes = {[-8] = "y", [-7] = "z", [-6] = "a", [-5] = "f", [-4] = "p",
	[-3] = "n", [-2] = "µ", [-1] = "m", [0] = "",  [1] = "k", [2] = "M",
	[3] = "G", [4] = "T", [5] = "P", [6] = "E", [7] = "Z", [8] = "Y"}
function module.EU(frame)
	frame = frame or {}
	local num = frame.args[1] or 0
	-- the small number added is due to floating point inaccuracy
	local b = math.floor(math.log10(math.abs(num)) +0.000001)
	local pref_i
	if b ~= 0 then
		-- b is decremented by 1 to avoid a single digit with many decimals,
		-- e.g. instead of 1.021 MEU, 1021 kEU is shown
		pref_i = math.floor((b - 1) / 3)
	else
		-- as special case, avoid showing e.g. 1100 mEU instead of 1.1 EU
		pref_i = 0
	end
	if not prefixes[pref_i] then
		-- This happens for 0, nan, inf, very big values, etc.
		if num == 0 then
			-- handle 0 explicilty to avoid showing "-0"
			if not constant_digit_count then
				return "0 EU"
			end
			-- gives 0.000
			return string.format("%.3f EU", 0)
		end
		return string.format("%.4g EU", num)
	end

	num = num * 10 ^ (-3 * pref_i)
	if true then
		local comma_digits_cnt = 3 - (b - 3 * pref_i)
		return string.format("%." .. comma_digits_cnt .. "f %sEU",
			num, prefixes[pref_i])
	end
	return string.format("%.4g %sEU", num, prefixes[pref_i])
end

-- shorten like 1.23k
local function sign(x) -- helper function for the formatting
	x = tonumber(x)
	if x < 0 then return "-" end
	return ""
end
local function trim(x,y)
	y = 10^y
	return math.floor(x*y)/y
end

-- shorten a number, using -illion suffix abbreviations (e.g 1000 -> 1k)
function module.shorten(frame)
	frame = frame or {}
	local num = frame.args[1] or 0
	local sign = sign(num)
	if math.abs(num) < 1000 then 
		if money == 0 then return "0" end
		return num
	end
	if math.abs(num) == math.huge then return "Infinity" end
	if num ~= num then return num end
	local shortlist = {[0] = "","k", "m", "b", "t"} -- until decillions, which is honestly enough
	for _, a in ipairs({"","ce"}) do
		for _, b in ipairs({"","de","vi","tg","qag","qig","sxg","spg","ocg","ng"}) do
			for _, c in ipairs({"","u","d","t","qa","qi","sx","sp","oc","no"}) do
				table.insert(shortlist,c..b..a)
			end
		end
	end
	table.remove(shortlist,5); table.remove(shortlist,5); table.remove(shortlist,5)
	local suffixid = math.floor((math.log(num)/math.log(1000))) -- funky way of doing log1000
	
	local x = num/(1000^suffixid)
	local y = math.floor(math.log10(num)%3)
	if y == 0 then -- case: 1.23k
		x = trim(x,2)
	elseif y == 1 then -- case: 12.3k
		x = trim(x,1)
	else -- case: 123k
		x = math.floor(x)
	end
	
	return sign..x..shortlist[suffixid]
end

return module