Changes

Jump to navigation Jump to search
1,244 bytes added ,  21:01, 12 February 2022
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 442: Line 444:  
-- END: Code required only for built-in units.
 
-- END: Code required only for built-in units.
 
------------------------------------------------------------------------
 
------------------------------------------------------------------------
 +
 +
local function add_style(parms, class)
 +
-- Add selected template style to parms if not already present.
 +
parms.templatestyles = parms.templatestyles or {}
 +
if not parms.templatestyles[class] then
 +
parms.templatestyles[class] = parms.frame:extensionTag({
 +
name = 'templatestyles', args = { src = text_code.titles[class] }
 +
})
 +
end
 +
end
 +
 +
local function get_styles(parms)
 +
-- Return string of required template styles, empty if none.
 +
if parms.templatestyles then
 +
local t = {}
 +
for _, v in pairs(parms.templatestyles) do
 +
table.insert(t, v)
 +
end
 +
return table.concat(t)
 +
end
 +
return ''
 +
end
    
local function get_range(word)
 
local function get_range(word)
Line 1,117: Line 1,141:  
local fracfmt = {
 
local fracfmt = {
 
{ -- Like {{frac}} (fraction slash).
 
{ -- Like {{frac}} (fraction slash).
-- 1/2    : sign, numerator, denominator
+
'<span class="frac" role="math">{SIGN}<span class="num">{NUM}</span>&frasl;<span class="den">{DEN}</span></span>', -- 1/2
-- 1+2/3  : signed_wholenumber, numerator, denominator
+
'<span class="frac" role="math">{SIGN}{WHOLE}<span class="sr-only">+</span><span class="num">{NUM}</span>&frasl;<span class="den">{DEN}</span></span>',  -- 1+2/3
'<span class="frac nowrap">%s<sup>%s</sup>&frasl;<sub>%s</sub></span>',
+
style = 'frac',
'<span class="frac nowrap">%s<span class="visualhide">&nbsp;</span><sup>%s</sup>&frasl;<sub>%s</sub></span>',
   
},
 
},
{ -- Like {{sfrac}} (fraction horizontal bar).
+
{ -- Like {{sfrac}} (stacked fraction, that is, horizontal bar).
-- 1//2  : sign, numerator, denominator (sign should probably be before the fraction, but then it can wrap, and html is already too long)
+
'<span class="sfrac tion" role="math">{SIGN}<span class="num">{NUM}</span><span class="sr-only">/</span><span class="den">{DEN}</span></span>', -- 1//2
-- 1+2//3 : signed_wholenumber, numerator, denominator
+
'<span class="sfrac" role="math">{SIGN}{WHOLE}<span class="sr-only">+</span><span class="tion"><span class="num">{NUM}</span><span class="sr-only">/</span><span class="den">{DEN}</span></span></span>',  -- 1+2//3
'<span class="sfrac nowrap" style="display:inline-block; vertical-align:-0.5em; font-size:85%%; text-align:center;"><span style="display:block; line-height:1em; padding:0 0.1em;">%s%s</span><span class="visualhide">/</span><span style="display:block; line-height:1em; padding:0 0.1em; border-top:1px solid;">%s</span></span>',
+
style = 'sfrac',
'<span class="sfrac nowrap">%s<span class="visualhide">&nbsp;</span><span style="display:inline-block; vertical-align:-0.5em; font-size:85%%; text-align:center;"><span style="display:block; line-height:1em; padding:0 0.1em;">%s</span><span class="visualhide">/</span><span style="display:block; line-height:1em; padding:0 0.1em; border-top:1px solid;">%s</span></span></span>',
   
},
 
},
 
}
 
}
Line 1,140: Line 1,162:  
wholestr = nil
 
wholestr = nil
 
end
 
end
if wholestr then
+
local substitute = {
local decorated = with_separator(parms, wholestr)
+
SIGN = negative and MINUS or '',
if negative then
+
WHOLE = wholestr and with_separator(parms, wholestr),
decorated = MINUS .. decorated
+
NUM = from_en(numstr),
end
+
DEN = from_en(denstr),
local fmt = fracfmt[style][2]
+
}
wikitext = format(fmt, decorated, from_en(numstr), from_en(denstr))
+
wikitext = fracfmt[style][wholestr and 2 or 1]:gsub('{(%u+)}', substitute)
else
  −
local sign = negative and MINUS or ''
  −
wikitext = format(fracfmt[style][1], sign, from_en(numstr), from_en(denstr))
  −
end
   
if do_spell then
 
if do_spell then
 
if negative then
 
if negative then
Line 1,159: Line 1,177:  
end
 
end
 
end
 
end
wikitext = spell_number(parms, inout, wholestr, numstr, denstr) or wikitext
+
local s = spell_number(parms, inout, wholestr, numstr, denstr)
 +
if s then
 +
return s
 +
end
 
end
 
end
 +
add_style(parms, fracfmt[style].style)
 
return wikitext
 
return wikitext
 
end
 
end
Line 1,528: 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,669: 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,689: 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,767: 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,787: 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,804: 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,820: 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,172: 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,404: 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,611: 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,234: 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,324: 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,530: 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
Line 3,660: Line 3,701:  
wikitext = wikitext .. parms.warnings
 
wikitext = wikitext .. parms.warnings
 
end
 
end
return true, wikitext, out_unit_table
+
return true, get_styles(parms) .. wikitext, out_unit_table
 
end
 
end
  
Anonymous user

Navigation menu