Module:Dni-numerals
From Guild of Archivists
Documentation for this module may be created at Module:Dni-numerals/doc
--
-- This module implements various functions related to dealing with D'ni numerals.
--
-- Exported Functions:
-- * number_to_dni_string(number)
-- Converts a number to the corresponding dnifont string that would display the number in D'ni when wrapped in a 'dni' element.
-- * number_to_dni_element(number)
-- Converts a number to the corresponding dnifont string wrapped in 'dni' tags to create a 'dni' element.
--
local module = {}
-- A lookup table mapping numbers to
-- their corresponding dnifont characters.
local lookup_table =
{
[0] = "0", [1] = "1", [2] = "2", [3] = "3", [4] = "4",
[5] = "5", [6] = "6", [7] = "7", [8] = "8", [9] = "9",
[10] = ")", [11] = "!", [12] = "@", [13] = "#", [14] = "$",
[15] = "%", [16] = "^", [17] = "&", [18] = "*", [19] = "(",
[20] = "[", [21] = "]", [22] = "\\", [23] = "{", [24] = "}",
[25] = "|",
}
-- Converts a number to a table containing
-- the digits of a dnifont string
local function _number_to_dni_digits(number)
-- If the number is exactly 0, exit early
if number == 0 then return { "0" } end
-- If the number is exactly 25,
-- return the special 25 digit.
if number == 25 then return { "|" } end
-- Cache some repeatedly used functions
-- to avoid repetative table lookup.
local floor = math.floor
local insert = table.insert
-- Create a table to store the individual
-- digits of the resulting string.
local digits = {}
-- Repeat the following
repeat
-- Take the remainder of division by 25
local result = (number % 25)
-- Use the remainder to select the appropriate digit
local digit = lookup_table[result]
-- Insert the digit into the start of the table
insert(digits, 1, digit)
-- Divide the number by 25 to begin work on the next digit
number = floor(number / 25)
-- If the result of the division was 0, the work is done,
-- else, repeat the process until no more digits remain.
until number == 0
-- Return the table containing the digits
return digits
end
-- Converts a number to a dnifont string
local function _number_to_dni_string(number)
-- If the number is exactly 0, exit early
if number == 0 then return "0" end
-- If the number is exactly 25,
-- return the special 25 digit.
if number == 25 then return "|" end
-- Else, defer to _number_to_dni_digits
return table.concat(_number_to_dni_digits(number))
end
-- Wrap the above function for export
function module.number_to_dni_string(frame)
-- If the frame wasn't provided with a proper argument, throw an error
if frame.args[1] == nil then error "Expected a non-nil argument." end
-- Attempt to convert the first parameter to a number
local number = tonumber(frame.args[1])
-- Pass the converted parameter to the conversion function.
return _number_to_dni_string(number)
end
-- Same as
function module.number_to_dni_element(frame)
-- If the frame wasn't provided with a proper argument, throw an error
if frame.args[1] == nil then error "Expected a non-nil argument." end
-- Attempt to convert the first parameter to a number
local number = tonumber(frame.args[1])
-- Pass the converted parameter to the conversion function.
local digits = _number_to_dni_digits(tonumber(frame.args[1]))
-- Prepend an open tag
table.insert(digits, 1, "<dni>")
-- Append a close tag
table.insert(digits, "</dni>")
-- Return the concatenated result
return table.concat(digits)
end
return module