Module:Dni-numerals: Difference between revisions

From Guild of Archivists
(Create a simple module for converting numbers to a corresponding string of D'ni font characters.)
 
(Add and export a 'number_to_dni_element' . Add some supporting local functions. Provide more error checking.)
Line 21: Line 21:
}
}


-- Converts a number to a dnifont string
-- Converts a number to a table containing
local function _number_to_dni_string(number)
-- the digits of a dnifont string
local function _number_to_dni_digits(number)
-- If the number is exactly 0, exit early
-- If the number is exactly 0, exit early
if number == 0 then return "0" end
if number == 0 then return { "0" } end
-- If the number is exactly 25,
-- If the number is exactly 25,
-- return the special 25 digit.
-- return the special 25 digit.
if number == 25 then return "|" end
if number == 25 then return { "|" } end
-- Cache some repeatedly used functions
-- Cache some repeatedly used functions
Line 57: Line 58:
until number == 0
until number == 0
-- Concatenate the digits to form the final string
-- Return the table containing the digits
return table.concat(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
end


-- Wrap the above function for export
-- Wrap the above function for export
function module.number_to_dni_string(frame)
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
-- Attempt to convert the first parameter to a number
-- and pass it to the conversion function.
local number = tonumber(frame.args[1])
return _number_to_dni_string(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
end


return module
return module

Revision as of 01:45, 24 December 2024

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.
--

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