Misplaced Pages

Module:Formatnum/sandbox: Difference between revisions

Article snapshot taken from Wikipedia with creative commons attribution-sharealike license. Give it a read and then ask your questions in the chat. We can research this topic together.
< Module:Formatnum Browse history interactivelyNext edit →Content deleted Content added
Revision as of 16:39, 22 October 2019 editRexxS (talk | contribs)Autopatrolled, Extended confirmed users, Pending changes reviewers, Rollbackers43,075 edits Create sandbox version of Module:Formatnum  Revision as of 16:49, 22 October 2019 edit undoRexxS (talk | contribs)Autopatrolled, Extended confirmed users, Pending changes reviewers, Rollbackers43,075 edits pick up arguments from frame; use tabsNext edit →
Line 3: Line 3:


function p.main(frame) function p.main(frame)
local args = frame:getParent().args local args = frame:getParent().args
local prec = args.prec or '' if not args and not args.number then
args = frame.args
local sep = args.sep or ''
end
local number = args or args.number or ''
local lang = args or args.lang or '' local prec = args.prec or ''
local sep = args.sep or ''
-- validate the language parameter within MediaWiki's caller frame
local number = args or args.number or ''
if lang == "arabic-indic" then -- only for back-compatibility ("arabic-indic" is not a SupportedLanguage)
local lang = args or args.lang or ''
lang = "fa" -- better support than "ks"
-- validate the language parameter within MediaWiki's caller frame
elseif lang == '' or not mw.language.isSupportedLanguage(lang) then
if lang == "arabic-indic" then -- only for back-compatibility ("arabic-indic" is not a SupportedLanguage)
-- Note that 'SupportedLanguages' are not necessarily 'BuiltinValidCodes', and so they are not necessarily
lang = "fa" -- better support than "ks"
-- 'KnownLanguages' (with a language name defined at least in the default localisation of the local wiki).
elseif lang == '' or not mw.language.isSupportedLanguage(lang) then
-- But they all are ValidLanguageCodes (suitable as Wiki subpages or identifiers: no slash, colon, HTML tags, or entities)
-- Note that 'SupportedLanguages' are not necessarily 'BuiltinValidCodes', and so they are not necessarily
-- In addition, they do not contain any capital letter in order to be unique in page titles (restriction inexistant in BCP47),
-- 'KnownLanguages' (with a language name defined at least in the default localisation of the local wiki).
-- but they may violate the standard format of BCP47 language tags for specific needs in MediaWiki.
-- But they all are ValidLanguageCodes (suitable as Wiki subpages or identifiers: no slash, colon, HTML tags, or entities)
-- Empty/unspecified and unsupported languages are treated here in Commons using the user's language,
-- In addition, they do not contain any capital letter in order to be unique in page titles (restriction inexistant in BCP47),
-- instead of the local 'ContentLanguage' of the Wiki.
-- but they may violate the standard format of BCP47 language tags for specific needs in MediaWiki.
lang = frame:callParserFunction( "int", "lang" ) -- get user's chosen language
-- Empty/unspecified and unsupported languages are treated here in Commons using the user's language,
end
-- instead of the local 'ContentLanguage' of the Wiki.
return p.formatNum(number, lang, prec, sep ~= '')
lang = frame:callParserFunction( "int", "lang" ) -- get user's chosen language
end
return p.formatNum(number, lang, prec, sep ~= '')
end end


