Module:ConvertNumeric: Difference between revisions

Jump to navigation Jump to search
m
Sync from sandbox
m (1 revision imported: Wikipedia article on Nicotine modules needed)
m (Sync from sandbox)
Line 189: Line 189:
}
}


local eng_lt20 = {
local engord_tens_end = {
['zeroth']      =  0,
['twentieth'] = 20,
['first']      =  1,
['thirtieth'] = 30,
['second']      =  2,
['fortieth'] = 40,
['third']      =  3,
['fiftieth'] = 50,
['fourth']      =  4,
['sixtieth'] = 60,
['fifth']      =  5,
['seventieth'] = 70,
['sixth']      =  6,
['eightieth'] = 80,
['seventh']    =  7,
['ninetieth'] = 90,
['eighth']      =  8,
['ninth']      =  9,
['tenth']      = 10,
['eleventh']    = 11,
['twelfth']    = 12,
['thirteenth']  = 13,
['fourteenth']  = 14,
['fifteenth']  = 15,
['sixteenth']  = 16,
['seventeenth'] = 17,
['eighteenth']  = 18,
['nineteenth']  = 19,
}
local eng_tens_end = {
['twentieth'] = 20,
['thirtieth'] = 30,
['fortieth']   = 40,
['fiftieth']   = 50,
['sixtieth']   = 60,
['seventieth'] = 70,
['eightieth'] = 80,
['ninetieth'] = 90,
}
}
local eng_tens_cont = {
local eng_tens_cont = {
['twenty'] = 20,
['twenty'] = 20,
['thirty'] = 30,
['thirty'] = 30,
['forty']   = 40,
['forty'] = 40,
['fifty']   = 50,
['fifty'] = 50,
['sixty']   = 60,
['sixty'] = 60,
['seventy'] = 70,
['seventy'] = 70,
['eighty'] = 80,
['eighty'] = 80,
['ninety'] = 90,
['ninety'] = 90,
}
}


-- Converts a given valid roman numeral (and some invalid roman numerals) to a number. Returns -1, errorstring on error
-- Converts a given valid roman numeral (and some invalid roman numerals) to a number. Returns { -1, errorstring } on error.
local function roman_to_numeral(roman)
local function roman_to_numeral(roman)
if type(roman) ~= "string" then return -1, "roman numeral not a string" end
if type(roman) ~= "string" then return -1, "roman numeral not a string" end
Line 259: Line 238:
end
end


-- Converts a given integer between 0 and 100 to English text (e.g. 47 -> forty-seven)
-- Converts a given integer between 0 and 100 to English text (e.g. 47 -> forty-seven).
local function numeral_to_english_less_100(num, ordinal, plural, zero)
local function numeral_to_english_less_100(num, ordinal, plural, zero)
local terminal_ones, terminal_tens
local terminal_ones, terminal_tens
Line 290: Line 269:
end
end


-- Converts a given integer (in string form) between 0 and 1000 to English text (e.g. 47 -> forty-seven)
-- Converts a given integer (in string form) between 0 and 1000 to English text (e.g. 47 -> forty-seven).
local function numeral_to_english_less_1000(num, use_and, ordinal, plural, zero)
local function numeral_to_english_less_1000(num, use_and, ordinal, plural, zero)
num = tonumber(num)
num = tonumber(num)
Line 302: Line 281:
end
end


-- Converts an English-text ordinal between 'zeroth' and 'ninety-ninth' to a number [0–99], else -1
-- Converts an ordinal in English text from 'zeroth' to 'ninety-ninth' inclusive to a number [0–99], else -1.
local function english_to_ordinal(english)
local function english_to_ordinal(english)
local eng = string.lower(english or '')
local eng = string.lower(english or '')
 
local eng_lt20 = eng_lt20
local engord_lt20 = {} -- ones_position_ord{} keys & values swapped
local eng_tens_end = eng_tens_end
for k, v in pairs( ones_position_ord ) do
local eng_tens_cont = eng_tens_cont
engord_lt20[v] = k
end
 
if engord_lt20[eng] then
return engord_lt20[eng] -- e.g. first -> 1
elseif engord_tens_end[eng] then
return engord_tens_end[eng] -- e.g. ninetieth -> 90
else
local tens, ones = string.match(eng, '^([a-z]+)[%s%-]+([a-z]+)$')
if tens and ones then
local tens_cont = eng_tens_cont[tens]
local ones_end  = engord_lt20[ones]
if tens_cont and ones_end then
return tens_cont + ones_end -- e.g. ninety-ninth -> 99
end
end
end
return -1 -- Failed
end
 
