Module:Fmtn
Jump to navigation
Jump to search
This module implements {{Fmtn}}
.
Dependencies[edit source]
[view] [edit] [history] [refresh]The above documentation is transcluded from Module:Fmtn/doc.
local p = {}
-- Known building patterns, with a transformation to become
-- a valid standard.
-- The pattern does not have to be perfect because it is validated as a number
-- after processing. So no problem if he can eventually
-- produce invalid numbers. Just take care that you do not
-- produce incorrect numbers.
-- Note: Many REGEXes are not valid on Lua.
-- See the documentation at:
-- https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns
local known_patterns = {
{ "^[%d,]*%.%d*$", -- format 1,123,123.123
false, -- does not require revision
{
{ ",", "" }, -- remove commas
}
},
{ "^[%d.]*,%d*$", -- format 1.123.123,123 or 1123123,123
false, -- does not require revision
{
{ "%.", "" }, -- remove dots
{ ",", "."}, -- replace comma by dot
}
},
{ "^[%d%s]*[,.]%d*$", -- format 1 123 123,123 or 1 123 123.123
false, -- do not mark for review
{
{ "%s", "" }, -- remove spaces
{ ",", "."}, -- replace comma by dot, if there are
}
},
{ "^[%d,]*,%d%d%d$", -- format 1,123,123
false, -- do not mark for review
{
{ ",", "" }, -- remove commas
}
},
{ "^[%d.]*%.%d%d%d$", -- format 1.123.123 (three digits in the last block)
false, -- do not mark for review
{
{ ",", "" }, -- remove dots
}
},
{ "^[%d,]*,%d%d%d$", -- format 1,123,123 (three digits in the last block)
false, -- do not mark for review
{
{ ",", "" }, -- remove commas
}
},
{ "^[%d%s]*%s%d%d%d$", -- format 1 123 123 (three digits in the last block)
false, -- do not mark for review
{
{ "%s", "" }, -- remove spaces
}
},
{ "^[%d.]*%.%d%d$", -- format 1.123.12 (two digits in the last block)
true, -- mark for review
{
{ ".", "" }, -- remove dots
{ "(%d%d)$", ".%1" }, -- insert a period before the last two digits
}
},
{ "^[%d,]*,%d%d$", -- format 1,123,12 (two digits in the last block)
true, -- mark for review
{
{ ",", "" }, -- remove commas
{ "(%d%d)$", ".%1" }, -- insert a period before the last two digits
}
},
{ "^[%d%s]%s%d%d$", -- format 1 123 12 (two digits in the last block)
true, -- mark for review
{
{ "%s", "" }, -- remove spaces
{ "(%d%d)$", ".%1" }, -- insert a period before the last two digits
}
},
}
function p.fmtn(frame)
local param1 = frame.args[1] or ""
local param2 = frame.args[2] or ""
local param3 = frame.args[3] or ""
num1, isnumber1, needcheck1 = recognize_number(param1)
num2, isnumber2, needcheck2 = recognize_number(param2)
num3, isnumber3, needcheck3 = recognize_number(param3)
isarticle = mw.title.getCurrentTitle().namespace == 0
prefix = ''
suffix = ''
if isnumber1 and not isnumber2 and not isnumber3 then
-- only the first number is valid
mynum = num1
needcheck = needcheck1
if param2 ~= '' then suffix = suffix .. ' ' .. param2 end
if param3 ~= '' then suffix = suffix .. ' ' .. param3 end
elseif not isnumber1 and isnumber2 and not isnumber3 then
-- only the second number is valid
mynum = num2
needcheck = needcheck2
if param1 ~= '' then prefix = prefix .. param1 .. ' ' end
if param3 ~= '' then suffix = suffix .. ' ' .. param3 end
elseif not isnumber1 and not isnumber2 and isnumber3 then
-- only the third number is valid
mynum = num3
needcheck = needcheck3
if param1 ~= '' then prefix = prefix .. param1 .. ' ' end
if param2 ~= '' then prefix = prefix .. param2 .. ' ' end
else
-- ERROR: There are more than two valid numbers, or none are valid
-- In this case, do what was already done before, try to format
-- what is possible and returns the parameters in the order they were
-- presented
-- Here the "callParserFunction" is used to copy the behavior that has already
-- been seen before this module existed and to prevent errors from being
-- printed
res = ''
if param1 ~= '' then
res = res .. formatnum(param1)
end
if param2 ~= '' then
if res ~= '' then res = res .. ' ' end
res = res .. formatnum(param2)
end
if param3 ~= '' then
if res ~= '' then res = res .. ' ' end
res = res .. formatnum(param3)
end
if isarticle then
res = res .. '[[Category:Pages with error using the default Fmtn]]'
end
return res
end
res = prefix .. formatnum(mynum) .. suffix
if needcheck and isarticle then
res = res .. '[[Category:Pages whose use of the default Fmtn should be reviewed]]'
end
return res
end
function formatnum(num)
frame = mw.getCurrentFrame()
return frame:callParserFunction{ name = 'formatnum', args = { num } }
-- Not used because it does not preserve the number of digits after the decimal point
-- lang = mw.language.getContentLanguage()
-- return lang:formatNum(mynum)
end
function recognize_number(num)
if tonumber(num) then
-- it's already a valid number, you do not have to do anything
isnumber = true
needcheck = false
else
isnumber = false
needcheck = true
-- is not a valid number, look at the patterns to see
-- if it can be converted to a valid standard
for _, rule in pairs(known_patterns) do
checkpattern = rule[1]
if string.find(num, checkpattern) then
newneedcheck = rule[2]
substitutions = rule[3]
newstr = num
for _, subs in pairs(substitutions) do
-- apply substitution in string
newstr = string.gsub(newstr, subs[1], subs[2])
end
if tonumber(newstr) then
-- verifies that the transformation produced a valid number
-- If so, close the loop
num = newstr
isnumber = true
needcheck = newneedcheck
break
end
end
end
-- if no pattern hit then it should be invalid
-- code returns the same last number and lets
-- the caller does its job
end
return num, isnumber, needcheck
end
return p