Module:Convert: Difference between revisions

m (1 revision imported)
wp>Johnuniq
(update from sandbox per Template talk:Convert#Module version 27)
Line 411: Line 411:
-- If no altitude given, use default (zero altitude = sea level).
-- If no altitude given, use default (zero altitude = sea level).
-- Table gives speed of sound in miles per hour at various altitudes:
-- Table gives speed of sound in miles per hour at various altitudes:
--  altitude = -17,499 to 302,499 feet
--  altitude = -17,499 to 402,499 feet
-- mach_table[a + 4] = s where
-- mach_table[a + 4] = s where
--  a = (altitude / 5000) rounded to nearest integer (-3 to 60)
--  a = (altitude / 5000) rounded to nearest integer (-3 to 80)
--  s = speed of sound (mph) at that altitude
--  s = speed of sound (mph) at that altitude
-- LATER: Should calculate result from an interpolation between the next
-- LATER: Should calculate result from an interpolation between the next
Line 423: Line 423:
660.1, 660.1, 660.1, 662.0, 664.3, 666.5, 668.9, 671.1, 673.4, 675.6,  -- 11 to 20
660.1, 660.1, 660.1, 662.0, 664.3, 666.5, 668.9, 671.1, 673.4, 675.6,  -- 11 to 20
677.9, 683.7, 689.9, 696.0, 702.1, 708.1, 714.0, 719.9, 725.8, 731.6,  -- 21 to 30
677.9, 683.7, 689.9, 696.0, 702.1, 708.1, 714.0, 719.9, 725.8, 731.6,  -- 21 to 30
737.3, 737.7, 737.7, 736.2, 730.5, 724.6, 718.8, 712.9, 707.0, 701.1,  -- 31 to 40
737.3, 737.7, 737.7, 736.2, 730.5, 724.6, 718.8, 712.9, 707.0, 701.0,  -- 31 to 40
695.0, 688.9, 682.8, 676.6, 670.4, 664.1, 657.8, 652.9, 648.3, 643.7,  -- 41 to 50
695.0, 688.9, 682.8, 676.6, 670.4, 664.1, 657.8, 652.9, 648.3, 643.7,  -- 41 to 50
639.1, 634.4, 629.6, 624.8, 620.0, 615.2, 613.2, 613.2, 613.2, 613.5,  -- 51 to 60
639.1, 634.4, 629.6, 624.8, 620.0, 615.2, 613.2, 613.2, 613.2, 613.5,  -- 51 to 60
614.4, 615.3, 616.7, 619.8, 623.4, 629.7, 635.0, 641.1, 650.6, 660.0,  -- 61 to 70
672.5, 674.3, 676.1, 677.9, 679.7, 681.5, 683.3, 685.1, 686.8, 688.6,  -- 71 to 80
}
}
altitude = altitude or 0
altitude = altitude or 0
Line 435: Line 437:
if a < -3 then
if a < -3 then
a = -3
a = -3
elseif a > 60 then
elseif a > 80 then
a = 60
a = 80
end
end
return mach_table[a + 4] * 0.44704  -- mph converted to m/s
return mach_table[a + 4] * 0.44704  -- mph converted to m/s
Line 1,548: Line 1,550:
--  v = value of text (text is a number)
--  v = value of text (text is a number)
--  f = true if value is an integer
--  f = true if value is an integer
-- Input can use en digits or digits in local language,
-- Input can use en digits or digits in local language or separators,
-- but no separators, no Unicode minus, and no fraction.
-- but no Unicode minus, and no fraction.
if text then
if text then
local number = tonumber(to_en(text))
local number = tonumber(to_en(text))
Line 1,689: Line 1,691:
end
end


