The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
Latest revision | Your text | ||
Line 1: | Line 1: | ||
-- Convert a value from one unit of measurement to another. | -- Convert a value from one unit of measurement to another. | ||
-- Example: {{convert|123|lb|kg}} --> 123 pounds (56 kg) | -- Example: {{convert|123|lb|kg}} --> 123 pounds (56 kg) | ||
-- See [[:en:Template:Convert/Transwiki guide]] if copying to another wiki. | |||
local MINUS = '−' -- Unicode U+2212 MINUS SIGN (UTF-8: e2 88 92) | local MINUS = '−' -- Unicode U+2212 MINUS SIGN (UTF-8: e2 88 92) | ||
Line 410: | 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 422: | 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 434: | 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 441: | 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 543: | Line 568: | ||
if key == 'symbol' then | if key == 'symbol' then | ||
value = self.si_prefix .. self._symbol | value = self.si_prefix .. self._symbol | ||
if value == 'l' then value = 'L' end | |||
elseif key == 'sym_us' then | elseif key == 'sym_us' then | ||
value = rawget(self, '_sym_us') | value = rawget(self, '_sym_us') | ||
Line 705: | Line 731: | ||
local success, result = lookup(parms, target, what, utable, fails, depth) | local success, result = lookup(parms, target, what, utable, fails, depth) | ||
if not success then return false, result end | if not success then return false, result end | ||
override_from(result, t, { 'customary', 'default', 'link', 'symbol', 'symlink' }) | override_from(result, t, { 'customary', 'default', 'link', 'symbol', 'symlink', 'usename' }) | ||
local multiplier = t.multiplier | local multiplier = t.multiplier | ||
if multiplier then | if multiplier then | ||
Line 811: | Line 837: | ||
-- and not if the unit has an offset or is a built-in. | -- and not if the unit has an offset or is a built-in. | ||
-- Only en digits are accepted. | -- Only en digits are accepted. | ||
local exponent, baseunit = unitcode:match('^ | local e, exponent, baseunit = unitcode:match('^([Ee])(%d+)(.*)') | ||
if exponent then | if exponent then | ||
local engscale = text_code.eng_scales[exponent] | local engscale = text_code.eng_scales[exponent] | ||
Line 817: | Line 843: | ||
local success, result = lookup(parms, baseunit, 'no_combination', utable, fails, depth) | local success, result = lookup(parms, baseunit, 'no_combination', utable, fails, depth) | ||
if success and not (result.offset or result.builtin or result.engscale) then | if success and not (result.offset or result.builtin or result.engscale) then | ||
if e == 'E' then | |||
result.this_number_word = true | |||
unitcode = 'e' .. unitcode:sub(2) | |||
end | |||
result.unitcode = unitcode -- 'e6cuft' not 'cuft' | result.unitcode = unitcode -- 'e6cuft' not 'cuft' | ||
result.defkey = unitcode -- key to lookup default exception | result.defkey = unitcode -- key to lookup default exception | ||
Line 884: | Line 914: | ||
-- The name may be linked and the target of the link must not be changed. | -- The name may be linked and the target of the link must not be changed. | ||
-- Hypothetical examples: | -- Hypothetical examples: | ||
-- [[ | -- [[long ton|ton]] → [[long ton|ton]] (no change) | ||
-- [[ | -- [[tonne|long ton]] → [[tonne|long-ton]] | ||
-- [[ | -- [[metric ton|long ton]] → [[metric ton|long-ton]] | ||
-- [[ | -- [[long ton]] → [[long ton|long-ton]] | ||
-- Input can also have multiple links in a single name like: | -- Input can also have multiple links in a single name like: | ||
-- [[ | -- [[United States customary units|U.S.]] [[US gallon|gallon]] | ||
-- [[ | -- [[mile]]s per [[United States customary units|U.S.]] [[quart]] | ||
-- [[ | -- [[long ton]]s per [[short ton]] | ||
-- Assume that links cannot be nested. | -- Assume that links cannot be nested (never like "[[abc[[def]]ghi]]"). | ||
-- This uses a simple and efficient procedure that works for most cases. | -- This uses a simple and efficient procedure that works for most cases. | ||
-- Some units (if used) would require more, and can later think about | -- Some units (if used) would require more, and can later think about | ||
Line 933: | Line 963: | ||
end | end | ||
if parts.n == 0 then | if parts.n == 0 then | ||
-- No link was found in the original name. | -- No link like "[[...]]" was found in the original name. | ||
parts:add(hyphenated(name, parts)) | parts:add(hyphenated(name, parts)) | ||
end | end | ||
Line 1,116: | Line 1,146: | ||
local fracfmt = { | local fracfmt = { | ||
{ -- Like {{frac}} (fraction slash). | { -- Like {{frac}} (fraction slash). | ||
'<span class="frac">{SIGN}<span class="num">{NUM}</span>⁄<span class="den">{DEN}</span></span>', -- 1/2 | |||
'<span class="frac">{SIGN}{WHOLE}<span class="sr-only">+</span><span class="num">{NUM}</span>⁄<span class="den">{DEN}</span></span>', -- 1+2/3 | |||
'<span class="frac | style = 'frac', | ||
'<span class="frac | |||
}, | }, | ||
{ -- Like {{sfrac}} (fraction horizontal bar). | { -- Like {{sfrac}} (stacked fraction, that is, horizontal bar). | ||
'<span class="sfrac tion">{SIGN}<span class="num">{NUM}</span><span class="sr-only">/</span><span class="den">{DEN}</span></span>', -- 1//2 | |||
'<span class="sfrac">{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 | style = 'sfrac', | ||
'<span class="sfrac | |||
}, | }, | ||
} | } | ||
Line 1,139: | Line 1,167: | ||
wholestr = nil | wholestr = nil | ||
end | end | ||
local substitute = { | |||
SIGN = negative and MINUS or '', | |||
WHOLE = wholestr and with_separator(parms, wholestr), | |||
NUM = from_en(numstr), | |||
DEN = from_en(denstr), | |||
} | |||
wikitext = fracfmt[style][wholestr and 2 or 1]:gsub('{(%u+)}', substitute) | |||
if do_spell then | if do_spell then | ||
if negative then | if negative then | ||
Line 1,158: | Line 1,182: | ||
end | end | ||
end | end | ||
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,527: | Line 1,555: | ||
-- 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,668: | Line 1,696: | ||
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,688: | Line 1,717: | ||
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,766: | Line 1,795: | ||
-- 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,786: | Line 1,807: | ||
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,803: | Line 1,824: | ||
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,819: | Line 1,853: | ||
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,171: | Line 2,205: | ||
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,403: | Line 2,441: | ||
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,610: | Line 2,654: | ||
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 2,850: | Line 2,897: | ||
local function make_link(link, id, unit_table) | local function make_link(link, id, unit_table) | ||
-- Return wikilink, possibly abbreviated as in examples: | -- Return wikilink "[[link|id]]", possibly abbreviated as in examples: | ||
-- [[ | -- [[Mile|mile]] --> [[mile]] | ||
-- [[ | -- [[Mile|miles]] --> [[mile]]s | ||
-- However, just id is returned if: | -- However, just id is returned if: | ||
-- * no link given (so caller does not need to check if a link was defined); or | -- * no link given (so caller does not need to check if a link was defined); or | ||
Line 2,878: | Line 2,925: | ||
end | end | ||
local function variable_name(clean, unit_table) | local function variable_name(clean, unit_table, exp_multiplier, key_id) | ||
-- | -- A unit name may depend on the value in some languages. | ||
-- Parameter clean is the unsigned | -- Parameter clean is the unsigned value in en digits, as a string. | ||
-- | -- It may represent a number ("1.0") or a fraction ("1+2/3"). | ||
-- In varname, fields are separated with "!" and are not empty. | |||
-- | |||
-- A field for a unit using an SI prefix has the prefix name inserted, | -- A field for a unit using an SI prefix has the prefix name inserted, | ||
-- replacing '#' if found, or before the field otherwise. | -- replacing '#' if found, or before the field otherwise. | ||
if clean:match('[./]') then -- float or fraction | |||
if clean | if exp_multiplier then | ||
clean = exp_multiplier -- force selection of name for a large integer | |||
if | |||
else | else | ||
clean = 34.5 -- force selection of name for a float value | |||
end | end | ||
if | else | ||
clean = tonumber(clean) * (exp_multiplier or 1) | |||
end | |||
local name1, vname | |||
if key_id == 'pername' and unit_table.pername then | |||
vname = unit_table.pername | |||
elseif unit_table.varname then | |||
local splitvname = split(unit_table.varname, '!') | |||
name1 = unit_table.name1 | |||
vname = mw.language.getContentLanguage():convertPlural(clean, name1, unpack(splitvname)) | |||
else | |||
return clean == 1 and unit_table.name1 or unit_table.name2 | |||
end | end | ||
if vname then | if vname == name1 then | ||
-- SI prefix (if any) has been inserted by unit_prefixed_mt. | |||
else | |||
local si_name = rawget(unit_table, 'si_name') or '' | local si_name = rawget(unit_table, 'si_name') or '' | ||
local pos = vname:find('#', 1, true) | local pos = vname:find('#', 1, true) | ||
Line 2,919: | Line 2,961: | ||
vname = si_name .. vname | vname = si_name .. vname | ||
end | end | ||
end | end | ||
return | return vname | ||
end | end | ||
local function linked_id(parms, unit_table, key_id, want_link, clean) | local function linked_id(parms, unit_table, key_id, want_link, clean, exp_multiplier) | ||
-- Return final unit id (symbol or name), optionally with a wikilink, | -- Return final unit id (symbol or name), optionally with a wikilink, | ||
-- and update unit_table.sep if required. | -- and update unit_table.sep if required. | ||
-- key_id is one of: 'symbol', 'sym_us', 'name1', 'name1_us', 'name2', 'name2_us'. | -- key_id is one of: 'symbol', 'sym_us', 'name1', 'name1_us', 'name2', 'name2_us', 'pername'. | ||
local abbr_on = (key_id == 'symbol' or key_id == 'sym_us') | local abbr_on = (key_id == 'symbol' or key_id == 'sym_us') | ||
if abbr_on and want_link then | if abbr_on and want_link then | ||
Line 2,962: | Line 3,003: | ||
else | else | ||
key_id2 = key_id | key_id2 = key_id | ||
end | |||
if key_id2 == 'name1' or key_id2 == 'name1_us' then | |||
key_id2 = unit2.pername and 'pername' or key_id2 -- ukwiki has some units with a different name in "per unitname" | |||
end | end | ||
local result | local result | ||
Line 2,974: | Line 3,018: | ||
end | end | ||
if want_link and unit_table.link then | if want_link and unit_table.link then | ||
if abbr_on or | if varname and not abbr_on then | ||
result = (unit1 and variable_name(clean, unit1, exp_multiplier) or '') .. result .. variable_name('1', unit2, exp_multiplier, key_id2) | |||
else | |||
result = (unit1 and linked_id(parms, unit1, key_id, false, clean) or '') .. result .. linked_id(parms, unit2, key_id2, false, '1') | result = (unit1 and linked_id(parms, unit1, key_id, false, clean) or '') .. result .. linked_id(parms, unit2, key_id2, false, '1') | ||
end | end | ||
if omit_separator(result) then | if omit_separator(result) then | ||
Line 3,010: | Line 3,054: | ||
multiplier = '' | multiplier = '' | ||
end | end | ||
local id = unit_table.fixed_name or ((varname and not abbr_on) and variable_name(clean, unit_table) or unit_table[key_id]) | local id = unit_table.fixed_name or ((varname and not abbr_on) and variable_name(clean, unit_table, exp_multiplier, key_id) or unit_table[key_id]) | ||
if omit_separator(id) then | if omit_separator(id) then | ||
unit_table.sep = '' | unit_table.sep = '' | ||
Line 3,071: | Line 3,115: | ||
local inout = unit_table.inout | local inout = unit_table.inout | ||
local info = unit_table.valinfo[which] | local info = unit_table.valinfo[which] | ||
local lk = parms.lk | local lk = parms.lk | ||
local want_link = (lk == 'on' or lk == inout) | local want_link = (lk == 'on' or lk == inout) | ||
local singular = info.singular | local singular = info.singular | ||
local want_name | local want_name | ||
if usename then | local exp_multiplier | ||
if unit_table.usename then | |||
want_name = true | want_name = true | ||
else | else | ||
if abbr_org == nil then | if parms.abbr_org == nil then | ||
if parms.wantname then | if parms.wantname then | ||
want_name = true | want_name = true | ||
Line 3,123: | Line 3,165: | ||
-- engscale: so "|1|e3kg" gives "1 thousand kilograms" (plural) | -- engscale: so "|1|e3kg" gives "1 thousand kilograms" (plural) | ||
singular = false | singular = false | ||
exp_multiplier = 10^unit_table.engscale.exponent -- '1 gram' and '1 thousand grams', for example, may use different names for the unit in some languages | |||
end | end | ||
key = ( | key = (parms.opt_adjectival or singular) and 'name1' or 'name2' | ||
if parms.opt_sp_us then | if parms.opt_sp_us then | ||
key = key .. '_us' | key = key .. '_us' | ||
Line 3,137: | Line 3,180: | ||
key = parms.opt_sp_us and 'sym_us' or 'symbol' | key = parms.opt_sp_us and 'sym_us' or 'symbol' | ||
end | end | ||
return linked_id(parms, unit_table, key, want_link, info.clean), want_name | return linked_id(parms, unit_table, key, want_link, info.clean, exp_multiplier), want_name | ||
end | end | ||
local function decorate_value(parms, unit_table, which, | local function decorate_value(parms, unit_table, which, enable_number_word) | ||
-- If needed, update unit_table so values will be shown with extra information. | -- If needed, update unit_table so values will be shown with extra information. | ||
-- For consistency with the old template (but different from fmtpower), | -- For consistency with the old template (but different from fmtpower), | ||
-- the style to display powers of 10 includes "display:none" to allow some | -- the style to display powers of 10 includes "display:none" to allow some | ||
-- browsers to copy, for example, "10³" as "10^3", rather than as "103". | -- browsers to copy, for example, "10³" as "10^3", rather than as "103". | ||
-- The engscale table may have entries such as either of the following: | |||
-- ["3"] = { "thousand", exponent = 3 }, | |||
-- ["3"] = { name1 = "A", varname = "B!C!D", exponent = 3 }, | |||
-- The first option always uses "thousand" as the exponent name. | |||
-- The second option uses one of A, B, C, D as the exponent name, depending on the value. | |||
local info | local info | ||
local engscale = unit_table.engscale | local engscale = unit_table.engscale | ||
Line 3,155: | Line 3,203: | ||
info.decorated = true | info.decorated = true | ||
if engscale then | if engscale then | ||
-- Range |10|-|20|e3km| gives '10×10³–20×10³' or '10–20 thousand'. | |||
local inout = unit_table.inout | local inout = unit_table.inout | ||
local abbr = parms.abbr | local abbr = parms.abbr | ||
if (abbr == 'on' or abbr == inout) and not parms.number_word then | if (abbr == 'on' or abbr == inout) and not (unit_table.this_number_word or parms.number_word) then | ||
info.show = info.show .. | info.show = info.show .. | ||
'<span style="margin-left:0.2em">×<span style="margin-left:0.1em">' .. | '<span style="margin-left:0.2em">×<span style="margin-left:0.1em">' .. | ||
Line 3,163: | Line 3,212: | ||
'</span></span><s style="display:none">^</s><sup>' .. | '</span></span><s style="display:none">^</s><sup>' .. | ||
from_en(tostring(engscale.exponent)) .. '</sup>' | from_en(tostring(engscale.exponent)) .. '</sup>' | ||
elseif | elseif enable_number_word then | ||
local number_id | local number_id | ||
local | local name = engscale.varname and variable_name(info.clean, engscale) or engscale[1] | ||
if lk == 'on' or lk == inout then | if parms.lk == 'on' or parms.lk == inout then | ||
number_id = make_link(engscale.link, | number_id = make_link(engscale.link, name) | ||
else | else | ||
number_id = | number_id = name | ||
end | end | ||
-- WP:NUMERAL recommends " " in values like "12 million". | -- WP:NUMERAL recommends " " in values like "12 million". | ||
Line 3,233: | Line 3,282: | ||
-- 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,275: | Line 3,324: | ||
if range then | if range then | ||
for i = 0, range.n do | for i = 0, range.n do | ||
local | local enable_number_word | ||
if i == range.n then | if i == range.n then | ||
add_unit = false | add_unit = false | ||
enable_number_word = true | |||
end | end | ||
decorate_value(parms, first_unit, i+1, | decorate_value(parms, first_unit, i+1, enable_number_word) | ||
local show = valinfo[i+1].show | local show = valinfo[i+1].show | ||
if add_unit then | if add_unit then | ||
Line 3,323: | Line 3,372: | ||
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,343: | Line 3,392: | ||
if range then | if range then | ||
for i = 0, range.n do | for i = 0, range.n do | ||
local | local enable_number_word | ||
if i == range.n then | if i == range.n then | ||
add_unit = false | add_unit = false | ||
enable_number_word = true | |||
end | end | ||
decorate_value(parms, out_current, i+1, | decorate_value(parms, out_current, i+1, enable_number_word) | ||
local show = valinfo[i+1].show | local show = valinfo[i+1].show | ||
if add_unit then | if add_unit then | ||
Line 3,529: | Line 3,578: | ||
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,543: | Line 3,592: | ||
local out_unit = parms.out_unit | local out_unit = parms.out_unit | ||
if out_unit == nil or out_unit == '' or type(out_unit) == 'function' then | if out_unit == nil or out_unit == '' or type(out_unit) == 'function' then | ||
-- out_unit can be set to a function by adjustparameters in Module:Convert/wikidata. | |||
if bad_input_mcode or parms.opt_input_unit_only then | if bad_input_mcode or parms.opt_input_unit_only then | ||
bad_output = '' | bad_output = '' | ||
Line 3,659: | Line 3,709: | ||
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 | ||
Line 3,713: | Line 3,763: | ||
-- (a table with two strings) to make an SI unit | -- (a table with two strings) to make an SI unit | ||
-- that will be used for the look up | -- that will be used for the look up | ||
-- link = true if result should be linked | -- link = true if result should be [[linked]] | ||
-- sort = 'on' or 'debug' if result should include a sort key in a | -- sort = 'on' or 'debug' if result should include a sort key in a | ||
-- span element ('debug' makes the key visible) | -- span element ('debug' makes the key visible) | ||
Line 3,722: | Line 3,772: | ||
-- text = requested symbol or name of unit, optionally linked | -- text = requested symbol or name of unit, optionally linked | ||
-- scaled_value = input value adjusted by unit scale; used for sort key | -- scaled_value = input value adjusted by unit scale; used for sort key | ||
-- sortspan = span element with sort key like that provided by ntsh, | -- sortspan = span element with sort key like that provided by {{ntsh}}, | ||
-- calculated from the result of converting value | -- calculated from the result of converting value | ||
-- to a base unit with scale 1. | -- to a base unit with scale 1. |