Módulo:FishRef

Fonte: Enciclopédia de conhecimento da Igreja de Deus
Saltar para a navegação Saltar para a pesquisa

A documentação para este módulo pode ser criada na página Módulo:FishRef/doc

require('strict')
local p = {}
local data = {}         
local templateArgs = {}  -- contains arguments passed to cite web
local target = {}        -- short cut to target table, e.g. fishbase, cof, etc
local function firstToUpper(str)
				return (str:gsub("^%l", string.upper))
end
-- define citation template and custom parameters for various sources
--####################### Default functions ##########################
data.default = {}
-- currently being tested on Avibase, but Fossilworks, Tropicos, FNA and a few others are candidates
data.default.id = function (id, source)
	local title = id
	local url = source.customArgs['baseURL'] .. (source.customArgs['searchStr'] or "") .. id
	return title, url
end
data.default.error = function()
	return "Minimal requirement is two of id, url and title parameters"
end
data.default.search = function (search, source)
	local title = "Search for " .. search
	local url = source.customArgs['baseURL'] .. source.customArgs['searchString'] .. search .. source.customArgs['searchSuffix'] 
	return title, url
end
--[[ handling for ID only (unused, original concept) 
p.genericIdCitation = function(frame, title, url)
				if not templateArgs['id'] then return "no id parameter detected" end
	
				templateArgs['url']= target.CustomArgs['baseURL'] .. target.CustomArgs['searchStr'] .. templateArgs['id']
				
				return p.citeWeb(frame, title, url)
end]]
--####################### FISH #####################################
--======================== Fishbase =================================
data.fishbase = {
	citationArgs = {
	['editor1-last']="Froese",  ['editor1-first']="Rainer", ['editor1-link']="Rainer Froese",
	['editor2-last']="Pauly",  ['editor2-first']="Daniel",   
	--['last-author-amp'] ="yes",
				['website'] = "[[Fishbase]]",
	--['publisher'] = ""
	},
	customArgs = { exclude= "order, family,genus, species, subspecies, 1, 2, 3, 4",
																baseURL = "http://www.fishbase.org/",
																defaultTitle = "Search FishBase"
	},
}
data.fishbase.species = function(genus, species, subspecies)
		local title = genus .. " " .. species
		local url = data.fishbase.customArgs['baseURL'] 
														.. "summary/SpeciesSummary.php?genusname=" .. genus .. "&speciesname=" .. species
		if subspecies then 
			url = url .. "+" .. subspecies
			title = title .. " " .. subspecies
		end               
		title =  "''" .. title  .. "''"
		return title, url
end
data.fishbase.genus = function(genus)
		local title = "Species in genus ''" .. firstToUpper(genus) .. "''"
		local url = data.fishbase.customArgs['baseURL'] ..  "identification/SpeciesList.php?genus=" .. genus   
		return title, url
end
data.fishbase.order = function(order) 
		local title =  "Order " .. firstToUpper(order)
		local url = data.fishbase.customArgs['baseURL'] ..  "Summary/OrdersSummary.php?order=" .. order
		return title, url
end
data.fishbase.family = function(family) 
		local title = "Family " .. firstToUpper(family)
		local url = data.fishbase.customArgs['baseURL'] ..  "Summary/FamilySummary.php?family=" .. family
		return title, url
end
data.fishbase.error = function()   
	return "No recognised taxon options: order, family, genus, species, subspecies."
end
data.fishbase.custom = function()    
				--TODO decide what to do with default date
				local version = "April 2006 version"  -- Should we have a default (probably not)
				if templateArgs['month'] then version = templateArgs['month'] end
				if templateArgs['year'] then version = templateArgs['year'] .. " version" end
				if templateArgs['month'] then version = templateArgs['month'] .. " " .. version end
				templateArgs['version'] = version
end
--================================ Catalog of Fishes ================================================
data.cof = {
	citationArgs = {
		--baseURL = "http://researcharchive.calacademy.org/research/ichthyology/catalog/fishcatget.asp?",
		['editor1-last']="Eschmeyer",  ['editor1-first']="William N.", ['editor1-link']="William N. Eschmeyer",
		['editor2-last']="Fricke",  ['editor2-first']="Ron",   
		['editor3-last']="van der Laan",  ['editor3-first']="Richard", 
		--['name-list-style'] ="amp",
					['website'] = "[[Catalog of Fishes]]",
		['publisher'] = "[[California Academy of Sciences]]"
	},
	customArgs = { exclude= "family,genus,species,genid,spid,id,list,1,2,3",
																baseURL = "http://researcharchive.calacademy.org/research/ichthyology/catalog/fishcatget.asp?",
																defaultTitle = "CAS - Eschmeyer's Catalog of Fishes"
	}
}
data.cof.species = function(genus, species, subspecies)
		local taxon = genus .. " " .. species
					local url = data.cof.customArgs['baseURL'] ..  'tbl=species&genus=' .. genus .. '&species=' .. species
					local title = "Species related to " .. "''" .. firstToUpper(taxon) .. "''"        -- .. "" species synonyms"
					return title, url
end
data.cof.genus  = function(genus)
					local url = data.cof.customArgs['baseURL'] .. 'tbl=species&genus=' .. genus
					local title = "Species in the genus ''" .. firstToUpper(genus) .. "''" 
					return title, url
end
							-- note the family works with subfamilies using &family=SUBFAMILY
data.cof.family  = function(family)
					local list = templateArgs['list'] or "genus"
					local url = data.cof.customArgs['baseURL'] .. 'tbl=' .. list .. '&family=' .. family
								local title = "Species"
								if list == "genus" then  title = "Genera" end 
								title = title .. ' in the family ' .. firstToUpper(family)  
								return title, url
end
data.cof.genid = function(genid)
								local searchStr =  "genid" .. '=' .. genid
								local title =  searchStr
								local url = data.cof.customArgs['baseURL'] .. searchStr
								return title, url
end
data.cof.spid = function(spid)
								local searchStr =  "spid" .. '=' .. spid
								local title =  searchStr
								local url = data.cof.customArgs['baseURL'] .. searchStr
								return title, url
end
data.cof.error = function()
					return "Error. No recognised option set by template (need one of family, genus, species (also requires genus), spid, or genid"
end
--======================Fishes of the World 5=============================== 
data.fotw5 = {
	citeTemplate = "Cite book",
	citationArgs = {
					--['website'] = "[[]]",
		first1 = "Joseph S.", last1 = "Nelson",
		first2="Terry C.", last2="Grande",
		first3="Mark V. H.", last3="Wilson", 
		--work = "Fishes of the World (work)",
		title = "Fishes of the World", edition="5th", year = 2016,
		publisher ="John Wiley and Sons", location="Hoboken",
		isbn = "978-1-118-34233-6", doi="10.1002/9781119174844" ,
	},
	customArgs = {exclude="gb-page,q,dq,1",
															baseURL = "https://onlinelibrary.wiley.com/doi/book/10.1002/9781119174844", -- online library
															defaultTitle = "Fishes of the World",
															altTitle = "[[Fishes of the World]]",               -- wikilinked for when using chapter/section title
															altURL = "https://sites.google.com/site/fotw5th/",  -- classification
	},
	GoogleBooks = { baseURL = "https://books.google.co.uk/books?id=",
														id = "E-MLDAAAQBAJ",
														defaultPage = "&pg=PP1"
	}
}
data.fotw5.default2 = function(targs)
					local title = data.fotw5.citationArgs['work']
					local url = data.fotw5.customArgs['baseURL']
					local chapterParams =  { title      = title,
																										['chapter-url']= data.fotw5.customArgs['googleBooks']
					}
					--return title, url, chapterParams
