require('strict')  local p = {} local templateArgs = {} local info = {}  local paramData = require( 'Module:Biota infobox/data' ) -- contains the taxon ranks in order  -- call parameter checking independently of taxobox display function p.main(frame) 	p._getArgs(frame) 	return info.parameterCategory  end -- get parameters for calling function function p.getArgs(frame, args, localinfo) 	templateArgs = args 	info = localinfo 	 p._getArgs(frame) end -- get the arguments and check them in vaious ways function p._getArgs(frame) 	local parents = mw.getCurrentFrame():getParent()     local tempArgs={} -- local copy of arguments that will be checked (empty, aliases, invalid)          -- get copy of parent arguments, aliasing spaces for underscores 	for k,v in pairs(parents.args) do 		if type (k) == 'string' then            -- no positional parameters  			--v = v:match('^%s*(.-)%s*$')       -- include trimming (only needed for positional parameters) 			if v and (v ~= "") then             -- check for content 				local j = k:gsub( " ", "_")     -- substitute spaces with underscore (aliases) 				tempArgs[j]=v                   -- parents.args[k] 			end 		end 	end 	 	-- do we need to check frame args? 	for k,v in pairs(frame.args) do 		if v and v ~= "" then                  --check for content 			tempArgs[k]=v  		end 	end  	-- parameters that can be set without a value, e.g. |extinct=  	if parents.args['extinct'] and parents.args['extinct'] == "" then templateArgs['extinct'] = "" end  	if parents.args['auto'] or frame.args['auto'] then  		info.auto = parents.args['auto']  or frame.args['auto']   -- keep template parameters seperate from control flow arguments 	end 	if parents.args['db'] or frame.args['db'] then  		info.db = parents.args['db']  or frame.args['db']   -- keep template parameters seperate from control flow arguments 	end	     p.preprocessArgs(tempArgs) -- check aliases, check valid parameters for calling template end  function p.preprocessArgs(tempArgs) -- handles aliases ajc validates parameters 	info.parameterCategory = ""     -- initialise empty string for tracking categories 	p.aliasParams(tempArgs)         -- check parameters for aliases     p.validateParams(tempArgs)      -- check parameters for invalid parameters (from allowed list) 	p._checkParameters(tempArgs)    -- check manual taxon ranks, orphaned parameters and invalid combinations end --[[ -------------------------------------------------------------------      function p.aliasParams(tempArgs)          -- alias of spaces to underscores handled in getArgs()          -- uses alias list from the data subpage (param.aliasmap)          -- e.g. local aliasMap = {  ['fossil_range'] = 'temporal_range',   		                             ['colour_as'] = 'color_as', ... } ]] function p.aliasParams(tempArgs)      -- change parameters using alias map     for k,v in pairs(paramData.aliasMap) do 		if tempArgs[k] then                 -- if templateArgs has parameter with alias name 			tempArgs[v] = tempArgs[k];	    -- create new element with alias' value as key 			tempArgs[k] = nil;			    -- delete the alias 		end     	end      --[[ alias: change parameters using spaces instead of underscores 	local localArgs = {} -- Note: adding new keys while iterating over a table gives unpredictable results     for k,v in pairs(templateArgs) do        if type(k)=='string' then 			local j,n = string.gsub(k, " ", "_")               -- substitute spaces 			if n > 0 then --if j ~= k then      -- if substitution made 				localArgs[j] = v	            -- create new key with underscore 			    localArgs[k] = nil;			    -- delete old key with space  	        else  	        	localArgs[k] = v         	end 		end 	end	     templateArgs = localArgs -- now copy the corrected table 	--templateArgs['debug'] = mw.dumpObject (templateArgs)     --]]  end --[[ ------------------------------------------------------------------------------------------- 	function p.validateParams(tempArgs) 	    - uses list of valid parametere accepted by template (from data subpage) 	        params.validList = { 						automatictaxobox = params.validAutomatictaxobox, 						speciesbox       = params.validSpeciesbox, 						subspeciesbox    = params.validSubspeciesbox, 					    infraspeciesbox  = params.validInfraspeciesbox,	} 	    - invalid parameters are retaining in tempArgs ]] function p.validateParams(tempArgs)  	local validParamsList = paramData.validList[info.auto] 	     if type(validParamsList) == 'table' then      -- if checklist for valid parameters 	    for k,v in pairs(validParamsList) do 	       if tempArgs[v] then                    -- v contains the name of valid parameter key 	       	   templateArgs[v] = tempArgs[v] 	       	   tempArgs[v] = nil                  -- delete so only invalid arguments left in tempArgs 	       end                                    -- TODO use these for tracking categories (partially done) 	    end 	     	    tempArgs['auto'] = nil                    -- this if not on tracking list but used internally 	    if #tempArgs  then                        -- table  not empty -- if next(tempArgs) ~= nil then 		    templateArgs['debug'] =  mw.dumpObject(tempArgs)  		    info.parameterCategory = info.parameterCategory .. "Category:Automatic taxobox with unsupported parameters" 		end	     else -- checklist for valid parameters not available for this option 	    for k,v in pairs(tempArgs) do 	    	templateArgs[k] = v         end 	end 	 	     --DISABLE the parameter checking is currently being call from the template (this is temporary)     -- this function checks for bad combinations (e.g. genus without species)     --info.parameterCategory = p._checkParameters(frame) end   CATEGORY FUNCTIONS -------------------------------- -- function for external invoke function p.checkParameters(frame)     p.getArgs(frame) -- populates templateArgs[] with parameters, after alias checking and validation of supported parameters                      -- then calls p._checkParameters for addition parameter checking           return info.parameterCategory -- return tracking categories end -- function that checks for extraneous parameters function p._checkParameters(tempArgs)          local categoryString = ""          -- (1) check for speciesbox with taxon and (genus or species)     if info.auto == "speciesbox" then 	    if templateArgs['taxon'] and (templateArgs['genus'] or templateArgs['species']) then 	    	categoryString = categoryString .. "Category:Speciesboxes using taxon with genus or species parameters" 	    end     end          -- (2) check for manual taxobox parameters 	for k,v in pairs(paramData.taxonRanks) do --run through manual taxobox parameter list 		 		if v == 'genus' then break end -- don't check at genus and below 		 		if tempArgs[v] then -- use tempArgs as these won't have been validated (produces redundant category?) 		   	categoryString = categoryString .. "Category:Automatic taxoboxes using manual rank parameters" 		end 	end 	 	local orphan = false 	local dependentParams = {  		image_caption =  'image',   image_alt = 'image',   image_upright = 'image', image_width = 'image', 		image2_caption =  'image2', image2_alt = 'image2', image2_upright = 'image2', image2_width = 'image2', 		range_map_caption = 'range_map', range_map_alt = 'range_map',   range_map_upright = 'range_map', range_map_width = 'range_map', 		range_map2_caption = 'range_map2', range_map2_alt = 'range_map2',   range_map2_upright = 'range_map2', range_map2_width = 'range_map2', 		range_map3_caption = 'range_map3', range_map3_alt = 'range_map3',   range_map3_upright = 'range_map3', range_map3_width = 'range_map3', 		range_map4_caption = 'range_map4', range_map4_alt = 'range_map4',   range_map4_upright = 'range_map4', range_map4_width = 'range_map4', 	} 	for k,v in pairs(dependentParams) do 	    if templateArgs[k] and not templateArgs[v] then orphan = true end 	    --templateArgs[k] = nil -- delete orphaned variable 	end 	if orphan then  		categoryString = categoryString .. "Category:Automatic taxoboxes with orphaned dependent parameters" 	end 	 	-- paraphyletic groups using manual taxonomy 	--categoryString = categoryString .. "Category:" .. mw.getCurrentFrame():getParent():getTitle()  .."" 	if mw.getCurrentFrame():getParent():getTitle() == "Template:Paraphyletic group" then 		if info.auto ~= "yes" and info.auto ~= "virus" and info.auto ~= "virusbox" and info.auto ~= "hybridbox" 		       and info.auto ~= "speciesbox" and info.auto ~= "subspeciesbox" and info.auto ~= "infraspeciesbox" then 			categoryString = categoryString .. "Category:Paraphyletic group infoboxes with manual taxonomy"  		end 		--categoryString = categoryString .. "Category:Paraphyletic group infoboxes"  	end 	 	-- add to category list 	info.parameterCategory = info.parameterCategory .. categoryString 	 	--return  categoryString end  return p