Module:Cite taxon

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. 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="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 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'] = data.BOW.citationArgs['last1'] or name -- don't everwrite supplied name

elseif i==2 then

data.BOW.citationArgs['first1'] = data.BOW.citationArgs['first1'] or name

elseif i > 2 then

--mw.addWarning ("name " .. i .. "=" .. name)

--data.BOW.citationArgs['last'..i-1] = name:match ('%s(%a-)$')

--data.BOW.citationArgs['first'..i-1] = name:match ('(.+)%s%a-$')

-- regex note: allow for space in names such as del Hoyo

-- used supplied parameter if available (used when fixing diacrticis) or parse name or use unparsed name if that fails

data.BOW.citationArgs['last'..i-1] = data.BOW.citationArgs['last'..i-1] or name:match ('%s([%a ]-)$') or name

data.BOW.citationArgs['first'..i-1] = data.BOW.citationArgs['first'..i-1] or 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 = ' 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 WoRMS - World Register of Marine Species - Heterobranchia

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=" .. id -- use entity = 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",

},

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",

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 = "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 = " 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 'Requires id and one of title, family, genus or species parameters'

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 = "NRCS",

website="PLANTS Database",

--publisher="United States Department of Agriculture (USDA)",

publisher="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

--[[================= Bacteria (LPSN) =========

-- LPSN - List of Prokaryotic names with Standing in Nomenclature

]]

data.lpsn = {

citationArgs = {

website="LPSN - List of Prokaryotic names with Standing in Nomenclature",

--['editor1-last']="xx", ['editor1-first']="xx",

--['editor2-last']="xx", ['editor2-first']="xx",

publsiher="Leibniz Institute DSMZ",

},

customArgs = { exclude = "id,1,rank",

baseURL = "https://lpsn.dsmz.de/",

searchStr ="",

defaultSuffix = "",

defaultTitle = "LPSN - List of Prokaryotic names with Standing in Nomenclature"

}

}

data.lpsn.taxon = function(taxon)

--[[ general form: https://lpsn.dsmz.de/RANK/TAXON_NAME

e.g. https://lpsn.dsmz.de/phylum/cyanobacteriota (for phyla)

https://lpsn.dsmz.de/class/cyanophyceae (for classes)

use title and url parameters

]]

local title = taxon

local rank =templateArgs['rank']

local url

if rank then

url = data.lpsn.customArgs['baseURL'] .. rank .. '/' .. taxon

end

return title, url

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] = '' .. refs[reference] .. ''

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