local digit = { -- substitution of decimal digits for languages not supported by mw.language:formatNum() in core Lua libraries for MediaWiki local digit = { -- substitution of decimal digits for languages not supported by mw.language:formatNum() in core Lua libraries for MediaWiki
= { '൦', '൧', '൨', '൩', '൪', '൫', '൬', '൭', '൮', '൯' }, = { '൦', '൧', '൨', '൩', '൪', '൫', '൬', '൭', '൮', '൯' },
= { '᠐', '᠑', '᠒', '᠓', '᠔', '᠕', '᠖', '᠗', '᠘', '᠙'}, = { '᠐', '᠑', '᠒', '᠓', '᠔', '᠕', '᠖', '᠗', '᠘', '᠙'},
= { '௦', '௧', '௨', '௩', '௪', '௫', '௬', '௭', '௮', '௯'}, = { '௦', '௧', '௨', '௩', '௪', '௫', '௬', '௭', '௮', '௯'},
= { '౦', '౧', '౨', '౩', '౪', '౫', '౬', '౭', '౮', '౯'}, = { '౦', '౧', '౨', '౩', '౪', '౫', '౬', '౭', '౮', '౯'},
= { '๐', '๑', '๒', '๓', '๔', '๕', '๖', '๗', '๘', '๙'} = { '๐', '๑', '๒', '๓', '๔', '๕', '๖', '๗', '๘', '๙'}
} }


function p.formatNum(number, lang, prec, compact) function p.formatNum(number, lang, prec, compact)
-- Do not alter the specified value when it is not a valid number, return it as is
local value = tonumber(number)
if value == nil then
return number
end
-- Basic ASCII-only formatting (without paddings)
number = tostring(value)


-- Check the presence of an exponent (incorrectly managed in mw.language:FormatNum() and even forgotten due to an internal bug, e.g. in Hindi)
-- Do not alter the specified value when it is not a valid number, return it as is
local exponent
local value = tonumber(number)
local pos = string.find(number, '')
if value == nil then
if pos ~= nil then
return number
exponent = string.sub(number, pos + 1, string.len(number))
end
number = string.sub(number, 1, pos - 1)
-- Basic ASCII-only formatting (without paddings)
else
number = tostring(value)
exponent = ''
end


-- Check the minimum precision requested
-- Check the presence of an exponent (incorrectly managed in mw.language:FormatNum() and even forgotten due to an internal bug, e.g. in Hindi)
prec = tonumber(prec) -- nil if not specified as a true number
local exponent
if prec ~= nil then
local pos = string.find(number, '')
prec = math.floor(prec)
if pos ~= nil then
if prec < 0 then
exponent = string.sub(number, pos + 1, string.len(number))
prec = nil -- discard an incorrect precision (not a positive integer)
number = string.sub(number, 1, pos - 1)
elseif prec > 14 then
else
prec = 14 -- maximum precision supported by tostring(number)
exponent = ''
end end
end


