Anonymous user
Module:Convert: Difference between revisions
update from sandbox per Template talk:Convert#Module version 5
(update from sandbox per Template talk:Convert#Module version 4) |
(update from sandbox per Template talk:Convert#Module version 5) |
||
Line 35:
local extra_module -- name of module with extra units
local extra_units -- nil or table of extra units from extra_module
local ignore_extra_units -- if true, do not require the extra module
local function from_en(text)
Line 289 ⟶ 290:
end
-- Escape user input so it does not break the message.
-- To avoid
--
-- replaced with
local append
local pos = s:find(string.char(127), 1, true)
if pos then
append = '...'
s = s:sub(1, pos - 1)
end
if limit and ulen(s) > limit then
s = usub(s, 1, limit)
end
s = nowiki(s) .. (append or '')
else
s = '?'
Line 778 ⟶ 773:
end
end
if not ignore_extra_units and not get_range(unitcode) then
-- Want the "what links here" list for the extra_module to show only cases
-- where an extra unit is used, so do not require it if invoked from {{val}}
-- or if looking up a range word which cannot be a unit.
if not extra_units then
local success, extra = pcall(function () return require(extra_module).extra_units end)
Line 1,239 ⟶ 1,237:
local function extract_fraction(parms, text, negative)
-- If text represents a fraction, return
-- value, altvalue, show
-- where
-- value is a number (value of the fraction in argument text)
-- altvalue is an alternate interpretation of any fraction for the hands
-- unit where "
-- show is a string (formatted text for display of an input value,
-- and is spelled if wanted and possible)
-- denominator is value of the denominator in the fraction
-- Otherwise, return nil.
-- Input uses en digits and '.' decimal mark (input has been translated).
-- Output uses digits in local language and
------------------------------------------------------------------------
-- Originally this function accepted x+y/z where x, y, z were any valid
-- numbers, possibly with a sign. For example '1.23e+2+1.2/2.4' = 123.5,
-- and '2-3/8' = 1.625. However, such usages were found to be errors or
-- misunderstandings, so since August 2014 the following restrictions apply:
-- x (if present) is an integer or has a single digit after decimal mark
-- y and z are unsigned integers
-- e notation is not accepted
-- The overall
-- and '-12-3/4' are valid).
-- Any leading negative sign is removed by the caller, so only inputs
-- like the following are accepted here (may have whitespace):
--
--
-- text = '1+2/3' '+1+2/3' '1-2/3'
-- text = '12.3+1/2' '+12.3+1/2' '12.3-1/2'
-- Values like '12.3+1/2' are accepted, but are intended only for use
-- with the hands unit (not worth adding code to enforce that).
------------------------------------------------------------------------
local numstr, whole
local leading_plus, prefix, numstr, slashes, denstr =
text:match('^%s*(%+?)%s*(.-)%s*(%d+)%s*(/+)%s*(%d+)%s*$')
if not leading_plus then
-- Accept a single U+2044 fraction slash because that may be pasted.
leading_plus, prefix, numstr, denstr =
text:match('^%s*(%+?)%s*(.-)%s*(%d+)%s*⁄%s*(%d+)%s*$')
slashes = '/'
end
local numerator = tonumber(numstr)
local denominator = tonumber(denstr)
if
return nil
end
if prefix == '' then
wholestr = ''
whole = 0
else
-- Any prefix must be like '12+' or '12-' (whole number and fraction sign);
-- '12.3+' and '12.3-' are also accepted (single digit after decimal point)
-- because '12.3+1/2 hands' is valid (12 hands 3½ inches).
local num1, num2, frac_sign = prefix:match('^(%d+)(%.?%d?)%s*([+-])$')
if num1 == nil then return nil end
if num2 == '' then -- num2 must be '' or like '.1' but not '.' or '.12'
wholestr = num1
else
if #num2 ~= 2 then return nil end
wholestr = num1 .. num2
end
if frac_sign ~= (negative and '-' or '+') then return nil end
whole = tonumber(wholestr)
if whole == nil then return nil end
end
local value = whole + numerator / denominator
if not valid_number(value) then return nil end
local altvalue = whole + numerator / (denominator * 10)
local style = #slashes -- kludge: 1 or 2 slashes can be used to select style
if style > 2 then style = 2 end
local wikitext = format_fraction(parms, 'in', negative, leading_plus .. wholestr, numstr, denstr,
return value, altvalue, wikitext
end
Line 1,314:
-- where info is a table with the result,
-- or return false, t where t is an error message table.
-- Input can use en digits or digits in local language
-- have one reference at the end. Accepting a reference is intended
-- for use in infoboxes with a field for a value passed to convert.
-- Parameter another = true if the expected value is not the first.
-- Before processing, the input text is cleaned:
Line 1,329 ⟶ 1,331:
-- clean = cleaned text with any separators and sign removed
-- (en digits and '.' decimal mark)
-- show = text formatted for output, possibly with ref strip marker
-- (digits in local language and custom decimal mark)
-- The resulting show:
Line 1,338 ⟶ 1,340:
-- '+' (if the input text used '+'), or is '' (if no sign in input).
text = strip(text or '')
local t, reference = text:match('^(.*)(\127UNIQ%x+%-ref%-%x+%-QINU\127)$')
if reference then -- found a single strip marker at end containing "-ref-"
text = strip(t)
end
local clean = to_en(text, parms)
if clean == '' then
Line 1,374 ⟶ 1,380:
end
if value == nil then
if not no_fraction then
value, altvalue, show
end
if value == nil then
Line 1,413 ⟶ 1,418:
singular = singular,
clean = clean,
show = show .. (reference or ''),
denominator = denominator,
}
Line 1,580 ⟶ 1,585:
end
local function get_composite(parms, iparm
-- Look for a composite input unit. For example, "{{convert|1|yd|2|ft|3|in}}"
-- would result in a call to this function with
-- iparm = 3 (parms[iparm] = "2", just after the first unit)
--
-- Return true, iparm, unit where
-- iparm = index just after the composite units (7 in above example)
Line 1,594 ⟶ 1,598:
local composite_units, count = { in_unit_table }, 1
local fixups = {}
local total = in_unit_table.valinfo[1].value
local subunit = in_unit_table
while subunit.subdivs do -- subdivs is nil or a table of allowed subdivisions
Line 1,825 ⟶ 1,830:
-- If the parameter is not a value, try unpacking it as a range ("1-23" for "1 to 23").
-- However, "-1-2/3" is a negative fraction (-1⅔), so it must be extracted first.
-- Do not unpack a parameter if it is like "3-1/2" which is sometimes incorrectly
-- used instead of "3+1/2" (and which should not be interpreted as "3 to ½").
-- Unpacked items are inserted into the parms table.
local valstr = strip(parms[i]) -- trim so any '-' as a negative sign will be at start
local success, result = extract_number(parms, valstr, i > 1)
if not success and valstr and not valstr:match('%-.*/') and i < 20 then -- check i to limit abuse
for _, sep in ipairs(text_code.ranges.words) do
local start, stop = valstr:find(sep, 2, true) -- start at 2 to skip any negative sign for range '-'
Line 1,852 ⟶ 1,859:
end
valinfo:add(info)
local
if not range_item then
break
Line 1,877 ⟶ 1,883:
local function simple_get_values(parms)
-- If input is like "{{convert|valid_value|valid_unit|...}}",
-- return true
-- 3 = index in parms of whatever follows valid_unit, if anything).
-- The valid_value is not negative and does not use a fraction, and
Line 1,900 ⟶ 1,905:
local success, in_unit_table = lookup(in_unit, parms.opt_sp_us, 'no_combination')
if not success then return end
in_unit_table.valinfo = { info }
return true, 3, in_unit, in_unit_table
end
Line 1,926 ⟶ 1,932:
local success, msg = translate_parms(parms, kv_pairs)
if not success then return false, msg end
ignore_extra_units = parms.opt_ignore_error
local success, i, in_unit, in_unit_table = simple_get_values(parms)
if not success then
local valinfo
success, valinfo, i = get_values(parms)
if not success then return false, valinfo end
Line 1,944 ⟶ 1,952:
utype = "length", scale = 1, bad_mcode = in_unit_table }, unit_mt)
end
in_unit_table.valinfo = valinfo
end
if parms.test == 'msg' then
Line 1,956 ⟶ 1,965:
end
end
in_unit_table.inout = 'in' -- this is an input unit
if not parms.range then
local success, inext, composite_unit = get_composite(parms, i
if not success then return false, inext end
if composite_unit then
|