Jump to content
Wikipedia The Free Encyclopedia

Module:Cite taxon

From Wikipedia, the free encyclopedia
(Redirected from Module:FishRef)
Module documentation[view] [edit] [history] [purge]
Warning This Lua module is used on approximately 30,000 pages and changes may be widely noticed. Test changes in the module's /sandbox or /testcases subpages, or in your own module sandbox. Consider discussing changes on the talk page before implementing them.

This module was created to generate {{cite web }} references to the Catalog of Fishes database. The capabilities were extended to handle other fish-related references and the module renamed FishRef. Further extension to cover taxonomy databases handling non-fish taxa led to creation of template {{BioRef }}. and {{Cite taxon }} templates and module name was changed to Cite taxon to better describe its function of handling citations for a wide variety taxonomy databases.

The module provides a wrapper to the citation template {{cite web }}, which means that the references can also include other parameters supported by the CS1/CS2 citation system. These include |access-date=, which is recommended, reference style formating parameters such as |mode=cs1|2 or |name-list-style=vanc, the archiving parameters |url-status=, |archive-url= and |archive-date=, and other general parameter such as |quote=. The template supplies authors or editors for some databases, but for others these can be added using the cite web parameters |author=, |last=, |first= or the editor equivalents.

Templates using the module

The module is used with {{Catalog of Fishes }}, which was designed to replace a series of templates that were originally written in the Wikipedia template language: {{Cof genus }}, {{Cof family }}, {{Cof species }}, {{Cof record }}.

Other templates using the module:

* The module currently handles ASW6, Amphibiaweb, Reptile Database, IOC, Avibase, TiF, WoRMS, POWO, GRIN, IPNI, World Plants, World Ferns, Tropicos, FNA, ATRF, Goffinet's Bryophyte classification, Algaebase, Paleobiology DB, ITIS

Usage of module

