module:convert/helper

-- This module provides some functions to prepare template parameters

-- for use with Template:Convert.

-- This module is not used by Template:Convert or Module:Convert.

local function stripToNil(text)

-- If text is a non-empty string, return its trimmed content,

-- otherwise return nothing (empty string or not a string).

if type(text) == 'string' then

return text:match('(%S.-)%s*$')

end

end

-- Remove commas and references (any strip markers) from a number.

-- First usage in Template:Infobox_UK_place/dist (June 2018)

local function cleanNumber(frame)

local args = frame.args

local text = stripToNil(args[1]) or ''

if text == '' or tonumber(text) then

return text

end

return mw.text.killMarkers(text):gsub(',', '')

end

local fractions = {

['½'] = '1/2',

['⅓'] = '1/3',

['⅔'] = '2/3',

['¼'] = '1/4',

['¾'] = '3/4',

['⅛'] = '1/8',

['⅜'] = '3/8',

['⅝'] = '5/8',

['⅞'] = '7/8',

}

local fractionNumbers = {

['½'] = 1/2,

['⅓'] = 1/3,

['⅔'] = 2/3,

['¼'] = 1/4,

['¾'] = 3/4,

['⅛'] = 1/8,

['⅜'] = 3/8,

['⅝'] = 5/8,

['⅞'] = 7/8,

}

-- Format regular input with fraction (MOS-confirmant) into Convert-format "12+3/8" ("+" added).

-- First usage in Template:NFL_predraft (August 2017)

local function number(frame)

--[[ Preprocess a template parameter to translate a number to be used as

input for {{convert}}.

{{#invoke:convert/helper|number|12 3/8}} → 12+3/8

Input Output

12 12

12 3/8 12+3/8

{{frac|12|3|8}} 12+3/8

12{{frac|3|8}} 12+3/8

12⅜ 12+3/8

Template:Fraction redirects to Template:Frac so either may be used in the input.

]]

local args = frame.args

local text = stripToNil(args[1]) or ''

if text == '' or tonumber(text) then

return text -- examples: '', '12', '12.3', '12.3e4', or negative

end

text = text:gsub(' ', ' '):gsub(' +', ' '):gsub(' *%+ *', '+'):gsub('⁄', '/'):gsub('⁄', '/')

local integer, numerator, denominator, rest

-- Look for a fraction of form '12 3/8' or '12+3/8' or '3/8'.

integer, numerator, denominator = text:match('^(%d+)[ +](%d+)/(%d+)$')

if integer then

return integer .. '+' .. numerator .. '/' .. denominator

end

numerator, denominator = text:match('^(%d+)/(%d+)$')

if numerator then

return numerator .. '/' .. denominator

end

-- Look for an expanded fraction such as the result of {{frac|12|3|8}} or 12{{frac|3|8}} or {{frac|3|8}}.

numerator, denominator = text:match('(%d+)/(%d+)')

if numerator then

integer = text:match('(%d+)') or

text:match('^(%d+)%s*​

text:match('^(%d+)%s*

return (integer and (integer .. '+') or '') .. numerator .. '/' .. denominator

end

-- Look for a fraction of form '12¾' or '¾'.

integer, rest = text:match('^(%d*)%s*(.*)')

local expand = fractions[rest]

if expand then

return (integer == '' and integer or (integer .. '+')) .. expand

end

return text

end

local function distanceNumber(text)

-- Return a number corresponding to text (0 if text is empty) or throw an error if invalid.

text = text or 0

if tonumber(text) then

return tonumber(text)

end

-- Look for a fraction of form '12¾' or '¾'.

local integer, expand = text:match('^(%d*)%s*(.*)')

if integer == '' then

integer = 0

else

integer = tonumber(integer)

end

if expand == '' then

expand = 0

else

expand = fractionNumbers[expand]

end

if integer and expand then

return integer + expand

end

error('Invalid number "' .. text .. '"', 0)

end

-- First usage in Template:Horse_race_distance (January 2024)

local function horseRaceDistance(frame)

local args = frame:getParent().args

local miles = stripToNil(args[1])

local furlongs = stripToNil(args[2])

local yards = stripToNil(args[3])

local show = {}

if miles then

table.insert(show, miles .. 'm')

end

if furlongs then

table.insert(show, furlongs .. 'f')

end

if yards then

table.insert(show, yards .. 'y')

end

miles = distanceNumber(miles)

furlongs = distanceNumber(furlongs)

yards = distanceNumber(yards)

local meters = miles * 1609.344 + furlongs * 201.168 + yards * 0.9144

return

'' ..

table.concat(show, ' ') ..

''

end

return {

number = number,

cleanNumber = cleanNumber,

horseRaceDistance = horseRaceDistance,

}