Module:ConvertNumeric: Difference between revisions
Richardpruen (talk | contribs) m 1 revision imported: Wikipedia article on Nicotine modules needed |
m Sync from sandbox |
||
Line 189: | Line 189: | ||
} | } | ||
local | local engord_tens_end = { | ||
['twentieth'] = 20, | |||
['thirtieth'] = 30, | |||
['fortieth'] = 40, | |||
['fiftieth'] = 50, | |||
['sixtieth'] = 60, | |||
['seventieth'] = 70, | |||
['eightieth'] = 80, | |||
['ninetieth'] = 90, | |||
['twentieth'] | |||
['thirtieth'] | |||
['fortieth'] | |||
['fiftieth'] | |||
['sixtieth'] | |||
['seventieth'] = 70, | |||
['eightieth'] | |||
['ninetieth'] | |||
} | } | ||
local eng_tens_cont = { | local eng_tens_cont = { | ||
['twenty'] | ['twenty'] = 20, | ||
['thirty'] | ['thirty'] = 30, | ||
['forty'] | ['forty'] = 40, | ||
['fifty'] | ['fifty'] = 50, | ||
['sixty'] | ['sixty'] = 60, | ||
['seventy'] = 70, | ['seventy'] = 70, | ||
['eighty'] | ['eighty'] = 80, | ||
['ninety'] | ['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 | -- 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 | local engord_lt20 = {} -- ones_position_ord{} keys & values swapped | ||
local | for k, v in pairs( ones_position_ord ) do | ||
local | 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. | return eng_lt20[eng] -- e.g. one -> 1 | ||
elseif | elseif eng_tens_cont[eng] then | ||
return | 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- | return tens_cont + ones_end -- e.g. ninety-nine -> 99 | ||
end | end | ||
end | end | ||
end | end | ||
return -1 -- | 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 | -- 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) |