Module:LoadLib

function toCamelCase(s) return s		:gsub(' (.)(.*)', 			function(a, b) 				return table.concat{ 					a:upper, 					b,				} 			end		) :gsub('[^%a]+', '') :gsub('^(.)(.*)', 			function(a, b) 				return table.concat{ 					a:lower, 					b,				} 			end		) end local _ = require('Module:LibraryUtil'), require('Module:MultiRequire'); local autoloads = require('Module:LoadLib/Autoloads') local yesno = require('Module:Yesno') local titleObj = mw.title.getCurrentTitle local pagename = titleObj.fullText

return function(...) local globalTable, lib, options = checkArgs({ 'table', { 'table', nilOk=true }, { 'table', nilOk=true } }, ...) local lib = lib or {} local options = options or {} local setVars, doAutoloads, substVars = unpack{ yesno(options.setVars or options.set or options[1], false), yesno(options.doAutoLoads or options.doLoads or options.auto or options[2], true), options.substVars or options.subst or options[3], }

local implicitLoads = { ['String']=1, ['Table']=1, ['Constructor']=1, ['Arguments']=1, ['Yesno']=1, ['Color']=1, ['LibraryUtil']=1, ['Currency']=1, ['Item']=1, ['Statname']=1, ['Link']=1, ['List']=1, ['Module:String']=1, ['Module:Table']=1, ['Module:Constructor']=1, ['Module:Arguments']=1, ['Module:Yesno']=1, ['Module:Color']=1, ['Module:LibraryUtil']=1, ['Module:Currency']=1, ['Module:Item']=1, ['Module:Statname']=1, ['Module:Link']=1, ['Module:List']=1, }	local skip = {} if yesno(options.doAutoloads, true) then for key, value in pairs(lib) do			local mName = type(value) == "string" and value or value[1] or value.m or value.module if implicitLoads[mName] then skip[mName]=true end end for key, value in pairs(autoloads) do			local mName = type(value) == "string" and value or value[1] or value.m or value.module or '' if not skip[mName] then if type(key) == 'number' then table.insert(lib, value) else lib[key] = value end end end end --Iterate over supplied module names/variables/fields to get for key, value in pairs(lib) do		local tpKey = type(key) local varToSet, fieldToGet, setVarsTmp, tmp --If key is a table, set some values if type(value) == "table" then varToSet, fieldToGet, setVarsTmp, tmp = unpack{ value.varToSet or value.value or value.values or value[3], value.fieldToGet or value.field or value[2], value.loadVars or value.setVars or value[4], value.module or value.m or value[1], }		end --Set module name local value = tmp and tmp or value local oldVal = value -- require enhancements if value:match('^%/') then value = titleObj.fullText..value elseif value:match('^%.%/') then value = titleObj.baseText..value:gsub('%.', '') end if value:match('%$%{.-%}') then local tpSubstVars = type(substVars) if value:match('%${parent}') or value:match('^%${base}$') then value = value:gsub('%${parent}', titleObj.baseText):gsub('%${base}', titleObj.baseText) end if value:match('%${root}') then value = value:gsub('%${root}', titleObj.rootText) end if value:match('%${fullpage}') then value = value:gsub('%${fullpage}', titleObj.fullText) end if value:match('%${page}') then value = value:gsub('%${page}', titleObj.text) end if value:match('%${subpage}') then value = value:gsub('%${subpage}', titleObj.subpageText) end if tpSubstVars == "table" then for k, v in pairs(substVars) do					substVars[k:lower] = v				end for var in value:gmatch('%${var:(.-)}') do					v = substVars[tostring(var):lower] if not v then error('Unknown variable "'..var..'" in require path "'..value..'"', 2) end value = value:gsub('%${var:'..var..'}', v)				end end if tpSubstVars ~= "table" and value:match('%${var:(.-)}') then error('Require path variables must have subsituion table to draw from (missing option `substVars`)', 2) end end local mName = 'Module:'..value:gsub('Module:', '') --Load actual module local success, res = pcall(globalTable.require, mName) assertTrue(success, not res and formatError(res, mName)..' (in path "'..oldVal..'")', 2, mName) local lib = res --Key the module was saved in		local savedKey = tpKey == "number" and toCamelCase(mName:gsub('Module:', '')) or key local function err(msg, ...) error(string.format('Invalid loader settings for module %q for index %q: '..msg, mName, key, ...), 3) end local tpFieldToGet = type(fieldToGet) local tpVarToSet = type(varToSet) --Check types on variable to be set if tpFieldToGet ~= "string" and tpFieldToGet ~= "nil" then err('function name to load must be a string or nil') end

--If the function supplied a singular field to get, set the global table index as the field if (varToSet or fieldToGet) and tpVarToSet ~= "table" and tpKey == "number" then globalTable[varToSet or fieldToGet] = lib[fieldToGet] or lib[varToSet] --Extra case if the user did not specify a field to get elseif tpKey ~= "number" and fieldToGet then globalTable[key] = lib[fieldToGet] end --Extra case if user set the values to get as a table if tpVarToSet == "table" and not fieldToGet then for k, v in pairs(varToSet) do				local tpK = type(k) --Check types on variables to be set if tpK ~= "number" and tpK ~= "string" then error(						string.format( 'Invalid table index type in loader settings for module %q for index %q: index must be a string', mName, key ),						2					)				--Also check types on the value to search for elseif type(v) ~= "string" then error(						string.format( 'Invalid table index value type in loader settings for module %q for index %q: index must be a string', mName, key ),						2					)				-- If the function is not found, error elseif not lib[v] then error(						string.format('Invalid loader configuration settings for module %q at index %q: specified function %q not found on %q', mName, key, v, mName ),						2					)				end

if tpK == "number" then globalTable[v] = lib[v] else globalTable[k] = lib[v] end end end --Else, set the loaded variable name as the module if tpKey ~= "number" and not fieldToGet then globalTable[savedKey] = lib end --If the option `setVars` is true, set global variables as required module methods if not fieldToGet and (setVarsTmp or setVars) and type(lib) == "table" then for k, v in pairs(lib) do				globalTable[k] = v 			end end end

return globalTable end