सामग्री पर जाएँ

"मॉड्यूल:Val": अवतरणों में अंतर

मुक्त ज्ञानकोश विकिपीडिया से
Content deleted Content added
rearrange to remove unnecessary globals; minor tweak
move code from Module:Val/units and use mw.loadData to access it
पंक्ति 64: पंक्ति 64:
local misc_tbl = {e=args.e, pre=args.p, suf=args.s, fmt=args.fmt or '', nocat=args.nocategory}
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)
return p._main(number,uncertainty,u_tbl,misc_tbl)
end

local function get_builtin_unit(unitcode, definitions)
-- Return table of information for the specified built-in unit, or nil if not known.
-- Each defined unit code must be followed by two spaces (not tab characters).
local _, pos = definitions:find('\n' .. unitcode .. ' ', 1, true)
if pos then
local endline = definitions:find('\n', pos, true)
if endline then
local result = {}
local n = 0
local text = definitions:sub(pos, endline - 1)
for item in (text .. ' '):gmatch('(%S[^\n]-)%s%s') do
if item == 'NOSPACE' then
result.nospace = true
else
n = n + 1
if n == 1 then
result.symbol = item
elseif n == 2 then
result.link = item
else
break
end
end
end
if n == 2 then
return result
end
-- Ignore invalid definition, treating it as a comment.
end
end
end

local function get_unit(ucode, value, want_link, want_longscale)
local data = mw.loadData('Module:Val/units')
local result = want_longscale and
get_builtin_unit(ucode, data.builtin_units_long_scale) or
get_builtin_unit(ucode, data.builtin_units)
local lookup = require('Module:Convert/sandbox')._unit
local convert_unit = lookup(ucode, { value = value, link = want_link })
if result then
-- Have: result.symbol + result.link + result.nospace
if want_link then
result.text = '[[' .. result.link .. '|' .. result.symbol .. ']]'
else
result.text = result.symbol
end
result.sortkey = convert_unit.sortkey
else
result = {
text = convert_unit.text,
sortkey = convert_unit.sortkey,
}
end
return result
end

local function makeunit(ucode, options)
-- Return wikitext, sortkey for the requested unit and options.
-- LATER The sortkey does not account for any per unit.
local function bracketed(ucode, text)
return ucode:find('[*./]') and '(' .. text .. ')' or text
end
options = options or {}
local unit = get_unit(ucode, options.value, options.link, options.longscale)
local text = unit.text
local percode = options.per
if percode then
local perunit = get_unit(percode, 0, options.per_link, options.longscale)
text = bracketed(ucode, text) .. '/' .. bracketed(percode, perunit.text)
end
if not unit.nospace then
text = ' ' .. text
end
return text, unit.sortkey
end
end


