local cat = wanted_category(text_code.all_categories[msg[3]]) or ''
local anchor = msg[4] or ''
local fmt = text_code.all_messages[msg.format or 'cvt_format'] or 'convert: bug'
title = title:gsub('"', '"')
return format(fmt, anchor, title, text, cat)
-- If enabled, add a warning that will be displayed after the convert result.
-- To reduce output noise, only the first warning is displayed.
if config.warnings or level < 0 then
if level <= (tonumber(config.warnings) or 1) then
if parms.warnings == nil then
if engscale then
local success, result = lookup(baseunit, opt_sp_us, 'no_combination', utable, fails, depth)
if not success then return false, result end if and not (result.offset or result.builtin or result.engscale) then
result.defkey = unitcode -- key to lookup default exception
result.engscale = engscale
return true
end
end
local function ntsh(num, debug)
-- Return html text to be used for a hidden sort key so that
-- the given number will be sorted in numeric order.
-- If debug == true, output is in a box (not hidden).
-- This implements Template:Ntsh (number table sorting, hidden).
num = num or 0
local result, style
if not valid_number(num) then
if num < 0 then
result = '1000000000000000000'
else
result = '9000000000000000000'
end
elseif num == 0 then
result = '5000000000000000000'
else
local mag = floor(log10(abs(num)) + 1e-14)
local prefix
if num > 0 then
prefix = 7000 + mag
else
prefix = 2999 - mag
num = num + 10^(mag+1)
end
result = format('%d', prefix) .. format('%015.0f', floor(num * 10^(14-mag)))
end
if debug then
style = 'border:1px solid'
else
style = 'display:none'
end
return '<span style="' .. style .. '">' .. result .. '</span>'
end
return name:sub(1, pos+1) .. name:sub(pos+2):gsub(' ', '-')
end
elseif name:sub(-1, -1) == ')' then
pos = name:find('(', 1, true)
if pos then
-- that allows input like 2e6 to be spelled as "two million" which works
-- because the spell module converts '2e6' to '2000000' before spelling.
local function rounded(value, default) local precision = parms.input_precisionopt_ri if precision and 0 <= precision and precision <= 8 then
local fmt = '%.' .. format('%d', precision) .. 'f'
return fmt:format(tonumber(value ) + 2e-14) -- fudge for some common cases of bad rounding
end
return default
end
singular = (value == 1)
local significand, exponent = clean:match('^([%d.]+)[Ee]([+%-]?%d+)')
if significand then
show = with_exponent(rounded(tonumber(significand, significand)) or significand, exponent)
scientific = true
else
show = with_separator(parms, rounded(value) or , clean))
end
show = propersign .. show
if parms.opt_spell_in then
show = spell_number(parms, 'in', propersign .. rounded(clean, clean)) or show
scientific = false
end
end
end
elseif en_name == 'stylein' or en_name == 'styleout' then
en_value = loc_value -- accept user text with no validation
else
en_value = text_code.en_option_value[en_name][loc_value]
if en_value and en_value:sub(-1) == '?' then
en_value = en_value:sub(1, -2)
add_warning(parms, -1, 'cvt_deprecated', loc_name .. '=' .. loc_value)
end
if en_value == nil then
if loc_value == '' then
add_warning(parms, 2, 'cvt_empty_option', loc_name)
else
-- loc_value can no longer be nil here add_warning(at one timeparms, that could occur -- with aliases like |sing=off|adj=on)1, 'cvt_unknown_option', but am retaining safety check. local text = loc_value and (loc_name .. '=' .. loc_value) or loc_name add_warning(parms, 1, 'cvt_unknown_option', text)
end
elseif en_value == '' then
elseif type(en_value) == 'string' and en_value:sub(1, 4) == 'opt_' then
for _, v in ipairs(split(en_value, ',')) do
local lhs, rhs = v:match('^(.-)=(.+)$') if rhs then parms[lhs] = tonumber(rhs) or rhs else parms[v] = true end
end
en_value = nil
else
add_warning(parms, 1, 'cvt_unknown_option', loc_name .. '=' .. loc_value)
end
end
if parms.adj then
if parms.adj:sub(1, 2) == 'ri' then
-- It is known that adj is 'riN' where N is a single digit, so precision is valid.
-- Only a single en digit is accepted.
parms.input_precision = tonumber(parms.adj:sub(-1))
parms.adj = nil
end
end
else
parms.abbr = 'out' -- default is to abbreviate output only (use symbol, not name)
end
if parms.opt_spell_out and not abbr_entered then
parms.abbr = 'off' -- should show unit name when spelling the output value
end
if parms.opt_flip then
parms.opt_values = true
end
local align parms.table_align = format('style="text-align: %s;"', parms.opt_table and 'right' or 'center') end if parms.table_align or parms.opt_sortable_on then parms.table_joins need_table_or_sort = { align .. '|', '\n|' .. align .. '|' }true
end
local disp_joins = text_code.disp_joins
-- Testing shows this function is successful for 96% of converts in articles,
-- and that on average it speeds up converts by 8%.
if parms.input_precision opt_ri or parms.opt_spell_in then return end
local clean = to_en(strip(parms[1] or ''), parms)
if #clean > 10 or not clean:match('^[0-9.]+$') then return end
end
return false, { 'cvt_bug_convert' } -- should never occur
end
local function user_style(parms, i)
-- Return text for a user-specified style for a table cell, or '' if none,
-- given i = 1 (input style) or 2 (output style).
local style = parms[(i == 1) and 'stylein' or 'styleout']
if style then
style = style:gsub('"', '')
if style ~= '' then
if style:sub(-1) ~= ';' then
style = style .. ';'
end
return style
end
end
return ''
end
local function make_table_or_sort(parms, invalue, info, in_current)
-- Set options to handle output for a table or a sort key, or both.
-- The text sort key is based on the value resulting from converting
-- the input to a fake base unit with scale = 1, and other properties
-- required for a conversion derived from the input unit.
local sortkey
if parms.opt_sortable_on then
local base = { -- a fake unit with enough fields for a valid convert
scale = 1,
invert = in_current.invert and 1,
iscomplex = in_current.iscomplex,
offset = in_current.offset and 0,
}
local outvalue, extra = convert(parms, invalue, info, in_current, base)
if extra then
outvalue = extra.outvalue
end
if not valid_number(outvalue) then
if outvalue < 0 then
sortkey = '1000000000000000000'
else
sortkey = '9000000000000000000'
end
elseif outvalue == 0 then
sortkey = '5000000000000000000'
else
local mag = floor(log10(abs(outvalue)) + 1e-14)
local prefix
if outvalue > 0 then
prefix = 7000 + mag
else
prefix = 2999 - mag
outvalue = outvalue + 10^(mag+1)
end
sortkey = format('%d', prefix) .. format('%015.0f', floor(outvalue * 10^(14-mag)))
end
end
if sortkey and (parms.opt_sortable_debug or not parms.table_align) then
parms.join_before = parms.opt_sortable_debug and
'<span style="border:1px solid">' .. sortkey .. '</span>' or
'<span style="display:none">' .. sortkey .. '</span>'
end
if parms.table_align then
local style = 'style="text-align:' .. parms.table_align .. ';'
local sort = sortkey and ' data-sort-value="' .. sortkey .. '"' or ''
local joins = {}
for i = 1, 2 do
joins[i] = (i == 1 and '' or '\n|') .. style .. user_style(parms, i) .. '"' .. sort .. '|'
end
parms.table_joins = joins
end
end
end
local outvalue, extra = convert(parms, invalue, info, in_current, out_current)
if parms.need_table_or_sort then
parms.need_table_or_sort = nil -- process using first input value only
make_table_or_sort(parms, invalue, info, in_current)
end
if extra then
if not outvalue then return false, extra end
precision = parms.precision
if not precision then
local sigfig = if parms.sigfig if sigfig then show, exponent = make_sigfig(outvalue, parms.sigfig) elseif parms.opt_round5 or parms.opt_round25 opt_round then local n = parms.opt_round5 and 5 or 25opt_round
show = format('%.0f', floor((outvalue / n) + 0.5) * n)
else
local i = t.multiple and table_len(combo) or 1
ucode = combo[i]
end
else
-- Try for an automatically generated combination.
local item = ucode:match('^(.-)%+') or ucode:match('^(%S+)%s')
if all_units[item] then
return item
end
end
local out_unit = parms.out_unit
if out_unit == nil or out_unit == '' then
if bad_input_mcode or parms.opt_input_unit_only then
bad_output = ''
else
end
local flipped = parms.opt_flip and not bad_input_mcode
local sortkey
if parms.opt_sortable_in then
sortkey = ntsh(invalue1, parms.opt_sortable_debug)
end
local parts = {}
for part = 1, 2 do
parts[part] = process_input(parms, in_unit_table)
elseif bad_output then
if bad_output ~= '' then parts[part] = (bad_output == '') and '' or message(bad_output) end
else
local outputs = {}
if not success then return false, item end
table.insert(outputs, item)
end
if parms.opt_sortable_out then
local value
local info = out_first and out_first.valinfo
if info then
info = info[1]
value = info.raw_absvalue
if value and info.sign == MINUS then
value = -value
end
end
sortkey = ntsh(value, parms.opt_sortable_debug)
end
if parms.opt_input_unit_only then
parts[part] = ''
else
local sep if = parms.table_joins then sep = and parms.table_joins[2] .. (sortkey or '') else sep = parms.join_between end
parts[part] = table.concat(outputs, sep)
end
end
end
if sortkey parms.join_before then for i, v in ipairs(parts) do if i [1] == 1 or parms.table_joins then join_before .. parts[i1] = sortkey .. v end end
end
local wikitext