The wiki has moved!

Visit the new wiki at stationeers-wiki.com The old wiki here at legacy.stationeers-wiki.com will sunset eventually.

Edits made after the 7th of March 6PM EST were NOT carried over to the new server as previously announced right here in this box.

 Actions

Module

Arguments

From Unofficial Stationeers Wiki

Revision as of 11:01, 7 December 2013 by Mr. Stradivarius (talk) (create argument-processing module)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Documentation for this module may be created at Module:Arguments/doc

-- This module provides easy processing of arguments passed to Scribunto from #invoke.

local function getArguments(frame, options)
	options = type(options) == 'table' and options or {}

	local fargs, pargs
	if frame == mw.getCurrentFrame() then
		fargs = frame.args
		pargs = frame:getParent().args
	else
		fargs = type(frame) == 'table' and frame or {}
		pargs = {}
	end

	local args, metaArgs, metatable = {}, {}, {}
	setmetatable(args, metatable)

	local function tidyVal(key, val)
		-- Processes a value according to the options given to getArguments. Can trim whitespace and remove blanks.
		-- Keys are not used here, but they can be used by user-generated functions, so defining it here to avoid breakage.
		if type(val) == 'string' then
			if options.trim ~= false then
				val = mw.text.trim(val)
			end
			if options.removeBlanks == false or mw.ustring.find(val, '%S') then
				return val
			end
		else
			return val
		end
	end

	local valueFunc = options.valueFunc
	if valueFunc then
		local valueFuncType = type(valueFunc)
		if valueFuncType == 'function' then
			tidyVal = valueFunc
		else
			error('type error in option "valueFunc": expected function, got ' .. valueFuncType, 2)
		end
	end

	local function mergeArgs(iterator, ...)
		-- Accepts multiple tables as input and merges their keys and values into one table using the specified iterator.
		-- If a value is already present it is not overwritten; tables listed earlier have precendence.
		local tables = {...}
		for _, t in ipairs(tables) do
			for key, val in iterator(t) do
				if metaArgs[key] == nil then
					metaArgs[key] = tidyVal(key, val)
				end
			end
		end
	end

	local firstArgs, secondArgs = fargs, pargs
	if options.parentFirst then
		firstArgs, secondArgs = pargs, fargs
	end

	metatable.__index = function (t, key)
		local val = metaArgs[key]
		if val ~= nil then
			return val
		else
			local firstVal = tidyVal(key, firstArgs[key])
			if firstVal ~= nil then
				return firstVal
			else
				return tidyVal(key, secondArgs[key])
			end
		end
	end

	metatable.__newindex = function (t, key, val)
		if not options.readOnly and (not options.noOverwrite or metaArgs[key] == nil) then
			metaArgs[key] = val
		end
	end

	metatable.__pairs = function ()
		if not metatable.donePairs then
			mergeArgs(pairs, firstArgs, secondArgs)
			metatable.donePairs = true
			metatable.doneIpairs = true
		end
		return pairs(metaArgs)
	end

	metatable.__ipairs = function ()
		if not metatable.doneIpairs then
			mergeArgs(ipairs, firstArgs, secondArgs)
			metatable.doneIpairs = true
		end
		return ipairs(metaArgs)
	end
	
	return args
end

return getArguments