Module:Convert: Difference between revisions

(update from sandbox per Template talk:Convert#Module version 8)
(update from sandbox per Template talk:Convert#Module version 9)
Line 139:
local speller -- function from that module to handle spelling (set if spelling is wanted)
 
local function set_config(frameargs)
-- Set configuration options from template #invoke or defaults.
config = frame.args
maxsigfig = config.maxsigfig or 14 -- maximum number of significant figures
local data_module, text_module
Line 243:
if type(text) == 'string' then
return text:match("^%s*(.-)%s*$")
end
end
 
local function table_len(t)
-- Return length (<100) of a numbered table to replace #t which is
-- documented to not work if t is accessed via mw.loadData().
for i = 1, 100 do
if t[i] == nil then
return i - 1
end
end
end
Line 539 ⟶ 549:
 
local unit_per_mt = {
-- Metatable to get values for a "per" unit of form "x/y".
-- This is never called to determine a unit name or link because "per" units
-- are handled as a special case.
-- Similarly, the default output is handled elsewhere.
Line 568 ⟶ 578:
 
local function make_per(unit_table, force_sp_us, ulookup)
-- Return true, t where t is a "per" unit with unit codes expanded to unit tables,
-- or return false, t where t is an error message table.
local result = { utype = unit_table.utype, per = {} }
Line 590 ⟶ 600:
local multiplier = unit_table.multiplier
if not result.utype then
-- Creating an automatic "per" unit.
local unit1 = result.per[1]
local utype = (unit1 and unit1.utype or prefix or '') .. '/' .. result.per[2].utype
Line 789 ⟶ 799:
local top, bottom = unitcode:match('^(.-)/([^/]+)$')
if top and not unitcode:find('e%d') then
-- If valid, create an automatic "per" unit for an "x/y" unit code.
-- The unitcode must not include extraneous spaces.
-- Engineering notation (apart from at start and which has been stripped before here),
Line 1,622 ⟶ 1,632:
end
 
local function range_text(range, want_name, parms, before, after, inout)
-- Return before .. rtext .. after
-- where rtext is the text that separates two values in a range.
local rtext, adj_text, exception
if type(range) == 'table' then
-- Table must specify range text for abbr=('off' and for abbr='on') or ('input' and 'output'),
-- and may specify range text for 'adj=on',
-- and may specify exception = true.
rtext = range[want_name and 'off' or 'on'] or
range[((inout == 'in') == (parms.opt_flip == true)) and 'output' or 'input']
adj_text = range['adj']
exception = range['exception']
Line 1,901 ⟶ 1,912:
-- used instead of "3+1/2" (and which should not be interpreted as "3 to ½").
-- Unpacked items are inserted into the parms table.
return-- extractor(i)The tail -- thisrecursion allows combinations like "1 x 21x2 to 3 x 43x4".
local valstr = strip(parms[i]) -- trim so any '-' as a negative sign will be at start
local success, result = extract_number(parms, valstr, i > 1)
if not success and valstr and not valstr:match('%-.*/') and i < 20 then -- check i to limit abuse
local lhs, sep, rhs = valstr:match('^(%S+)%s+(%S+)%s+(%S.*)')
for _, sep in ipairs(text_code.ranges.words) do
if lhs and not (sep == '-' and rhs:match('/')) then
local start, stop = valstr:find(sep, 2, true) -- start at 2 to skip any negative sign for range '-'
if startsep:find('%d') then
return success, result -- to reject {{convert|1 234 567|m}} with a decent message (en only)
parms[i] = valstr:sub(stop + 1)
end
table.insert(parms, i, sep)
table.insert(parms, [i, valstr:sub(1, start] -= 1))rhs
table.insert(parms, i, sep)
return extractor(i) -- this allows combinations like "1 x 2 to 3 x 4"
table.insert(parms, i, lhs)
return extractor(i)
end
if not valstr:match('%-.*/') then
for _, sep in ipairs(text_code.ranges.words) do
local start, stop = valstr:find(sep, 2, true) -- start at 2 to skip any negative sign for range '-'
if start then
parms[i] = valstr:sub(stop + 1)
table.insert(parms, i, sep)
table.insert(parms, i, valstr:sub(1, start - 1))
return extractor(i)
end
end
end
Line 1,977 ⟶ 2,001:
end
 
local function get_parms(pframeargs)
-- If successful, return true, parms, unit where
-- parms is a table of all arguments passed to the template
Line 1,991 ⟶ 2,015:
local parms = {} -- arguments passed to template, after translation
local kv_pairs = {} -- table of input key:value pairs where key is a name; needed because cannot iterate parms and add new fields to it
for k, v in pairs(pframe.args) do
if type(k) == 'number' or k == 'test' then -- parameter "test" is reserved for testing and is not translated
parms[k] = v
Line 2,571 ⟶ 2,595:
if combo then
-- For a multiple like ftin, the "first" unit (ft) is last in the combination.
local i = t.multiple and #t.combinationtable_len(combo) or 1
ucode = combo[i]
end
Line 2,981 ⟶ 3,005:
-- For simplicity and because more not needed, handle one range item only.
local prefix2 = make_id(parms, 2, first_unit) .. '&nbsp;'
result = range_text(range[1], want_name, parms, result, prefix2 .. valinfo[2].show, 'in')
end
return preunit .. result
Line 3,049 ⟶ 3,073:
result = valinfo[1].show
end
result = range_text(range[1], want_name, parms, result, valinfo[2].show, 'in')
else
-- Like {{convert|1|x|2|x|3|ft}} (two or more range items): simplify.
Line 3,056 ⟶ 3,080:
for i = 1, range.n do
decorate_value(parms, in_current, i+1)
result = range_text(range[i], want_name, parms, result, valinfo[i+1].show, 'in')
end
end
Line 3,090 ⟶ 3,114:
if range then
-- For simplicity and because more not needed, handle one range item only.
result = range_text(range[1], want_name, parms, result, prefix .. valinfo[2].show, 'out')
end
return preunit .. result
Line 3,121 ⟶ 3,145:
result = valinfo[1].show
end
result = range_text(range[1], want_name, parms, result, valinfo[2].show, 'out')
else
-- Like {{convert|1|x|2|x|3|ft}} (two or more range items): simplify.
Line 3,128 ⟶ 3,152:
for i = 1, range.n do
decorate_value(parms, out_current, i+1)
result = range_text(range[i], want_name, parms, result, valinfo[i+1].show, 'out')
end
end
Line 3,297 ⟶ 3,321:
local success, result2 = make_result(valinfo[i+1])
if not success then return false, result2 end
result = range_text(range[i], want_name, parms, result, result2, 'out')
end
end
Line 3,446 ⟶ 3,470:
local function main_convert(frame)
-- Do convert, and if needed, do it again with higher default precision.
set_config(frame.args)
local result, out_unit_table
local success, parms, in_unit_table = get_parms(frame:getParent().args)
if success then
for i = 1, 2 do -- use counter so cannot get stuck repeating convert
Anonymous user