local function range_text(range, want_name, parms, before, after, inout)
local function range_text(range, want_name, parms, before, after, inout, options)
-- Return before .. rtext .. after
-- Return before .. rtext .. after
-- where rtext is the text that separates two values in a range.
-- where rtext is the text that separates two values in a range.
local rtext, adj_text, exception
local rtext, adj_text, exception
options = options or {}
if type(range) == 'table' then
if type(range) == 'table' then
-- Table must specify range text for ('off' and 'on') or ('input' and 'output'),
-- Table must specify range text for ('off' and 'on') or ('input' and 'output'),
Line 1,709: Line 1,712:
end
end
end
end
if rtext == '–' and after:sub(1, #MINUS) == MINUS then
if rtext == '–' and (options.spaced or after:sub(1, #MINUS) == MINUS) then
rtext = '&nbsp;– '
rtext = '&nbsp;– '
end
end
Line 1,787: Line 1,790:
-- Return true if successful or return false, t where t is an error message table.
-- Return true if successful or return false, t where t is an error message table.
currency_text = nil  -- local testing can hold module in memory; must clear globals
currency_text = nil  -- local testing can hold module in memory; must clear globals
local accept_any_text = {
input = true,
qid = true,
qual = true,
stylein = true,
styleout = true,
tracking = true,
}
if kv_pairs.adj and kv_pairs.sing then
if kv_pairs.adj and kv_pairs.sing then
-- For enwiki (before translation), warn if attempt to use adj and sing
-- For enwiki (before translation), warn if attempt to use adj and sing
Line 1,807: Line 1,802:
local en_name = text_code.en_option_name[loc_name]
local en_name = text_code.en_option_name[loc_name]
if en_name then
if en_name then
local en_value
local en_value = text_code.en_option_value[en_name]
if en_name == '$' or en_name == 'frac' or en_name == 'sigfig' then
if en_value == 'INTEGER' then  -- altitude_ft, altitude_m, frac, sigfig
en_value = nil
if loc_value == '' then
if loc_value == '' then
add_warning(parms, 2, 'cvt_empty_option', loc_name)
add_warning(parms, 2, 'cvt_empty_option', loc_name)
elseif en_name == '$' then
-- Value should be a single character like "€" for the euro currency symbol, but anything is accepted.
currency_text = (loc_value == 'euro') and '€' or loc_value
else
else
local minimum
local minimum
local number, is_integer = get_number(loc_value)
local number, is_integer = get_number(loc_value)
if en_name == 'frac' then
if en_name == 'sigfig' then
minimum = 1
elseif en_name == 'frac' then
minimum = 2
minimum = 2
if number and number < 0 then
if number and number < 0 then
Line 1,824: Line 1,819:
end
end
else
else
minimum = 1
minimum = -1e6
end
end
if number and is_integer and number >= minimum then
if number and is_integer and number >= minimum then
en_value = number
en_value = number
else
else
add_warning(parms, 1, (en_name == 'frac' and 'cvt_bad_frac' or 'cvt_bad_sigfig'), loc_name .. '=' .. loc_value)
local m
if en_name == 'frac' then
m = 'cvt_bad_frac'
elseif en_name == 'sigfig' then
m = 'cvt_bad_sigfig'
else
m = 'cvt_bad_altitude'
end
add_warning(parms, 1, m, loc_name .. '=' .. loc_value)
end
end
end
end
elseif accept_any_text[en_name] then
elseif en_value == 'TEXT' then -- $, input, qid, qual, stylein, styleout, tracking
en_value = loc_value ~= '' and loc_value or nil  -- accept non-empty user text with no validation
en_value = loc_value ~= '' and loc_value or nil  -- accept non-empty user text with no validation
if en_name == 'input' then
if not en_value and (en_name == '$' or en_name == 'qid' or en_name == 'qual') then
add_warning(parms, 2, 'cvt_empty_option', loc_name)
elseif en_name == '$' then
-- Value should be a single character like "€" for the euro currency symbol, but anything is accepted.
currency_text = (loc_value == 'euro') and '€' or loc_value
elseif en_name == 'input' then
-- May have something like {{convert|input=}} (empty input) if source is an infobox
-- May have something like {{convert|input=}} (empty input) if source is an infobox
-- with optional fields. In that case, want to output nothing rather than an error.
-- with optional fields. In that case, want to output nothing rather than an error.
Line 1,840: Line 1,848:
end
end
else
else
en_value = text_code.en_option_value[en_name][loc_value]
en_value = en_value[loc_value]
if en_value and en_value:sub(-1) == '?' then
if en_value and en_value:sub(-1) == '?' then
en_value = en_value:sub(1, -2)
en_value = en_value:sub(1, -2)
Line 2,192: Line 2,200:
end
end
if in_unit_table.builtin == 'mach' then
if in_unit_table.builtin == 'mach' then
-- As with old template, a number following Mach as the input unit is the altitude,
-- As with old template, a number following Mach as the input unit is the altitude.
-- and there is no way to specify an altitude for the output unit.
-- That is deprecated: should use altitude_ft=NUMBER or altitude_m=NUMBER.
-- Could put more code in this function to get any output unit and check for
local success, info
-- an altitude following that unit.
success = tonumber(parms[i])  -- this will often work and will give correct result for values like 2e4 without forcing output scientific notation
local success, info = extract_number(parms, parms[i], false, true)
if success then
info = { value = success }
else
success, info = extract_number(parms, parms[i], false, true)
end
if success then
if success then
i = i + 1
i = i + 1
Line 2,424: Line 2,436:
end
end
if in_builtin == 'mach' or out_builtin == 'mach' then
if in_builtin == 'mach' or out_builtin == 'mach' then
local adjust
-- Should check that only one altitude is given but am planning to remove
-- in_current.altitude (which can only occur when Mach is the input unit),
-- and out_current.altitude cannot occur.
local alt = parms.altitude_ft or in_current.altitude
if not alt and parms.altitude_m then
alt = parms.altitude_m / 0.3048  -- 1 ft = 0.3048 m
end
local spd = speed_of_sound(alt)
if in_builtin == 'mach' then
if in_builtin == 'mach' then
inscale = speed_of_sound(in_current.altitude)
inscale = spd
adjust = outscale / 0.1
return invalue * (inscale / outscale)
else
outscale = speed_of_sound(out_current.altitude)
adjust = 0.1 / inscale
end
end
outscale = spd
local adjust = 0.1 / inscale
return true, {
return true, {
outvalue = invalue * (inscale / outscale),
outvalue = invalue * (inscale / outscale),
Line 2,631: Line 2,649:
show = format('%.0f', floor((outvalue / n) + 0.5) * n)
show = format('%.0f', floor((outvalue / n) + 0.5) * n)
end
end
elseif in_current.builtin == 'mach' then
local sigfig = info.clean:gsub('^[0.]+', ''):gsub('%.', ''):len() + 1
show, exponent = make_sigfig(outvalue, sigfig)
else
else
local inclean = info.clean
local inclean = info.clean
Line 3,254: Line 3,275:
-- For simplicity and because more not needed, handle one range item only.
-- For simplicity and because more not needed, handle one range item only.
local prefix2 = make_id(parms, 2, first_unit) .. '&nbsp;'
local prefix2 = make_id(parms, 2, first_unit) .. '&nbsp;'
result = range_text(range[1], want_name, parms, result, prefix2 .. valinfo[2].show, 'in')
result = range_text(range[1], want_name, parms, result, prefix2 .. valinfo[2].show, 'in', {spaced=true})
end
end
return preunit .. result
return preunit .. result
Line 3,344: Line 3,365:
if range then
if range then
-- For simplicity and because more not needed, handle one range item only.
-- 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, inout)
result = range_text(range[1], want_name, parms, result, prefix .. valinfo[2].show, inout, {spaced=true})
end
end
return preunit .. result
return preunit .. result
Line 3,550: Line 3,571:
local success, result2 = make_result(valinfo[i+1])
local success, result2 = make_result(valinfo[i+1])
if not success then return false, result2 end
if not success then return false, result2 end
result = range_text(range[i], want_name, parms, result, result2, inout)
result = range_text(range[i], want_name, parms, result, result2, inout, {spaced=true})
end
end
end
end
Anonymous user