पंक्ति 141: पंक्ति 217:
local unit_text
local unit_text
if u_tbl.u then
if u_tbl.u then
local makeunit = require('Module:Val/units')
unit_text = makeunit(u_tbl.u,{
unit_text = makeunit(u_tbl.u,{
link=u_tbl.ul,
link=u_tbl.ul,

04:10, 8 जुलाई 2015 का अवतरण

"इस मॉड्यूल हेतु प्रलेख मॉड्यूल:Val/doc पर बनाया जा सकता है"

local p = {}

local getArgs
local delimit_groups = require('Module:Gapnum').groups

-- Specific message for {{Val}} errors
local 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
local 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

function p.main(frame)
	if not getArgs then
		getArgs = require('Module:Arguments').getArgs
	end
	local args = getArgs(frame, {wrappers = { 'Template:Val', 'Template:Val/sandboxlua' }})
	local number = {n=args[1], nend=args['end']}
	local nocat = args.nocategory

	-- Error checking
	if args[1] and 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

local function get_builtin_unit(unitcode, definitions)
	-- Return table of information for the specified built-in unit, or nil if not known.
	-- Each defined unit code must be followed by two spaces (not tab characters).
	local _, pos = definitions:find('\n' .. unitcode .. '  ', 1, true)
	if pos then
		local endline = definitions:find('\n', pos, true)
		if endline then
			local result = {}
			local n = 0
			local text = definitions:sub(pos, endline - 1)
			for item in (text .. '  '):gmatch('(%S[^\n]-)%s%s') do
				if item == 'NOSPACE' then
					result.nospace = true
				else
					n = n + 1
					if n == 1 then
						result.symbol = item
					elseif n == 2 then
						result.link = item
					else
						break
					end
				end
			end
			if n == 2 then
				return result
			end
			-- Ignore invalid definition, treating it as a comment.
		end
	end
end

local function get_unit(ucode, value, want_link, want_longscale)
	local data = mw.loadData('Module:Val/units')
	local result = want_longscale and
		get_builtin_unit(ucode, data.builtin_units_long_scale) or
		get_builtin_unit(ucode, data.builtin_units)
	local lookup = require('Module:Convert/sandbox')._unit
	local convert_unit = lookup(ucode, { value = value, link = want_link })
	if result then
		-- Have: result.symbol + result.link + result.nospace
		if want_link then
			result.text = '[[' .. result.link .. '|' .. result.symbol .. ']]'
		else
			result.text = result.symbol
		end
		result.sortkey = convert_unit.sortkey
	else
		result = {
			text = convert_unit.text,
			sortkey = convert_unit.sortkey,
		}
	end
	return result
end

local function makeunit(ucode, options)
	-- Return wikitext, sortkey for the requested unit and options.
	-- LATER The sortkey does not account for any per unit.
	local function bracketed(ucode, text)
		return ucode:find('[*./]') and '(' .. text .. ')' or text
	end
	options = options or {}
	local unit = get_unit(ucode, options.value, options.link, options.longscale)
	local text = unit.text
	local percode = options.per
	if percode then
		local perunit = get_unit(percode, 0, options.per_link, options.longscale)
		text = bracketed(ucode, text) .. '/' .. bracketed(percode, perunit.text)
	end
	if not unit.nospace then
		text = '&nbsp;' .. text
	end
	return text, unit.sortkey
end

-- TODO: Add other format options
local function delimit(n,fmt)
	local prefix,num
	if not fmt then fmt = '' end
	fmt = fmt:lower()
	-- look for + or - preceding the number
	if n:find('[-+]') then
		prefix,num = mw.ustring.match(n,'([-+])([%d.]+)')
	else
		num = n
	end

	-- integer and decimal parts of number
	-- if there is no decimal part, delimit_groups only returns 1 table
	local ipart, dpart = delimit_groups(num)
	-- comma formatting
	if fmt == 'commas' then
		num = table.concat(ipart,',')
		if dpart then
			dpart = table.concat(dpart)
			num = num..'.'..dpart
		end
	-- No special formatting
	elseif fmt == 'none' then
		-- default to delimiting with .25em spaces
		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

	-- add prefix back if it had one
	if prefix then
		-- change hyphen to proper minus sign
		if prefix == '-' then
			prefix = '&minus;'
		end
		num = prefix..num
	end

	return tostring(num)
end

function p._main(number,uncertainty,u_tbl,misc_tbl)
	-- format number
	local fmt = misc_tbl.fmt
	local n
	if number.n then
		n = delimit(number.n,fmt)
	end

	local e_10 = misc_tbl.e

	-- number suffix
	if n and number.nend then
		n = n..number.nend
	end

	-- If units are defined, load the unit submodule to create a string
	local unit_text
	if u_tbl.u then
		unit_text = makeunit(u_tbl.u,{
						link=u_tbl.ul,
						per=u_tbl.p,
						per_link=u_tbl.pl,
						value=number.n,
						longscale=nil,  -- TODO set from 'long scale' parameter
					})
	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 unit_text then
				uncU = uncU..unit_text
				uncL = uncL..unit_text
			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)..'</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 error suffix
			if uncertainty.errend then
				unc = unc..uncertainty.errend
			end
			-- Add units if no exponent argument
			if not e_10 and unit_text then
				unc = unc..unit_text
			end
		end
	end
	-- Add units if no exponent argument and no parentheses for uncertainty
	if not e_10 and unit_text and not paren_uncertainty then
		n = (n or '')..unit_text
	end
	-- If exponent defined, create 10<sup>e</sup>
	-- Add units if they're defined
	if e_10 then
		e_10 = '10<sup>'..delimit(misc_tbl.e)..'</sup>'
		if n then
			e_10 = '<span style="margin-left:0.25em;margin-right:0.15em">×</span>'..e_10
		end
		if unit_text then
			e_10 = e_10..unit_text
		end
	else
		e_10 = ''
	end
	-- Table to concat in order of what goes where
	local ret =
	table.concat({
				'<span class="nowrap">',
				-- prefix
				misc_tbl.pre or '',
				-- opening parenthesis if needed
				paren_wrap and '(' or '',
				-- number
				n or '',
				-- uncertainties
				unc or '',
				-- closes parenthesis if needed
				paren_wrap and ')' or '',
				-- 10^e if needed
				e_10,
				-- suffix
				misc_tbl.suf or '',
				'</span>'
			})
	return ret
end

return p