Module:Val: Difference between revisions
From Zoophilia Wiki
Jump to navigationJump to search
meta>The Mol Man No edit summary |
meta>The Mol Man No edit summary |
||
| Line 3: | Line 3: | ||
local getArgs | local getArgs | ||
local delimit_groups = require('Module:Gapnum').groups | local delimit_groups = require('Module:Gapnum').groups | ||
function p.main(frame) | function p.main(frame) | ||
| Line 16: | Line 14: | ||
-- Error checking | -- Error checking | ||
if not validnumber(args[1]) then | if not validnumber(args[1]) then | ||
return valerror(' | return valerror('first argument is not a valid number.',nocat) | ||
end | end | ||
if args[2] and not validnumber(args[2]) then | if args[2] and not validnumber(args[2]) then | ||
return valerror(' | return valerror('second argument is not a valid number.',nocat) | ||
end | end | ||
if args[3] and not validnumber(args[3]) then | if args[3] and not validnumber(args[3]) then | ||
return valerror(' | return valerror('third argument is not a valid number.',nocat) | ||
end | end | ||
-- Negative third param | -- Negative third param | ||
if args[3] and (not mw.ustring.find(args[3],'[−%-]') or mw.ustring.find(args[3],'^%D0$')) then | if args[3] and (not mw.ustring.find(args[3],'[−%-]') or mw.ustring.find(args[3],'^%D0$')) then | ||
return valerror(' | return valerror('third argument is not negative.',nocat) | ||
end | end | ||
if args.e and not validnumber(args.e) then | if args.e and not validnumber(args.e) then | ||
return valerror(' | return valerror('exponent argument (<b>e</b>) is not a valid number.',nocat) | ||
end | end | ||
if args.u and args.ul then | if args.u and args.ul then | ||
return valerror(' | return valerror('unit (<b>u</b>) and units with link (<b>ul</b>) are both specified, only one is allowed.',nocat) | ||
end | end | ||
if args.up and args.upl then | if args.up and args.upl then | ||
return valerror(' | return valerror('unit per (<b>up</b>) and units per with link (<b>upl</b>) are both specified, only one is allowed.',nocat) | ||
end | end | ||
-- Group arguments into related categories and unpack when needed | |||
local uncertainty = {upper=args[2], lower=args[3], | local uncertainty = {upper=args[2], lower=args[3], | ||
errend=args.errend, | errend=args.errend, | ||
| Line 52: | Line 51: | ||
local e_10 = misc_tbl.e | local e_10 = misc_tbl.e | ||
if number.nend then | if number.nend then | ||
n:wikitext(number.nend) | n:wikitext(number.nend) | ||
end | end | ||
-- If units are defined, load the unit submodule to create a string | |||
if u_tbl.u then | if u_tbl.u then | ||
local makeunit = require('Module:Val/units') | |||
units = makeunit(u_tbl.u, | units = makeunit(u_tbl.u, | ||
{link=u_tbl.ul, | {link=u_tbl.ul, | ||
| Line 66: | Line 62: | ||
per_link=u_tbl.pl}) | per_link=u_tbl.pl}) | ||
end | end | ||
-- Uncertainty | |||
local unc | |||
-- Upper and lower | |||
local uncU, uncL = uncertainty.upper, uncertainty.lower | |||
-- Whether or not the entire number needs to be wrapped in parentheses | |||
-- true if: | |||
---- the expontent parameter (e) is defined | |||
---- AND | |||
---- no lower uncertainty is defined | |||
---- AND | |||
---- upper uncertainty is defined and contains no parentheses | |||
local paren_wrap = misc_tbl.e and (not uncL and (uncU and not uncU:find('%('))) | |||
-- boolean to be defined and used later | |||
local paren_uncertainty | local paren_uncertainty | ||
-- Upper is always used, so look for it first | |||
if uncU then | if uncU then | ||
-- Look for lower uncertainty | |||
if uncL then | if uncL then | ||
-- Load the sup/sub module | |||
local mSu = require('Module:Su')._main | |||
-- Format upper and lower | |||
uncU = delimit(uncU,fmt) | uncU = delimit(uncU,fmt) | ||
uncL = delimit(uncL,fmt) | uncL = delimit(uncL,fmt) | ||
-- If no exponent is defined, and there are units, add them | |||
if not e_10 and units then | if not e_10 and units then | ||
uncU = uncU..units | uncU = uncU..units | ||
uncL = uncL..units | uncL = uncL..units | ||
end | end | ||
-- Add the uncertainty suffixes here | |||
uncU = uncU..(uncertainty.upperend or '') | uncU = uncU..(uncertainty.upperend or '') | ||
uncL = uncL..(uncertainty.lowerend or '') | uncL = uncL..(uncertainty.lowerend or '') | ||
unc = '<span style="margin-left:0.3em;">'..mSu(uncU,uncL)..'</span>' | unc = '<span style="margin-left:0.3em;">'..mSu(uncU,uncL)..'</span>' | ||
else | else | ||
-- Look for parentheses surrounding upper uncertainty | |||
local uncU_n = mw.ustring.match(uncU,('%((.+)%)')) or uncU | local uncU_n = mw.ustring.match(uncU,('%((.+)%)')) or uncU | ||
-- If no parens, use ± | |||
if uncU == uncU_n then | if uncU == uncU_n then | ||
unc = '<span style="margin-left:0.3em;margin-right:0.15em">±</span>'..delimit(uncU_n,fmt) | unc = '<span style="margin-left:0.3em;margin-right:0.15em">±</span>'..delimit(uncU_n,fmt) | ||
unc = unc..'</span>' | unc = unc..'</span>' | ||
-- Otherwise tidy the number and put it back in parentheses | |||
-- Indicate parentheses were used (for later) | |||
else | else | ||
unc = '('..delimit(uncU_n,fmt)..')' | unc = '('..delimit(uncU_n,fmt)..')' | ||
paren_uncertainty = true | paren_uncertainty = true | ||
end | end | ||
-- Add units if no exponent argument | |||
if not e_10 and units then | if not e_10 and units then | ||
unc = unc..units | unc = unc..units | ||
| Line 92: | Line 116: | ||
end | end | ||
end | end | ||
-- Add units if no exponent argument and no parentheses for uncertainty | |||
if not e_10 and units and not paren_uncertainty then | if not e_10 and units and not paren_uncertainty then | ||
n = n..units | n = n..units | ||
end | end | ||
-- If exponent defined, create 10<sup>e</sup> | |||
-- Add units if they're defined | |||
if e_10 then | if e_10 then | ||
e_10 = '<span style="margin-left:0.25em;margin-right:0.15em">×</span>10<sup>'..delimit(misc_tbl.e)..'</sup>' | e_10 = '<span style="margin-left:0.25em;margin-right:0.15em">×</span>10<sup>'..delimit(misc_tbl.e)..'</sup>' | ||
| Line 105: | Line 130: | ||
e_10 = '' | e_10 = '' | ||
end | end | ||
local ret = { | -- Table to concat in order of what goes where | ||
local ret = | |||
table.concat({ | |||
-- prefix | |||
misc_tbl.pre or '', | misc_tbl.pre or '', | ||
-- opening parenthesis if needed | |||
paren_wrap and '(' or '', | paren_wrap and '(' or '', | ||
-- number | |||
n, | n, | ||
-- uncertainties | |||
unc or '', | unc or '', | ||
-- closes parenthesis if needed | |||
paren_wrap and ')' or '', | paren_wrap and ')' or '', | ||
-- 10^e if needed | |||
e_10, | e_10, | ||
-- suffix | |||
misc_tbl.suf or '' | misc_tbl.suf or '' | ||
} | }) | ||
return ret | return ret | ||
end | end | ||
| Line 158: | Line 190: | ||
end | end | ||
-- Specific message for {{Val}} errors | |||
function valerror(msg,nocat) | function valerror(msg,nocat) | ||
local ret = mw.html.create('strong') | local ret = mw.html.create('strong') | ||
:addClass('error') | :addClass('error') | ||
:wikitext(msg) | :wikitext('Error in {{Val}}: '..msg) | ||
-- Not in talk, user, user_talk, or wikipedia_talk | -- Not in talk, user, user_talk, or wikipedia_talk | ||
if not nocat and not mw.title.getCurrentTitle():inNamespaces(1,2,3,5) then | if not nocat and not mw.title.getCurrentTitle():inNamespaces(1,2,3,5) then | ||
| Line 169: | Line 202: | ||
end | end | ||
-- true/false whether or not the string is a valid number | |||
-- ignores parentheses and parity symbolts | |||
function validnumber(n) | function validnumber(n) | ||
-- Look for a number that may be surrounded by parentheses or may have +/- | -- Look for a number that may be surrounded by parentheses or may have +/- | ||
Revision as of 20:52, 9 January 2015
Documentation for this module may be created at Module:Val/doc
local p = {}
local getArgs
local delimit_groups = require('Module:Gapnum').groups
function p.main(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
local args = getArgs(frame, {wrappers = 'Template:Val'})
local number = {n=args[1], nend=args['end']}
local nocat = args.nocategory
-- Error checking
if not validnumber(args[1]) then
return valerror('first argument is not a valid number.',nocat)
end
if args[2] and not validnumber(args[2]) then
return valerror('second argument is not a valid number.',nocat)
end
if args[3] and not validnumber(args[3]) then
return valerror('third argument is not a valid number.',nocat)
end
-- Negative third param
if args[3] and (not mw.ustring.find(args[3],'[−%-]') or mw.ustring.find(args[3],'^%D0$')) then
return valerror('third argument is not negative.',nocat)
end
if args.e and not validnumber(args.e) then
return valerror('exponent argument (<b>e</b>) is not a valid number.',nocat)
end
if args.u and args.ul then
return valerror('unit (<b>u</b>) and units with link (<b>ul</b>) are both specified, only one is allowed.',nocat)
end
if args.up and args.upl then
return valerror('unit per (<b>up</b>) and units per with link (<b>upl</b>) are both specified, only one is allowed.',nocat)
end
-- Group arguments into related categories and unpack when needed
local uncertainty = {upper=args[2], lower=args[3],
errend=args.errend,
upperend=args['+errend'], lowerend=args['-errend']}
local u_tbl = {u=args.ul or args.u, ul=args.ul ~= nil,
p=args.upl or args.up, pl=args.upl ~= nil}
local misc_tbl = {e=args.e, pre=args.p, suf=args.s, fmt=args.fmt or '', nocat=args.nocategory}
return p._main(number,uncertainty,u_tbl,misc_tbl)
end
function p._main(number,uncertainty,u_tbl,misc_tbl)
local fmt = misc_tbl.fmt
local n = delimit(number.n,fmt)
local e_10 = misc_tbl.e
if number.nend then
n:wikitext(number.nend)
end
-- If units are defined, load the unit submodule to create a string
if u_tbl.u then
local makeunit = require('Module:Val/units')
units = makeunit(u_tbl.u,
{link=u_tbl.ul,
per=u_tbl.p,
per_link=u_tbl.pl})
end
-- Uncertainty
local unc
-- Upper and lower
local uncU, uncL = uncertainty.upper, uncertainty.lower
-- Whether or not the entire number needs to be wrapped in parentheses
-- true if:
---- the expontent parameter (e) is defined
---- AND
---- no lower uncertainty is defined
---- AND
---- upper uncertainty is defined and contains no parentheses
local paren_wrap = misc_tbl.e and (not uncL and (uncU and not uncU:find('%(')))
-- boolean to be defined and used later
local paren_uncertainty
-- Upper is always used, so look for it first
if uncU then
-- Look for lower uncertainty
if uncL then
-- Load the sup/sub module
local mSu = require('Module:Su')._main
-- Format upper and lower
uncU = delimit(uncU,fmt)
uncL = delimit(uncL,fmt)
-- If no exponent is defined, and there are units, add them
if not e_10 and units then
uncU = uncU..units
uncL = uncL..units
end
-- Add the uncertainty suffixes here
uncU = uncU..(uncertainty.upperend or '')
uncL = uncL..(uncertainty.lowerend or '')
unc = '<span style="margin-left:0.3em;">'..mSu(uncU,uncL)..'</span>'
else
-- Look for parentheses surrounding upper uncertainty
local uncU_n = mw.ustring.match(uncU,('%((.+)%)')) or uncU
-- If no parens, use ±
if uncU == uncU_n then
unc = '<span style="margin-left:0.3em;margin-right:0.15em">±</span>'..delimit(uncU_n,fmt)
unc = unc..'</span>'
-- Otherwise tidy the number and put it back in parentheses
-- Indicate parentheses were used (for later)
else
unc = '('..delimit(uncU_n,fmt)..')'
paren_uncertainty = true
end
-- Add units if no exponent argument
if not e_10 and units then
unc = unc..units
end
end
end
-- Add units if no exponent argument and no parentheses for uncertainty
if not e_10 and units and not paren_uncertainty then
n = n..units
end
-- If exponent defined, create 10<sup>e</sup>
-- Add units if they're defined
if e_10 then
e_10 = '<span style="margin-left:0.25em;margin-right:0.15em">×</span>10<sup>'..delimit(misc_tbl.e)..'</sup>'
if units then
e_10 = e_10..units
end
else
e_10 = ''
end
-- Table to concat in order of what goes where
local ret =
table.concat({
-- prefix
misc_tbl.pre or '',
-- opening parenthesis if needed
paren_wrap and '(' or '',
-- number
n,
-- uncertainties
unc or '',
-- closes parenthesis if needed
paren_wrap and ')' or '',
-- 10^e if needed
e_10,
-- suffix
misc_tbl.suf or ''
})
return ret
end
-- TODO: Add other format options
function delimit(n,fmt)
local prefix,num
if not fmt then fmt = '' end
if n:find('[%-%+]') then
prefix,num = mw.ustring.match(n,'([-+])([%d.]+)')
else
num = n
end
local ipart, dpart = delimit_groups(num)
if fmt:lower() == 'commas' then
num = table.concat(ipart,',')
if dpart then
dpart = table.concat(dpart)
num = num..'.'..dpart
end
else
num = {}
num[1] = table.remove(ipart,1)
for _, v in ipairs(ipart) do
table.insert(num,'<span style="margin-left:.25em">'..v..'</span>')
end
if dpart then
table.insert(num,'.'..table.remove(dpart,1))
for _, v in ipairs(dpart) do
table.insert(num,'<span style="margin-left:.25em">'..v..'</span>')
end
end
num = table.concat(num)
end
if prefix then
if prefix == '-' then
prefix = '−'
end
num = prefix..num
end
return num
end
-- Specific message for {{Val}} errors
function valerror(msg,nocat)
local ret = mw.html.create('strong')
:addClass('error')
:wikitext('Error in {{Val}}: '..msg)
-- Not in talk, user, user_talk, or wikipedia_talk
if not nocat and not mw.title.getCurrentTitle():inNamespaces(1,2,3,5) then
ret:wikitext('[[Category:Pages with incorrect formatting templates use]]')
end
return tostring(ret)
end
-- true/false whether or not the string is a valid number
-- ignores parentheses and parity symbolts
function validnumber(n)
-- Look for a number that may be surrounded by parentheses or may have +/-
n = mw.ustring.match(tostring(n),'^%(?[±%-%+]?([%d\.]+)%)?$')
return tonumber(n) ~= nil
end
return p