end
data.BentonVP4 = {
	citeTemplate = "Cite book",
	citationArgs = {
		first1 = "Michael J.", last1 = "Benton",
		title = "Vertebrate Palaeontology", edition="4th", year = 2014,
		publisher ="John Wiley & Sons", 
		isbn = "978-1-118-40764-6", 
	},
	customArgs = {exclude="gb-page,q,dq,1",
															--baseURL = "",
															defaultTitle = "Vertebrate Palaeontology",
															altTitle = "[[Vertebrate Palaeontology]]"  -- wikilinked for when using chapter/section title
	},
	GoogleBooks = { baseURL = "https://books.google.co.uk/books?id=",
														id = "qak-BAAAQBAJ",
														defaultPage = "&pg=PP1",
	}
}
--====================TODO FishWisePro================================================== 
data.fishwisepro = {
	citationArgs = {
					['website'] = "[[FishWisePro]]",
	},
	customArgs = {exclude="family,genus,species,1",
															baseURL = ""
	}
}
-- #################### AMPHIBIA and REPTILES ###############################
-- ================= Amphibian Species of the World (ASW6)
--[[Recommended citation: Frost, Darrel R. 2019. Amphibian Species of the World: an Online Reference. Version 6.0 (Date of access). Electronic Database accessible at http://research.amnh.org/herpetology/amphibia/index.html. American Museum of Natural History, New York, USA.
				URL for family page: http://research.amnh.org/vz/herpetology/amphibia/Amphibia/Anura/Allophrynidae
											baseURL      = http://research.amnh.org/vz/herpetology/amphibia/
											suffix       = Amphibia/Anura/Allophrynidae
											note: needs the whole hierarchy (except the superfamily which is optional)
				Template for main taxonomic listing: {{BioRef|ASW6 |title=Amphibia |year=2019 |url=http://research.amnh.org/herpetology/amphibia/index.html |access-date=27 September 2019}}
				SEARCH http://research.amnh.org/vz/herpetology/amphibia/amphib/basic_search?basic_query=Atelopus&stree=&stree_id=
											searchSuffix = amphib/basic_search?basic_query=Atelopus&stree=&stree_id=
				SEARCH http://research.amnh.org/vz/herpetology/amphibia/content/search?taxon=Allophryn*&subtree=&subtree_id=&english_name=&author=&year=&country=
											searchSuffix = /content/search?taxon=Allophryn*&subtree=&subtree_id=&english_name=&author=&year=&country=
											minimul      = /content/search?taxon=Allophryn*&subtree
				]]
data.ASW6 ={
	citationArgs = {
		website  ="Amphibian Species of the World, an Online Reference.",
		version  = "Version 6.0",
		publisher = "American Museum of Natural History, New York",
		['last1']="Frost",  ['first1']="Darrel R.", ['author1-link']="Darrel R. Frost",
	},
	customArgs = { exclude = "taxon,species,genus,family, superfamily,1,2,3",
																baseURL = "http://research.amnh.org/herpetology/amphibia/",
																defaultSuffix = "index.html",
																defaultTitle = "ASW Home"  
	}
}
data.ASW6.species = function(genus, species, subspecies)
		-- search for genus+species  ()
					local title = "Search for taxon: " .. "''" .. genus .. " " .. species .. "''"
	
				--local search = ""?action=names&taxon="" -- old version (pre ASW6)
				--local search =  "amphib/basic_search?basic_query="  -- basic search
			local search = "content/search?taxon="              -- guided search for taxon name
				
		local url = data.ASW6.customArgs['baseURL'] .. search  -- .. genus .. '+AND+' .. species
																.. '"' .. genus .. '+' .. species .. '"'
		return title, url
end
data.ASW6.genus = function(genus)
	return data.ASW6.taxon(genus)  -- use genus as alias of taxon
end
data.ASW6.taxon = function(taxon)  
					local title = "Search for Taxon: " .. taxon
					local url= data.ASW6.customArgs['baseURL'] .. "content/search?taxon=" .. taxon
					return title, url
end
data.ASW6.family = function(family) 
		local order = data.ASW6.checkOrder(family)
		local url= data.ASW6.customArgs['baseURL'] .. "Amphibia/" .. order .. "/" .. firstToUpper(family)
		local title = firstToUpper(family) 
		return title, url
end
data.ASW6.checkOrder = function(family)
	local gymnophiona={ "Caeciliidae", "Chikilidae", "Dermophiidae", "Herpelidae", "Ichthyophiidae", "Grandisoniidae", "Indotyphlidae", "Rhinatrematidae", "Scolecomorphidae", "Siphonopidae", "Typhlonectidae" }
				local caudata = { "Ambystomatidae", "Amphiumidae", "Cryptobranchidae", "Hynobiidae", "Plethodontidae", "Proteidae", "Rhyacotritonidae", "Salamandridae", "Sirenidae" }
			
				for k,v in pairs(caudata) do
					if v == family then return "Caudata" end
				end
				for k,v in pairs(gymnophiona) do
					if v == family then return "Gymnophiona" end
				end
				
				return "Anura"
end   
--============================= AmphibiaWeb ===================================
--[[   Citation: AmphibiaWeb. 2019. <https://amphibiaweb.org> University of California, Berkeley, CA, USA. Accessed 27 Sep 2019.
							Code:     {{BioRef|amphibiaweb |title=Amphibia |year=2019 |url=https://amphibiaweb.org/taxonomy/AW_FamilyPhylogeny.html |access-date=27 September 2019}}
--]]
data.amphibiaweb = {
	citationArgs = {
		website  = "AmphibiaWeb",
		publisher = "University of California, Berkeley",
		--['editor1-last']="",  ['editor1-first']="", ['editor1-link']="",
	},
				customArgs = { exclude = "taxon,species,genus,family,1,2,3",
																baseURL = "https://amphibiaweb.org/",
																defaultSuffix = "taxonomy/AW_FamilyPhylogeny.html",
																defaultTitle = "AmphibiaWeb Family Taxonomy"
	}
}
data.amphibiaweb.species = function (genus, species, subspecies)
		local title = "''" .. genus .. " " .. species .. "''"
				--https://amphibiaweb.org/cgi/amphib_query?where-genus=Altiphrynoides&where-species=malcolmi
		local url = data.amphibiaweb.customArgs['baseURL'] .. "cgi/amphib_query?rel-genus=equals&where-genus="
																							.. genus .. "&rel-species=equals&where-species=" .. species
		return title, url
end
data.amphibiaweb.genus = function (genus)
		local title = "''" .. genus ..  "''"
				--https://amphibiaweb.org/cgi/amphib_query?where-genus=Altiphrynoides&where-species=malcolmi
		local url = data.amphibiaweb.customArgs['baseURL'] .. "cgi/amphib_query?rel-genus=equals&where-genus=" 
																				.. genus .. "&include_synonymies=Yes&show_photos=Yes"
		return title, url
end 
data.amphibiaweb.family = function (family)  -- if family use standardised url
			local url = data.amphibiaweb.customArgs['baseURL'] .. "lists/" .. firstToUpper(templateArgs['family']) .. ".shtml"
			local title = templateArgs['family']
			return title, url
end
	


--=========================== The Reptile Database
data.reptileDB = {
	-- http://reptile-database.reptarium.cz/species?genus=Epacrophis&species=boulengeri
	-- recommended citation: Uetz, P., Freed, P. & Hošek, J. (eds.) (2019) The Reptile Database, http://www.reptile-database.org, accessed [insert date here]
	citationArgs = {
		--website="reptile-database.org",
		website="[[The Reptile Database]]",
		['editor1-last']="Uetz",  ['editor1-first']="P.", --['editor1-link']="Peter Uetz",
		['editor2-last']="Freed",  ['editor2-first']="P.", 
		['editor3-last']="Hošek",  ['editor3-first']="J.", 
		--year=2019
		
	},
	customArgs = { exclude = "taxon,species,genus,family,1,2,3",
																baseURL = "http://reptile-database.reptarium.cz/"
	}
}
data.reptileDB.species = function(genus, species)
					local title = "''" .. genus .. " " .. species .. "''"
					--http://reptile-database.reptarium.cz/species?genus=Loxocemus&species=bicolor
		local url = data.reptileDB.customArgs['baseURL'] .. "species?genus=" .. genus .. "&species=" .. species
		return  title, url
end
data.reptileDB.genus = function(genus)
					local title = "''" .. genus .. "''" 
					--http://reptile-database.reptarium.cz/advanced_search?genus=Malayopython&submit=Search
					local url = data.reptileDB.customArgs['baseURL'] .. "advanced_search?genus=" .. genus .. "&exact%5B0%5D=taxon&submit=search"
		return  title, url
end
data.reptileDB.family = function(family)
							return data.reptileDB.taxon(family)
end
data.reptileDB.order = function(order)
							return data.reptileDB.taxon(order)
end
data.reptileDB.taxon = function(taxon)
					local title = taxon
		--http://reptile-database.reptarium.cz/advanced_search?taxon=Viperidae&exact%5B0%5D=taxon&submit=Search
		local url = data.reptileDB.customArgs['baseURL'] .. "advanced_search?taxon=" .. taxon .. "&exact%5B0%5D=taxon&submit=search"
		return  title, url
end
	

			

--################################### BIRDS ########################################
--====================Handbook of the Birds of the World Alive (HBW Alive)==============
data.HBWalive = {         
	citationArgs = {
		website="[[Handbook of the Birds of the World|Handbook of the Birds of the World Alive]]", 
		publisher="Lynx Edicions"
	},
	customArgs = { exclude="order,family,genus,species,taxon,id,1",
																baseURL = "https://www.hbw.com/",
																defaultSuffix = "family/home",
																defaultTitle = "Family | HBW Alive"
																
	}
}
--############################## HBW ALIVE #########################################
			-- family and species entries have mix of common name and taxon name so cannot be prempted; 
			-- must use title + url (which uses default functions in this module)
data.HBWalive.order = function(order)
					local title = "Order " .. firstToUpper(order)
					--https://www.hbw.com/order/struthioniformes
					local url = target.customArgs['baseURL'] .. "order/" .. order
					return title, url
end
	

--[[======================IOC World Bird List==========================
									Gill, F & D Donsker (Eds). 2019. IOC World Bird List (v9.2). doi :  10.14344/IOC.ML.9.2.
									Gill F, D Donsker & P Rasmussen  (Eds). 2020. IOC World Bird List (v10.2). doi :  10.14344/IOC.ML.10.1.
]]
data.IOC = {         
	citationArgs = {
		website="[[IOC World Bird List]]", 
	-- version="Version 9.2",                               -- shouldn't default; should be hardcode so it doesn't change
		['editor1-last']="Gill",  ['editor1-first']="F.",  ['editor1-link']="Frank Gill (ornithologist)",
		['editor2-last']="Donsker",  ['editor2-first']="D.",
		['editor3-last']="Rasmussen",  ['editor3-first']="P.",  -- TODO only show from version 10.1 onwards
	-- doi = "10.14344/IOC.ML.9.2",                          -- this changes by version number and is not a useful part of the cictation
		publisher="International Ornithological Congress"
	},
	customArgs = { exclude="order,family,genus,species,taxon,id,1",
																baseURL = "https://www.worldbirdnames.org/",
																defaultSuffix = "",
																defaultTitle = "IOC World Bird List: Welcome"
																
	},
}
data.IOC.version = function()
	local version =  templateArgs['version'] 
	local old = false
	if version then
		version = string.gsub( version, "[Vv]ersion ", "")
						local versionNumber = tonumber(version)
					if versionNumber < 10.1 then
						old = true
		end
	else
		local Date = require('Module:Date')._Date
		if Date(templateArgs['access-date']) < Date('1 January 2020') then
			old = true
		end
	end
	
	if old then
						data.IOC.citationArgs['editor3-last'] = nil
						data.IOC.citationArgs['editor3-first'] = nil
	end
end
data.IOC.order = function(order) 
					data.IOC.version()
								local IOCorders = {Struthioniformes='ratites',Rheiformes='ratites',Apterygiformes='ratites',Casuariiformes='ratites',Tinamiformes='ratites',Galliformes='megapodes',Anseriformes='waterfowl',Caprimulgiformes='nightjars',Apodiformes='swifts',Musophagiformes='turacos',Otidiformes='turacos',Cuculiformes='turacos',Mesitornithiformes='turacos',Pterocliformes='turacos',Columbiformes='pigeons',Gruiformes='flufftails',Podicipediformes='grebes',Phoenicopteriformes='grebes',Charadriiformes='sandpipers',Eurypygiformes='loons',Phaethontiformes='loons',Gaviiformes='loons',Sphenisciformes='loons',Procellariiformes='loons',Ciconiiformes='storks',Suliformes='storks',Pelecaniformes='pelicans',Opisthocomiformes='raptors',Accipitriformes='raptors',Strigiformes='owls',Coliiformes='mousebirds',Leptosomiformes='mousebirds',Trogoniformes='mousebirds',Bucerotiformes='mousebirds',Coraciiformes='rollers',Piciformes='woodpeckers',Cariamiformes='falcons',Falconiformes='falcons',Psittaciformes='parrots',
																Passeriformes='nz_wrens'} -- passeriformes link not very useful
					local title = "Order " .. firstToUpper(order)
					local url = data.IOC.customArgs['baseURL'] .. "/bow/" .. IOCorders[order]
					return title, url     
end
data.IOC.family = function(family)
					data.IOC.version()
					local IOCfamilies = { Struthionidae = {"ratites", 4}, Alcippeidae = {"babblers", 24989 } }      -- temporary partial list for testing
					
					local title = "Family " .. firstToUpper(family)
					--https://www.worldbirdnames.org/Family/Struthionidae
					local url = data.IOC.customArgs['baseURL'] .. "Family/" .. family   -- old version (might be resurrected by IOC)
					
					-- https://www.worldbirdnames.org/new/bow/babblers/#1338626516R24989
					if IOCfamilies[family] then                                             -- test version local partial list
						url = data.IOC.customArgs['baseURL'] .. "new/bow/" ..  IOCfamilies[family][1] .. "/#1338626516R" .. IOCfamilies[family][2]
					end
					return title, url
end    
data.IOC.default = function( title, url) 
					data.IOC.version()
					return title, url
end
data.BOW = {         
	citationArgs = {
		website="Birds of the World Online", 
	-- doi = "",                          
	-- ['last1']="Winkler",  ['first1']="David W.",              -- are these always the authors in version 1? no, perhaps for family page
	-- ['last2']="Billerman",  ['first2']="Shawn M.",
	-- ['last3']="Lovette",  ['first3']="Irby J.",  
	-- ['editor1-last']="Billerman",  ['editor1-first']="S. M.",  --['editor1-link']="",
	-- ['editor2-last']="Keeney",  ['editor2-first']="B. K.",
	-- ['editor3-last']="Rodewald",  ['editor3-first']="P. G.",  
	--    ['editor4-last']="Schulenberg",  ['editor4-first']="T. S.",
	--    ['version'] = 1,   ['year'] = 2020,                                             -- may not want to default
		publisher="[[Cornell Lab of Ornithology]], Ithaca, NY."
	},
	customArgs = { exclude="citation,make,order,family,genus,species,taxon,id,1",
																baseURL = "https://birdsoftheworld.org/bow/species",
																defaultSuffix = "",
																defaultTitle = "Explore Taxonomy"
																
	},
}
data.BOW.default =  function( title, url)  
		--data.BOW.citationArgs['version'] = "Version 1"
		return title, url
end
--[[ make BOW to parse standard citation, {{BioRef|BOW|citation=CITATION}}
				vesrion 1 (family): Winkler, D. W., S. M. Billerman, and I.J. Lovette (2020). Bulbuls (Pycnonotidae), version 1.0. In Birds of the World 
																								(S. M. Billerman, B. K. Keeney, P. G. Rodewald, and T. S. Schulenberg, Editors). Cornell Lab of Ornithology, Ithaca, NY, USA. 
																								https://doi.org/10.2173/bow.pycnon4.01
				version 2 (species): Limparungpatthanakij , W. L., L. Fishpool, and J. Tobias (2020). Buff-vented Bulbul (Iole crypta), version 2.0. In Birds of the World 
																								(S. M. Billerman and B. K. Keeney, Editors). Cornell Lab of Ornithology, Ithaca, NY, USA. 
																								https://doi.org/10.2173/bow.buvbul1.02
]]
data.BOW.citation =  function( value)  
	local citation  = templateArgs['citation'] 
				data.BOW.citationArgs['year']  = citation:match ('^%D+(%d%d%d%d)')
				data.BOW.citationArgs['doi']  = citation:match ('10%.2173/bow%..+')                           -- https://doi.org/10.2173/bow.pycnon4.01
				--data.BOW.citationArgs['version']  = citation:match ('version %d%.%d')                       -- version applies to page, not whole BOW
				local title = citation:match ('%d%d%d%d%)%.(.*, version %d%.%d)');                            -- include version number in title
				local suffix = citation:match ('10%.2173/bow%.(.+%d)%.');                                     -- https://doi.org/10.2173/bow.pycnon4.01
				local version = "/cur/"                                                                       -- for the current version
				version = citation:match ('version (%d%.%d)')                                                 -- for the cited version
				local url = data.BOW.customArgs['baseURL'] .. '/' .. suffix .. '/'  .. version .. '/' 
				
				title = title:gsub( '%((%D+) (%D+)%)' , "(''%1 %2'')")
				
				local authors = citation:match ('^(%D+) %(%d%d%d%d%)')
				--data.BOW.citationArgs['authors'] = citation:match ('^(%D+)%(%d%d%d%d%)')
				--data.BOW.citationArgs['editors'] = citation:match ('In Birds of the World %((.-)Editors%)' ) -- omit editors as cite web psoitioning is weird
				if authors then           -- split authors with modified code from make cite iucn
					local list = {}
					authors = authors:gsub(", and ", ", ")
					--local names = author_names:gsub ('%.?,?%s+&%s+', '.|'):gsub ('%.,%s+', '.|'); -- replace 'separators' (<dot><comma><space> and <opt. dot><opt. comma><space><ampersand><space>) with <dot><pipe>
					local names = authors:gsub (',%s+', '|');       -- replace any comma
																						--    :gsub ('%.?,?%s+and%s+', '|') -- replace 'separators' <opt. dot><opt. comma><space>and<space>) with <dot><pipe>
																						--    :gsub ('%.,%s+', '.|');       -- replace 'separators' <dot><comma><space> with <dot><pipe>
							list = mw.text.split (names, '|');           -- split the string on the pipes into entries in list
		if #list == 0 then
			data.BOW.citationArgs['authors'] = authors               -- no 'names' of the proper form; return the original as a single |author= parameter
		else
			for i, name in ipairs (list) do           -- for each author in list 
									data.BOW.citationArgs['author'..i-1] = name          -- add |authorn= parameter names
				-- list[i] = table.concat ({'|author', (i == 1) and '' or i, '=', name}); -- add |authorn= parameter names; create |author= instead of |author1=
			end
			data.BOW.citationArgs['author1'] = data.BOW.citationArgs['author0'] .. ', ' .. data.BOW.citationArgs['author1']
		end   
				
				end
		--if not url then url = data.BOW.customArgs['baseURL']  end
		--if not title then title = "Title parameter required" end
		
		return title, url
end
-- basic handling for Taxonomy in Flux website
data.tif = {         
	citationArgs = {
		website="Taxonomy in Flux", 
		['editor1-last']="Boyd III",  ['editor1-first']="John H.",    --['editor1-link']="",
	},
	customArgs = { exclude="order,family,genus,species,taxon,id,1",
																baseURL = "http://jboyd.net/Taxo/",
																defaultSuffix = "List.html",
																defaultTitle = "Taxonomy in Flux"
																
	},
}
--[[ ------------- Avibase
																			e.g. https://avibase.bsc-eoc.org/species.jsp?avibaseid=9144EF4017F2D8B1
]]
data.avibase = {
		citationArgs = {
		website="Avibase", 
		['editor1-last']="Lepage",  ['editor1-first']="Denis",    --['editor1-link']="",
	},
	customArgs = { exclude="order,family,genus,species,taxon,id,1",
																baseURL = "https://avibase.bsc-eoc.org/",
																searchStr = "species.jsp?avibaseid=",
																defaultTitle = "Avibase - The World Bird Database"
	}
}
--[[ use default function
data.avibase.id = function (id)
				
				local title = "Avibase id: " .. id
	local url = data.avibase.customArgs['baseURL'] .. data.avibase.customArgs['searchStr'] .. id
	return title, url
end
--]]
-- ============================= IUCN =================================================
-- for species in taxon; for species assessments, us {{cite iucn}}
-- https://www.iucnredlist.org/search?query=Murexia&searchType=species 
-- https://www.iucnredlist.org/search?query=aonyx&searchType=species
data.iucn = {
	citationArgs = {
		website="[[IUCN Red List of Threatened Species]]", 
		--publisher="[[IUCN]]"
	},
	customArgs = { exclude="family,genus,species,taxon,id,1",
																baseURL = "https://www.iucnredlist.org",
																searchString = "/search?query=",
																searchSuffix = "&searchType=species",
																defaultSuffix = "",
																defaultTitle="IUCN Red List of Threatened Species"
	} 
}
data.iucn.genus  = function(genus)  return data.iucn.taxon(genus, "TITLE_ITALICS") end
data.iucn.family = function(family) return data.iucn.taxon(family) end
data.iucn.order  = function(order)  return data.iucn.taxon(order) end
data.iucn.taxon  = function(taxon, titleItalics)
				local title = firstToUpper(taxon)
				if titleItalics then title = "''" .. title .. "''" end
				local url = data.iucn.customArgs['baseURL'] .. data.iucn.customArgs['searchString'] .. taxon .. data.iucn.customArgs['searchSuffix']
				return title, url
end   
-- ============================= ASM Mammal Diversity Database ========================
data.asm = {
	citationArgs = {
		website="ASM Mammal Diversity Database", 
		publisher="[[American Society of Mammalogists]]"
	},
	customArgs = { exclude="family,genus,species,taxon,id,1,2,3",
																baseURL = "https://www.mammaldiversity.org/",
																defaultTitle="ASM Mammal Diversity Database"
																
	}
}
data.asm.species = function(genus, species)
	-- new url = https://www.mammaldiversity.org/explore.html#genus=Dipodomys&species=deserti&id=1001892
				local title = "''" .. genus .. " " .. species .. "''"
		--https://mammaldiversity.org/species-account.php?genus=ursus&species=arctos
	local url = data.asm.customArgs['baseURL'] .. "explore.html#genus=" .. genus .. "&species=" .. species
	if templateArgs['id'] then url = url .. "&id=" .. templateArgs['id'] end
	return title, url
end     
data.asm.id = function(id)
					--local url = data.asm.customArgs['baseURL'] .. "species-account/species-id=" .. templateArgs['id']
					--local title = "Species-id=" .. id
					
					-- new format https://www.mammaldiversity.org/explore.html#species-id=1006310
					--local url = data.asm.customArgs['baseURL'] .. "explore.html#species-id=" .. id -- templateArgs['id']
					local url = data.asm.customArgs['baseURL'] .. "explore.html#genus=&species=&id=" .. id -- templateArgs['id']
					local title = "Species-id=" .. id
					return title, url
end
data.asm.genus  = function(genus)  return data.asm.taxon(genus, "TITLE_ITALICS") end
data.asm.family = function(family) return data.asm.taxon(family) end
data.asm.order  = function(order)  return data.asm.taxon(order) end
data.asm.taxon  = function(taxon, titleItalics)
					--https://mammaldiversity.org/#ZmVsaWRhZSZnbG9iYWxfc2VhcmNoPXRydWUmbG9vc2U9dHJ1ZQ
					--                             Base64.encode(felidae&global_search=true&loose=true)
				local title = firstToUpper(taxon)
				if titleItalics then title = "''" .. title .. "''" end
				local url = data.asm.customArgs['baseURL'] 
														.. '#' .. data.asm.Base64.encode(taxon.."&global_search=true&loose=false")
				return title, url
end   
--############################## Base64 encode and decode (used for ASM#####################
local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
-- encoding
data.asm.Base64 = {}
data.asm.Base64.encode = function(data)
				return ((data:gsub('.', function(x) 
								local r,b='',x:byte()
								for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
								return r;
				end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
								if (#x < 6) then return '' end
								local c=0
								for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end
								return b:sub(c+1,c+1)
				end)..({ '', '==', '=' })[#data%3+1])
end
-- decoding
data.asm.Base64.decode=function(data)
				data = string.gsub(data, '[^'..b..'=]', '')
				return (data:gsub('.', function(x)
								if (x == '=') then return '' end
								local r,f='',(b:find(x)-1)
								for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end
								return r;
				end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x)
								if (#x ~= 8) then return '' end
								local c=0
								for i=1,8 do c=c+(x:sub(i,i)=='1' and 2^(8-i) or 0) end
								return string.char(c)
				end))
end
--######################## Misc ##################################
--[[ 3 approaches to handling DB: 
								1) use DB as website and use author for editors (if known)
												(a) use via to append WoRMS
												(b) use postscript to append WoRMs
												(c) use publisher for WoRMS
								2) use WoRMS as website and designate DB as author (recommended by WoRMS) CURRENT
												(option) add editors [TODO see cite WoRMS for list]
												issue: what to do about editors changing (need to use access-date)
]]
data.WoRMS = {
	citationArgs = {
					author = "WoRMS",
					website = "[[World Register of Marine Species]]",
					--['via'] = "[[World Register of Marine Species]]",
					--postscript = '&#32;from the [[World Register of Marine Species]].'
	},
	customArgs = {exclude="id,db,1",
															baseURL = "http://www.marinespecies.org/aphia.php?",
															searchStr = "p=taxdetails&id=",
															defaultTitle="World Register of Marine Species"
	}
}
data.WoRMS.id = function(id)
				--[[ Two styles
									1. http://www.marinespecies.org/aphia.php?p=taxdetails&id=14712
												>  WoRMS (2018). Heterobranchia. Accessed at: http://marinespecies.org/aphia.php?p=taxdetails&id=14712 on 2018-11-28 
									2. http://www.marinespecies.org/aphia.php?p=taxdetails&id=1057249
												> MolluscaBase (2018). Ringipleura. Accessed through: World Register of Marine Species at: http://www.marinespecies.org/aphia.php?p=taxdetails&id=1057249 on 2018-11-28 
				]]
				if not templateArgs['id'] then return "no id parameter detected" end
				local searchStr = "p=taxdetails&id=" .. templateArgs['id']
				
				if templateArgs['db'] then
					data.WoRMS.db (templateArgs['db'])
				--[[else -- WoRMS is primary source (note cite WoRMs uses WoRMS as publisher and the db as the work)
						templateArgs['via'] = nil
						templateArgs['postscript'] = nil]]
				end
								--templateArgs['website'] = templateArgs['db']  -- alternative (and use |postscript)
					--templateArgs['publisher'] = templateArgs['via']
					
				--page <title>WoRMS - World Register of Marine Species - Heterobranchia</title>
				local title = "WoRMS taxon details: AphiaID " .. id
				local url = data.WoRMS.customArgs['baseURL'] .. data.WoRMS.customArgs['searchStr'] .. id
				return title, url    
end
data.WoRMS.default = function()
		if templateArgs['db'] then
					data.WoRMS.db (templateArgs['db'])
					end
end
data.WoRMS.db = function(db) -- if database hosted by WoRMS
				db = string.lower( db )
	if db == "world of copepods database" or db == "copepoda" or db == "copepods" or db == "copepod" then
		templateArgs['author'] = "World of Copepods Database"
		templateArgs['editor-last1']="Walter"; templateArgs['editor-first1']="T.C."
		templateArgs['editor-last2']="Boxshall"; templateArgs['editor-first2']="G."
		-- year ? (2022). 
	elseif db == "world amphipoda database" or db == "amphipoda" or db == "amphipod"then
		templateArgs['author'] = "World Amphipoda Database"
		templateArgs['editor-last1']="Horton"; templateArgs['editor-first1']="T."
		templateArgs['editor-last2']="Lowry"; templateArgs['editor-first2']="J."
		templateArgs['editor-last3']="De Broyer"; templateArgs['editor-first3']="C."
		templateArgs['display-editors']="etal";  -- full list is about 20 names
	elseif db == "world isopoda database" or db == "isopoda" or db == "isopod"then
		templateArgs['author'] = "World Marine, Freshwater and Terrestrial Isopod Crustaceans database"
		templateArgs['editor-last1']="Boyko"; templateArgs['editor-first1']="C.B."
		templateArgs['editor-last2']="Bruce"; templateArgs['editor-first2']="N.L."
		templateArgs['editor-last3']="Hadfield"; templateArgs['editor-first3']="K.A."
		templateArgs['editor-last4']="Merrin"; templateArgs['editor-first4']="K.L."
		templateArgs['editor-last5']="Ota."; templateArgs['editor-first5']="Y."
		templateArgs['editor-last6']="Poore"; templateArgs['editor-first6']="G.C.B."
		templateArgs['editor-last7']="Taiti"; templateArgs['editor-first7']="S."
	elseif db == "millibase" or db == "diplopoda" or db == "diplopod"then
		templateArgs['author'] = "MilliBase"
		templateArgs['editor-last1']="Sierwald"; templateArgs['editor-first1']="P."
		templateArgs['editor-last2']="Spelda"; templateArgs['editor-first2']="J."
	elseif db == "molluscabase" or db == "mollusca" or db == "mollusc" then
		templateArgs['author'] = "MolluscaBase"
	else
		templateArgs['author'] = templateArgs['db']  -- this is recommended by WoRMS
	end
end
--[[ ITIS - Integrated Taxonomic Information System
										https://www.itis.gov/servlet/SingleRpt/SingleRpt?search_topic=TSN&search_value=95601#null
]]
data.itis = {
	citationArgs = {
					website   = "[[Integrated Taxonomic Information System]]",
					--publisher = "",
	},
	customArgs = {exclude="id,1,2,3,4,5",
															baseURL = "https://www.itis.gov/",
															searchStr = "servlet/SingleRpt/SingleRpt?search_topic=TSN&search_value=",
															defaultTitle="Integrated Taxonomic Information System"
	}
}
data.itis.id = function(id)   
				local title = "ITIS id=" .. id
				local url = data.itis.customArgs['baseURL'] .. data.itis.customArgs['searchStr'] .. id
		
	return title, url    
	
end
--[[ Catalogue of Life:
		Roskov Y., Ower G., Orrell T., Nicolson D., Bailly N., Kirk P.M., Bourgoin T., DeWalt R.E., Decock W., van Nieukerken E.J., Penev L. (eds.) (2020). 
		Species 2000 & ITIS Catalogue of Life, 2020-12-01. 
		Digital resource at www.catalogueoflife.org. Species 2000: Naturalis, Leiden, the Netherlands. ISSN 2405-8858.
		Species 2000 & ITIS Catalogue of Life, 2020-12-01. Digital resource at www.catalogueoflife.org. 
		Species 2000: Naturalis, Leiden, the Netherlands. ISSN 2405-8858.
]]
data.col = {
	db       = "col",  -- need rethink this
	citationArgs = {
					--author = "Catalogue of Life",
					--['editor-last1'] = "Roskov",   ['editor-first1'] = "Y.", ['editor-last2'] = "Ower",     ['editor-first2'] = "G.",      ['editor-last3'] = "Orrell",   ['editor-first3'] = "T.", ['editor-last4'] = "Nicolson", ['editor-first4'] = "D.",      ['editor-last5'] = "Bailly",   ['editor-first5'] = "N.", ['editor-last6'] = "Kirk",     ['editor-first6'] = "P.M.",      ['editor-last7'] = "Bourgoin", ['editor-first7'] = "T.", ['editor-last8'] = "DeWalt",   ['editor-first8'] = "R.E.",      ['editor-last9'] = "Decock",   ['editor-first9'] = "W.", ['editor-last10'] = "van Nieukerken", ['editor-first10'] = "E.J.",      ['editor-last11'] = "Penev", ['editor-first11'] = "L.", 
					--website   = "[[Catalogue of Life]]",
					--website   = "[[Catalogue of Life|Species 2000 & ITIS Catalogue of Life]]",
					-- website   = "[[Species 2000]] & [[ITIS]] [[Catalogue of Life]]",
					website   = "[[Catalogue of Life]]",
					publisher = "[[Species 2000]]: Leiden, the Netherlands",
					--others    = "Species 2000 & ITIS"
	},
	customArgs = {exclude="id,db,1,2,3,4,5,legacy,option",
															baseURL = "https://www.catalogueoflife.org/data/",
															searchStr = "browse?taxonKey=",
															defaultTitle="Catalogue of Life"
	}
}
data.col.id = function(id)   
	
				--[[ Catalogue of Life
								browse option: https://www.catalogueoflife.org/data/browse?taxonKey=4JQ8
												use id for taxoKey
												
								taxon option    https://www.catalogueoflife.org/data/taxon/6HR5M
				]]
				local title = "Catalogue of Life taxonKey " .. id
				local url = data.col.customArgs['baseURL']
				
				-- some new CoL are numbers e.g. 64553 in https://www.catalogueoflife.org/data/taxon/64553
	if not tonumber(id)  and string.find( id,  "^[0-9abcdef]+$" ) then                                            -- if old-style id
		local year = "2019"        -- last old-style version available
					if templateArgs['version'] and string.find( templateArgs['version'], "^%d%d%d%d$"  ) then --if version specied
									year = templateArgs['version']
								end
					if templateArgs['option'] == "browse" then 
						url = "http://www.catalogueoflife.org/annual-checklist/" .. year .. "/browse/tree/id/" .. id
		else -- default to option=taxon
						url = "http://www.catalogueoflife.org/annual-checklist/" .. year .. "/details/species/id/" .. id
		end
				else                                                                                  -- else use current version
					if templateArgs['option'] == "browse" then 
						url = url .. "browse?taxonKey=" .. id
		else -- default to option=taxon
						url = url .. "taxon/" .. id
		end
				end
	return title, url    
	
end
--[[ current links
					https://www.catalogueoflife.org/data/search?q=" Chinchilla+chinchilla&type=EXACT
	legacy links with redirect
					Species pages:    http://www.catalogueoflife.org/col/details/species/id/12dca9c49741815f82400bb7bff50553
					Species searches: http://www.catalogueoflife.org/col/search/all/key/Dracula+antonii/
				old-style links
																				http://www.catalogueoflife.org/col/details/species/id/7539827da517bd6273a4a3836578cb24
																				http://www.catalogueoflife.org/col/search/scientific/genus/Chinchilla/species/chinchilla/match/1/
																				http://www.catalogueoflife.org/col/browse/tree/id/003e480e646d0e7647ab67efc1218197
	year specific links
								2019              http://www.catalogueoflife.org/annual-checklist/2019/details/species/id/7539827da517bd6273a4a3836578cb24
																										http://www.catalogueoflife.org/annual-checklist/2019/search/all/key/Chinchilla+chinchilla/fossil/1/match/1 
																										http://www.catalogueoflife.org/annual-checklist/2019/search/scientific/genus/Chinchilla/species/chinchilla/match/1/
																					?    http://www.catalogueoflife.org/annual-checklist/2016/browse/tree?6d600f4985f19b1207d41d847424edd0 
																					?    http://www.catalogueoflife.org/col/browse/tree/id/003e480e646d0e7647ab67efc1218197
								browse            http://www.catalogueoflife.org/annual-checklist/2019/browse/tree/id/003e480e646d0e7647ab67efc1218197
	]]
data.col.default = function(mode)  -- this handles the old style template with positional parameters (mode unused?)
			
	local para1 = templateArgs[1] 
	local para2 = templateArgs[2] 
	local para3 = templateArgs[3]  
	local para4 = templateArgs[4]  
	if para1 then para1 = mw.text.trim(para1) end
	if para2 then para2 = mw.text.trim(para2) end
	if para3 then para3 = mw.text.trim(para3) end
	if para4 then para4 = mw.text.trim(para4) end
	
	local title, url
	
	if para1 then
								--local match = "7539827da517bd6273a4a3836578cb24" 
		local match = "^[0-9abcdef]+$" 
		if string.find( para1, match ) then
			url = "http://www.catalogueoflife.org/col/details/species/id/" .. para1  -- ""Old style id"
			--url ="https://www.catalogueoflife.org/data/search?q=" .. para1
			if para2 then
				title = para2
			else
				title = "Oldstyle id: " .. para1
			end
			
		else
			--https://www.catalogueoflife.org/data/search?q=" Chinchilla+chinchilla&type=EXACT
			
			if para1 ~= "" then
				url = "https://www.catalogueoflife.org/data/search?q=" .. para1 
				title = "''" .. para1 
				if para2  then
					url = url .. "+" .. para2 
					title = title .. " " .. para2
				end
				url = url .. "&type=EXACT"
				title = title .. "''"
			end
			
		end 
		if para3 then title = title .. " " .. para3 end   -- add authority
		if para4 == "nv" then templateArgs['trans-title'] = "synonym" end   -- if nv add [synonym]. Note that this parameter is not used to add COinS metadata 
	else
		-- no parameter 1
	end
	
	return title, url    
end
--======================  Fossilworks =======================================
data.fossilworks = {
	citationArgs = {
		website="[[Fossilworks]]",
		--publisher="Paleobiology Database",
		--postscript = 'none',
		postscript = "&#32;from the [[Paleobiology Database]].",
		--via="''fossilworks.org''"   -- an alternative format to using |website=
	},
	customArgs = { exclude = "id,collection,date,1",
																baseURL = "http://www.fossilworks.org/cgi-bin/",
																searchStr ="bridge.pl?a=taxonInfo&taxon_no=",
																defaultTitle = "Fossilworks: Gateway to the Paleobiology Database"
	}
	--id = function(id) return p.genericIdCitation (frame, title, url)
}
data.fossilworks.id = function(id)
--[[ http://fossilworks.org/cgi-bin/bridge.pl?a=taxonInfo&taxon_no=83087 
				if not templateArgs['id'] then return "no id parameter detected" end
				local searchStr = "bridge.pl?a=taxonInfo&taxon_no=" .. templateArgs['id']
				templateArgs['url']= target.CustomArgs['baseURL'] .. searchStr
				]]
				local title = "PaleoDB taxon number: " .. id
				local url = data.fossilworks.customArgs['baseURL'] .. data.fossilworks.customArgs['searchStr'] .. id
				return title, url  
end
data.fossilworks.collection = function(collection)
	-- http://fossilworks.org/bridge.pl?a=collectionSearch&collection_no=20072
	local title = "PaleoDB collection number: " .. collection
	local url = data.fossilworks.customArgs['baseURL'] .. "bridge.pl?a=collectionSearch&collection_no=" .. collection
	return title, url 
end
data.fossilworks.error = function()
	return "Requires id and title parameters"
end
--======================  Paleobiology Database: paleobiodb.org =======================================
data.paleobiodb = {
	citationArgs = {
		website="[[Paleobiology Database]]"
	},
	customArgs = { exclude = "id,collection,date,1",
																baseURL = "https://paleobiodb.org/classic/",
																searchStr ="basicTaxonInfo?taxon_no=",
																defaultTitle = "Paleobiology Database"
	}
	--id = function(id) return p.genericIdCitation (frame, title, url)
}
data.paleobiodb.id = function(id)
--[[ https://paleobiodb.org/classic/basicTaxonInfo?taxon_no=22786 
				if not templateArgs['id'] then return "no id parameter detected" end
				]]
				local title = "PaleoDB taxon number: " .. id
				local url = data.paleobiodb.customArgs['baseURL'] .. data.paleobiodb.customArgs['searchStr'] .. id
				return title, url  
end
data.paleobiodb.collection = function(collection)
	-- https://paleobiodb.org/classic/basicCollectionSearch?collection_no=24193
	local title = "PaleoDB collection number: " .. collection
	local url = data.paleobiodb.customArgs['baseURL'] .. "basicCollectionSearch?collection_no=" .. collection
	return title, url 
end
data.paleobiodb.error = function()
	return "Requires id and title parameters"
end
--======================================= PLANTS =========================
--[[ Plant authorities can end in a period. This is stripped by the citation templates. 
					This function encloses titles ending in such authorities in double parentheses, i.e. ((title))   
		]]
local addAuthority = function(formattedTaxonName)
				if templateArgs['authority'] then
					local title = formattedTaxonName .. " " .. templateArgs['authority']
						return string.gsub( title, "(.*%.)$", "((%1))")  -- if authority ends in "." enclose ((title)) to prevent removal
				end
				return formattedTaxonName
end
--[[ Hassler, Michael (2004 - 2020): World Plants. Synonymic Checklist and Distribution of the World Flora. 
							Version x.xx; last update xx.xx.xxxx. - www.worldplants.de. Last accessed dd/mm/yyyy.
							https://www.worldplants.de/world-plants-complete-list/complete-plant-list#1599996425
					Hassler, Michael (2004 - 2020): World Ferns. Synonymic Checklist and Distribution of Ferns and Lycophytes of the World. 
							Version x.xx; last update xx.xx.xxxx. - www.worldplants.de/ferns/. Last accessed dd/mm/yyyy.
							https://www.worldplants.de/world-ferns/ferns-and-lycophytes-list#1599997555
				deeplinks:
		Genus:  [https://www.worldplants.de?deeplink=Helosciadium-Koch ''Helosciadium'']
		Species: [https://www.worldplants.de?deeplink=Helosciadium-longipedunculatum ''Helosciadium longipedunculatum'']
		
		Genus:  [https://www.worldplants.de?deeplink=Lycopodium-L. ''Lycopodium'']
		Species: [https://www.worldplants.de?deeplink=Lycopodium-clavatum ''Lycopodium clavatum'']
--]]
data.worldplants = {
	citationArgs = {
		last1 = "Hassler", first1 = "Michael",
		website="World Plants. Synonymic Checklist and Distribution of the World Flora.",
		--publisher=""
	},
	customArgs = { exclude = "id,authority,family,genus,species,1",
																baseURL = "https://www.worldplants.de",
																searchStr ="/world-plants-complete-list/complete-plant-list#",
																defaultSuffix = "",
																defaultTitle = "World Plants"
	}
}
data.worldplants.genus = function(genus)
	local title = addAuthority("''" .. genus .. "''")
	local genusString = genus 
	if templateArgs['authority'] then genusString = genus .. "-" .. templateArgs['authority'] end
	local url = data.worldplants.customArgs['baseURL'] .. "?deeplink=" .. genusString
	return title, url  
end
data.worldplants.species = function(genus, species)
	local title = addAuthority("''" .. genus .. " " .. species .. "''")
	local url = data.worldplants.customArgs['baseURL'] .. "?deeplink=" .. genus .. "-" .. species .. " " .. (templateArgs['authority'] or "")
	return title, url  
end
--[[ experimental, don't leave live 
data.worldplants.taxon = function(taxon)
	local title =  taxon .. " " .. (templateArgs['authority'] or "")
	local url = data.worldplants.customArgs['baseURL'] .. "?deeplink=" .. taxon
	return title, url  
end
data.worldplants.family = function(family)
	local title = family .. " " .. (templateArgs['authority'] or "")
	local url = data.worldplants.customArgs['baseURL'] .. "?deeplink=" .. family
	return title, url  
end
--]]
data.worldferns = {
	citationArgs = {
		last1 = "Hassler", first1 = "Michael",
		website="World Ferns. Synonymic Checklist and Distribution of the World Flora.",
		--publisher=""
	},
	customArgs = { exclude = "id,authority,family,genus,species,1",
																baseURL = "https://www.worldplants.de/",
																searchStr ="world-ferns/ferns-and-lycophytes-list?name=",
																defaultSuffix = "",
																defaultTitle = "World Ferns"
	}
}
data.worldferns.genus = function(genus)
	local title = addAuthority("''" .. genus .. "''")
	local genusString = genus 
	if templateArgs['authority'] then genusString = genus .. "-" .. templateArgs['authority'] end
	local url = data.worldferns.customArgs['baseURL'] .. data.worldferns.customArgs['searchStr'] ..  genusString
	return title, url  
end
data.worldferns.species = function(genus, species)
	local title = addAuthority("''" .. genus .. " " .. species .. "''")
	local url = data.worldferns.customArgs['baseURL'] .. data.worldferns.customArgs['searchStr'] .. genus .. "-" .. species .. " " .. (templateArgs['authority'] or "")
	return title, url  
end
--[[Plants of the World online
				http://powo.science.kew.org/taxon/urn:lsid:ipni.org:names:30003057-2  -- use id
				http://powo.science.kew.org/?q=Selaginellaceae                        -- use search
				http://powo.science.kew.org/?family=Selaginellaceae                   -- can also use family= [gets same result as q=]
				http://powo.science.kew.org/?genus=Selago                             -- or genus
				http://powo.science.kew.org/?genus=Selago&species=abietina            -- or genus + species
				http://powo.science.kew.org/?genus=Selago&f=accepted_names            -- filter for accepted names
				http://powo.science.kew.org/?genus=Selago&f=genus_f                   -- filter for genus (no species selected)
				http://powo.science.kew.org/?genus=Selago&f=genus_f%2Caccepted_names  -- filter for genus and accepted names
				http://powo.science.kew.org/?page.size=480&f=family_f%2Caccepted_names -- list of accepted families
				-- all these searches get the search result (no apparent way to target the article when unique)
]]
data.POWO = {
	citationArgs = {
		website="[[Plants of the World Online]]",
		publisher="Royal Botanic Gardens, Kew",
		--postscript = 'none',
	},
	customArgs = { exclude = "id,authority,family,genus,species,1",
																baseURL = "http://powo.science.kew.org/taxon/",
																searchStr ="urn:lsid:ipni.org:names:",
																defaultSuffix = "",
																defaultTitle = "Plants of the World Online"
	}
	--id = function(id) return p.genericIdCitation (frame, title, url)
}
--[[ http://powo.science.kew.org/taxon/urn:lsid:ipni.org:names:30003057-2 ]]
data.POWO.id = function(id)
	local id = data.POWO.getValidID()
	if not id then return data.POWO.error() end
				local title = id                                                                          -- as default value
	local url = data.POWO.customArgs['baseURL'] .. data.POWO.customArgs['searchStr'] .. id
				return title, url  
end
data.POWO.family = function(family)
	local title = addAuthority(family)
	local id = templateArgs['id']
	if not id then return data.POWO.error() end
	local url = data.POWO.customArgs['baseURL'] .. data.POWO.customArgs['searchStr'] .. id
				return title, url  
end
data.POWO.genus = function(genus)
	local title = addAuthority("''" .. genus .. "''")
	local id = data.POWO.getValidID()
	if not id then return data.POWO.error() end
	local url = data.POWO.customArgs['baseURL'] .. data.POWO.customArgs['searchStr'] .. id
				return title, url  
end
data.POWO.species = function(genus,species)
	local title = addAuthority("''" .. genus .. " " .. species .. "''")
	local id = data.POWO.getValidID()
	if not id then return data.POWO.error() end
	local url = data.POWO.customArgs['baseURL'] .. data.POWO.customArgs['searchStr'] ..id
				return title, url  
end
data.POWO.getValidID = function()
	local id = templateArgs['id']
	if id then 
		return string.gsub( id, "urn:lsid:ipni.org:names:", "") -- don't want this twice
	end
	return nil
end
data.POWO.error = function()
	return '<span style="color:red">Requires id and one of title, family, genus or species parameters</span>'
end
--[[Gouda, E.J., Butcher, D. & Gouda, C.S. (cont.updated) 
Encyclopaedia of Bromeliads, Version 4. http://bromeliad.nl/encyclopedia/ Utrecht University Botanic Gardens
]]
data.bromeliad = {
	citationArgs = {
		last1="Gouda", first1="E.J.",
		last2="Butcher", first2="D.",
		last3="Gouda", first3="C.S",
		website="[[Encyclopaedia of Bromeliads]]",
		version="Version 4",
		publisher="Utrecht University Botanic Gardens",
		--postscript = 'none',
	},
	customArgs = { exclude = "id,authority,family,genus,species,list,1",
																baseURL = "https://bromeliad.nl/",
																searchStr ="encyclopedia/index.php?find=",
																defaultSuffix = "",
																defaultTitle = "Encyclopaedia of Bromeliads, Version 4"
	}
	--id = function(id) return p.genericIdCitation (frame, title, url)
}
--[[ https://bromeliad.nl/encyclopedia/index.php?find=Hylaeaicum ]]
data.bromeliad.search = function(search)
				local title = search                                                                          -- as default value
	local url = data.bromeliad.customArgs['baseURL'] .. data.bromeliad.customArgs['searchStr'] .. search
				return title, url  
end
--[[ http://bromeliad.nl/species/Bromeliaceae ]]
data.bromeliad.taxon = function(taxon)
				local title = addAuthority(taxon)                                                                          -- as default value
	local url = data.bromeliad.customArgs['baseURL'] .. "species/" .. taxon
				return title, url  
end
--[[ genus ]]
data.bromeliad.genus = function(genus)
				local title = addAuthority("''" .. genus .. "''")                                                                          -- as default value
	local url = data.bromeliad.customArgs['baseURL'] .. "species/" .. genus
	if templateArgs['list'] == "species" then
								url = data.bromeliad.customArgs['baseURL'] .. "encyclopedia/brome.php?action=showSpeciesIndex&name=" .. genus .. "&flags="
				end
				return title, url  
end
--[[  ]]
data.bromeliad.species = function(genus, species)
				local title = addAuthority("''" .. genus .. " " .. species .. "''")                                                                          -- as default value
	local url = data.bromeliad.customArgs['baseURL'] .. "species/" .. genus .. "/" .. species 
				return title, url  
end
--[[ https://bromeliad.nl/encyclopedia/brome.php?action=showTaxon&id=10093 ]]
data.bromeliad.id = function(id)
				local title = id                                                                          -- as default value
	local url = data.bromeliad.customArgs['baseURL'] .. "encyclopedia/brome.php?action=showTaxon&id=" .. id
				return title, url  
end
--[[GRIN 
	Cite as: USDA, Agricultural Research Service, National Plant Germplasm System. 2021. Germplasm Resources Information Network (GRIN Taxonomy). National Germplasm Resources Laboratory, Beltsville, Maryland.
	URL: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomyfamily?type=tribe&id=1571. Accessed 27 October 2021. 
	Family record: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomyfamily?id=440
				Genus list: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomygenuslist?id=440&type=family
	Subfamily record: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomyfamily?type=subfamily&id=1507
				Genus list: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomygenuslist?id=3265&type=subfamily
	Tribe record: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomyfamily?type=tribe&id=1551 (Millettieae)
				Genus list: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomygenuslist?id=1551&type=tribe
	Subtribe record: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomyfamily?type=subtribe&id=1507
				Genus list: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomygenuslist?id=1507&type=subtribe
	Genus record: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomygenus?id=191 (Genus Adenodolichos Harms)
			Species list: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomyspecieslist?id=191&type=genus
	Species record: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomydetail?id=489203 ( Adenodolichos paniculatus)
	
]]
data.GRIN = {     
	citationArgs = {
		website="[[Germplasm Resources Information Network]] (GRIN)",
		publisher="[[Agricultural Research Service]] (ARS), [[United States Department of Agriculture]] (USDA)",
		--postscript = 'none',
	},
	customArgs = { exclude = "id,authority,family,genus,species,1",
																baseURL = "https://npgsweb.ars-grin.gov/gringlobal",
																searchStr ="/taxon/taxonomydetail?",                             -- for species record
																defaultSuffix = "",
																defaultTitle = "GRIN-Global"
	}
	--id = function(id) return p.genericIdCitation (frame, title, url)
}
data.GRIN.id = function(id)
				local title = data.GRIN.customArgs['defaultTitle'] .. ' ' .. id
				local url = data.GRIN.customArgs['baseURL'] .. data.GRIN.customArgs['searchStr'] .. id
				return title, url  
end
-- IPNI
--→ "Meconopsis Vig." International Plant Names Index (IPNI). Royal Botanic Gardens, Kew.
---  https://www.ipni.org/n/30149252-2
--- as {{IPNI |id=30149252-2 |taxon=((Meconopsis |authority=Vig.))}} 
data.IPNI = {     
	citationArgs = {
		website="[[International Plant Names Index]] (IPNI)",
		publisher="Royal Botanic Gardens, Kew",
		--postscript = 'none',
	},
	customArgs = { exclude = "id,authority,family,genus,species,1",
																baseURL = "https://www.ipni.org",
																searchStr ="/n/",
																defaultSuffix = "",
																defaultTitle = "IPNI"
	}
	--id = function(id) return p.genericIdCitation (frame, title, url)
}
data.IPNI.id = function(id)
				local title = id
				local url = data.IPNI.customArgs['baseURL'] .. data.IPNI.customArgs['searchStr'] .. id
				return title, url  
end
data.IPNI.species  = function(genus, species)  return data.IPNI.taxon(genus .. " " .. species, "TITLE_ITALICS") end
data.IPNI.genus  = function(genus)  return data.IPNI.taxon(genus, "TITLE_ITALICS") end
data.IPNI.taxon = function(taxon, italics)
	local title = taxon 
	if italics then title = "''" .. title .. "''"  end
	title = addAuthority(title)
--[[ if templateArgs['authority'] then
		title = title .. " " .. templateArgs['authority']
		title = string.gsub( title, "(.*%.)$", "((%1))")  -- if authority ends in "." enclose ((title)) to prevent removal
	end ]]
	local url = data.IPNI.customArgs['baseURL'] .. data.IPNI.customArgs['searchStr'] .. templateArgs['id']
				return title, url  
end
--[[World Flora Online 
					http://www.worldfloraonline.org/taxon/wfo-4000012284  -- id
]]
data.WFO = {
	citationArgs = {
		website="[[World Flora Online]]",
		--publisher="Missouri Botanical Gardens",
		--postscript = 'none',
	},
	customArgs = { exclude = "id,family,genus,species,authority,1",
																baseURL = "http://www.worldfloraonline.org",
																searchStr ="/taxon/wfo-",                                       -- not strictly search string
																defaultSuffix = "",
																--defaultTitle = "World Flora Online"
																defaultTitle = "An Online Flora of All Known Plants"
	}
}
data.WFO.id = function(id)
--[[ http://www.worldfloraonline.org/taxon/wfo-4000012284 
				]]
				local title = id
				local url = data.WFO.customArgs['baseURL'] .. data.WFO.customArgs['searchStr'] .. id
				return title, url  
end
data.WFO.family = function(family)
	local title = addAuthority(family) 
	local url = data.WFO.customArgs['baseURL'] .. data.WFO.customArgs['searchStr'] .. templateArgs['id']
				return title, url  
end
data.WFO.genus = function(genus)
	local title = addAuthority("''" .. genus .. "''") 
	local url = data.WFO.customArgs['baseURL'] .. data.WFO.customArgs['searchStr'] .. templateArgs['id']
				return title, url  
end
data.WFO.species = function(genus,species)
	local title = addAuthority("''" .. genus .. " " .. species .. "''") 
	local url = data.WFO.customArgs['baseURL'] .. data.WFO.customArgs['searchStr'] .. templateArgs['id']
				return title, url  
end
data.WFO.error = function()
	return "Requires id and title parameters"
end
data.Tropicos = {
	citationArgs = {
		website="[[Tropicos]]",
		--publisher="Missouri Botanical Gardens",
		--postscript = 'none',
	},
	customArgs = { exclude = "id,1",
																baseURL = "http://legacy.tropicos.org/Name/",
																searchStr ="",
																defaultSuffix = "",
																defaultTitle = "Tropicos"
	}
}
data.Tropicos.id = function(id)
--[[ hhttp://legacy.tropicos.org/Name/100444532 
				]]
				local title = id
				local url = data.Tropicos.customArgs['baseURL'] .. data.Tropicos.customArgs['searchStr'] .. id
				return title, url  
end
data.Tropicos.error = function()
	return "Requires id and title parameters"
end
data.FNA = {
	citationArgs = {
														website="[[Flora of North America]]",
														--publisher="http://www.efloras.org",
														--postscript = 'none',
	},
	customArgs = { exclude = "id,1",
																baseURL = "http://www.efloras.org/florataxon.aspx",
																searchStr ="?flora_id=1&taxon_id=",
																defaultSuffix = "",
																defaultTitle = "Flora of North America"
	}
	--id = function(id) return p.genericIdCitation (frame, title, url)
}
data.FNA.id = function(id)
--[[ http://www.efloras.org/florataxon.aspx?flora_id=1&taxon_id=125683
				]]
				local title = id
				local url = data.FNA.customArgs['baseURL'] .. data.FNA.customArgs['searchStr'] .. id
				return title, url  
end
data.FNA.error = function()
	return "Requires id and title parameters"
end
-- ATRP: Australian Tropical Rainforest Plants 
data.ATRP = {
	citationArgs = {
														website="[[Australian Tropical Rainforest Plants]]",
														publisher="[[Commonwealth Scientific and Industrial Research Organisation]] (CSIRO)",
														version = "Edition 8",
								year = 2020,
														--postscript = 'none',
														last1= "Zich", first1="F. A.", 
														last2= "Hyland",  first2= "B. P. M.", ['author2-link']="Bernard Hyland",
														last3= "Whiffin", first3= "T.", 
														last4= "Kerrigan",  first4= "R.A.",
														--['display-authors']=3,
	},
	customArgs = { exclude = "genus, species,authority, id,1",
																baseURL = "https://apps.lucidcentral.org/rainforest",
																searchStr ="/text/entities/",
																defaultSuffix = ".htm",
																defaultTitle = "[[Australian Tropical Rainforest Plants]]"
	}
	--id = function(id) return p.genericIdCitation (frame, title, url)
}
data.ATRP.species = function(genus,species)
--[[ https://apps.lucidcentral.org/rainforest/text/entities/buckinghamia_celsissima.htm
				]]
				local title = addAuthority("''" .. genus .. " " .. species .. "''") --"''" .. genus .. " " .. species .. "''"
				local url = data.ATRP.customArgs['baseURL'] .. data.ATRP.customArgs['searchStr'] .. genus .. "_" .. species .. data.ATRP.customArgs['defaultSuffix']
				return title, url  
end
data.ATRP.error = function()
	return "Requires genus and species parameters"
end
-- ============================= Mosses (Goffinet's site) =================================================-- for species in taxon; for species assessments, us {{cite iucn}}
-- https://bryology.uconn.edu/classification/#Hypnanae
-- https://bryology.uconn.edu/classification/#Bryales
data.goffinet = {
	citationArgs = {
		first1="B.", last1="Goffinet", 
		first2="W.R.", last2="Buck",
		website="Classification of extant moss genera"
		--publisher="[[xxx]]"
	},
	customArgs = { exclude="family,genus,species,taxon,id,1",
																baseURL = "https://bryology.uconn.edu/classification/",
																searchString = "#",
																searchSuffix = "",
																defaultSuffix = "",
																defaultTitle="Classification of the Bryophyta"
	} 
}
data.goffinet.genus  = function(genus)  return data.goffinet.taxon(genus, "GENUS") end
data.goffinet.family = function(family) return data.goffinet.taxon(family, "FAMILY") end
data.goffinet.order  = function(order)  return data.goffinet.taxon(order, "ORDER") end
data.goffinet.taxon  = function(taxon, rank)
				local title = firstToUpper(taxon)
				if rank == "GENUS" then title = "''" .. title .. "''" end
				if not (rank == "GENUS" or rank == "FAMILY") then  -- upper case anchors for orders and above
					if taxon ~= "Bryanae" and taxon ~= "Hypnanae" and taxon ~= "Bryales" and taxon ~= "Bryidae" then -- check for exceptions (inconsistencies at website)
						taxon = taxon:upper()
					end
				end
				local url = data.goffinet.customArgs['baseURL'] .. data.goffinet.customArgs['searchString'] .. taxon .. data.goffinet.customArgs['searchSuffix']
				return title, url
end 
--[[ AlgaeBase
				taxonomy browser url (Volvox) = https://www.algaebase.org/browse/taxonomy/?id=6898
				genus article url (Volvox) =  https://www.algaebase.org/search/genus/detail/?genus_id=43497 (different id)
				genus article url (Torodinium)= https://www.algaebase.org/search/genus/detail/?genus_id=44698
				Please cite this record as:   M.D. Guiry in Guiry, M.D. & Guiry, G.M. 2020. AlgaeBase. 
																																		World-wide electronic publication, National University of Ireland, Galway. 
																																		http://www.algaebase.org; searched on 10 May 2020.              
]]
data.AlgaeBase = {
	citationArgs = {
													website="[[AlgaeBase]]",
																['editor1-last']="Guiry", ['editor1-first']="M.D.",
																['editor2-last']="Guiry", ['editor2-first']="G.M.",
													publisher="National University of Ireland, Galway",
	},
	customArgs = { exclude = "id,1,genus_id,species_id,spid,genid",
																baseURL = "https://www.algaebase.org/",
																searchStr ="browse/taxonomy/?id=",
																defaultSuffix = "",
																defaultTitle = "AlgaeBase"
	}
}
data.AlgaeBase.id = function(id)
--[[ https://www.algaebase.org/browse/taxonomy/?id=6898 (id for taxonomy page)
				]]
				local title = id
				local url = data.AlgaeBase.customArgs['baseURL'] .. data.AlgaeBase.customArgs['searchStr'] .. id
				return title, url  
end
data.AlgaeBase.genid = function(genid)
--[[ https://www.algaebase.org/search/genus/detail/?genus_id=43497 (different id for genus page)
				]]
				local title = genid
				local url = data.AlgaeBase.customArgs['baseURL'] .. "search/genus/detail/?genus_id=" .. genid
				return title, url  
end
data.AlgaeBase.spid = function(spid)
--[[ https://www.algaebase.org/search/species/detail/?species_id=52713 (id for species page)
				]]
				local title = spid
				local url = data.AlgaeBase.customArgs['baseURL'] .. "search/species/detail/?species_id=" .. spid
				return title, url  
end
data.AlgaeBase.error = function()
	return "Requires id and title parameters"
end
--############################## General Functions ########################################
local function getArgs (frame, args)
	local parents = mw.getCurrentFrame():getParent()
		
	for k,v in pairs(parents.args) do
		--check content
		if v and v ~= "" then
			args[k]=v --parents.args[k]
		end
	end
	for k,v in pairs(frame.args) do
		--check content
		if v and v ~= "" then
			args[k]=v 
		end
	end
end
local function initialise(frame, sourceDB)
	
	target=sourceDB
	templateArgs = sourceDB.citationArgs -- get custom arguments for target (fishbase, cof etc
				
	getArgs(frame, templateArgs) -- get template arguments from parent frame and frane
	
	
	local url = (target.customArgs['baseURL'] or "") .. (target.customArgs['defaultSuffix'] or "")
	local title = target.customArgs['defaultTitle'] or ""
	return title, url
end 
-- moved up top for scope
local function firstToUpper2(str)
				return (str:gsub("^%l", string.upper))
end
-- clear template arguments that won't be recognised by {{cite web}}
local function clearCustomArgs()
	
	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(frame, title, url)
				
				-- set url and title if not provided (template parameters override above)
				if not templateArgs['url'] and url then
						templateArgs['url']= url
				end
				local title = templateArgs['title'] or templateArgs['título']
				if not title and title then
												templateArgs['title'] = title
												templateArgs['título'] = ''
				end
				clearCustomArgs()--blank template parameters not for cite web
	
	local citeTemplate = 'citar web'          -- use Template:Cite web unless specified
	--if target.citeTemplate then citeTemplate = target.citeTemplate end
	return frame:expandTemplate{ title = citeTemplate, args = templateArgs  }
end
-- p.CiteBook
-- for reasons of consisitency within BioRef/FishRef the title parameter is the section-title of {{cite book}}
p.citeBook = function(frame, 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 {{#if:{{{text|{{{dq|}}}}}}|&dq={{urlencode:{{{text|{{{dq|}}}}}}}}}}
						if templateArgs['q'] then searchStr = "&q=" .. mw.text.encode( templateArgs['q'] ) end
						-- search #if:{{{keywords|{{{q|}}}}}}|&q={{urlencode:{{{keywords|{{{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 = 'citar livro'          -- use Template:Cite web unless specified
	--if target.citeTemplate then citeTemplate = target.citeTemplate end
	return frame: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(frame) 
	local msw = require('Module:FishRef/MSW')
	initialise(frame, msw.MSW3)
	return msw.MSW3.main(frame,templateArgs)
end
p.MSW3merged = function(frame) 
	local data = require('Module:FishRef/MSW')
	return p._main(frame, data.MSW3)
end
p.MSW3_standalone = function(frame) 
	
	local data = require('Module:FishRef/MSW')
	initialise(frame, 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 frame:expandTemplate{ title = 'citar livro', args = templateArgs  }
end
--########################### Functions for access (using invoke) ##############################################
--================ Fishbase, Catalog of Fishes (cof) ================
p.fishbase    = function(frame) return p._main(frame, data.fishbase) end
p.cof         = function(frame) return p._main(frame, data.cof) end 
p.fotw5       = function(frame) return p._main(frame, data.fotw5) end 
--=================== ASW6, AmphibiaWeb, ReptileDB
p.reptileDB   = function(frame) return p._main(frame, data.reptileDB) end
p.ASW6        = function(frame) return p._main(frame, data.ASW6) end
p.amphibiaweb = function(frame) return p._main(frame, data.amphibiaweb) end
--=========== Birds
p.HBWa        = function(frame) return p._main(frame, data.HBWalive) end
p.HBWalive    = function(frame) return p._main(frame, data.HBWalive)  end
p.IOC         = function(frame) return p._main(frame, data.IOC) end
--======= Mammals
p.asm         = function(frame) return p._main(frame, data.asm) end
-- MSW3 has custom handling (see above)
--=========== Other
p.fossilworks = function(frame) return p._main(frame, data.fossilworks) end
p.worms       = function(frame) return p._main(frame, data.WoRMS) end
p.WoRMS       = function(frame) return p._main(frame, data.WoRMS) end
p.col         = function(frame) return p._main(frame, data.col) end 
--fallback = function() return "hello" end
--#########################################################
p.main = function(frame) 
	local source = mw.text.trim(frame.args[1])
	
	if source == "MSW3" then return p.MSW3(frame) end
	
	if source == "ref" or source == "reference" then source = "Reference" end   -- aliases
	if source == "Reference" then return p.Reference(frame) end
				
				if source == "HBWa" then source = "HBWalive" end   -- aliases
				if source == "powo" then source = "POWO" end   -- aliases
	--return p[source]['test']
	if source == "fishbase" 
		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 == "AlgaeBase"
		-- and so on
					then return p._main(frame,data[source])
	else
		-- 
		-- is there a point in the default if it needs the named object/table?
		return p._main(frame,data[source])
	end
end
p._main = function(frame, source) 
				--TODO in modular version source will be provided in frame arguments 
				--local source = mw.getCurrentFrame():getParent().args[1]
				local chapterParams = {} -- used for cite book (only MSW3 at moment)
				
				if not source then return "Error: unrecognised source." end
				
				local title, url = initialise(frame, source)
				
				--taxon related parameters
				local genus, species, subspecies
				
				if source.db ~= "col" then                             -- col legacy uses positional parameters differently
					genus, species, subspecies = getGenusSpecies()             
				end
				
				local family = templateArgs['family']
				local order = templateArgs['order']
				local taxon = templateArgs['taxon']
	
	local id = templateArgs['id']                                       --id related parameters
	local spid = templateArgs['spid'] or templateArgs['species_id']
	local genid = templateArgs['genid'] or templateArgs['genus_id']
	local citation = templateArgs['citation'] 
				local collection = templateArgs['collection'] or templateArgs['collection_no'] 
	local search = templateArgs['search']
				local mode, value
				
				-- the functions
				if genus and species and source.species then
					title, url = source.species(genus,species,subspecies)
				else -- functions with just their own name as parameter
					
					if genus then mode = "genus"; value = genus 
					elseif family then mode = "family"; value = family
					elseif order then mode = "order"; value = order
					elseif taxon then mode = "taxon"; value = taxon
					elseif id then mode = "id"; value = id
					elseif spid then mode = "spid"; value = spid
					elseif genid then mode = "genid"; value = genid 
								elseif search then mode = "search"; value = search 
								elseif citation then mode = "citation"; value = citation 
								elseif collection then mode = "collection"; value = collection 
					else
						-- no suitable parameter (use default page)
						if source.default then
							title, url, chapterParams = source.default(title, url)
						end
					end
				end
				if mode then
					if source[mode] then
						title, url, chapterParams = source[mode](value)  
					elseif data.default[mode] then
						title, url, chapterParams = data.default[mode](value, source)
					else
						if source.error then return source.error() end             -- custom error message
									return "Error: parameter not supported for this source" .. " (" .. mode .. ")"
					end
				else 
					-- if no mode then use the default title and url set by initialize()
				end
				if source.citeTemplate == "Citar livro" then
					return p.citeBook(frame, title, url, chapterParams)
				end
	return p.citeWeb(frame, title, url)
	
end  -- End the function.
p.Reference = function(frame)
	
	local refs = require('Module:FishRef/refs')
	getArgs(frame, templateArgs)
	
	if templateArgs[2] then
		local reference = mw.text.trim(templateArgs[2])
		if reference ~= "" and refs[reference] then 
			if templateArgs['pages'] then 
				refs[reference] = refs[reference]:gsub("}}", "|pages="..templateArgs['pages'].."}}")
				refs[reference] = refs[reference]:gsub("|pages=[^|{}%[%]]*(|[^|{}}%[%]]*|pages=)", "%1")
			end
						if templateArgs['expand'] and templateArgs['expand']=='no' or templateArgs['raw']  then
							return refs[reference]
						else
							return frame:preprocess(refs[reference])
						end
					else
						return 'Reference not found: "' .. templateArgs[2] .. '"'
		end
	end
	return "Reference parameter missing."
end -- End the function.
-- All modules end by returning the variable containing its functions to Wikipedia.
return p