Module:Convert: Difference between revisions
Richardpruen (talk | contribs) m 1 revision imported |
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 | -- 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 | -- 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. | 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 > | elseif a > 80 then | ||
a = | 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 | -- 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 = ' – ' | rtext = ' – ' | ||
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 | ||
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 | 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) | ||
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 = | 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 | ||
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 | 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 = | 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. | ||
-- | -- That is deprecated: should use altitude_ft=NUMBER or altitude_m=NUMBER. | ||
-- | local success, info | ||
success = tonumber(parms[i]) -- this will often work and will give correct result for values like 2e4 without forcing output scientific notation | |||
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 | -- 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 = | inscale = spd | ||
return invalue * (inscale / outscale) | |||
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) .. ' ' | local prefix2 = make_id(parms, 2, first_unit) .. ' ' | ||
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 |