-- Converts a number in English text from 'zero' to 'ninety-nine' inclusive to a number [0–99], else -1.
local function english_to_numeral(english)
local eng = string.lower(english or '')
 
local eng_lt20 = { ['single'] = 1 } -- ones_position{} keys & values swapped
for k, v in pairs( ones_position ) do
eng_lt20[v] = k
end
 
if eng_lt20[eng] then
if eng_lt20[eng] then
return eng_lt20[eng] --e.g. first -> 1
return eng_lt20[eng] -- e.g. one -> 1
elseif eng_tens_end[eng] then
elseif eng_tens_cont[eng] then
return eng_tens_end[eng] --e.g. ninetieth -> 90
return eng_tens_cont[eng] -- e.g. ninety -> 90
else
else
local tens, ones = string.match(eng, '^([a-z]+)%-([a-z]+)$')
local tens, ones = string.match(eng, '^([a-z]+)[%s%-]+([a-z]+)$')
if tens and ones then
if tens and ones then
local tens_cont = eng_tens_cont[tens]
local tens_cont = eng_tens_cont[tens]
local ones_end  = eng_lt20[ones]
local ones_end  = eng_lt20[ones]
if tens_cont and ones_end then
if tens_cont and ones_end then
return tens_cont + ones_end --e.g. ninety-ninth -> 99
return tens_cont + ones_end -- e.g. ninety-nine -> 99
end
end
end
end
end
end
return -1 --failed
return -1 -- Failed
end
end


Line 380: Line 386:
end
end


-- Rounds a number to the nearest two-word number (round = up, down, or "on" for round to nearest)
-- Rounds a number to the nearest two-word number (round = up, down, or "on" for round to nearest).
-- Numbers with two digits before the decimal will be rounded to an integer as specified by round.
-- Numbers with two digits before the decimal will be rounded to an integer as specified by round.
-- Larger numbers will be rounded to a number with only one nonzero digit in front and all other digits zero.
-- Larger numbers will be rounded to a number with only one nonzero digit in front and all other digits zero.
Line 515: Line 521:
-- capitalize (boolean): whether to capitalize the result (e.g. 'One' instead of 'one')
-- capitalize (boolean): whether to capitalize the result (e.g. 'One' instead of 'one')
-- use_and (boolean): whether to use the word 'and' between tens/ones place and higher places
-- use_and (boolean): whether to use the word 'and' between tens/ones place and higher places
-- hyphenate (boolean): whether to hyphenate all words in the result, useful for use as an adjective
-- hyphenate (boolean): whether to hyphenate all words in the result, useful as an adjective
-- ordinal (boolean): whether to produce an ordinal (e.g. 'first' instead of 'one')
-- ordinal (boolean): whether to produce an ordinal (e.g. 'first' instead of 'one')
-- plural (boolean): whether to pluralize the resulting number
-- plural (boolean): whether to pluralize the resulting number
Line 656: Line 662:
roman_to_numeral = roman_to_numeral,
roman_to_numeral = roman_to_numeral,
spell_number = _numeral_to_english,
spell_number = _numeral_to_english,
spell_number2 = _numeral_to_english2,
spell_number2 = _numeral_to_english2,
english_to_ordinal = english_to_ordinal,
english_to_ordinal = english_to_ordinal,
english_to_numeral = english_to_numeral,
}
}


Line 666: Line 673:
function p._english_to_ordinal(frame) -- callable via {{#invoke:ConvertNumeric|_english_to_ordinal|First}}
function p._english_to_ordinal(frame) -- callable via {{#invoke:ConvertNumeric|_english_to_ordinal|First}}
return english_to_ordinal(frame.args[1])
return english_to_ordinal(frame.args[1])
end
function p._english_to_numeral(frame) -- callable via {{#invoke:ConvertNumeric|_english_to_numeral|One}}
return english_to_numeral(frame.args[1])
end
end


Line 707: Line 718:
if div >= 1 then return decToHexDigit(div)..dig[mod+1] else return dig[mod+1] end
if div >= 1 then return decToHexDigit(div)..dig[mod+1] else return dig[mod+1] end
end -- I think this is supposed to be done with a tail call but first I want something that works at all
end -- I think this is supposed to be done with a tail call but first I want something that works at all
---- finds all the decimal numbers in the input text and hexes each of them
---- finds all the decimal numbers in the input text and hexes each of them
function p.decToHex(frame)
function p.decToHex(frame)
Anonymous user
Cookies help us deliver our services. By using our services, you agree to our use of cookies.

Navigation menu