General form: {{#invoke:Cite taxon|main|db|parameters}}

Examples: {{#invoke:Cite taxon|main|cof|parameters}}, {{#invoke:Cite taxon|main|fishbase|parameters}}, {{#invoke:Cite taxon|main|reptileDB|parameters}}, {{#invoke:Cite taxon|main|ASW6|parameters}}, {{#invoke:Cite taxon|main|POWO|parameters}}, etc.

The module stores information about each database in a data table (e.g. data.cof for Catalog of Fishes). The table has a CitationArgs table, for parameters to be passed to {{cite web }}, a CustomArgs table for parameters used for internal workings to set other {{cite web }} parameters, and one or more custom functions handling different types of citation parameter. Typical functions are id, species, genus, family, order, and taxon. Which functions are needed depend on the options provided by the external database, some use a common format with an id for all links, others have taxon-specific links.

General rules

Different databases provide different options so uniformity is not possible. Some provide links that allow handling of species, genera, families, orders and other taxon ranks using the taxon names. This allows specific function to handle different taxa. Other just provide an id which can be used to generate the url, but needs a title. The following are the general rules for what functions are available:

  1. All databases can take a |title= and |url=. The templates then just add the general citation information about the website.
  2. Many take a |id=. The template will complete the url and add a default title, although adding a title is recommended.
  3. Some databases allow taxon names that can be used with |genus=, |family=, |order= or |taxon=
  4. Species can also often be handled when given |genus= and |species=, and in some cases also |subspecies=. These can usually be added as position parameters, but it is recommended that the parameter names are given


Examples of templates using the Module:FishRef

Catalog of Fishes

Examples using {{Catalog of Fishes }}

Template usage Results
{{Catalog of Fishes |family=Xiphiidae |list=species |access-date=7 June 2018}}
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "Species in the family Xiphiidae". Catalog of Fishes . California Academy of Sciences . Retrieved 7 June 2018.
{{Catalog of Fishes |family=Cyprinidae |access-date=7 June 2018}}
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "Genera in the family Cyprinidae". Catalog of Fishes . California Academy of Sciences . Retrieved 7 June 2018.
{{Catalog of Fishes |family=Salmonidae |list=genus |access-date=7 June 2018}}
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "Genera in the family Salmonidae". Catalog of Fishes . California Academy of Sciences . Retrieved 7 June 2018.
{{Catalog of Fishes |genus=Vinagarra |access-date=7 June 2018}}
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "Species in the genus Vinagarra". Catalog of Fishes . California Academy of Sciences . Retrieved 7 June 2018.
{{Catalog of Fishes |genus=Vinagarra |species=elongata |access-date=7 June 2018}} 
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "Species related to Vinagarra elongata". Catalog of Fishes . California Academy of Sciences . Retrieved 7 June 2018.
{{Catalog of Fishes |genus=Abbottina |species=rivularis |access-date=7 June 2018}}
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "Species related to Abbottina rivularis". Catalog of Fishes . California Academy of Sciences . Retrieved 7 June 2018.
{{Catalog of Fishes |genus=Tylognathus |species=sinensis |access-date=7 June 2018}}
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "Species related to Tylognathus sinensis". Catalog of Fishes . California Academy of Sciences . Retrieved 7 June 2018.
{{Catalog of Fishes |genid=150 |access-date=8 June 2018}} 
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "genid=150". Catalog of Fishes . California Academy of Sciences . Retrieved 8 June 2018.
{{Catalog of Fishes |genid=150 |title=Syngnathus |access-date=8 June 2018}} 
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "Syngnathus". Catalog of Fishes . California Academy of Sciences . Retrieved 8 June 2018.
{{Catalog of Fishes|spid=14756 |access-date=8 June 2018}}
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "spid=14756". Catalog of Fishes . California Academy of Sciences . Retrieved 8 June 2018.
{{Catalog of Fishes |spid=14756 |title=Syngnathus abaster |access-date=8 June 2018}}
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "Syngnathus abaster". Catalog of Fishes . California Academy of Sciences . Retrieved 8 June 2018.

Examples using {{Cof family }}, {{Cof genus }}, {{Cof species }} and {{Cof record }} templates

Template usage Results
{{Cof family |Xiphiidae|access-date=7 June 2018}}
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "Species in the genus Xiphiidae". Catalog of Fishes . California Academy of Sciences . Retrieved 7 June 2018.
{{Cof family |family=Xiphiidae |list=species |access-date=7 June 2018}}
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "Species in the family Xiphiidae". Catalog of Fishes . California Academy of Sciences . Retrieved 7 June 2018.
{{Cof family |family=Cyprinidae |access-date=7 June 2018}}
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "Genera in the family Cyprinidae". Catalog of Fishes . California Academy of Sciences . Retrieved 7 June 2018.
{{Cof family |family=Salmonidae |list=genus |access-date=7 June 2018}}
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "Genera in the family Salmonidae". Catalog of Fishes . California Academy of Sciences . Retrieved 7 June 2018.
{{Cof genus |Garra|access-date=7 June 2018}}
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "Species in the genus Garra". Catalog of Fishes . California Academy of Sciences . Retrieved 7 June 2018.
{{Cof genus |genus=Vinagarra |access-date=7 June 2018}}
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "Species in the genus Vinagarra". Catalog of Fishes . California Academy of Sciences . Retrieved 7 June 2018.
{{Cof species |genus=Vinagarra |species=elongata|access-date=7 June 2018}} 
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "Species related to Vinagarra elongata". Catalog of Fishes . California Academy of Sciences . Retrieved 7 June 2018.
{{Cof species |Abbottina|rivularis|access-date=7 June 2018}}
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "Species related to Abbottina rivularis". Catalog of Fishes . California Academy of Sciences . Retrieved 7 June 2018.
{{Cof species |Tylognathus|sinensis|access-date=7 June 2018}}
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "Species related to Tylognathus sinensis". Catalog of Fishes . California Academy of Sciences . Retrieved 7 June 2018.
{{Cof record |genid=150 |title=Syngnathus |access-date=8 June 2018}} 
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "Syngnathus". Catalog of Fishes . California Academy of Sciences . Retrieved 8 June 2018.
{{Cof record |spid=14756 |title=Syngnathus abaster |access-date=8 June 2018}}
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "Syngnathus abaster". Catalog of Fishes . California Academy of Sciences . Retrieved 8 June 2018.
{{Cof record |genid=150 |access-date=8 June 2018}} 
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "genid=150". Catalog of Fishes . California Academy of Sciences . Retrieved 8 June 2018.
{{Cof record |spid=14756 |access-date=8 June 2018}}
Eschmeyer, William N.; Fricke, Ron & van der Laan, Richard (eds.). "spid=14756". Catalog of Fishes . California Academy of Sciences . Retrieved 8 June 2018.

Using {{FishBase/sandbox }}

Template usage Results
Species with positional parameters]:
{{FishBase/sandbox|Danio|rerio|year=2018}} 
Froese, Rainer; Pauly, Daniel, eds. (2018). "Danio rerio". FishBase .
Subspecies with position parameters:
{{FishBase/sandbox|Emmelichthys|nitidus|cyanescens}} 
Froese, Rainer; Pauly, Daniel (eds.). "Emmelichthys nitidus cyanescens". FishBase .
Species with named parameters:
{{FishBase/sandbox|genus=Danio|species=rerio}} 
Froese, Rainer; Pauly, Daniel (eds.). "Danio rerio". FishBase .
Subspecies with named parameters:
{{FishBase/sandbox|genus=Emmelichthys|species=nitidus|subspecies=cyanescens}} 
Froese, Rainer; Pauly, Daniel (eds.). "Emmelichthys nitidus cyanescens". FishBase .
Genus:
{{FishBase/sandbox|genus=Emmelichthys}}
Froese, Rainer; Pauly, Daniel (eds.). "Species in genus Emmelichthys". FishBase .
Family:
{{FishBase/sandbox|family=Percidae}}
Froese, Rainer; Pauly, Daniel (eds.). "Family Percidae". FishBase .
Order:
{{FishBase/sandbox|order=Perciformes|access-date=19 November 2018|mode=cs2}}
Froese, Rainer; Pauly, Daniel (eds.), "Order Perciformes", FishBase , retrieved 19 November 2018

Using {{BioRef }}

Fishbase:

Template usage Results
Species with positional parameters:
{{BioRef|fishbase|Danio|rerio}}
Froese, Rainer; Pauly, Daniel (eds.). "Danio rerio". FishBase .
Subspecies with positional parameters:
{{BioRef|fishbase|Emmelichthys|nitidus|cyanescens}}
Froese, Rainer; Pauly, Daniel (eds.). "Emmelichthys nitidus cyanescens". FishBase .
Species with named parameters:
{{BioRef|fishbase|genus=Danio|species=rerio}}
Froese, Rainer; Pauly, Daniel (eds.). "Danio rerio". FishBase .
Subspecies with named parameters:
{{BioRef|fishbase|genus=Emmelichthys|species=nitidus|subspecies=cyanescens}}
Froese, Rainer; Pauly, Daniel (eds.). "Emmelichthys nitidus cyanescens". FishBase .
Genus:
{{BioRef|fishbase|genus=Emmelichthys}}
Froese, Rainer; Pauly, Daniel (eds.). "Species in genus Emmelichthys". FishBase .
Family:
{{BioRef|fishbase|family=Percidae}}
Froese, Rainer; Pauly, Daniel (eds.). "Family Percidae". FishBase .
Order:
{{BioRef|fishbase|order=Perciformes|access-date=19 November 2018|mode=cs2}}
Froese, Rainer; Pauly, Daniel (eds.), "Order Perciformes", FishBase , retrieved 19 November 2018


Amphibian Species of the World (ASW6)

Template usage Results
Default page with family listing:
{{BioRef|ASW6 |access-date=27 September 2019}}
Frost, Darrel R. "ASW Home". Amphibian Species of the World, an Online Reference. Version 6.0. American Museum of Natural History, New York. Retrieved 27 September 2019.
Title + url:
{{BioRef|ASW6 |title=Hylidae Rafinesque, 1815|year=2019 |url=http://research.amnh.org/vz/herpetology/amphibia/Amphibia/Anura/Hylidae |access-date=27 September 2019}}
Frost, Darrel R. (2019). "Hylidae Rafinesque, 1815". Amphibian Species of the World, an Online Reference. Version 6.0. American Museum of Natural History, New York. Retrieved 27 September 2019.
Family (currently only works for Anura):
{{BioRef|ASW6 |family=Hylidae |year=2019 |access-date=27 September 2019}}
Frost, Darrel R. (2019). "Hylidae". Amphibian Species of the World, an Online Reference. Version 6.0. American Museum of Natural History, New York. Retrieved 27 September 2019.
Genus + species (named parameters)::
{{BioRef|ASW6 |genus=Chiromantis |species=cherrapunjiae |year=2019 |access-date=27 September 2019}} 
Frost, Darrel R. (2019). "Search for taxon: Chiromantis cherrapunjiae". Amphibian Species of the World, an Online Reference. Version 6.0. American Museum of Natural History, New York. Retrieved 27 September 2019.
Genus + species (positional parameters)::
{{BioRef|ASW6 | Chiromantis| cherrapunjiae |year=2019 |access-date=27 September 2019}}
Frost, Darrel R. (2019). "Search for taxon: Chiromantis cherrapunjiae". Amphibian Species of the World, an Online Reference. Version 6.0. American Museum of Natural History, New York. Retrieved 27 September 2019.
Note: the citation title can changed with |title=My title


AmphibiaWeb

Template usage Results
Default page with for interactive family listing:
{{BioRef|amphibiaweb |access-date=27 September 2019}}
"AmphibiaWeb Family Taxonomy". AmphibiaWeb. University of California, Berkeley. Retrieved 27 September 2019.
Title with url:
{{BioRef|amphibiaweb |title=Ranidae |year=2019 |url=https://amphibiaweb.org/lists/Ranidae.shtml |access-date=27 September 2019}}
"Ranidae". AmphibiaWeb. University of California, Berkeley. 2019. Retrieved 27 September 2019.
Family:
{{BioRef|amphibiaweb |family=Ranidae |year=2019 |access-date=27 September 2019}} 
"Ranidae". AmphibiaWeb. University of California, Berkeley. 2019. Retrieved 27 September 2019.
Genus + species (named parameters):
{{BioRef|amphibiaweb |genus=Altiphrynoides |species=malcolmi |year=2019 |access-date=27 September 2019}}
"Altiphrynoides malcolmi". AmphibiaWeb. University of California, Berkeley. 2019. Retrieved 27 September 2019.
Genus + species (positional parameters):
{{BioRef|amphibiaweb | Altiphrynoides | malcolmi |year=2019 |access-date=27 September 2019}}
"Altiphrynoides malcolmi". AmphibiaWeb. University of California, Berkeley. 2019. Retrieved 27 September 2019.
Note: the citation title can changed with |title=My title



Reptile database:

Template usage Results
Species:
{{BioRef|reptileDB |genus=Loxocemus |species=bicolor|access-date=22 November 2018}}
Uetz, P.; et al. (eds.). "Loxocemus bicolor". The Reptile Database . Retrieved 22 November 2018.
Species (positional parameters) with title:
{{BioRef|reptileDB |Python |natalensis |title=''Python natalensis'' SMITH, 1840|access-date=14 October 2019}}
Uetz, P.; et al. (eds.). "Python natalensis SMITH, 1840". The Reptile Database . Retrieved 14 October 2019.
Genus:
{{BioRef|reptileDB |genus=Cylindrophis|access-date=22 November 2018}}
Uetz, P.; et al. (eds.). "Cylindrophis". The Reptile Database . Retrieved 22 November 2018.
Use |taxon= parameter for higher taxa:
Family:
{{BioRef|reptileDB |taxon=Pythonidae|title=Species in Family Pythonidae|access-date=22 November 2018}}
Uetz, P.; et al. (eds.). "Species in Family Pythonidae". The Reptile Database . Retrieved 22 November 2018.
Other taxon (e.g. infraorder):
{{BioRef|reptileDB |taxon=Alethinophidia|access-date=22 November 2018}}
Uetz, P.; et al. (eds.). "Alethinophidia". The Reptile Database . Retrieved 22 November 2018.



ASM Mammal Diversity Database

Template usage Results
Family using |taxon= parameter:
{{BioRef|asm |order=Carnivora |access-date=28 February 2024 |mode=cs2}}
"Carnivora", ASM Mammal Diversity Database, American Society of Mammalogists , retrieved 28 February 2024
Family using |family= parameter:
{{BioRef|asm |family=Canidae |access-date=19 November 2018 |mode=cs2}}
"Canidae", ASM Mammal Diversity Database, American Society of Mammalogists , retrieved 19 November 2018
Genus using |genus= parameter:
{{BioRef|asm |genus=Ursus |access-date=19 November 2018}}
"Ursus". ASM Mammal Diversity Database. American Society of Mammalogists . Retrieved 19 November 2018.
Species using |id= parameter:
{{BioRef|asm |id=8541 |title=Sand cat|access-date=19 November 2018}}
"Sand cat". ASM Mammal Diversity Database. American Society of Mammalogists . Retrieved 19 November 2018.
Species with |genus= and |species= parameters:
{{BioRef|asm |genus=Panthera|species=leo |access-date=19 November 2018}}
"Panthera leo". ASM Mammal Diversity Database. American Society of Mammalogists . Retrieved 19 November 2018.
The above documentation is transcluded from Module:Cite taxon/doc. (edit | history)
Editors can experiment in this module's sandbox (edit | diff) and testcases (create) pages.
Subpages of this module.

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", ['editor2-link']="Daniel Pauly",
	--['last-author-amp'] ="yes",
 ['website'] = "[[FishBase]]",
	--['publisher'] = ""
	},
	customArgs = { exclude= "order, family,genus, species, subspecies, 1, 2, 3, 4, month",
	 baseURL = "http://www.fishbase.org/",
	 defaultTitle = "Search FishBase"
	},
}
data.fishbase.species = function(genus, species, subspecies)
		data.fishbase.version()
		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)
		data.fishbase.version()
		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) 
		data.fishbase.version()
		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) 
		data.fishbase.version()
		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.version = function() 
 local defaultDate = false
 if defaultDate then -- default month and year as original template (now not used)
	 local month = templateArgs['month'] or "April" -- default month 
	 local year = templateArgs['year'] or "2006" -- default year
	 --if isnumber(tostring(month)))
	 templateArgs['version'] = month .. " " .. year .. " version" 
	 templateArgs['year'] =year -- old template gave redundant version and year 
 else --But defaulting the date to April 2006 invites errors and isn't helpful
	 local month = templateArgs['month'] -- no default month 
	 local year = templateArgs['year']
	 if month and year then
	 if tonumber(month) then 
	 	local months = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }
	 	month = months[tonumber(month)] -- convert digital month to month name
	 end
	 	templateArgs['version'] = month .. " " .. year .. " version" -- set version if month and year provided
	 	templateArgs['year'] = nil -- don't use year as well as version
	 templateArgs['month'] = nil
 end
 end
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]
	-- newer: Uetz, P., Freed, P, Aguilar, R., Reyes, F., Kudera, J. & Hošek, J. (eds.) (2024) The Reptile Database, http://www.reptile-database.org, accessed [insert date here
	citationArgs = {
		--website="reptile-database.org",
		website="[[Reptile Database|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,
		['display-editors'] = 1 -- shows eds as Uetz et al as number of editors has increased and is date dependent
		
	},
	customArgs = { exclude = "taxon,species,genus,family,1,2,3",
	 defaultURL = "http://reptile-database.org/",
	 baseURL = "http://reptile-database.reptarium.cz/",
	 defaultTitle = "The Reptile Database"
	 
	}
}
data.reptileDB.species = function(genus, species)
	 data.reptileDB.getDate()
	 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)
	 data.reptileDB.getDate()
	 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)
	 data.reptileDB.getDate()
	 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