-- Check the minimum precision requested -- Preprocess the minimum precision in the ASCII string
local dot
prec = tonumber(prec) -- nil if not specified as a true number
if prec ~= nil then if (prec or 0) > 0 then
pos = string.find(number, '.', 1, true) -- plain search, no regexp
prec = math.floor(prec)
if prec < 0 then if pos ~= nil then
prec = pos + prec - string.len(number) -- effective number of trailing decimals to add or remove
prec = nil -- discard an incorrect precision (not a positive integer)
dot = '' -- already present
elseif prec > 14 then
else
prec = 14 -- maximum precision supported by tostring(number)
end dot = '.' -- must be added
end end
else
dot = '' -- don't add dot
prec = 0 -- don't alter the precision
end
if lang ~= nil and mw.language.isKnownLanguageTag(lang) == true then
-- Convert number to localized digits, decimal separator, and group separators
local language = mw.getLanguage(lang)
if compact then
number = language:formatNum(tonumber(number), { noCommafy = 'y' }) -- caveat: can load localized resources for up to 20 languages
else
number = language:formatNum(tonumber(number)) -- caveat: can load localized resources for up to 20 languages
end
-- Postprocessing the precision
if prec > 0 then
local zero = language:formatNum(0)
number = number .. dot .. mw.ustring.rep(zero, prec)
elseif prec < 0 then
-- TODO: rounding of last decimal; here only truncate decimals in excess
number = mw.ustring.sub(number, 1, mw.ustring.len(number) + prec)
end
-- Append the localized base-10 exponent without grouping separators (there's no reliable way to detect a localized leading symbol 'E')
if exponent ~= '' then
number = number .. 'E' .. language:formatNum(tonumber(exponent),{noCommafy=true})
end
else -- not localized, ASCII only
-- Postprocessing the precision
if prec > 0 then
number = number .. dot .. mw.string.rep('0', prec)
elseif prec < 0 then
-- TODO: rounding of last decimal; here only truncate decimals in excess
number = mw.string.sub(number, 1, mw.string.len(number) + prec)
end
-- Append the base-10 exponent
if exponent ~= '' then
number = number .. 'E' .. exponent
end
end


-- Special cases for substitution of ASCII digits (missing support in Lua core libraries for some languages)
-- Preprocess the minimum precision in the ASCII string
if digit then
local dot
for i, v in ipairs(digit) do
if (prec or 0) > 0 then
number = mw.ustring.gsub(number, tostring(i - 1), v)
pos = string.find(number, '.', 1, true) -- plain search, no regexp
end
if pos ~= nil then
end
prec = pos + prec - string.len(number) -- effective number of trailing decimals to add or remove
dot = '' -- already present
else
dot = '.' -- must be added
end
else
dot = '' -- don't add dot
prec = 0 -- don't alter the precision
end


return number
if lang ~= nil and mw.language.isKnownLanguageTag(lang) == true then
-- Convert number to localized digits, decimal separator, and group separators
local language = mw.getLanguage(lang)
if compact then
number = language:formatNum(tonumber(number), { noCommafy = 'y' }) -- caveat: can load localized resources for up to 20 languages
else
number = language:formatNum(tonumber(number)) -- caveat: can load localized resources for up to 20 languages
end
-- Postprocessing the precision
if prec > 0 then
local zero = language:formatNum(0)
number = number .. dot .. mw.ustring.rep(zero, prec)
elseif prec < 0 then
-- TODO: rounding of last decimal; here only truncate decimals in excess
number = mw.ustring.sub(number, 1, mw.ustring.len(number) + prec)
end

-- Append the localized base-10 exponent without grouping separators (there's no reliable way to detect a localized leading symbol 'E')
if exponent ~= '' then
number = number .. 'E' .. language:formatNum(tonumber(exponent),{noCommafy=true})
end
else -- not localized, ASCII only
-- Postprocessing the precision
if prec > 0 then
number = number .. dot .. mw.string.rep('0', prec)
elseif prec < 0 then
-- TODO: rounding of last decimal; here only truncate decimals in excess
number = mw.string.sub(number, 1, mw.string.len(number) + prec)
end

-- Append the base-10 exponent
if exponent ~= '' then
number = number .. 'E' .. exponent
end
end

-- Special cases for substitution of ASCII digits (missing support in Lua core libraries for some languages)
if digit then
for i, v in ipairs(digit) do
number = mw.ustring.gsub(number, tostring(i - 1), v)
end
end

return number
end end



Revision as of 16:49, 22 October 2019

This is the module sandbox page for Module:Formatnum (diff).
See also the companion subpage for test cases (run).
Module documentation[view] [edit] [history] [purge]

This module provides a number formatting function. This function can be used from #invoke or from other Lua modules.

This module is used by Module:Complex date

Use from other Lua modules

To use the module from normal wiki pages, no special preparation is needed. If you are using the module from another Lua module, first you need to load it, like this:

local mf = require('Module:Formatnum')

(The mf variable stands for Module Formatnum; you can choose something more descriptive if you prefer.)

Most functions in the module have a version for Lua and a version for #invoke. It is possible to use the #invoke functions from other Lua modules, but using the Lua functions has the advantage that you do not need to access a Lua frame object. Lua functions are preceded by _, whereas #invoke functions are not.

main

{{#invoke:Formatnum|main|x|lang=|prec=|sep=}}
mf.formatNum(x, lang, prec, sep)

See also

Math templates
  • Functions
  • Numeral systems
Functions
Numeral systems
Conversions
convert many units (see: list)
cvt abbreviated {{convert}}
convinfobox {{convert}} for infoboxes
bbl to t barrels of oil to tonnes
long ton long hundredweights, quarters and pounds to kilograms;
long tons and hundredweights to pounds and metric tons
miles-chains miles and chains to kilometres linking "chains"
decdeg degrees, minutes, and seconds to decimal degrees
deg2dms decimal degrees to degrees, minutes, and seconds
deg2hms decimal degrees to hour angle (in hours, minutes, and seconds)
hms2deg hour angle (in hours, minutes, and seconds) to decimal degrees
inflation calculate inflation of Consumer Price Index-related prices
pop density population density in an area
track gauge railway track gauges
Notation and formatting
bigmath bigger font to match TeX \displaystyle (standalone formulas only)
bra–ket notation
ceil, floor calculations :mw:Help:#expr; formatting indicators ⌈3.14⌉, ⌊3.14⌋ (no calculation performed)
fraction slant fractions 3⁄5 (not for maths/science articles; use standing or upright fractions {{sfrac}} instead)
intmath integral symbols
  • langle
  • rangle
  • angbr
  • angular brackets
  • ldelim
  • rdelim
  • multiline delimiters (2–5 lines inclusive)
    abs absolute values (paired vertical lines)
    math short text-based formulas
    mathcal calligraphic font; alternative to LaTeX \mathcal{...}
    mvar individual italicized maths variables in normal text
  • overline
  • underline
  • a line set above/below a sequence of characters
    overarc an arc set above a sequence of characters
  • overset
  • underset
  • arbitrary characters/diacritics set above/below one another
    pars parentheses that can be resized (∑)
    sfrac "standing" or upright fractions ⁠3/5⁠ (use in maths/science articles instead of{{fraction}})
  • sub
  • sup
  • su
  • subscripts and superscripts
    tmath Wrap TeX in <math> tags
    tombstone symbol indicating the end of a proof
    val measurement values, uncertainties and units
    vec various overarrows, underarrows, etc.
  • Boxes
  • Tags
  • Notices
  • BoxesTags
    The above documentation is transcluded from Module:Formatnum/doc. (edit | history)
    Editors can experiment in this module's sandbox (edit | diff) and testcases (edit | run) pages.
    Add categories to the /doc subpage. Subpages of this module.
    -- This module is intended to replace the functionality of Template:Formatnum and related templates. 
    local p = {}
    
    function p.main(frame)
    	local args = frame:getParent().args
    	if not args and not args.number then
    		args = frame.args
    	end
    	local prec    = args.prec or ''
    	local sep     = args.sep or ''
    	local number  = args or args.number or ''
    	local lang    = args or args.lang or ''
    	-- validate the language parameter within MediaWiki's caller frame
    	if lang == "arabic-indic" then -- only for back-compatibility ("arabic-indic" is not a SupportedLanguage)
    		lang = "fa" -- better support than "ks"
    	elseif lang == '' or not mw.language.isSupportedLanguage(lang) then
    		-- Note that 'SupportedLanguages' are not necessarily 'BuiltinValidCodes', and so they are not necessarily
    		-- 'KnownLanguages' (with a language name defined at least in the default localisation of the local wiki).
    		-- But they all are ValidLanguageCodes (suitable as Wiki subpages or identifiers: no slash, colon, HTML tags, or entities)
    		-- In addition, they do not contain any capital letter in order to be unique in page titles (restriction inexistant in BCP47),
    		-- but they may violate the standard format of BCP47 language tags for specific needs in MediaWiki.
    		-- Empty/unspecified and unsupported languages are treated here in Commons using the user's language,
    		-- instead of the local 'ContentLanguage' of the Wiki.
    		lang = frame:callParserFunction( "int", "lang" ) -- get user's chosen language
    	end
    	return p.formatNum(number, lang, prec, sep ~= '')
    end
    
    local digit = { -- substitution of decimal digits for languages not supported by mw.language:formatNum() in core Lua libraries for MediaWiki
    	 = { '൦', '൧', '൨', '൩', '൪', '൫', '൬', '൭', '൮', '൯' },
    	     = { '᠐', '᠑', '᠒', '᠓', '᠔', '᠕', '᠖', '᠗', '᠘', '᠙'},
    	     = { '௦', '௧', '௨', '௩', '௪', '௫', '௬', '௭', '௮', '௯'},
    	     = { '౦', '౧', '౨', '౩', '౪', '౫', '౬', '౭', '౮', '౯'},
    	     = { '๐', '๑', '๒', '๓', '๔', '๕', '๖', '๗', '๘', '๙'}
    }
    
    function p.formatNum(number, lang, prec, compact)
    	-- Do not alter the specified value when it is not a valid number, return it as is
    	local value = tonumber(number)
    	if value == nil then
    		return number
    	end
    	-- Basic ASCII-only formatting (without paddings)
    	number = tostring(value)
    
    	-- Check the presence of an exponent (incorrectly managed in mw.language:FormatNum() and even forgotten due to an internal bug, e.g. in Hindi)
    	local exponent
    	local pos = string.find(number, '')
    	if pos ~= nil then
    		exponent = string.sub(number, pos + 1, string.len(number))
    		number = string.sub(number, 1, pos - 1)
    	else
    		exponent = ''
    	end
    
    	-- Check the minimum precision requested
    	prec = tonumber(prec) -- nil if not specified as a true number
    	if prec ~= nil then
    		prec = math.floor(prec)
    		if prec < 0 then
    			prec = nil -- discard an incorrect precision (not a positive integer)
    		elseif prec > 14 then
    			prec = 14 -- maximum precision supported by tostring(number)
    		end
    	end
    
    	-- Preprocess the minimum precision in the ASCII string
    	local dot
    	if (prec or 0) > 0 then
    		pos = string.find(number, '.', 1, true) -- plain search, no regexp
    		if pos ~= nil then
    			prec = pos + prec - string.len(number) -- effective number of trailing decimals to add or remove
    			dot = '' -- already present
    		else
    			dot = '.' -- must be added
    		end
    	else
    		dot = '' -- don't add dot
    		prec = 0 -- don't alter the precision
    	end
    	
    	if lang ~= nil and mw.language.isKnownLanguageTag(lang) == true then
    	    -- Convert number to localized digits, decimal separator, and group separators
    	    local language = mw.getLanguage(lang)
    	    if compact then
    			number = language:formatNum(tonumber(number), { noCommafy = 'y' }) -- caveat: can load localized resources for up to 20 languages
    	    else
    			number = language:formatNum(tonumber(number)) -- caveat: can load localized resources for up to 20 languages
    	    end
    	    -- Postprocessing the precision
    	    if prec > 0 then
    			local zero = language:formatNum(0)
    			number = number .. dot .. mw.ustring.rep(zero, prec)
    	    elseif prec < 0 then
    			-- TODO: rounding of last decimal; here only truncate decimals in excess
    			number = mw.ustring.sub(number, 1, mw.ustring.len(number) + prec)
    	    end
    	    -- Append the localized base-10 exponent without grouping separators (there's no reliable way to detect a localized leading symbol 'E')
    	    if exponent ~= '' then
    			number = number .. 'E' .. language:formatNum(tonumber(exponent),{noCommafy=true})
    	    end
    	else -- not localized, ASCII only
    		-- Postprocessing the precision
    		if prec > 0 then
    			number = number .. dot .. mw.string.rep('0', prec)
    		elseif prec < 0 then
    			-- TODO: rounding of last decimal; here only truncate decimals in excess
    			number = mw.string.sub(number, 1, mw.string.len(number) + prec)
    		end
    		-- Append the base-10 exponent
    		if exponent ~= '' then
    			number = number .. 'E' .. exponent
    		end
    	end
    
    	-- Special cases for substitution of ASCII digits (missing support in Lua core libraries for some languages)
    	if digit then
    	for i, v in ipairs(digit) do
    		number = mw.ustring.gsub(number, tostring(i - 1), v)
    	end
    	end
    
    	return number
    end
    
    return p
    
    Category: