Jump to content
Wikipedia The Free Encyclopedia

Module:ConvertNumeric

From Wikipedia, the free encyclopedia
Module documentation[view] [edit] [history] [purge]
Warning This Lua module is used on approximately 19,000 pages and changes may be widely noticed. Test changes in the module's /sandbox or /testcases subpages, or in your own module sandbox. Consider discussing changes on the talk page before implementing them.
[画像:Warning] This Lua module is used in MediaWiki:Watchlist-messages , and on approximately 19,000 pages.
Changes to it can cause immediate changes to the Wikipedia user interface.
To avoid major disruption, any changes should be tested in the module's /sandbox or /testcases subpages, or in your own module sandbox. The tested changes can be added to this page in a single edit. Please discuss changes on the talk page before implementing them.

Usage

{{#invoke:ConvertNumeric|function_name}}

See also

The above documentation is transcluded from Module:ConvertNumeric/doc. (edit | history)
Editors can experiment in this module's sandbox (edit | diff) and testcases (edit | run) pages.
Subpages of this module.

 -- Module for converting between different representations of numbers. See talk page for user documentation.
 -- For unit tests see: [[Module:ConvertNumeric/testcases]]
 -- When editing, preview with: [[Module_talk:ConvertNumeric/testcases]]
 -- First, edit [[Module:ConvertNumeric/sandbox]], then preview with [[Module_talk:ConvertNumeric/sandbox/testcases]]
 require('strict')

 localones_position={
 [0]='zero',
 [1]='one',
 [2]='two',
 [3]='three',
 [4]='four',
 [5]='five',
 [6]='six',
 [7]='seven',
 [8]='eight',
 [9]='nine',
 [10]='ten',
 [11]='eleven',
 [12]='twelve',
 [13]='thirteen',
 [14]='fourteen',
 [15]='fifteen',
 [16]='sixteen',
 [17]='seventeen',
 [18]='eighteen',
 [19]='nineteen'
 }

 localones_position_ord={
 [0]='zeroth',
 [1]='first',
 [2]='second',
 [3]='third',
 [4]='fourth',
 [5]='fifth',
 [6]='sixth',
 [7]='seventh',
 [8]='eighth',
 [9]='ninth',
 [10]='tenth',
 [11]='eleventh',
 [12]='twelfth',
 [13]='thirteenth',
 [14]='fourteenth',
 [15]='fifteenth',
 [16]='sixteenth',
 [17]='seventeenth',
 [18]='eighteenth',
 [19]='nineteenth'
 }

 localones_position_plural={
 [0]='zeros',
 [1]='ones',
 [2]='twos',
 [3]='threes',
 [4]='fours',
 [5]='fives',
 [6]='sixes',
 [7]='sevens',
 [8]='eights',
 [9]='nines',
 [10]='tens',
 [11]='elevens',
 [12]='twelves',
 [13]='thirteens',
 [14]='fourteens',
 [15]='fifteens',
 [16]='sixteens',
 [17]='seventeens',
 [18]='eighteens',
 [19]='nineteens'
 }

 localtens_position={
 [2]='twenty',
 [3]='thirty',
 [4]='forty',
 [5]='fifty',
 [6]='sixty',
 [7]='seventy',
 [8]='eighty',
 [9]='ninety'
 }

 localtens_position_ord={
 [2]='twentieth',
 [3]='thirtieth',
 [4]='fortieth',
 [5]='fiftieth',
 [6]='sixtieth',
 [7]='seventieth',
 [8]='eightieth',
 [9]='ninetieth'
 }

 localtens_position_plural={
 [2]='twenties',
 [3]='thirties',
 [4]='forties',
 [5]='fifties',
 [6]='sixties',
 [7]='seventies',
 [8]='eighties',
 [9]='nineties'
 }

 localgroups={
 [1]='thousand',
 [2]='million',
 [3]='billion',
 [4]='trillion',
 [5]='quadrillion',
 [6]='quintillion',
 [7]='sextillion',
 [8]='septillion',
 [9]='octillion',
 [10]='nonillion',
 [11]='decillion',
 [12]='undecillion',
 [13]='duodecillion',
 [14]='tredecillion',
 [15]='quattuordecillion',
 [16]='quindecillion',
 [17]='sexdecillion',
 [18]='septendecillion',
 [19]='octodecillion',
 [20]='novemdecillion',
 [21]='vigintillion',
 [22]='unvigintillion',
 [23]='duovigintillion',
 [24]='tresvigintillion',
 [25]='quattuorvigintillion',
 [26]='quinquavigintillion',
 [27]='sesvigintillion',
 [28]='septemvigintillion',
 [29]='octovigintillion',
 [30]='novemvigintillion',
 [31]='trigintillion',
 [32]='untrigintillion',
 [33]='duotrigintillion',
 [34]='trestrigintillion',
 [35]='quattuortrigintillion',
 [36]='quinquatrigintillion',
 [37]='sestrigintillion',
 [38]='septentrigintillion',
 [39]='octotrigintillion',
 [40]='noventrigintillion',
 [41]='quadragintillion',
 [51]='quinquagintillion',
 [61]='sexagintillion',
 [71]='septuagintillion',
 [81]='octogintillion',
 [91]='nonagintillion',
 [101]='centillion',
 [102]='uncentillion',
 [103]='duocentillion',
 [104]='trescentillion',
 [111]='decicentillion',
 [112]='undecicentillion',
 [121]='viginticentillion',
 [122]='unviginticentillion',
 [131]='trigintacentillion',
 [141]='quadragintacentillion',
 [151]='quinquagintacentillion',
 [161]='sexagintacentillion',
 [171]='septuagintacentillion',
 [181]='octogintacentillion',
 [191]='nonagintacentillion',
 [201]='ducentillion',
 [301]='trecentillion',
 [401]='quadringentillion',
 [501]='quingentillion',
 [601]='sescentillion',
 [701]='septingentillion',
 [801]='octingentillion',
 [901]='nongentillion',
 [1001]='millinillion',
 }

 localroman_numerals={
 I=1,
 V=5,
 X=10,
 L=50,
 C=100,
 D=500,
 M=1000
 }

 localengord_tens_end={
 ['twentieth']=20,
 ['thirtieth']=30,
 ['fortieth']=40,
 ['fiftieth']=50,
 ['sixtieth']=60,
 ['seventieth']=70,
 ['eightieth']=80,
 ['ninetieth']=90,
 }

 localeng_tens_cont={
 ['twenty']=20,
 ['thirty']=30,
 ['forty']=40,
 ['fifty']=50,
 ['sixty']=60,
 ['seventy']=70,
 ['eighty']=80,
 ['ninety']=90,
 }

 -- Converts a given valid roman numeral (and some invalid roman numerals) to a number. Returns { -1, errorstring } on error.
 localfunctionroman_to_numeral(roman)
 iftype(roman)~="string"thenreturn-1,"roman numeral not a string"end
 localrev=roman:reverse()
 localraising=true
 locallast=0
 localresult=0
 fori=1,#revdo
 localc=rev:sub(i,i)
 localnext=roman_numerals[c]
 ifnext==nilthenreturn-1,"roman numeral contains illegal character "..cend
 ifnext>lastthen
 result=result+next
 raising=true
 elseifnext<lastthen
 result=result-next
 raising=false
 elseifraisingthen
 result=result+next
 else
 result=result-next
 end
 last=next
 end
 returnresult
 end

 -- Converts a given integer between 0 and 100 to English text (e.g. 47 -> forty-seven).
 localfunctionnumeral_to_english_less_100(num,ordinal,plural,zero)
 localterminal_ones,terminal_tens
 ifordinalthen
 terminal_ones=ones_position_ord
 terminal_tens=tens_position_ord
 elseifpluralthen
 terminal_ones=ones_position_plural
 terminal_tens=tens_position_plural
 else
 terminal_ones=ones_position
 terminal_tens=tens_position
 end

 ifnum==0andzero~=nilthen
 returnzero
 elseifnum<20then
 returnterminal_ones[num]
 elseifnum%10==0then
 returnterminal_tens[num/10]
 else
 returntens_position[math.floor(num/10)]..'-'..terminal_ones[num%10]
 end
 end

 localfunctionstandard_suffix(ordinal,plural)
 ifordinalthenreturn'th'end
 ifpluralthenreturn's'end
 return''
 end

 -- Converts a given integer (in string form) between 0 and 1000 to English text (e.g. 47 -> forty-seven).
 localfunctionnumeral_to_english_less_1000(num,use_and,ordinal,plural,zero)
 num=tonumber(num)
 ifnum<100then
 returnnumeral_to_english_less_100(num,ordinal,plural,zero)
 elseifnum%100==0then
 returnones_position[num/100]..' hundred'..standard_suffix(ordinal,plural)
 else
 returnones_position[math.floor(num/100)]..' hundred '..(use_andand'and 'or'')..numeral_to_english_less_100(num%100,ordinal,plural,zero)
 end
 end

 -- Converts an ordinal in English text from 'zeroth' to 'ninety-ninth' inclusive to a number [0–99], else -1.
 localfunctionenglish_to_ordinal(english)
 localeng=string.lower(englishor'')

 localengord_lt20={}-- ones_position_ord{} keys & values swapped
 fork,vinpairs(ones_position_ord)do
 engord_lt20[v]=k
 end

 ifengord_lt20[eng]then
 returnengord_lt20[eng]-- e.g. first -> 1
 elseifengord_tens_end[eng]then
 returnengord_tens_end[eng]-- e.g. ninetieth -> 90
 else
 localtens,ones=string.match(eng,'^([a-z]+)[%s%-]+([a-z]+)$')
 iftensandonesthen
 localtens_cont=eng_tens_cont[tens]
 localones_end=engord_lt20[ones]
 iftens_contandones_endthen
 returntens_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.
 localfunctionenglish_to_numeral(english)
 localeng=string.lower(englishor'')

 localeng_lt20={['single']=1}-- ones_position{} keys & values swapped
 fork,vinpairs(ones_position)do
 eng_lt20[v]=k
 end

 ifeng_lt20[eng]then
 returneng_lt20[eng]-- e.g. one -> 1
 elseifeng_tens_cont[eng]then
 returneng_tens_cont[eng]-- e.g. ninety -> 90
 else
 localtens,ones=string.match(eng,'^([a-z]+)[%s%-]+([a-z]+)$')
 iftensandonesthen
 localtens_cont=eng_tens_cont[tens]
 localones_end=eng_lt20[ones]
 iftens_contandones_endthen
 returntens_cont+ones_end-- e.g. ninety-nine -> 99
 end
 end
 end
 return-1-- Failed
 end

 -- Converts a number expressed as a string in scientific notation to a string in standard decimal notation
 -- e.g. 1.23E5 -> 123000, 1.23E-5 = .0000123. Conversion is exact, no rounding is performed.
 localfunctionscientific_notation_to_decimal(num)
 localexponent,subs=num:gsub("^%-?%d*%.?%d*%-?[Ee]([+%-]?%d+)$","%1")
 ifsubs==0thenreturnnumend-- Input not in scientific notation, just return unmodified
 exponent=tonumber(exponent)

 localnegative=num:find("^%-")
 local_,decimal_pos=num:find("%.")
 -- Mantissa will consist of all decimal digits with no decimal point
 localmantissa=num:gsub("^%-?(%d*)%.?(%d*)%-?[Ee][+%-]?%d+$","%1%2")
 ifnegativeanddecimal_posthendecimal_pos=decimal_pos-1end
 ifnotdecimal_posthendecimal_pos=#mantissa+1end

 -- Remove leading zeros unless decimal point is in first position
 whiledecimal_pos>1andmantissa:sub(1,1)=='0'do
 mantissa=mantissa:sub(2)
 decimal_pos=decimal_pos-1
 end
 -- Shift decimal point right for exponent > 0
 whileexponent>0do
 decimal_pos=decimal_pos+1
 exponent=exponent-1
 ifdecimal_pos>#mantissa+1thenmantissa=mantissa..'0'end
 -- Remove leading zeros unless decimal point is in first position
 whiledecimal_pos>1andmantissa:sub(1,1)=='0'do
 mantissa=mantissa:sub(2)
 decimal_pos=decimal_pos-1
 end
 end
 -- Shift decimal point left for exponent < 0
 whileexponent<0do
 ifdecimal_pos==1then
 mantissa='0'..mantissa
 else
 decimal_pos=decimal_pos-1
 end
 exponent=exponent+1
 end

 -- Insert decimal point in correct position and return
 return(negativeand'-'or'')..mantissa:sub(1,decimal_pos-1)..'.'..mantissa:sub(decimal_pos)
 end

 -- Rounds a number to the nearest integer (NOT USED)
 localfunctionround_num(x)
 ifx%1>=0.5then
 returnmath.ceil(x)
 else
 returnmath.floor(x)
 end
 end

 -- 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.
 -- Larger numbers will be rounded to a number with only one nonzero digit in front and all other digits zero.
 -- Negative sign is preserved and does not count towards word limit.
 localfunctionround_for_english(num,round)
 -- If an integer with at most two digits, just return
 ifnum:find("^%-?%d?%d%.?$")thenreturnnumend

 localnegative=num:find("^%-")
 ifnegativethen
 -- We're rounding magnitude so flip it
 ifround=='up'thenround='down'elseifround=='down'thenround='up'end
 end

 -- If at most two digits before decimal, round to integer and return
 local_,_,small_int,trailing_digits,round_digit=num:find("^%-?(%d?%d?)%.((%d)%d*)$")
 ifsmall_intthen
 ifsmall_int==''thensmall_int='0'end
 if(round=='up'andtrailing_digits:find('[1-9]'))or(round=='on'andtonumber(round_digit)>=5)then
 small_int=tostring(tonumber(small_int)+1)
 end
 return(negativeand'-'or'')..small_int
 end

 -- When rounding up, any number with > 1 nonzero digit will round up (e.g. 1000000.001 rounds up to 2000000)
 localnonzero_digits=0
 fordigitinnum:gfind("[1-9]")do
 nonzero_digits=nonzero_digits+1
 end

 num=num:gsub("%.%d*$","")-- Remove decimal part
 -- Second digit used to determine which way to round lead digit
 local_,_,lead_digit,round_digit,round_digit_2,rest=num:find("^%-?(%d)(%d)(%d)(%d*)$")
 iftonumber(lead_digit..round_digit)<20and(1+#rest)%3==0then
 -- In English numbers < 20 are one word so put 2 digits in lead and round based on 3rd
 lead_digit=lead_digit..round_digit
 round_digit=round_digit_2
 else
 rest=round_digit_2..rest
 end

 if(round=='up'andnonzero_digits>1)or(round=='on'andtonumber(round_digit)>=5)then
 lead_digit=tostring(tonumber(lead_digit)+1)
 end
 -- All digits but lead digit will turn to zero
 rest=rest:gsub("%d","0")
 return(negativeand'-'or'')..lead_digit..'0'..rest
 end

 localdenominators={
 [2]={'half',plural='halves'},
 [3]={'third'},
 [4]={'quarter',us='fourth'},
 [5]={'fifth'},
 [6]={'sixth'},
 [8]={'eighth'},
 [9]={'ninth'},
 [10]={'tenth'},
 [16]={'sixteenth'},
 }

 -- Return status, fraction where:
 -- status is a string:
 -- "finished" if there is a fraction with no whole number;
 -- "ok" if fraction is empty or valid;
 -- "unsupported" if bad fraction;
 -- fraction is a string giving (numerator / denominator) as English text, or is "".
 -- Only unsigned fractions with a very limited range of values are supported,
 -- except that if whole is empty, the numerator can use "-" to indicate negative.
 -- whole (string or nil): nil or "" if no number before the fraction
 -- numerator (string or nil): numerator, if any (default = 1 if a denominator is given)
 -- denominator (string or nil): denominator, if any
 -- sp_us (boolean): true if sp=us
 -- negative_word (string): word to use for negative sign, if whole is empty
 -- use_one (boolean): false: 2+1/2 → "two and a half"; true: "two and one-half"
 localfunctionfraction_to_english(whole,numerator,denominator,sp_us,negative_word,use_one)
 ifnumeratorordenominatorthen
 localfinished=(whole==nilorwhole=='')
 localsign=''
 ifnumeratorthen
 iffinishedandnumerator:sub(1,1)=='-'then
 numerator=numerator:sub(2)
 sign=negative_word..' '
 end
 else
 numerator='1'
 end
 ifnotnumerator:match('^%d+$')ornotdenominatorornotdenominator:match('^%d+$')then
 return'unsupported',''
 end
 numerator=tonumber(numerator)
 denominator=tonumber(denominator)
 localdendata=denominators[denominator]
 ifnot(dendataand1<=numeratorandnumerator<=99)then
 return'unsupported',''
 end
 localnumstr,denstr
 localsep='-'
 ifnumerator==1then
 denstr=sp_usanddendata.usordendata[1]
 iffinishedoruse_onethen
 numstr='one'
 elseifdenstr:match('^[aeiou]')then
 numstr='an'
 sep=' '
 else
 numstr='a'
 sep=' '
 end
 else
 numstr=numeral_to_english_less_100(numerator)
 denstr=dendata.plural
 ifnotdenstrthen
 denstr=(sp_usanddendata.usordendata[1])..'s'
 end
 end
 iffinishedthen
 return'finished',sign..numstr..sep..denstr
 end
 return'ok',' and '..numstr..sep..denstr
 end
 return'ok',''
 end

 -- Takes a decimal number and converts it to English text.
 -- Return nil if a fraction cannot be converted (only some numbers are supported for fractions).
 -- num (string or nil): the number to convert.
 -- Can be an arbitrarily large decimal, such as "-123456789123456789.345", and
 -- can use scientific notation (e.g. "1.23E5").
 -- May fail for very large numbers not listed in "groups" such as "1E4000".
 -- num is nil if there is no whole number before a fraction.
 -- numerator (string or nil): numerator of fraction (nil if no fraction)
 -- denominator (string or nil): denominator of fraction (nil if no fraction)
 -- 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
 -- 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')
 -- plural (boolean): whether to pluralize the resulting number
 -- links: nil: do not add any links; 'on': link "billion" and larger to Orders of magnitude article;
 -- any other text: list of numbers to link (e.g. "billion,quadrillion")
 -- negative_word: word to use for negative sign (typically 'negative' or 'minus'; nil to use default)
 -- round: nil or '': no rounding; 'on': round to nearest two-word number; 'up'/'down': round up/down to two-word number
 -- zero: word to use for value '0' (nil to use default)
 -- use_one (boolean): false: 2+1/2 → "two and a half"; true: "two and one-half"
 localfunction_numeral_to_english(num,numerator,denominator,capitalize,use_and,hyphenate,ordinal,plural,links,negative_word,round,zero,use_one)
 ifnotnegative_wordthen
 ifuse_andthen
 -- TODO Should 'minus' be used when do not have sp=us?
 -- If so, need to update testcases, and need to fix "minus zero".
 -- negative_word = 'minus'
 negative_word='negative'
 else
 negative_word='negative'
 end
 end
 localstatus,fraction_text=fraction_to_english(num,numerator,denominator,notuse_and,negative_word,use_one)
 ifstatus=='unsupported'then
 returnnil
 end
 ifstatus=='finished'then
 -- Input is a fraction with no whole number.
 -- Hack to avoid executing stuff that depends on num being a number.
 locals=fraction_text
 ifhyphenatethens=s:gsub("%s","-")end
 ifcapitalizethens=s:gsub("^%l",string.upper)end
 returns
 end
 num=scientific_notation_to_decimal(num)
 ifroundandround~=''then
 ifround~='on'andround~='up'andround~='down'then
 error("Invalid rounding mode")
 end
 num=round_for_english(num,round)
 end

 -- Separate into negative sign, num (digits before decimal), decimal_places (digits after decimal)
 localMINUS='−'-- Unicode U+2212 MINUS SIGN (may be in values from [[Module:Convert]])
 ifnum:sub(1,#MINUS)==MINUSthen
 num='-'..num:sub(#MINUS+1)-- replace MINUS with '-'
 elseifnum:sub(1,1)=='+'then
 num=num:sub(2)-- ignore any '+'
 end
 localnegative=num:find("^%-")
 localdecimal_places,subs=num:gsub("^%-?%d*%.(%d+)$","%1")
 ifsubs==0thendecimal_places=nilend
 num,subs=num:gsub("^%-?(%d*)%.?%d*$","%1")
 ifnum==''anddecimal_placesthennum='0'end
 ifsubs==0ornum==''thenerror("Invalid decimal numeral")end

 -- For each group of 3 digits except the last one, print with appropriate group name (e.g. million)
 locals=''
 while#num>3do
 ifs~=''thens=s..' 'end
 localgroup_num=math.floor((#num-1)/3)
 localgroup=groups[group_num]
 localgroup_digits=#num-group_num*3
 s=s..numeral_to_english_less_1000(num:sub(1,group_digits),false,false,false,zero)..' '
 iflinksand(((links=='on'andgroup_num>=3)orlinks:find(group))andgroup_num<=13)then
 s=s..'[[Orders_of_magnitude_(numbers)#10'..group_num*3..'|'..group..']]'
 else
 s=s..group
 end
 num=num:sub(1+group_digits)
 num=num:gsub("^0*","")-- Trim leading zeros
 end

 -- Handle final three digits of integer part
 ifs~=''andnum~=''then
 if#num<=2anduse_andthen
 s=s..' and '
 else
 s=s..' '
 end
 end
 ifs==''ornum~=''then
 s=s..numeral_to_english_less_1000(num,use_and,ordinal,plural,zero)
 elseifordinalorpluralthen
 -- Round numbers like "one million" take standard suffixes for ordinal/plural
 s=s..standard_suffix(ordinal,plural)
 end

 -- For decimal places (if any) output "point" followed by spelling out digit by digit
 ifdecimal_placesthen
 s=s..' point'
 fori=1,#decimal_placesdo
 s=s..' '..ones_position[tonumber(decimal_places:sub(i,i))]
 end
 end

 s=s:gsub("^%s*(.-)%s*$","%1")-- Trim whitespace
 ifordinalandpluralthens=s..'s'end-- s suffix works for all ordinals
 ifnegativeands~=zerothens=negative_word..' '..send
 s=s:gsub("negative zero","zero")
 s=s..fraction_text
 ifhyphenatethens=s:gsub("%s","-")end
 ifcapitalizethens=s:gsub("^%l",string.upper)end
 returns
 end

 localfunction_numeral_to_english2(args)
 localnum=tostring(args.num)

 num=num:gsub("^%s*(.-)%s*$","%1")-- Trim whitespace
 num=num:gsub(",","")-- Remove commas
 num=num:gsub("^<span[^<>]*></span>","")-- Generated by Template:age
 ifnum~=''then-- a fraction may have an empty whole number
 ifnotnum:find("^%-?%d*%.?%d*%-?[Ee]?[+%-]?%d*$")then
 -- Input not in a valid format, try to eval it as an expr to see
 -- if that produces a number (e.g. "3 + 5" will become "8").
 localnoerr,result=pcall(mw.ext.ParserFunctions.expr,num)
 ifnoerrthen
 num=result
 end
 end
 end

 -- Call helper function passing args
 return_numeral_to_english(
 num,
 args['numerator'],
 args['denominator'],
 args['capitalize'],
 args['use_and'],
 args['hyphenate'],
 args['ordinal'],
 args['plural'],
 args['links'],
 args['negative_word'],
 args['round'],
 args['zero'],
 args['use_one']
 )or''
 end

 localp={-- Functions that can be called from another module
 roman_to_numeral=roman_to_numeral,
 spell_number=_numeral_to_english,
 spell_number2=_numeral_to_english2,
 english_to_ordinal=english_to_ordinal,
 english_to_numeral=english_to_numeral,
 }

 functionp._roman_to_numeral(frame)-- Callable via {{#invoke:ConvertNumeric|_roman_to_numeral|VI}}
 returnroman_to_numeral(frame.args[1])
 end

 functionp._english_to_ordinal(frame)-- callable via {{#invoke:ConvertNumeric|_english_to_ordinal|First}}
 returnenglish_to_ordinal(frame.args[1])
 end

 functionp._english_to_numeral(frame)-- callable via {{#invoke:ConvertNumeric|_english_to_numeral|One}}
 returnenglish_to_numeral(frame.args[1])
 end

 functionp.numeral_to_english(frame)
 localargs=frame.args
 -- Tail call to helper function passing args from frame
 return_numeral_to_english2{
 ['num']=args[1],
 ['numerator']=args['numerator'],
 ['denominator']=args['denominator'],
 ['capitalize']=args['case']=='U'orargs['case']=='u',
 ['use_and']=args['sp']~='us',
 ['hyphenate']=args['adj']=='on',
 ['ordinal']=args['ord']=='on',
 ['plural']=args['pl']=='on',
 ['links']=args['lk'],
 ['negative_word']=args['negative'],
 ['round']=args['round'],
 ['zero']=args['zero'],
 ['use_one']=args['one']=='one'-- experiment: using '|one=one' makes fraction 2+1/2 give "two and one-half" instead of "two and a half"
 }
 end

 ---- recursive function for p.decToHex
 localfunctiondecToHexDigit(dec)
 localdig={"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"}
 localdiv=math.floor(dec/16)
 localmod=dec-(16*div)
 ifdiv>=1thenreturndecToHexDigit(div)..dig[mod+1]elsereturndig[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

 ---- finds all the decimal numbers in the input text and hexes each of them
 functionp.decToHex(frame)
 localargs=frame.args
 localparent=frame.getParent(frame)
 localpargs={}
 ifparentthenpargs=parent.argsend
 localtext=args[1]orpargs[1]or""
 localminlength=args.minlengthorpargs.minlengthor1
 minlength=tonumber(minlength)
 localprowl=mw.ustring.gmatch(text,"(.-)(%d+)")
 localoutput=""
 repeat
 localchaff,dec=prowl()
 ifnot(dec)thenbreakend
 localhex=decToHexDigit(dec)
 while(mw.ustring.len(hex)<minlength)dohex="0"..hexend
 output=output..chaff..hex
 untilfalse
 localchaff=mw.ustring.match(text,"(%D+)$")or""
 returnoutput..chaff
 end

 returnp

AltStyle によって変換されたページ (->オリジナル) /