end  
local function make_id(parms, which, unit_table)
-- Return id, f where
-- id = unit name or symbol, possibly modified
-- f = true if id is a name, or false if id is a symbol
-- using the value for index 'which', and for 'in' or 'out' (unit_table.inout).
-- Result is '' if no symbol/name is to be used.
-- In addition, set unit_table.sep = ' ' or '&nbsp;' or ''
-- (the separator that caller will normally insert before the id).
if parms.opt_values then
unit_table.sep = ''
return ''
end
local inout = unit_table.inout
local info = unit_table.valinfo[which]
local abbr_org = parms.abbr_org
local adjectival = parms.opt_adjectival
local lk = parms.lk
local want_link = (lk == 'on' or lk == inout)
local usename = unit_table.usename
local singular = info.singular
local want_name
if usename then
want_name = true
else
if abbr_org == nil then
if parms.wantname then
want_name = true
end
if unit_table.usesymbol then
want_name = false
end
end
if want_name == nil then
local abbr = parms.abbr
if abbr == 'on' or abbr == inout or (abbr == 'mos' and inout == 'out') then
want_name = false
else
want_name = true
end
end
end
local key
if want_name then
if lk == nil and unit_table.builtin == 'hand' then
want_link = true
end
if parms.opt_use_nbsp then
unit_table.sep = '&nbsp;'
else
unit_table.sep = ' '
end
if parms.opt_singular then
local value
if inout == 'in' then
value = info.value
else
value = info.absvalue
end
if value then -- some unusual units do not always set value field
value = abs(value)
singular = (0 < value and value < 1.0001)
end
end
if unit_table.engscale then
-- engscale: so "|1|e3kg" gives "1 thousand kilograms" (plural)
singular = false
end
key = (adjectival or singular) and 'name1' or 'name2'
if parms.opt_sp_us then
key = key .. '_us'
end
else
if unit_table.builtin == 'hand' then
if parms.opt_hand_hh then
unit_table.symbol = 'hh' -- LATER: might want i18n applied to this
end
end
unit_table.sep = '&nbsp;'
key = parms.opt_sp_us and 'sym_us' or 'symbol'
end
return linked_id(parms, unit_table, key, want_link, info.clean), want_name
end  
local function decorate_value(parms, unit_table, which, number_word)
-- If needed, update unit_table so values will be shown with extra information.
-- For consistency with the old template (but different from fmtpower),
-- the style to display powers of 10 includes "display:" to allow some
-- browsers to copy, for example, "10³" as "10^3", rather than as "103".
local info
local engscale = unit_table.engscale
local prefix = unit_table.vprefix
if engscale or prefix then
info = unit_table.valinfo[which]
if info.decorated then
return -- do not redecorate if repeating convert
end
info.decorated = true
if engscale then
local inout = unit_table.inout
local abbr = parms.abbr
if (abbr == 'on' or abbr == inout) and not parms.number_word then
info.show = info.show ..
'<span>×<span>' ..
from_en('10') ..
'</span></span>
^
<sup>' ..
from_en(tostring(engscale.exponent)) .. '</sup>'
elseif number_word then
local number_id
local lk = parms.lk
if lk == 'on' or lk == inout then
number_id = make_link(engscale.link, engscale[1])
else
number_id = engscale[1]
end
-- WP:NUMERAL recommends "&nbsp;" in values like "12 million".
info.show = info.show .. (parms.opt_adjectival and '-' or '&nbsp;') .. number_id
end
end
if prefix then
info.show = prefix .. info.show
end
end
end  
local function process_input(parms, in_current)
-- Processing required once per conversion.
-- Return block of text to represent input (value/unit).
if parms.opt_output_only or parms.opt_output_number_only or parms.opt_output_unit_only then
parms.joins = { *, * }
return ''
end
local first_unit
local composite = in_current.composite -- nil or table of units
if composite then
first_unit = composite[1]
else
first_unit = in_current
end
local id1, want_name = make_id(parms, 1, first_unit)
local sep = first_unit.sep -- separator between value and unit, set by make_id
local preunit = parms.preunit1
if preunit then
sep = '' -- any separator is included in preunit
else
preunit = ''
end
if parms.opt_input_unit_only then
parms.joins = { *, * }
if composite then
local parts = { id1 }
for i, unit in ipairs(composite) do
if i > 1 then
table.insert(parts, (make_id(parms, 1, unit)))
end
end
id1 = table.concat(parts, ' ')
end
if want_name and parms.opt_adjectival then
return preunit .. hyphenated(id1)
end
return preunit .. id1
end
if parms.opt_also_symbol and not composite and not parms.opt_flip then
local join1 = parms.joins[1]
if join1 == ' (' or join1 == ' [' then
parms.joins = { ' [' .. first_unit[parms.opt_sp_us and 'sym_us' or 'symbol'] .. ']' .. join1 , parms.joins[2] }
end
end
if in_current.builtin == 'mach' and first_unit.sep ~= * then -- * means omitsep with non-enwiki name
local prefix = id1 .. '&nbsp;'
local range = parms.range
local valinfo = first_unit.valinfo
local result = prefix .. valinfo[1].show
if range then
-- For simplicity and because more not needed, handle one range item only.
local prefix2 = make_id(parms, 2, first_unit) .. '&nbsp;'
result = range_text(range[1], want_name, parms, result, prefix2 .. valinfo[2].show, 'in')
end
return preunit .. result
end
if composite then
-- Simplify: assume there is no range, and no decoration.
local mid = (not parms.opt_flip) and parms.mid or ''
local sep1 = '&nbsp;'
local sep2 = ' '
if parms.opt_adjectival and want_name then
sep1 = '-'
sep2 = '-'
end
if omitsep and sep == '' then
-- Testing the id of the most significant unit should be sufficient.
sep1 = ''
sep2 = ''
end
local parts = { first_unit.valinfo[1].show .. sep1 .. id1 }
for i, unit in ipairs(composite) do
if i > 1 then
table.insert(parts, unit.valinfo[1].show .. sep1 .. (make_id(parms, 1, unit)))
end
end
return table.concat(parts, sep2) .. mid
end
local add_unit = (parms.abbr == 'mos') or
parms[parms.opt_flip and 'out_range_x' or 'in_range_x'] or
(not want_name and parms.abbr_range_x)
local range = parms.range
if range and not add_unit then
unlink(first_unit)
end
local id = range and make_id(parms, range.n + 1, first_unit) or id1
local extra, was_hyphenated = hyphenated_maybe(parms, want_name, sep, id, 'in')
if was_hyphenated then
add_unit = false
end
local result
local valinfo = first_unit.valinfo
if range then
for i = 0, range.n do
local number_word
if i == range.n then
add_unit = false
number_word = true
end
decorate_value(parms, first_unit, i+1, number_word)
local show = valinfo[i+1].show
if add_unit then
show = show .. first_unit.sep .. (i == 0 and id1 or make_id(parms, i+1, first_unit))
end
if i == 0 then
result = show
else
result = range_text(range[i], want_name, parms, result, show, 'in')
end
end
else
decorate_value(parms, first_unit, 1, true)
result = valinfo[1].show
end
return result .. preunit .. extra
end  
local function process_one_output(parms, out_current)
-- Processing required for each output unit.
-- Return block of text to represent output (value/unit).
local inout = out_current.inout -- normally 'out' but can be 'in' for order=out
local id1, want_name = make_id(parms, 1, out_current)
local sep = out_current.sep -- set by make_id
local preunit = parms.preunit2
if preunit then
sep = '' -- any separator is included in preunit
else
preunit = ''
end
if parms.opt_output_unit_only then
if want_name and parms.opt_adjectival then
return preunit .. hyphenated(id1)
end
return preunit .. id1
end
if out_current.builtin == 'mach' and out_current.sep ~= * then -- * means omitsep with non-enwiki name
local prefix = id1 .. '&nbsp;'
local range = parms.range
local valinfo = out_current.valinfo
local result = prefix .. valinfo[1].show
if range then
-- 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)
end
return preunit .. result
end
local add_unit = (parms[parms.opt_flip and 'in_range_x' or 'out_range_x'] or
(not want_name and parms.abbr_range_x)) and
not parms.opt_output_number_only
local range = parms.range
if range and not add_unit then