local lang = mw.language.getContentLanguage()
local Math = require('Module:Math')
local SortKey = require('Module:Sortkey')
-- constants
local INF = math.huge
local NEGINF = -math.huge
local MINUS = '−' -- Unicode U+2212
--------------------------------------------------------------------------------
-- Nts class
--------------------------------------------------------------------------------
local Nts = {}
Nts.__index = Nts
Nts.formats = {
no = true,
yes = true,
}
function Nts.new(args)
local self = setmetatable({}, Nts)
self:parseNumber(args[1])
self.format = args.format or 'yes'
if not Nts.formats[self.format] then
error(string.format("'%s' is not a valid format", tostring(self.format)), 0)
end
self.prefix = args.prefix or ''
self.debug = args.debug or 'no'
self.quiet = args.quiet or 'no'
return self
end
--------------------------------------------------------------------------------
-- Parse number
--------------------------------------------------------------------------------
function Nts:parseNumber(s)
s = s or ''
s = string.gsub(s, '−', '-')
s = string.gsub(s, MINUS, '-')
self.rawNumberString = s
if string.find(s, '/', 1, true) then
error('Fractions are not supported', 0)
end
self.isScientificNotation = string.find(s, 'e', 1, true) ~= nil
self.number = lang:parseFormattedNumber(s) or tonumber(s) or NEGINF
self.sign = self.number < 0 and MINUS or ''
self.absNumber = math.abs(self.number)
if self.absNumber ~= INF and self.absNumber > 0 then
self.magnitude = math.floor(math.log10(self.absNumber))
self.precision = tonumber(Math._precision(self.rawNumberString)) or 0
if self.precision < 0 then
self.precision = 0
elseif self.precision > 10 then
self.precision = 10
end
else
self.magnitude = 0
self.precision = 0
end
end
--------------------------------------------------------------------------------
-- Display
--------------------------------------------------------------------------------
function Nts:makeDisplay()
if self.quiet == 'yes' then
return ''
end
local ret = {}
ret[#ret + 1] = self.prefix
local sciNotation = tostring(self.number):find('e', 1, true)
if self.absNumber == INF or isNaN(self.number) or not self.magnitude then
ret[#ret + 1] = string.gsub(self.rawNumberString, '-', MINUS)
elseif sciNotation or math.abs(self.magnitude) >= 9 then
ret[#ret + 1] = self.sign
local base = math.abs(self.number * 10 ^ -self.magnitude)
if self.format == 'yes' then
ret[#ret + 1] = lang:formatNum(base)
else
ret[#ret + 1] = tostring(base)
end
ret[#ret + 1] =
'<span style="margin-left:0.2em">×<span style="margin-left:0.1em">10</span></span>' ..
'<s style="display:none">^</s><sup>' ..
(self.magnitude < 0 and (MINUS .. -self.magnitude) or self.magnitude) ..
'</sup>'
else
ret[#ret + 1] = self.sign
ret[#ret + 1] = string.format(
'%.' .. self.precision .. 'f',
self.absNumber
)
end
return table.concat(ret)
end
--------------------------------------------------------------------------------
-- Sort key (unchanged)
--------------------------------------------------------------------------------
function Nts:makeSortKey()
return SortKey._sortKeyForNumber(self.number) .. '♠'
end
--------------------------------------------------------------------------------
-- Helpers
--------------------------------------------------------------------------------
function isNaN(n)
return n ~= n
end
--------------------------------------------------------------------------------
-- tostring
--------------------------------------------------------------------------------
function Nts:__tostring()
local root = mw.html.create()
local span = root:tag('span')
:attr('data-sort-value', self:makeSortKey())
if self.debug == 'yes' then
span:tag('span')
:css('border', '1px solid')
:wikitext(self:makeSortKey())
elseif self.quiet ~= 'no' then
span:css('display', 'none')
end
if self.quiet == 'no' then
span:wikitext(self:makeDisplay())
end
return tostring(root)
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p = {}
function p._main(args)
local ok, res = pcall(function()
return tostring(Nts.new(args))
end)
if ok then
return res
end
local err = string.format(
'<strong class="error">Error in [[Template:Nts]]: %s</strong>',
res
)
if mw.title.getCurrentTitle().namespace == 0 then
err = err .. '[[تصنيف:أخطاء قالب ترتيب جدول الأرقام]]'
end
return err
end
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame, {
wrappers = { 'Template:Number table sorting' },
})
return p._main(args)
end
return p