Edge Rewrite
// HTMLRewriter · presentation

This page was redesigned at the edge.

Cloudflare fetched the original article and streamed it through HTMLRewriter to apply an entirely new visual system without rebuilding the source page.

Jump to content

Module:Percentage

Permanently protected module
From Wikipedia, the free encyclopedia

--
-- This module implements [[Template:Percentage]]
--
local p = {}

local math_module = require( "Module:Math" )
local precision = math_module._precision
local sortkey = require( "Module:Sortkey" )

local function rnd(num, digits)
	-- This function implements {{rnd}}
	return math_module._precision_format(tostring(num), digits)
end

local function oom(num)
	-- This function implements {{order of magnitude}}
	return math_module._order(tostring(num))
end

function _nonscinote(num)
	-- This function undoes scientific notation
	if mw.ustring.match(num or '', '^%s*(%d)%.(%d+)<span[^<>]*>×</span>10<sup>([%-−]*)(%d)</sup>%s*$') then
		local a,b,c,d = mw.ustring.match(num or '', '^%s*(%d)%.(%d+)<span[^<>]*>×</span>10<sup>([%-−]*)(%d)</sup>%s*$')
		d = tonumber(d) or 1
		if c ~= '' then
			return '0.' .. mw.ustring.rep('0', d - 1) .. a .. b
		else
			return a .. mw.ustring.sub(b .. mw.ustring.rep('0', d ), 1, d)
		end
	end
	return num
end

local function fmtout(num,snote)
	if snote then
		return _nonscinote(num)
	else
		return num
	end
end

local function fixminus(s)
	-- Converts a leading ASCII hyphen-minus (U+002D) to a Unicode minus sign (U+2212),
	-- preserving any leading padding whitespace. Only the sign of the number is touched.
	return (mw.ustring.gsub(tostring(s), '^(%s*)%-', '%1−'))
end

function _percentage(n1, n2, prec, suffix, pad, sigfig, sn)
	local pct = 100*n1/n2
	skey = '<span data-sort-value="'
			.. sortkey._sortKeyForNumber(pct) .. '♠" style="display:none"></span>'

	-- prec = math.floor(prec)

	if sigfig ~= '' then
		local out
		if pct ~= 0 then
			out = fmtout(rnd(pct, tonumber(sigfig) - oom(pct) - 1), sn)
		else
			out = fmtout(rnd(pct, tonumber(sigfig) - 3), sn)
		end
		return skey .. fixminus(out) .. suffix
	end
	if pad ~= '' then
		return skey .. fixminus(fmtout(rnd(pct, prec), sn)) .. suffix
	end
	
	prec = (prec < 0) and 0 or prec
	if pct ~= 0 then
		pct = ((pct < 0) and -1 or 1)*math.floor(math.abs(pct * 10^prec) + 0.5) / 10^prec
	end
	
	return skey .. fixminus(fmtout(pct, sn)) .. suffix
end

function p.main(frame)
	local args = frame.args[1] and frame.args or frame:getParent().args
	local yesno = require('Module:Yesno')
	return _percentage(
		math_module._cleanNumber(args[1] or 0, true) or 0,
		math_module._cleanNumber(args[2] or 100, true) or 100,
		tonumber(args[3]) or tonumber(args['pad']) or 0,
		args['%'] or '%', args['pad'] or '',
		args['sigfig'] or '',
		yesno(args['nonscinote'] or 'no')
		)
end

return p