Module:Sortkey
This module is rated as ready for general use. It has reached a mature form and is thought to be relatively bug-free and ready for use wherever appropriate. It is ready to mention on help pages and other Wikipedia resources as an option for new users to learn. To reduce server load and bad output, it should be improved by sandbox testing rather than repeated trial-and-error editing. |
This module sanitizes and escapes sortkeys so that they can be used inside the data-sort-value attribute of HTML tags in combination with table sorting. Use it when you cannot be certain that the provided sortkey input is a correct sortkey.
Usage
{{#invoke:Sortkey|escape|sortkey to sanitize}}
local getArgs = require('Module:Arguments').getArgs
local p = {}
function p._encode(sortkey)
-- Protect against sortkey nesting.
-- Example: {{sort|{{dts|2013|07|07}}|{{dts|1990|12|01}}}}
if string.find(sortkey, "sortkey") or string.find(sortkey, "data-sort-value") then
return "";
end
return mw.text.encode(sortkey)
end
function p.encode(frame)
local args = getArgs(frame);
return p._encode(args[1] or "")
end
local function valid_number(num)
-- Return true if num is a valid number.
-- In Scribunto (different from some standard Lua), when expressed as a string,
-- overflow or other problems are indicated with text like "inf" or "nan"
-- which are regarded as invalid here (each contains "n").
if type(num) == 'number' and tostring(num):find('n', 1, true) == nil then
return true
end
end
function p._sortKeyForNumber(value)
local sortkey
if not valid_number(value) then
if value < 0 then
sortkey = '1000000000000000000'
else
sortkey = '9000000000000000000'
end
elseif value == 0 then
sortkey = '5000000000000000000'
else
local mag = math.floor(math.log10(math.abs(value)) + 1e-14)
local prefix
if value > 0 then
prefix = 7000 + mag
else
prefix = 2999 - mag
value = value + 10^(mag+1)
end
sortkey = string.format('%d', prefix) .. string.format('%015.0f', math.floor(value * 10^(math.min(28,14-mag))))
end
return sortkey;
end
function p.sortKeyForNumber(frame)
local args = getArgs(frame);
return p._sortKeyForNumber(args[1] or "")
end
return p