local excludeTable = { 'genus', 'species', 'subspecies', 'family', 'order', 'taxon',
'id', 'search' , 'citation', 1, 2, 3, 4 } -- add defaults ?  
if target.customArgs['exclude'] then
local customTable = mw.text.split (target.customArgs['exclude'] , "%s*,%s*");
for k,v in pairs(customTable) do
table.insert (excludeTable, v )
end
end
for k,v in pairs(excludeTable) do
if tonumber (v) then
v = tonumber (v) --convert positional parameters (numbers as string) to a number
end
templateArgs[v]=nil --clear content
end
end  
-- function handling the cite web template
p.citeWeb = function(, title, url)  
-- set url and title if not provided (template parameters override above)
if not templateArgs['url'] and url then
templateArgs['url']= url
end
if not templateArgs['title'] and title then
templateArgs['title'] = title
end  
clearCustomArgs--blank template parameters not for cite web  
local citeTemplate = 'cite web' -- use Template:Cite web unless specified
--if target.citeTemplate then citeTemplate = target.citeTemplate end
return :expandTemplate{ title = citeTemplate, args = templateArgs }  
end
-- p.CiteBook
-- for reasons of consisitency within BioRef/FishRef the title parameter is the section-title of
p.citeBook = function(, title, url, chapterParams) -- very much a msw3 function  
--if (1==1) then return templateArgs['title'] end  
-- set url and title if not provided (template parameters override above)
if not templateArgs['url'] and url then
templateArgs['url']= url
if target.GoogleBooks then
templateArgs['url'] = target.GoogleBooks['baseURL'] .. target.GoogleBooks['id']
.. (target.GoogleBooks['defaultPage'] or "&pg=PP1")  
end
end
if not templateArgs['title'] and title then
-- templateArgs['title'] = title
end
if templateArgs['title'] ~= title or templateArgs['taxon-title'] then -- do we have a section title provided
templateArgs['section'] = templateArgs['title'] -- chapter/section title passed as title parameter
templateArgs['title'] = title -- the work is the book title given in the source data
if target.GoogleBooks then  
templateArgs['section-url'] = target.GoogleBooks['baseURL'] .. target.GoogleBooks['id']
local pageSuffix = target.GoogleBooks['defaultPage'] or ""
if templateArgs['page'] or templateArgs['gb-page'] then
pageSuffix = "&pg=PT" .. (templateArgs['gb-page'] or templateArgs['page'] )
end
local searchStr = ""
-- quoted search |&dq=}}}}
if templateArgs['q'] then searchStr = "&q=" .. mw.text.encode( templateArgs['q'] ) end
-- search #if:}}|&q=}}}}
if templateArgs['dq'] then searchStr = "&dq=" .. mw.text.encode( templateArgs['dq'] ) end  
templateArgs['section-url'] = templateArgs['section-url'] .. pageSuffix .. searchStr
templateArgs['url'] = nil -- no need for second link to google books
end  
-- if the chapter/section is linked, we can link the main book chapter differently
if target.customArgs['altTitle'] then -- if we are using a chapter/section, we can wikilink the book title
templateArgs['title'] = target.customArgs['altTitle'] -- alternative to allow wikilink
elseif target.customArgs['altURL'] then
templateArgs['url'] = target.customArgs['altURL']
end  
end -- end if using supplied title for chapter/section  
clearCustomArgs--blank template parameters not for cite web  
local citeTemplate = 'cite book' -- use Template:Cite web unless specified
--if target.citeTemplate then citeTemplate = target.citeTemplate end
return :expandTemplate{ title = citeTemplate, args = templateArgs }  
end  
-- common function for genus and species
local function getGenusSpecies
--TODO standardise genus species handling
local genus, species, subspecies
if (templateArgs['genus'] or templateArgs[2] ) then
genus = templateArgs['genus'] or templateArgs[2]
genus = firstToUpper(mw.text.trim(genus))
end
if (templateArgs['species'] or templateArgs[3] ) then
species = templateArgs['species'] or templateArgs[3]
species = mw.text.trim(species)
end
if (templateArgs['subspecies'] or templateArgs[4] ) then
subspecies = templateArgs['subspecies'] or templateArgs[4]
subspecies = mw.text.trim(subspecies)
end  
return genus, species, subspecies
end  
--#################### MSW3 -- uses cite book
p.MSW3 = function
local msw = require('Module:FishRef/MSW')
initialise(, msw.MSW3)
return msw.MSW3.main(,templateArgs)
end
p.MSW3merged = function
local data = require('Module:FishRef/MSW')
return p._main(, data.MSW3)
end
p.MSW3_standalone = function  
local data = require('Module:FishRef/MSW')
initialise(, data.MSW3)
local url = target.CustomArgs['baseURL']  
if templateArgs['title'] and templateArgs['id'] then
templateArgs['chapter-url']= url .. target.CustomArgs['searchStr'] .. templateArgs['id']
templateArgs['chapter'] = templateArgs['title']  
templateArgs['title'] = target.CustomArgs['bookTitle']
if templateArgs['page'] then
templateArgs['url'] = target.CustomArgs['googleBooksURL'] .. templateArgs['page']
else
--return "Page number for google books required"
end
elseif templateArgs['order'] then
templateArgs['chapter'] = "Order " .. templateArgs['order']
local chapter = target.chapters[templateArgs['order']]
for k,v in pairs(chapter) do -- add chapter specific parameters
templateArgs[k] = v
end
templateArgs['chapter-url']= url .. target.CustomArgs['searchStr'] .. templateArgs['id']
templateArgs['url']= target.CustomArgs['googleBooksURL'] .. templateArgs['page']
if templateArgs['pages'] and templateArgs['page'] then templateArgs['page'] = nil end
else -- default output
templateArgs['url']= target.CustomArgs['googleBooksURL'] .. "1" -- default to book
templateArgs['url']= url
end
-- using cite book
clearCustomArgs--blank template parameters not for cite web
return :expandTemplate{ title = 'cite book', args = templateArgs }
end  
--########################### Functions for access (using invoke) ##############################################  
--================ Fishbase, Catalog of Fishes (cof) ================
p.fishbase = function return p._main(, data.fishbase) end
p.cof = function return p._main(, data.cof) end
p.fotw5 = function return p._main(, data.fotw5) end
--=================== ASW6, AmphibiaWeb, ReptileDB
p.reptileDB = function return p._main(, data.reptileDB) end
p.ASW6 = function return p._main(, data.ASW6) end
p.amphibiaweb = function return p._main(, data.amphibiaweb) end
--=========== Birds
p.HBWa = function return p._main(, data.HBWalive) end
p.HBWalive = function return p._main(, data.HBWalive) end
p.IOC = function return p._main(, data.IOC) end
--======= Mammals
p.asm = function return p._main(, data.asm) end
--======= Plants
p.WFO = function return p._main(, data.WFO) end
p.POWO = function return p._main(, data.POWO) end
-- MSW3 has custom handling (see above)
--=========== Other
p.fossilworks = function return p._main(, data.fossilworks) end
p.worms = function return p._main(, data.WoRMS) end
p.WoRMS = function return p._main(, data.WoRMS) end
p.col = function return p._main(, data.col) end
--fallback = function return "hello" end
--#########################################################
p.main = function
local source = mw.text.trim(.args[1])
--TODO force to lower case and use lower case for all functions above  
if source == "MSW3" then return p.MSW3 end  
if source == "ref" or source == "reference" then source = "Reference" end -- aliases
if source == "Reference" then return p.Reference end  
if source == "HBWa" then source = "HBWalive" end -- aliases
if source == "powo" then source = "POWO" end -- aliases
if source == "wfo" then source = "WFO" end -- aliases
if source == "mdd" then source = "asm" end -- aliases
--return p[source]['test']
if source == "fishbase" -- unnecessary?
or source == "cof"
or source == "fotw5" or source == "Fotw5"
or source == "reptileDB"
or source == "amphibiaweb"
or source == "ASW6"
or source == "asm"
or source == "HBWalive" or source == "HBWa"
or source == "fossilworks"
or source == "WoRMS" or source == "worms"
or source == "POWO" or source == "powo"
or source == "WFO" or source == "wfo"
or source == "AlgaeBase"
-- and so on