data.reptileDB.getDate = function()
 if templateArgs['date'] and templateArgs['year'] then
 templateArgs['access-date'] =	templateArgs['date'] .. " " .. templateArgs['year']
 templateArgs['date'] = nil
	 templateArgs['year'] = nil
 end
end
data.reptileDB.default = function()
	local url = data.reptileDB.customArgs['defaultURL'] 
	local title = data.reptileDB.customArgs['defaultTitle'] 
	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']="Frank", ['editor1-link']="Frank Gill (ornithologist)",
		['editor2-last']="Donsker", ['editor2-first']="David",
		['editor3-last']="Rasmussen", ['editor3-first']="Pamela C.", ['editor3-link']="Pamela C. Rasmussen", -- only shown 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 citation
	--	publisher="International Ornithological Congress" -- relationship confusing, see https://www.worldbirdnames.org/new/history/
	},
	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"
	 
	},
}
-- function not needed of not adding anything else
data.BOW.default2 = function( title, url) 
	 --data.BOW.citationArgs['version'] = "Version 1"
	 --mw.addWarning("testing BOW.default function")
	 return title, url
end
-- id works with the default function data.default.id (id, source)
data.BOW.id2 = function( id) 
 local url = data.IOC.customArgs['baseURL'] ..id
 local title = "BOW id=" .. id 
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%)')
 if authors then -- split authors with modified code from make cite iucn
 	local list = {}
 	--mw.addWarning ("author string: " .. authors)
 	authors = authors:gsub(", Jr.", "XYZJrX") -- protect author name from splitting on comma
 	authors = authors:gsub(", and ", ", ") -- for 3 or more authors
 	authors = authors:gsub(" and ", ", ") -- for 2 editors
 	list = mw.text.split (authors, ',');									 -- split the string on the commas into entries in list
		if #list == 0 then
			--mw.addWarning ("Zero length author list. Please report example of BOW citation at Cite BOW template talk page.");
			data.BOW.citationArgs['author'] = 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 
			 --mw.addWarning ("list " .. i .. "=" .. list[i])
			 if i==1 then --note the first name has last name followed by initials after comma, so takes fill first two parts of the split
			 	data.BOW.citationArgs['last1'] = name
			 elseif i==2 then
			 	data.BOW.citationArgs['first1'] = name
			 elseif i > 2 then
			 	--data.BOW.citationArgs['last'..i-1] = name:match ('%s(%a-)$')
			 	--data.BOW.citationArgs['first'..i-1] = name:match ('(.+)%s%a-$')
			 	data.BOW.citationArgs['last'..i-1] = name:match ('%s([%a ]-)$') -- for non-standard names e.g. del Hoyo
			 	data.BOW.citationArgs['first'..i-1] = name:match ('(.-)%s[%a ]-$')
			 	--data.BOW.citationArgs['author'..i-1] = nil
			 else -- something has gone wrong (use author)
			 	data.BOW.citationArgs['author'..i-1] = name 
			 end
			 if i>1 and 1==2 then
					--mw.addWarning ("last" .. tostring(i-1) .. "=" .. data.BOW.citationArgs['last'..i-1])
			 	--mw.addWarning ("first".. tostring(i-1) .. "=" .. data.BOW.citationArgs['first'..i-1])
			 end
			end
			for i, name in ipairs (list) do											-- for each author in list 
			 if data.BOW.citationArgs['last'..i] then
				 	 --mw.addWarning ("check " .. i .. "=" .. data.BOW.citationArgs['last'..i] )
			 	 data.BOW.citationArgs['last'..i] =string.gsub(data.BOW.citationArgs['last'..i], "XYZJrX", ", Jr.") -- restored protected string
			 end
			end
		end 
 end
 -- now parse editors
 local editors = citation:match ('In Birds of the World %((.-), Editors?%)' ) -- omit editors as cite web psoitioning is weird
 if editors then -- split editors with modified code from make cite iucn
 	local list = {}
 	--mw.addWarning ("editor string: " .. editors)
 	editors = editors:gsub(", and ", ", ") -- for 3 or more authors
 	editors = editors:gsub(" and ", ", ") -- for 2 editors
 	list = mw.text.split (editors, ',');									 -- split the string on the commas into entries in list
		if #list == 0 then
		 mw.addWarning ("problem with editor splitting")
			data.BOW.citationArgs['editor'] = editors 					 	-- 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 
			 if i>0 then --note the editor names are all same format (unlike authors)
			 	-- data.BOW.citationArgs['editor-last'..i] = name:match ('%s(%a-)$')
			 	-- data.BOW.citationArgs['editor-first'..i] = name:match ('(.+)%s%a-$')
			 data.BOW.citationArgs['editor-last'..i] = name:match ('%s([%a ]-)$') -- [%a ] for "del Hoyo" or "de Juana"
			 	data.BOW.citationArgs['editor-first'..i] = name:match ('(.-)%s[%a ]-$')
			 	--data.BOW.citationArgs['editor'..i-1] = nil
			 else -- something has gone wrong (use editor)
