Module:Person height: Difference between revisions
Appearance
Content deleted Content added
m remove one line from prior edit that was not needed, tested with /sandbox and test cases |
(1) fix precision issue identified on the talk page, and (2) add optional |ri=cmin to round inputs to nearest cm or in per talk page |
||
Line 36: | Line 36: | ||
end |
end |
||
local function |
local function trimspace(s) |
||
if s then |
|||
s = mw.ustring.gsub(s, '^%s*(.-)%s*$', '%1') |
|||
end |
|||
return s |
|||
end |
|||
local function get_convert_args(s, prefer, enforce, ri) |
|||
local prefer_m = (prefer or '') == 'm' |
local prefer_m = (prefer or '') == 'm' |
||
local force_m = (enforce or '') == 'm' |
local force_m = (enforce or '') == 'm' |
||
local prefer_cm = (prefer or '') == 'cm' |
local prefer_cm = (prefer or '') == 'cm' |
||
local force_cm = (enforce or '') == 'cm' |
local force_cm = (enforce or '') == 'cm' |
||
ri = (ri or '') == 'cmin' and 'cmin' or '' |
|||
unconverted = clean(s or '') -- basic unit cleaning |
unconverted = clean(s or '') -- basic unit cleaning |
||
Line 54: | Line 63: | ||
return '', unconverted |
return '', unconverted |
||
end |
end |
||
local adj = nil |
|||
if c ~= nil and f == nil and i == nil then |
if c ~= nil and f == nil and i == nil then |
||
local n = mw.ustring.sub(s, 1, c - 1) |
local n = mw.ustring.sub(s, 1, c - 1) |
||
if isnumber(n) then |
if isnumber(n) then |
||
if force_m then |
|||
local prec = require("Module:Math")._precision(trimspace(n)) |
|||
adj = (prec == 1) and 'ri3' or 'ri2' |
|||
end |
|||
if ri ~= '' then |
|||
adj = force_m and 'ri2' or 'ri0' |
|||
end |
|||
return force_m |
return force_m |
||
and {n/100,'m','ftin',0,['abbr']='on'} |
and {n/100,'m','ftin',0,['abbr']='on', ['adj']=adj} |
||
or {n,'cm','ftin',0,['abbr']='on'}, mw.ustring.sub(s, c+2) |
or {n,'cm','ftin',0,['abbr']='on', ['adj']=adj}, mw.ustring.sub(s, c+2) |
||
end |
end |
||
return '', unconverted |
return '', unconverted |
||
Line 67: | Line 85: | ||
if m ~= nil and c == nil and f == nil and i == nil then |
if m ~= nil and c == nil and f == nil and i == nil then |
||
local n = mw.ustring.sub(s, 1, m - 1) |
local n = mw.ustring.sub(s, 1, m - 1) |
||
if ri ~= '' then |
|||
adj = force_cm and 'ri0' or 'ri2' |
|||
end |
|||
if isnumber(n) then |
if isnumber(n) then |
||
return force_cm |
return force_cm |
||
and {n*100,'cm','ftin',0,['abbr']='on'} |
and {n*100,'cm','ftin',0,['abbr']='on',['adj']=adj} |
||
or {n,'m','ftin',0,['abbr']='on'}, mw.ustring.sub(s, m+1) |
or {n,'m','ftin',0,['abbr']='on',['adj']=adj}, mw.ustring.sub(s, m+1) |
||
end |
end |
||
return '', unconverted |
return '', unconverted |
||
Line 79: | Line 100: | ||
local n2 = mw.ustring.sub(s, f+2, i - 1) |
local n2 = mw.ustring.sub(s, f+2, i - 1) |
||
if isnumber(n1) and isnumber(n2) then |
if isnumber(n1) and isnumber(n2) then |
||
if ri ~= '' then |
|||
adj = 'ri0' |
|||
end |
|||
return (force_m or prefer_m) |
return (force_m or prefer_m) |
||
and {n1,'ft',n2,'in', 'm',2,['abbr']='on'} |
and {n1,'ft',n2,'in', 'm',2,['abbr']='on',['adj']=adj} |
||
or {n1,'ft',n2,'in', 'cm',0,['abbr']='on'}, mw.ustring.sub(s, i+2) |
or {n1,'ft',n2,'in', 'cm',0,['abbr']='on',['adj']=adj}, mw.ustring.sub(s, i+2) |
||
end |
end |
||
return '', unconverted |
return '', unconverted |
||
Line 89: | Line 113: | ||
local n = mw.ustring.sub(s, 1, f - 1) |
local n = mw.ustring.sub(s, 1, f - 1) |
||
if isnumber(n) then |
if isnumber(n) then |
||
if ri ~= '' then |
|||
local n2 = 12*(n - math.floor(n)) |
|||
adj = 'ri0' |
|||
return (force_m or prefer_m) |
|||
and {math.floor(n),'ft',n2, 'in','m',2,['abbr']='on',['adj']=adj} |
|||
or {math.floor(n),'ft',n2,'in','cm',0,['abbr']='on',['adj']=adj}, mw.ustring.sub(s, f+2) |
|||
end |
|||
return (force_m or prefer_m) |
return (force_m or prefer_m) |
||
and {n,'ft','m',2,['abbr']='on'} |
and {n,'ft','m',2,['abbr']='on'} |
||
Line 99: | Line 130: | ||
local n = mw.ustring.sub(s, 1, i - 1) |
local n = mw.ustring.sub(s, 1, i - 1) |
||
if isnumber(n) then |
if isnumber(n) then |
||
if ri ~= '' then |
|||
adj = 'ri0' |
|||
end |
|||
return (force_m or prefer_m) |
return (force_m or prefer_m) |
||
and {n,'in','m',2,['abbr']='on'} |
and {n,'in','m',2,['abbr']='on'} |
||
Line 110: | Line 144: | ||
function convert(frame, args) |
function convert(frame, args) |
||
local targs, str = get_convert_args(args[1], args['prefer'] or '', args['enforce'] or '') |
local targs, str = get_convert_args(args[1], args['prefer'] or '', args['enforce'] or '', args['ri'] or '') |
||
if type(targs) == 'table' then |
if type(targs) == 'table' then |
Revision as of 19:08, 19 May 2023
![]() | This Lua module is used on approximately 274,000 pages. To avoid major disruption and server load, 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. Consider discussing changes on the talk page before implementing them. |
![]() | This module is rated as beta, and is ready for widespread use. It is still new and should be used with some caution to ensure the results are as expected. |
![]() | This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing. |
Usage
Intended for use in infoboxes; {{#invoke:person height|main|5ft 6in}}
→ 5 ft 6 in (168 cm). See Template:Infobox person/height for details.
See also
-- This module implements [[Template:Infobox person/height]]
local p = {}
local function clean(s)
s = mw.ustring.gsub(s, 'metre', 'm')
s = mw.ustring.gsub(s, '([^a])meter', '%1m') -- prevents "parameter" from being changed to "param"
s = mw.ustring.gsub(s, 'centi', 'c') -- changes "centim" to "cm"
s = mw.ustring.gsub(s, 'ms', 'm')
s = mw.ustring.gsub(s, 'm[%.,]', 'm')
s = mw.ustring.gsub(s, 'feet', 'ft')
s = mw.ustring.gsub(s, 'foot', 'ft')
s = mw.ustring.gsub(s, 'ft[%.,]', 'ft')
s = mw.ustring.gsub(s, 'inches', 'in')
s = mw.ustring.gsub(s, 'inch', 'in')
s = mw.ustring.gsub(s, 'ins', 'in')
s = mw.ustring.gsub(s, 'in[%.,]', 'in')
s = mw.ustring.gsub(s, '%[%[[Mm]%]%]s', '[[Metre|m]]')
s = mw.ustring.gsub(s, '%[%[[Cc]m%]%]s', '[[Centimetre|cm]]')
s = mw.ustring.gsub(s, '%[%[[Cc]entim|cm%]%]', '[[Centimetre|cm]]')
s = mw.ustring.gsub(s, '%[%[[Ii]n|in%]%]', '[[inch|in]]')
return s
end
local function isnumber(s)
if s then
s = mw.ustring.gsub(s, '%+%s*%d+%s*/%s*%d+%s*$', '')
return tonumber(s)
end
return nil
end
local function trimspace(s)
if s then
s = mw.ustring.gsub(s, '^%s*(.-)%s*$', '%1')
end
return s
end
local function get_convert_args(s, prefer, enforce, ri)
local prefer_m = (prefer or '') == 'm'
local force_m = (enforce or '') == 'm'
local prefer_cm = (prefer or '') == 'cm'
local force_cm = (enforce or '') == 'cm'
ri = (ri or '') == 'cmin' and 'cmin' or ''
unconverted = clean(s or '') -- basic unit cleaning
s = mw.ustring.gsub(unconverted, '&[Nn][Bb][Ss][Pp];', ' ')
local m = mw.ustring.find(s, 'm')
local c = mw.ustring.find(s, 'cm')
local f = mw.ustring.find(s, 'ft')
local i = mw.ustring.find(s, 'in')
if m == nil and f == nil and i == nil then
return '', unconverted
end
local adj = nil
if c ~= nil and f == nil and i == nil then
local n = mw.ustring.sub(s, 1, c - 1)
if isnumber(n) then
if force_m then
local prec = require("Module:Math")._precision(trimspace(n))
adj = (prec == 1) and 'ri3' or 'ri2'
end
if ri ~= '' then
adj = force_m and 'ri2' or 'ri0'
end
return force_m
and {n/100,'m','ftin',0,['abbr']='on', ['adj']=adj}
or {n,'cm','ftin',0,['abbr']='on', ['adj']=adj}, mw.ustring.sub(s, c+2)
end
return '', unconverted
end
if m ~= nil and c == nil and f == nil and i == nil then
local n = mw.ustring.sub(s, 1, m - 1)
if ri ~= '' then
adj = force_cm and 'ri0' or 'ri2'
end
if isnumber(n) then
return force_cm
and {n*100,'cm','ftin',0,['abbr']='on',['adj']=adj}
or {n,'m','ftin',0,['abbr']='on',['adj']=adj}, mw.ustring.sub(s, m+1)
end
return '', unconverted
end
if f ~= nil and i ~=nil and m == nil then
local n1 = mw.ustring.sub(s, 1, f - 1)
local n2 = mw.ustring.sub(s, f+2, i - 1)
if isnumber(n1) and isnumber(n2) then
if ri ~= '' then
adj = 'ri0'
end
return (force_m or prefer_m)
and {n1,'ft',n2,'in', 'm',2,['abbr']='on',['adj']=adj}
or {n1,'ft',n2,'in', 'cm',0,['abbr']='on',['adj']=adj}, mw.ustring.sub(s, i+2)
end
return '', unconverted
end
if f ~= nil and i == nil and m == nil then
local n = mw.ustring.sub(s, 1, f - 1)
if isnumber(n) then
if ri ~= '' then
local n2 = 12*(n - math.floor(n))
adj = 'ri0'
return (force_m or prefer_m)
and {math.floor(n),'ft',n2, 'in','m',2,['abbr']='on',['adj']=adj}
or {math.floor(n),'ft',n2,'in','cm',0,['abbr']='on',['adj']=adj}, mw.ustring.sub(s, f+2)
end
return (force_m or prefer_m)
and {n,'ft','m',2,['abbr']='on'}
or {n,'ft','cm',0,['abbr']='on'}, mw.ustring.sub(s, f+2)
end
return '', unconverted
end
if i ~= nil and f == nil and m == nil then
local n = mw.ustring.sub(s, 1, i - 1)
if isnumber(n) then
if ri ~= '' then
adj = 'ri0'
end
return (force_m or prefer_m)
and {n,'in','m',2,['abbr']='on'}
or {n,'in','cm',0,['abbr']='on'}, mw.ustring.sub(s, i+2)
end
return '', unconverted
end
return '', unconverted
end
function convert(frame, args)
local targs, str = get_convert_args(args[1], args['prefer'] or '', args['enforce'] or '', args['ri'] or '')
if type(targs) == 'table' then
return frame:expandTemplate{ title = 'convert', args = targs} .. str
else
return str
end
end
function p.main(frame)
return convert(frame, frame.args[1] and frame.args or frame:getParent().args)
end
return p