Module:Person height
Appearance
![]() | This Lua module is used on approximately 272,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 splitsuffix(s)
local suffix = ''
if mw.ustring.match(s,'^(.-)(<sup.*)$') then
local a = mw.ustring.gsub(s, '^(.-)(<sup.*)$', '%1')
local b = mw.ustring.gsub(s, '^(.-)(<sup.*)$', '%2')
s = a
suffix = b .. suffix
end
if mw.ustring.match(s,'^(.-)(%[%[[Cc]ategory:.*)$') then
local a = mw.ustring.gsub(s, '^(.-)(%[%[[Cc]ategory:.*)$', '%1')
local b = mw.ustring.gsub(s, '^(.-)(%[%[[Cc]ategory:.*)$', '%2')
s = a
suffix = b .. suffix
end
return s, suffix
end
local function clean(s)
s = mw.ustring.gsub(s, '[Mm]etre', 'm')
s = mw.ustring.gsub(s, '([^a])meter', '%1m') -- prevents "parameter" from being changed to "param"
s = mw.ustring.gsub(s, '[Cc]enti', 'c') -- changes "centim" to "cm"
s = mw.ustring.gsub(s, 'ms', 'm')
s = mw.ustring.gsub(s, 'm[%.,]', 'm')
s = mw.ustring.gsub(s, '[Ff]eet', 'ft')
s = mw.ustring.gsub(s, 'foot', 'ft')
s = mw.ustring.gsub(s, 'ft[%.,]', 'ft')
s = mw.ustring.gsub(s, '[Ii]nches', 'in')
s = mw.ustring.gsub(s, '[Ii]nch', '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, '%[%[[Mm]|[Mm]%]%]', '[[Metre|m]]')
s = mw.ustring.gsub(s, '%[%[[Cc]m%]%]s', '[[Centimetre|cm]]')
s = mw.ustring.gsub(s, '%[%[[Cc]m|[Cc]m%]%]', '[[Centimetre|cm]]')
s = mw.ustring.gsub(s, '%[%[[Cc]entim|cm%]%]', '[[Centimetre|cm]]')
s = mw.ustring.gsub(s, '%[%[[Ii]n|in%]%]', '[[inch|in]]')
s = mw.ustring.gsub(s, '(%d)%s+[Cc][Mm]', '%1 cm')
s = mw.ustring.gsub(s, '(%d)%s+[Mm]', '%1 m')
s = mw.ustring.gsub(s, '(%d)%s+[Ff][Tt]', '%1 ft')
s = mw.ustring.gsub(s, '(%d)%s+[Ii][Nn]', '%1 in')
s = mw.ustring.gsub(s, '(%d&[Nn][Bb][Ss][Pp];)[Cc][Mm]', '%1cm')
s = mw.ustring.gsub(s, '(%d&[Nn][Bb][Ss][Pp];)[Mm]', '%1m')
s = mw.ustring.gsub(s, '(%d&[Nn][Bb][Ss][Pp];)[Ff][Tt]', '%1ft')
s = mw.ustring.gsub(s, '(%d&[Nn][Bb][Ss][Pp];)[Ii][Nn]', '%1in')
s = mw.ustring.gsub(s, '(%d)%s*[′\']%s*([%d]%d*)%s*[\"″]', '%1 ft %2 in')
return s
end
local function isnumber(s)
if s then
s = mw.ustring.gsub(s, '%+%s*%d+%s*/%s*%d+%s*$', '')
s = mw.ustring.gsub(s, '%s*1%s*/%s*2%s*$', '0.5')
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 force_unit(s, t)
s = mw.ustring.gsub(s, '&[Nn][Bb][Ss][Pp];', '★')
if (t == 'cm') then
s = mw.ustring.gsub(s, '(%d*)%.(%d%d)(%d+[★%s]+)m', '%1%2.%3cm')
s = mw.ustring.gsub(s, '(%d*)%.(%d%d)(%d+[★%s]+)%[%[[Mm]et[re][re]|m%]%]', '%1%2.%3[[centimetre|cm]]')
s = mw.ustring.gsub(s, '(%d*)%.(%d%d)([★%s]+)m', '%1%2%3cm')
s = mw.ustring.gsub(s, '(%d*)%.(%d%d)([★%s]+)%[%[[Mm]et[re][re]|m%]%]', '%1%2%3[[centimetre|cm]]')
s = mw.ustring.gsub(s, '(%d*)%.(%d)([★%s]+)m', '%1%20%3cm')
s = mw.ustring.gsub(s, '(%d*)%.(%d)([★%s]+)%[%[[Mm]et[re][re]|m%]%]', '%1%20%3[[centimetre|cm]]')
s = mw.ustring.gsub(s, '(%d*)%.([★%s]+)m', '%100.%2cm')
s = mw.ustring.gsub(s, '(%d*)%.([★%s]+)%[%[[Mm]et[re][re]|m%]%]', '%100.%2[[centimetre|cm]]')
s = mw.ustring.gsub(s, '^(%s*%d+)([★%s]+)m', '%100%2cm')
s = mw.ustring.gsub(s, '([%(★%s]%d+)([★%s]+)m', '%100%2cm')
s = mw.ustring.gsub(s, '^(%s*%d+)([★%s]+)%[%[[Mm]et[re][re]|m%]%]', '%100%2[[centimetre|cm]]')
s = mw.ustring.gsub(s, '([%(★%s]%d+)([★%s]+)%[%[[Mm]et[re][re]|m%]%]', '%100%2[[centimetre|cm]]')
s = mw.ustring.gsub(s, '0(%d+%.?%d*[★%s]+cm)', '%1')
s = mw.ustring.gsub(s, '0(%d+%.?%d*[★%s]+%[%[[Cc]entimet[re][re]|cm%]%])', '%1')
else
s = mw.ustring.gsub(s, '(%d)(%d%d)%.(%d*[★%s]+)cm', '%1.%2%3m')
s = mw.ustring.gsub(s, '(%d)(%d%d)%.(%d*[★%s]+)%[%[[Cc]entimet[re][re]|cm%]%]', '%1.%2%3[[metre|m]]')
s = mw.ustring.gsub(s, '(%d)(%d%d)([★%s]+)cm', '%1.%2%3m')
s = mw.ustring.gsub(s, '(%d)(%d%d)([★%s]+)%[%[[Cc]entimet[re][re]|cm%]%]', '%1.%2%3[[metre|m]]')
s = mw.ustring.gsub(s, '(%d%d)%.(%d*[★%s]+)cm', '0.%1%2m')
s = mw.ustring.gsub(s, '(%d%d)%.(%d*[★%s]+)%[%[[Cc]entimet[re][re]|cm%]%]', '0.%1%2[[metre|m]]')
s = mw.ustring.gsub(s, '(%d%d)([★%s]+)cm', '0.%1%2m')
s = mw.ustring.gsub(s, '(%d%d)([★%s]+)%[%[[Cc]entimet[re][re]|cm%]%]', '0.%1%2[[metre|m]]')
end
s = mw.ustring.gsub(s, '★', ' ')
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
if force_cm and c == nil then
return '', force_unit(unconverted, 'cm')
end
if force_m and c ~= nil then
return '', force_unit(unconverted, 'm')
end
return '', unconverted
end
function convert(frame, args)
local str, suffix = splitsuffix(args[1] or '')
local targs, str = get_convert_args(str, args['prefer'] or '', args['enforce'] or '', args['ri'] or '')
str = str .. suffix
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