--			 	data.BOW.citationArgs['editor'..i] = name 
			 end
			 if i>0 and 1==2 then
					mw.addWarning ("editor-last" .. tostring(i) .. "=" .. data.BOW.citationArgs['editor-last'..i])
			 	mw.addWarning ("editor-first".. tostring(i) .. "=" .. data.BOW.citationArgs['editor-first'..i])
			 end
			end
		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, use {{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.species2 = function(genus, species) -- use species function below
 -- old url = https://mammaldiversity.org/species-account.php?genus=ursus&species=arctos
	-- new url = https://www.mammaldiversity.org/explore.html#genus=Dipodomys&species=deserti&id=1001892 (only id required)
 local title = "''" .. genus .. " " .. species .. "''"
	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']
 	-- new format https://www.mammaldiversity.org/explore.html#species-id=1006310
 	--local url = data.asm.customArgs['baseURL'] .. "explore.html#species-id=" .. id -- templateArgs['id']
 	-- newer format https://www.mammaldiversity.org/explore.html#genus=Leopardus&species=colocola&id=1005993 (genus and species can be blank)
 	-- newer (Mar 2024) https://www.mammaldiversity.org/taxon/1006020
 	
 	local title = "Species-id=" .. id
 	local hashString = "genus=&species=&id=" .. id -- if id only, requires blank genus and species (superceded by /taxon/link)
 	if templateArgs['genus'] and templateArgs['species'] then
 		title = "''" .. templateArgs['genus'] .. " " .. templateArgs['species'] .. "'' (id=" .. id ..")"
 		hashString = "genus=" .. templateArgs['genus'] .. "&species=" .. templateArgs['species'] .. "&id=" .. id
 	end
 	--local url = data.asm.customArgs['baseURL'] .. "explore.html#genus=&species=&id=" .. id -- templateArgs['id']
 	-- url = data.asm.customArgs['baseURL'] .. "explore.html#" .. hashString
 	local url = data.asm.customArgs['baseURL'] .. "taxon/" .. id
 	return title, url
end
data.asm.species = function(genus, species)
	if templateArgs['id'] then 
		return data.asm.id(templateArgs['id']) -- use the ASM explore page if ID given (as permalink)
 end
	if genus and species then -- otherwisee use the treeview page with the species info
		local title = "''" .. firstToUpper(genus) .. " " .. species .. "''" 
		local url = data.asm.customArgs['baseURL'] .. "tree.html#genus=" .. genus .. "&species=" .. species 
	 return title, url
	end
	
end
data.asm.genus = function(genus) return data.asm.taxon(genus, "genus", "TITLE_ITALICS") end
data.asm.family = function(family) return data.asm.taxon(family, "family") end
data.asm.order = function(order) return data.asm.taxon(order, "order") end
data.asm.taxon = function(taxon, rank, 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'] .. "tree.html" 
	if rank then -- no rank if taxon called directly
		url = url .. "#" .. rank .. "=" .. taxon 
	end
 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
--[[ Species files
 -- takes db parameter
 --https://db.speciesfile.org/otus/$ID/overview
 --https://plecoptera.speciesfile.org/otus/890815/overview
]]
data.speciesfile = {
	citationArgs = {
	 website = " Species File",
	 --publisher = "",
	},
	customArgs = {exclude="id,1,2,3,4,5,db",
	 --baseURL = "https://" .. firstToUpper(templateArgs['db'] ) .. ".speciesfile.org/",
	 --searchStr = "otus/",
	 -- defaultSuffix = "/overview",
	 --defaultTitle= " Species File"
	}
}
data.speciesfile.id = function(id) -- e.g. https://plecoptera.speciesfile.org/otus/890815/overview
	local db = data.speciesfile.db() -- customise for speciesfile
 local title = firstToUpper(db) .. " Species File id&#61;" .. id -- use entity &#61; for = to avoid missing pipe CS1 warning
 --local url = data.speciesfile.customArgs['baseURL'] .. data.speciesfile.customArgs['searchStr'] .. id .. data.speciesfile.customArgs['defaultSuffix ']
 local url = "https://" ..db .. ".speciesfile.org/otus/" .. id .. "/overview"
 
	return title, url 
end
data.speciesfile.default = function()
 local db = data.speciesfile.db ()
 local title = firstToUpper(db) .. " Species File" 
 local url = "https://" ..db .. ".speciesfile.org/"
 return title, url 
end
data.speciesfile.db = function()
 local db = string.lower( templateArgs['db'] )
	--	templateArgs['editor-last1']="Hopkins"; templateArgs['editor-first1']="H."
	if db == "zoraptera" then -- ed: Hopkins, H.
		templateArgs['editor-last1']="Hopkins"; templateArgs['editor-first1']="H."
	elseif db == "dermaptera" then -- eds: Hopkins, H., Haas, F. & Deem, L.S.
		templateArgs['editor-last1']="Hopkins"; templateArgs['editor-first1']="H."
		templateArgs['editor-last2']="Johnson"; templateArgs['editor-first2']="K.P."
		templateArgs['editor-last3']="Smith"; templateArgs['editor-first3']="V.S."
	elseif db == "plecoptera" then -- (eds) DeWalt RE, Hopkins H, Neu-Becker U, and Stueber G
		templateArgs['editor-last1']="DeWalt"; templateArgs['editor-first1']="R.E."
		templateArgs['editor-last2']="Hopkins"; templateArgs['editor-first2']="H."
		templateArgs['editor-last3']="Neu-Becker"; templateArgs['editor-first3']="U."
		templateArgs['editor-last4']="Stueber"; templateArgs['editor-first4']="G."
	elseif db == "orthoptera" then --eds: Cigliano, M.M., H. Braun, D.C. Eades & D. Otte.
		templateArgs['editor-last1']="Cigliano"; templateArgs['editor-first1']="M.M."
		templateArgs['editor-last2']="Braun"; templateArgs['editor-first2']="H."
		templateArgs['editor-last3']="Eades"; templateArgs['editor-first3']="D.C."
		templateArgs['editor-last4']="Otte"; templateArgs['editor-first4']="D."
	elseif db == "grylloblattodea" then -- ed: Hopkins, H.
		templateArgs['editor-last1']="Hopkins"; templateArgs['editor-first1']="H."
	elseif db == "mantophasmatodea" then -- ed: Hopkins, H.
		templateArgs['editor-last1']="Hopkins"; templateArgs['editor-first1']="H."
	elseif db == "embioptera" then -- ed: Hopkins, H.
		templateArgs['editor-last1']="Hopkins"; templateArgs['editor-first1']="H."
	elseif db == "phasmida" then -- eds: Brock PD, Büscher TH, Baker E. 
		templateArgs['editor-last1']="Brock"; templateArgs['editor-first1']="P.D."
		templateArgs['editor-last2']="Büscher"; templateArgs['editor-first2']="T.H."
		templateArgs['editor-last3']="Baker"; templateArgs['editor-first3']="E."
	elseif db == "mantodea" then		-- not updated yet
	elseif db == "cockroach" then -- ed: Beccaloni, G.W.
		templateArgs['editor-last1']="Beccaloni"; templateArgs['editor-first1']="G.W."
	elseif db == "isoptera" then -- ed: Hopkins, H.
		templateArgs['editor-last1']="Hopkins"; templateArgs['editor-first1']="H."
	elseif db == "psocodea" then --eds: Hopkins, H., Johnson, K.P., & Smith, V.S. 
		templateArgs['editor-last1']="Hopkins"; templateArgs['editor-first1']="H."
		templateArgs['editor-last2']="Johnson"; templateArgs['editor-first2']="K.P."
		templateArgs['editor-last3']="Smith"; templateArgs['editor-first3']="V.S."
	elseif db == "aphid" then -- ed: Colin FAVRET
		templateArgs['editor-last1']="Favret"; templateArgs['editor-first1']="Colin"
	elseif db == "coleorrhyncha" then -- ed: Hopkins, H.
		templateArgs['editor-last1']="Hopkins"; templateArgs['editor-first1']="H."
	elseif db == "coreoidea" then -- not updated yet
	elseif db == "lygaeoidea" then -- eds: Dellapé, Pablo M. & Thomas J. Henry
		templateArgs['editor-last1']="Dellapé"; templateArgs['editor-first1']="Pablo M."
		templateArgs['editor-last2']="Henry"; templateArgs['editor-first2']="Thomas J."
	elseif db == "hoppers" then -- eds: Dmitriev, D.A., Anufriev, G.A., Bartlett, C.R., Blanco-Rodríguez, E., Borodin, Oleg I., Cao, Y.-H., Deitz, L.L., Dietrich, C.H., Dmitrieva, M.O., El-Sonbati, S.A., Evangelista de Souza, O., Gjonov, I.V., Gonçalves, A.C., Hendrix, S., McKamey, S., Kohler, M., Kunz, G., Malenovský, I., Morris, B.O., Novoselova, M., Pinedo-Escatel, J.A., Rakitov, R.A., Rothschild, M.J., Sanborn, A.F., Takiya, D.M., Wallace, M.S., Zahniser, J.N.
		templateArgs['editor-last1']="Dmitriev"; templateArgs['editor-first1']="D.A."
		templateArgs['editor-last2']="Anufriev"; templateArgs['editor-first2']="G.A."
		templateArgs['editor-last3']="Bartlett"; templateArgs['editor-first3']="C.R."
		templateArgs['display-editors']="etal"; -- full list is about 28 names	
	else
		--return "Species File database not recognised"
	end
	if db == "hoppers" then
		data.speciesfile.citationArgs['website'] = "World Auchenorrhyncha Database"
	else
	 data.speciesfile.citationArgs['website'] = firstToUpper(db) .. data.speciesfile.citationArgs['website']
	end
 return db
end
--[[ Lepindex 
]]
data.lepindex = {
	citationArgs = {
	 website = "[[The Global Lepidoptera Names Index]]",
	 ['editor-last1'] = "Beccaloni", ['editor-first1'] = "George", 	['editor-last2'] = "Scoble", ['editor-first2'] = "Malcolm",
	 ['editor-last3'] = "Kitching", ['editor-first3'] = "Ian",	 ['editor-last4'] = "Simonsen", ['editor-first4'] = "Thomas",
	 ['editor-last5'] = "Robinson", ['editor-first5'] = "Gaden", 	['editor-last6'] = "Pitkin", ['editor-first6'] = "Brian", 
	 ['editor-last7'] = "Hine", ['editor-first7'] = "Adrian",	['editor-last8'] = "Lyal", ['editor-first8'] = "Chris",
	 publisher = "[[Natural History Museum, London|Natural History Museum]]",
	},
	customArgs = {exclude="id,1,2,3,4,5",
	 baseURL = "https://www.nhm.ac.uk/our-science/data/lepindex/",
	 suffixStr = "detail/?taxonno=",
	 defaultTitle="Lepindex"
	}
}
data.lepindex.id = function(id) -- https://www.nhm.ac.uk/our-science/data/lepindex/detail/?taxonno=51506
 local title = "Lepindex id=" .. id
 local url = data.lepindex.customArgs['baseURL'] .. data.lepindex.customArgs['suffixStr'] .. id
 
	return title, url 
end
--[[ Global Lepidoptra Index
]]
data.gli = {
	
	--Beccaloni, G., Scoble, M., Kitching, I., Simonsen, T., Robinson, G., Pitkin, B., Hine, A., Lyal, C., Ollerenshaw, J., Wing, P., & Hobern, D. (2024). Global Lepidoptera Index (D. Hobern, Ed.; 1.1.24.171).
	citationArgs = {
	 website = "Global Lepidoptera Index",
	 ['last1'] = "Beccaloni", ['first1'] = "George", 
	 ['last2'] = "Scoble", ['first2'] = "Malcolm",
	 ['last3'] = "Kitching", ['first3'] = "Ian",
	 ['last4'] = "Simonsen", ['first4'] = "Thomas",
	 ['last5'] = "Robinson", ['first5'] = "Gaden", 
	 ['last6'] = "Pitkin", ['first6'] = "Brian", 
	 ['last7'] = "Hine", ['first7'] = "Adrian",
	 ['last8'] = "Lyal", ['first8'] = "Chris",
	 ['last9'] = "Ollerenshaw", ['first9'] = "Justin", 
	 ['last10'] = "Wing", ['first10'] = "Peter", 
	 ['last11'] = "Hobern", ['first11'] = "Donald",
	 ['editor-last'] = "Hobern", ['editor-first'] = "Donald", 
	 publisher = "[[Natural History Museum, London|Natural History Museum]]",
	 via = "ChecklistBank",
	},
	customArgs = {exclude="id,1,2,3,4,5",
	 baseURL = "https://www.checklistbank.org/dataset/55434/",
	 suffixStr = "taxon/",
	 defaultTitle="Global Lepidoptera Index",
	 defaultURL = "https://www.checklistbank.org/dataset/55434/about",
	}
}
data.gli.id = function(id) -- https://www.checklistbank.org/dataset/55434/taxon/233256 
	 -- https://www.checklistbank.org/dataset/DATASET_ID/taxon/TAXON_ID -- the dataset ID will change with version so need version handling or just use URL 
 local title = "GLI id=" .. id
 local url = data.gli.customArgs['baseURL'] .. data.gli.customArgs['suffixStr'] .. id
 
	return title, url 
end
data.gli.default2 = function()
 
 local title = ""
 local url = ""
 return title, url 
end
--[[ CarabCat - Ground Beetles of the World
 https://www.itis.gov/servlet/SingleRpt/SingleRpt?search_topic=TSN&search_value=95601#null
 https://www.checklistbank.org/dataset/1146/taxon/208583
]]
data.carabcat = {
	citationArgs = {
	 website = "CarabCat",
	 ['last'] = "Lorenz", ['first'] = "Wolfgang", 
	 publisher = "ChecklistBank",
	 version = "03 (08/2021)",
	 year = 2021
	},
	customArgs = {exclude="id,1,2,3,4,5",
	 baseURL = "https://www.checklistbank.org/dataset/1146/",
	 searchStr = "taxon/",
	 defaultTitle="CarabCat"
	}
}
data.carabcat.id = function(id) 
 local title = "CarabCat on ChecklistBank id=" .. id
 local url = data.carabcat.customArgs['baseURL'] .. data.carabcat.customArgs['searchStr'] .. id
 
	return title, url 
	
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[2] 
	local para2 = templateArgs[3] 
	local para3 = templateArgs[4] 
	local para4 = templateArgs[5] 
	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]]",
		agency="Gateway to the [[Paleobiology Database]]",
		--publisher="Paleobiology Database",
		--postscript = 'none',
		-- postscript = "&#32;from the [[Paleobiology Database]].", -- gives maintenance warning
		--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
--[[ USDA PLANTS
	default search page: https://plants.sc.egov.usda.gov/
	taxon: https://plants.sc.egov.usda.gov/plant-profile/RUID (Rubus idaeus L., American red raspberry)
]]
data.PLANTS = { 
	citationArgs = {
		--last = "[[Natural Resources Conservation Service|NRCS]]",
		website="PLANTS Database",
		--publisher="[[United States Department of Agriculture]] (USDA)", 
		publisher="[[Natural Resources Conservation Service|USDA Natural Resources Conservation Service]]", 
		--postscript = 'none',
	},
	customArgs = { exclude = "id,1",
	 baseURL = "https://plants.sc.egov.usda.gov/", 
	 searchStr ="plant-profile/", -- for species profile
	 defaultSuffix = "",
	 defaultTitle = "Plants Database"
	}
	--id = function(id) return p.genericIdCitation (frame, title, url)
}
data.PLANTS.id = function(id)
 local title = data.PLANTS.customArgs['defaultTitle'] .. ' ' .. id
 local url = data.PLANTS.customArgs['baseURL'] .. data.PLANTS.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.getValidID = function()
	local id = templateArgs['id']
	if id then 
		return string.gsub( id, "wfo%-", "") -- don't want this twice (must escape -)
	end
	mw.addWarning("Citations for WFO require a valid ID")
	return ""
end
data.WFO.id = function(id)
--[[ http://www.worldfloraonline.org/taxon/wfo-4000012284	
 ]]
 id = data.WFO.getValidID()
 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'] .. data.WFO.getValidID()
 return title, url 
end
data.WFO.genus = function(genus)
	local title = addAuthority("''" .. genus .. "''") 
	local url = data.WFO.customArgs['baseURL'] .. data.WFO.customArgs['searchStr'] .. data.WFO.getValidID()
 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'] ..data.WFO.getValidID()
 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
--[[ ============================= Bryonames (Mosses etc) The Bryophyte Nomenclator =================================================
	https://www.bryonames.org/nomenclator?group=Bryidae&group_id=35210272 (A Classification of the Bryidae)
	https://www.bryonames.org/nomenclator?group=Hedwigiales (A Classification of the Hedwigiale)
	https://www.bryonames.org/nomenclator?group=Rhacocarpus (A synopsis of Rhacocarpus)
--]]
data.bryonames = {
	citationArgs = {
		['editor1-first']="John C.", ['editor1-last']="Brinda", 
		['editor2-first']="John J.", ['editor2-last']="Atwood",
		website="The Bryophyte Nomenclator"
		--publisher="[[xxx]]"
	},
	customArgs = { exclude="family,genus,species,taxon,id,1",
	 baseURL = "https://www.bryonames.org/",
	 searchString = "nomenclator?group=",
	 defaultTitle="Classification of the Bryophyta"
	}	
}
data.bryonames.genus = function(genus) return data.bryonames.taxon(genus, "GENUS") end
data.bryonames.family = function(family) return data.bryonames.taxon(family, "FAMILY") end
data.bryonames.order = function(order) return data.bryonames.taxon(order, "ORDER") end
data.bryonames.taxon = function(taxon, rank)
 taxon = firstToUpper(taxon)
 local title = "A Classification of the " .. taxon -- default title for suprafamilia taxa
 local url = data.bryonames.customArgs['baseURL'] .. data.bryonames.customArgs['searchString'] .. taxon -- url
 if rank == "GENUS" then taxon = "''" .. taxon .. "''" end -- italicise genus
 if rank == "GENUS" or rank == "FAMILY" then title = "A synopsis of " .. taxon end -- title for genus and familiees
 
 return title, url
end 
-- ============================= Mosses (Goffinet's site) =================================================
-- 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
 (old) taxonomy browser url (Volvox) = https://www.algaebase.org/browse/taxonomy/?id=6898
 taxonomy browser url (Volvox) = https://www.algaebase.org/browse/taxonomy/?#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=", (old)
	 searchStr ="browse/taxonomy/?#",
	 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
--================= Viruses =========
data.ictv = {
	citationArgs = {
		 website="ictv.global",
	 --['editor1-last']="xx", ['editor1-first']="xx",
	 --['editor2-last']="xx", ['editor2-first']="xx",
		 author="International Committee on Taxonomy of Viruses (ICTV)",
	},
	customArgs = { exclude = "id,1",
	 baseURL = "https://ictv.global/taxonomy/",
	 searchStr ="taxondetails?taxnode_id=",
	 defaultSuffix = "",
	 defaultTitle = "Taxonomy Browser"
	}
}
data.ictv.id = function(id)
--[[ https://ictv.global/taxonomy/taxondetails?taxnode_id=202308917&taxon_name=Campanilevirus%20YC (for species Campanilevirus YC)
 https://ictv.global/taxonomy/taxondetails?taxnode_id=202308917 (also works with just the id)
 ]]
 local title = id
 local url = data.ictv.customArgs['baseURL'] .. data.ictv.customArgs['searchStr'] .. id
 return title, url 
end
data.ictv.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
 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 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 = 'cite book' -- 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 = 'cite book', 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
p.BOW = function(frame) return p._main(frame, data.BOW) end
--======= Mammals
p.asm = function(frame) return p._main(frame, data.asm) end
--======= Plants
p.WFO = function(frame) return p._main(frame, data.WFO) end
p.POWO = function(frame) return p._main(frame, data.POWO) 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])
	--TODO force to lower case and use lower case for all functions above
	
	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
 if source == "wfo" then source = "WFO" end -- aliases
 if source == "mdd" then source = "asm" end -- aliases
 if source == "PBDB" then source = "paleobiodb" 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 == "BOW"
		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
	 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 taxon then mode = "taxon"; value = taxon
 	elseif order then mode = "order"; value = order
 	elseif family then mode = "family"; value = family
 	elseif genus then mode = "genus"; value = genus 
 	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 == "Cite book" 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['reftags'] == "yes" then
				refs[reference] = '<ref name=' .. templateArgs[2] ..'>' .. refs[reference] .. '</ref>'
			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

AltStyle によって変換されたページ (->オリジナル) /