Модуль:Number table sorting
Көрүнүш
Documentation for this module may be created at Модуль:Number table sorting/doc
local lang = mw.language.getContentLanguage()
local Math = require('Module:Math')
local SortKey = require('Module:Sortkey')
-- константалар
local INF = math.huge
local NEGINF = -math.huge
local MINUS = '−' -- Unicode U+2212 MINUS SIGN
--------------------------------------------------------------------------------
-- Nts класс (санды форматтоо жана сорттоо)
--------------------------------------------------------------------------------
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' жараксыз формат", tostring(self.format)), 0)
end
-- Сан алдында текст кошуу (мисалы, "approx. 1,000")
self.prefix = args.prefix or ''
-- отладка (debug) жана тынч режим
self.debug = args.debug or 'no'
self.quiet = args.quiet or 'no'
return self
end
-- Киргизилген санды талдоо
function Nts:parseNumber(s)
s = s or ''
s = string.gsub(s, '−', '-')
s = string.gsub(s, MINUS, '-')
self.rawNumberString = s
-- Бөлүк сан текшерүү (колдоосу жок)
self.isFraction = (string.find(s, '/') ~= nil)
if self.isFraction then
error("Бөлүк сандар колдоого алынбайт: " .. tostring(s), 0)
end
-- илимий экспоненциалдык жазуу текшерүү
self.isScientificNotation = (string.find(s, 'e') ~= nil)
-- тилдин форматынан parse кылуу
self.number = lang:parseFormattedNumber(s)
-- эгер parse болбосо, tonumber колдонуу
if not self.number then
self.number = tonumber(s)
end
-- бош сапка жол берүү
if not self.number then
self.number = NEGINF
end
-- белгиси
if self.number < 0 then self.sign = MINUS else self.sign = '' end
self.absNumber = math.abs(self.number)
if self.absNumber ~= INF then
self.magnitude = math.floor(math.log10(self.absNumber))
self.significand = self.number / 10^self.magnitude
self.precision = Math._precision(self.rawNumberString)
self.integer = math.floor(self.absNumber)
self.fractional = math.abs(self.number - self.integer)
end
end
-- Корутунду чыгаруу (экранга)
function Nts:makeDisplay()
local ret = {}
if self.quiet == 'yes' then return '' end
ret[#ret+1] = self.prefix
-- чоң сандар жана илимий жазуу шарттары
local sci = string.find(tostring(self.number), 'e')
if self.absNumber == INF or isNaN(self.number) or not self.magnitude then
ret[#ret+1] = string.gsub(self.rawNumberString, '-', MINUS)
elseif sci or math.abs(self.magnitude) >= 9 then
ret[#ret+1] = self.sign
if self.format == 'yes' then
ret[#ret+1] = lang:formatNum(math.abs(self.number * 10^-self.magnitude))
else
ret[#ret+1] = math.abs(self.number * 10^-self.magnitude)
end
ret[#ret+1] = '<span style="margin-left:0.2em">×<span style="margin-left:0.1em">10</span></span><sup>'
ret[#ret+1] = (self.magnitude < 0 and MINUS) or '' .. math.abs(self.magnitude)
ret[#ret+1] = '</sup>'
else
ret[#ret+1] = self.sign
if self.format == 'yes' then
ret[#ret+1] = Math._precision_format(self.absNumber, self.precision)
else
ret[#ret+1] = tostring(self.absNumber)
local newp = Math._precision(self.absNumber)
if newp < self.precision then
if self.integer == self.absNumber then ret[#ret+1] = '.' end
ret[#ret+1] = string.rep('0', math.min(12, self.precision - newp))
end
end
end
return table.concat(ret)
end
-- Сорттоо ачкычы түзүү
function Nts:makeSortKey()
return SortKey._sortKeyForNumber(self.number) .. '♠'
end
-- NaN текшерүү
function isNaN(n) return n ~= n end
-- Трекинг категория чыгаруу
function Nts:renderTrackingCategories()
if self.hasDeprecatedParameters then
return '[[Категория:Nts шаблондору эски параметрлери менен]]'
else
return ''
end
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
root:wikitext(self:renderTrackingCategories())
return tostring(root)
end
--------------------------------------------------------------------------------
-- Экспорт жана негизги функция
--------------------------------------------------------------------------------
local p = {}
function p._exportClasses() return { Nts = Nts } end
-- Иштетүү негизги логика
function p._main(args)
local ok, ret = pcall(function() return tostring(Nts.new(args)) end)
if ok then return ret else
ret = string.format('<strong class="error">Ката: Калып:Nts: %s</strong>', ret)
if mw.title.getCurrentTitle().namespace == 0 then
ret = ret .. '[[Категория:Nts шаблондору каталары менен]]'
end
return ret
end
end
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame, {wrappers={'Калып:Nts'}})
return p._main(args)
end
return p