Mô đun:FishRef

require('strict')

local p = {}
local data = {}
local templateArgs = {} -- contains arguments passed to cite web
local target = {} -- short cut to target table, e.g. fishbase, cof, etc

local function firstToUpper(str)
return (str:gsub("^%l", string.upper))
end
-- define citation template and custom parameters for various sources

-- Default functions
data.default = {}
-- currently being tested on Avibase, but Fossilworks, Tropicos, FNA and a few others are candidates
data.default.id = function (id, source)
local title = id
local url = source.customArgs['baseURL'] .. (source.customArgs['searchStr'] or "") .. id
return title, url
end
data.default.error = function()
return "Minimal requirement is two of id, url and title parameters"
end
data.default.search = function (search, source)
local title = "Search for " .. search
local url = source.customArgs['baseURL'] .. source.customArgs['searchString'] .. search .. source.customArgs['searchSuffix']
return title, url
end

--[[ handling for ID only (unused, original concept)
p.genericIdCitation = function(frame, title, url)

if not templateArgs['id'] then return "no id parameter detected" end

templateArgs['url']= target.CustomArgs['baseURL'] .. target.CustomArgs['searchStr'] .. templateArgs['id']

return p.citeWeb(frame, title, url)
end]]
-- FISH
-- Fishbase
data.fishbase = {
citationArgs = {
['editor1-last']="Froese", ['editor1-first']="Rainer", ['editor1-link']="Rainer Froese",
['editor2-last']="Pauly", ['editor2-first']="Daniel",
--['last-author-amp'] ="yes",
['website'] = "Fishbase",
--['publisher'] = ""
},
customArgs = { exclude= "order, family,genus, species, subspecies, 1, 2, 3, 4",
baseURL = "http://www.fishbase.org/",
defaultTitle = "Search FishBase"
},
}
data.fishbase.species = function(genus, species, subspecies)

local title = genus .. " " .. species
local url = data.fishbase.customArgs['baseURL']
.. "summary/SpeciesSummary.php?genusname=" .. genus .. "&speciesname=" .. species
if subspecies then
url = url .. "+" .. subspecies
title = title .. " " .. subspecies
end
title = "" .. title .. ""
return title, url
end
data.fishbase.genus = function(genus)
local title = "Species in genus " .. firstToUpper(genus) .. ""
local url = data.fishbase.customArgs['baseURL'] .. "identification/SpeciesList.php?genus=" .. genus
return title, url
end
data.fishbase.order = function(order)
local title = "Order " .. firstToUpper(order)
local url = data.fishbase.customArgs['baseURL'] .. "Summary/OrdersSummary.php?order=" .. order
return title, url
end
data.fishbase.family = function(family)
local title = "Family " .. firstToUpper(family)
local url = data.fishbase.customArgs['baseURL'] .. "Summary/FamilySummary.php?family=" .. family
return title, url
end
data.fishbase.error = function()
return "No recognised taxon options: order, family, genus, species, subspecies."
end
data.fishbase.custom = function()
--TODO decide what to do with default date
local version = "April 2006 version" -- Should we have a default (probably not)
if templateArgs['month'] then version = templateArgs['month'] end
if templateArgs['year'] then version = templateArgs['year'] .. " version" end
if templateArgs['month'] then version = templateArgs['month'] .. " " .. version end
templateArgs['version'] = version
end
-- Catalog of Fishes
data.cof = {
citationArgs = {
--baseURL = "http://researcharchive.calacademy.org/research/ichthyology/catalog/fishcatget.asp?",
['editor1-last']="Eschmeyer", ['editor1-first']="William N.", ['editor1-link']="William N. Eschmeyer",
['editor2-last']="Fricke", ['editor2-first']="Ron",
['editor3-last']="van der Laan", ['editor3-first']="Richard",
['name-list-style'] ="amp",
['website'] = "Catalog of Fishes",
['publisher'] = "California Academy of Sciences"
},
customArgs = { exclude= "family,genus,species,genid,spid,id,list,1,2,3",
baseURL = "http://researcharchive.calacademy.org/research/ichthyology/catalog/fishcatget.asp?",
defaultTitle = "CAS - Eschmeyer's Catalog of Fishes"
}
}
data.cof.species = function(genus, species, subspecies)
local taxon = genus .. " " .. species
local url = data.cof.customArgs['baseURL'] .. 'tbl=species&genus=' .. genus .. '&species=' .. species
local title = "Species related to " .. "" .. firstToUpper(taxon) .. "" -- .. "" species synonyms"
return title, url
end
data.cof.genus = function(genus)
local url = data.cof.customArgs['baseURL'] .. 'tbl=species&genus=' .. genus
local title = "Species in the genus " .. firstToUpper(genus) .. ""
return title, url
end
-- note the family works with subfamilies using &family=SUBFAMILY
data.cof.family = function(family)
local list = templateArgs['list'] or "genus"
local url = data.cof.customArgs['baseURL'] .. 'tbl=' .. list .. '&family=' .. family
local title = "Species"
if list == "genus" then title = "Genera" end
title = title .. ' in the family ' .. firstToUpper(family)
return title, url
end
data.cof.genid = function(genid)
local searchStr = "genid" .. '=' .. genid
local title = searchStr
local url = data.cof.customArgs['baseURL'] .. searchStr
return title, url
end
data.cof.spid = function(spid)
local searchStr = "spid" .. '=' .. spid
local title = searchStr
local url = data.cof.customArgs['baseURL'] .. searchStr
return title, url
end
data.cof.error = function()
return "Error. No recognised option set by template (need one of family, genus, species (also requires genus), spid, or genid"
end
--Fishes of the World 5
data.fotw5 = {
citeTemplate = "Cite book",
citationArgs = {
--['website'] = "[[]]",
first1 = "Joseph S.", last1 = "Nelson",
first2="Terry C.", last2="Grande",
first3="Mark V. H.", last3="Wilson",
--work = "Fishes of the World (work)",
title = "Fishes of the World", edition="5th", year = 2016,
publisher ="John Wiley and Sons", location="Hoboken",
isbn = "978-1-118-34233-6", doi="10.1002/9781119174844" ,
},
customArgs = {exclude="gb-page,q,dq,1",
baseURL = "https://onlinelibrary.wiley.com/doi/book/10.1002/9781119174844", -- online library
defaultTitle = "Fishes of the World",
altTitle = "Fishes of the World", -- wikilinked for when using chapter/section title
altURL = "https://sites.google.com/site/fotw5th/", -- classification
},
GoogleBooks = { baseURL = "https://books.google.co.uk/books?id=",
id = "E-MLDAAAQBAJ",
defaultPage = "&pg=PP1"
}
}
data.fotw5.default2 = function(targs)
local title = data.fotw5.citationArgs['work']
local url = data.fotw5.customArgs['baseURL']
local chapterParams = { title = title,
['chapter-url']= data.fotw5.customArgs['googleBooks']
}
--return title, url, chapterParams
end

data.BentonVP4 = {
citeTemplate = "Cite book",
citationArgs = {
first1 = "Michael J.", last1 = "Benton",
title = "Vertebrate Palaeontology", edition="4th", year = 2014,
publisher ="John Wiley & Sons",
isbn = "978-1-118-40764-6",
},
customArgs = {exclude="gb-page,q,dq,1",
--baseURL = "",
defaultTitle = "Vertebrate Palaeontology",
altTitle = "Vertebrate Palaeontology" -- wikilinked for when using chapter/section title
},
GoogleBooks = { baseURL = "https://books.google.co.uk/books?id=",
id = "qak-BAAAQBAJ",
defaultPage = "&pg=PP1",
}
}

--TODO FishWisePro
data.fishwisepro = {
citationArgs = {
['website'] = "FishWisePro",

},
customArgs = {exclude="family,genus,species,1",
baseURL = ""
}
}

-- AMPHIBIA and REPTILES
-- ================= Amphibian Species of the World (ASW6)
--Recommended citation: Frost, Darrel R. 2019. Amphibian Species of the World: an Online Reference. Version 6.0 (Date of access). Electronic Database accessible at http://research.amnh.org/herpetology/amphibia/index.html. American Museum of Natural History, New York, USA.
URL for family page: http://research.amnh.org/vz/herpetology/amphibia/Amphibia/Anura/Allophrynidae
baseURL = http://research.amnh.org/vz/herpetology/amphibia/
suffix = Amphibia/Anura/Allophrynidae
note: needs the whole hierarchy (except the superfamily which is optional)
Template for main taxonomic listing:
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
.. '&quot;' .. genus .. '+' .. species .. '&quot;'
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", "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:
--
data.amphibiaweb = {
citationArgs = {
website = "AmphibiaWeb",
publisher = "University of California, Berkeley",
--['editor1-last']="", ['editor1-first']="", ['editor1-link']="",
},
customArgs = { exclude = "taxon,species,genus,family,1,2,3",
baseURL = "https://amphibiaweb.org/",
defaultSuffix = "taxonomy/AW_FamilyPhylogeny.html",
defaultTitle = "AmphibiaWeb Family Taxonomy"
}
}
data.amphibiaweb.species = function (genus, species, subspecies)
local title = "" .. genus .. " " .. species .. ""
--https://amphibiaweb.org/cgi/amphib_query?where-genus=Altiphrynoides&where-species=malcolmi
local url = data.amphibiaweb.customArgs['baseURL'] .. "cgi/amphib_query?rel-genus=equals&where-genus="
.. genus .. "&rel-species=equals&where-species=" .. species
return title, url
end
data.amphibiaweb.genus = function (genus)
local title = "" .. genus .. ""
--https://amphibiaweb.org/cgi/amphib_query?where-genus=Altiphrynoides&where-species=malcolmi
local url = data.amphibiaweb.customArgs['baseURL'] .. "cgi/amphib_query?rel-genus=equals&where-genus="
.. genus .. "&include_synonymies=Yes&show_photos=Yes"
return title, url
end
data.amphibiaweb.family = function (family) -- if family use standardised url
local url = data.amphibiaweb.customArgs['baseURL'] .. "lists/" .. firstToUpper(templateArgs['family']) .. ".shtml"
local title = templateArgs['family']
return title, url
end


--=========================== The Reptile Database
data.reptileDB = {
-- http://reptile-database.reptarium.cz/species?genus=Epacrophis&species=boulengeri
-- recommended citation: Uetz, P., Freed, P. & Hošek, J. (eds.) (2019) The Reptile Database, http://www.reptile-database.org, accessed [insert date here]
citationArgs = {
--website="reptile-database.org",
website="The Reptile Database",
['editor1-last']="Uetz", ['editor1-first']="P.", --['editor1-link']="Peter Uetz",
['editor2-last']="Freed", ['editor2-first']="P.",
['editor3-last']="Hošek", ['editor3-first']="J.",
--year=2019

},
customArgs = { exclude = "taxon,species,genus,family,1,2,3",
baseURL = "http://reptile-database.reptarium.cz/"
}
}

data.reptileDB.species = function(genus, species)
local title = "" .. genus .. " " .. species .. ""
--http://reptile-database.reptarium.cz/species?genus=Loxocemus&species=bicolor
local url = data.reptileDB.customArgs['baseURL'] .. "species?genus=" .. genus .. "&species=" .. species
return title, url
end
data.reptileDB.genus = function(genus)
local title = "" .. genus .. ""
--http://reptile-database.reptarium.cz/advanced_search?genus=Malayopython&submit=Search
local url = data.reptileDB.customArgs['baseURL'] .. "advanced_search?genus=" .. genus .. "&exact%5B0%5D=taxon&submit=search"
return title, url
end
data.reptileDB.family = function(family)
return data.reptileDB.taxon(family)
end
data.reptileDB.order = function(order)
return data.reptileDB.taxon(order)
end
data.reptileDB.taxon = function(taxon)
local title = taxon
--http://reptile-database.reptarium.cz/advanced_search?taxon=Viperidae&exact%5B0%5D=taxon&submit=Search
local url = data.reptileDB.customArgs['baseURL'] .. "advanced_search?taxon=" .. taxon .. "&exact%5B0%5D=taxon&submit=search"
return title, url
end




-- BIRDS
--Handbook of the Birds of the World Alive (HBW Alive)
data.HBWalive = {
citationArgs = {
website="Handbook of the Birds of the World Alive",
publisher="Lynx Edicions"
},
customArgs = { exclude="order,family,genus,species,taxon,id,1",
baseURL = "https://www.hbw.com/",
defaultSuffix = "family/home",
defaultTitle = "Family | HBW Alive"

}
}
-- HBW ALIVE
-- family and species entries have mix of common name and taxon name so cannot be prempted;
-- must use title + url (which uses default functions in this module)
data.HBWalive.order = function(order)
local title = "Order " .. firstToUpper(order)
--https://www.hbw.com/order/struthioniformes
local url = target.customArgs['baseURL'] .. "order/" .. order
return title, url
end


--IOC World Bird List
Gill, F & D Donsker (Eds). 2019. IOC World Bird List (v9.2). doi : 10.14344/IOC.ML.9.2.
Gill F, D Donsker & P Rasmussen (Eds). 2020. IOC World Bird List (v10.2). doi : 10.14344/IOC.ML.10.1.

data.IOC = {
citationArgs = {
website="IOC World Bird List",
-- version="Version 9.2", -- shouldn't default; should be hardcode so it doesn't change
['editor1-last']="Gill", ['editor1-first']="F.", ['editor1-link']="Frank Gill (ornithologist)",
['editor2-last']="Donsker", ['editor2-first']="D.",
['editor3-last']="Rasmussen", ['editor3-first']="P.", -- TODO only show from version 10.1 onwards
-- doi = "10.14344/IOC.ML.9.2", -- this changes by version number and is not a useful part of the cictation
publisher="International Ornithological Congress"
},
customArgs = { exclude="order,family,genus,species,taxon,id,1",
baseURL = "https://www.worldbirdnames.org/",
defaultSuffix = "",
defaultTitle = "IOC World Bird List: Welcome"

},
}
data.IOC.version = function()
local version = templateArgs['version']
local old = false
if version then
version = string.gsub( version, "[Vv]ersion ", "")
local versionNumber = tonumber(version)
if versionNumber and ) with
local names = authors:gsub (',%s+', '|'); -- replace any comma
-- :gsub ('%.?,?%s+and%s+', '|') -- replace 'separators' and) with
-- :gsub ('%.,%s+', '.|'); -- replace 'separators' with
list = mw.text.split (names, '|'); -- split the string on the pipes into entries in list
if list == 0 then
data.BOW.citationArgs['authors'] = authors -- no 'names' of the proper form; return the original as a single |author= parameter
else
for i, name in ipairs (list) do -- for each author in list
data.BOW.citationArgs['author'..i-1] = name -- add |authorn= parameter names
-- list[i] = table.concat ({'|author', (i == 1) and or i, '=', name}); -- add |authorn= parameter names; create |author= instead of |author1=
end
data.BOW.citationArgs['author1'] = data.BOW.citationArgs['author0'] .. ', ' .. data.BOW.citationArgs['author1']
end

end

--if not url then url = data.BOW.customArgs['baseURL'] end
--if not title then title = "Title parameter required" end

return title, url
end

-- basic handling for Taxonomy in Flux website
data.tif = {
citationArgs = {
website="Taxonomy in Flux",
['editor1-last']="Boyd III", ['editor1-first']="John H.", --['editor1-link']="",
},
customArgs = { exclude="order,family,genus,species,taxon,id,1",
baseURL = "http://jboyd.net/Taxo/",
defaultSuffix = "List.html",
defaultTitle = "Taxonomy in Flux"

},
}
-- ------------- Avibase
e.g. https://avibase.bsc-eoc.org/species.jsp?avibaseid=9144EF4017F2D8B1

data.avibase = {
citationArgs = {
website="Avibase",
['editor1-last']="Lepage", ['editor1-first']="Denis", --['editor1-link']="",
},
customArgs = { exclude="order,family,genus,species,taxon,id,1",
baseURL = "https://avibase.bsc-eoc.org/",
searchStr = "species.jsp?avibaseid=",
defaultTitle = "Avibase - The World Bird Database"
}
}
--[[ use default function
data.avibase.id = function (id)

local title = "Avibase id: " .. id
local url = data.avibase.customArgs['baseURL'] .. data.avibase.customArgs['searchStr'] .. id
return title, url
end
--]]

-- IUCN
-- for species in taxon; for species assessments, us
-- https://www.iucnredlist.org/search?query=Murexia&searchType=species
-- https://www.iucnredlist.org/search?query=aonyx&searchType=species
data.iucn = {
citationArgs = {
website="IUCN Red List of Threatened Species",
--publisher="IUCN"
},
customArgs = { exclude="family,genus,species,taxon,id,1",
baseURL = "https://www.iucnredlist.org",
searchString = "/search?query=",
searchSuffix = "&searchType=species",
defaultSuffix = "",
defaultTitle="IUCN Red List of Threatened Species"
}
}
data.iucn.genus = function(genus) return data.iucn.taxon(genus, "TITLE_ITALICS") end
data.iucn.family = function(family) return data.iucn.taxon(family) end
data.iucn.order = function(order) return data.iucn.taxon(order) end
data.iucn.taxon = function(taxon, titleItalics)
local title = firstToUpper(taxon)
if titleItalics then title = "" .. title .. "" end
local url = data.iucn.customArgs['baseURL'] .. data.iucn.customArgs['searchString'] .. taxon .. data.iucn.customArgs['searchSuffix']
return title, url
end

-- ASM Mammal Diversity Database
data.asm = {
citationArgs = {
website="ASM Mammal Diversity Database",
publisher="American Society of Mammalogists"
},
customArgs = { exclude="family,genus,species,taxon,id,1,2,3",
baseURL = "https://www.mammaldiversity.org/",
defaultTitle="ASM Mammal Diversity Database"

}
}

data.asm.species = function(genus, species)
local title = "" .. genus .. " " .. species .. ""
--https://mammaldiversity.org/species-account.php?genus=ursus&species=arctos
local url = data.asm.customArgs['baseURL'] .. "species-account.php?genus=" .. genus .. "&species=" .. species
return title, url
end
data.asm.id = function(id)
--local url = data.asm.customArgs['baseURL'] .. "species-account/species-id=" .. templateArgs['id']
--local title = "Species-id=" .. id

-- new format https://www.mammaldiversity.org/explore.htmlspecies-id=1006310
local url = data.asm.customArgs['baseURL'] .. "explore.htmlspecies-id=" .. id -- templateArgs['id']
local title = "Species-id=" .. id
return title, url
end
data.asm.genus = function(genus) return data.asm.taxon(genus, "TITLE_ITALICS") end
data.asm.family = function(family) return data.asm.taxon(family) end
data.asm.order = function(order) return data.asm.taxon(order) end
data.asm.taxon = function(taxon, titleItalics)
--https://mammaldiversity.org/ZmVsaWRhZSZnbG9iYWxfc2VhcmNoPXRydWUmbG9vc2U9dHJ1ZQ
-- Base64.encode(felidae&global_search=true&loose=true)
local title = firstToUpper(taxon)
if titleItalics then title = "" .. title .. "" end
local url = data.asm.customArgs['baseURL']
.. '' .. data.asm.Base64.encode(taxon.."&global_search=true&loose=false")
return title, url
end
-- Base64 encode and decode (used for ASM
local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
-- encoding
data.asm.Base64 = {}
data.asm.Base64.encode = function(data)
return ((data:gsub('.', function(x)
local r,b=,x:byte()
for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
return r;
end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
if (x 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 via to append WoRMS
2) use DB as website and use postscript to append WoRMS
3) use WoRMSa as website and designate DB as author (recommended by WoRMS) CURRENT

data.WoRMS = {
citationArgs = {
author = "WoRMS",
website = "World Register of Marine Species",
--['via'] = "World Register of Marine Species",
--postscript = '&32;from the World Register of Marine Species.'

},
customArgs = {exclude="id,db,1",
baseURL = "http://www.marinespecies.org/aphia.php?",
searchStr = "p=taxdetails&id=",
defaultTitle="World Register of Marine Species"
}
}
data.WoRMS.id = function(id)
-- Two styles
1. http://www.marinespecies.org/aphia.php?p=taxdetails&id=14712
> WoRMS (2018). Heterobranchia. Accessed at: http://marinespecies.org/aphia.php?p=taxdetails&id=14712 on 2018-11-28
2. http://www.marinespecies.org/aphia.php?p=taxdetails&id=1057249
> MolluscaBase (2018). Ringipleura. Accessed through: World Register of Marine Species at: http://www.marinespecies.org/aphia.php?p=taxdetails&id=1057249 on 2018-11-28

if not templateArgs['id'] then return "no id parameter detected" end
local searchStr = "p=taxdetails&id=" .. templateArgs['id']

if templateArgs['db'] then -- if database hosted by WoRMS
templateArgs['author'] = templateArgs['db'] -- this is recommended by WoRMS
--templateArgs['website'] = templateArgs['db'] -- alternative (and use |postscript)
--templateArgs['publisher'] = templateArgs['via']
--[[else -- WoRMS is primary source
templateArgs['via'] = nil
templateArgs['postscript'] = nil]]
end
--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
-- Catalgue 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",
publisher = "Species 2000: Naturalis, 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']


if 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

local para1 = templateArgs[1]
local para2 = templateArgs[2]
local para3 = templateArgs[3]
local para4 = templateArgs[4]
if para1 then para1 = mw.text.trim(para1) end
if para2 then para2 = mw.text.trim(para2) end
if para3 then para3 = mw.text.trim(para3) end
if para4 then para4 = mw.text.trim(para4) end

local title, url

if para1 then
--local match = "7539827da517bd6273a4a3836578cb24"
local match = "^[0-9abcdef]+$"
if string.find( para1, match ) then
url = "http://www.catalogueoflife.org/col/details/species/id/" .. para1 -- ""Old style id"
--url ="https://www.catalogueoflife.org/data/search?q=" .. para1
if para2 then
title = para2
else
title = "Oldstyle id: " .. para1
end

else

--https://www.catalogueoflife.org/data/search?q=" Chinchilla+chinchilla&type=EXACT

if para1 ~= "" then
url = "https://www.catalogueoflife.org/data/search?q=" .. para1
title = "" .. para1
if para2 then
url = url .. "+" .. para2
title = title .. " " .. para2
end
url = url .. "&type=EXACT"
title = title .. ""
end

end
if para3 then title = title .. " " .. para3 end -- add authority
if para4 == "nv" then templateArgs['trans-title'] = "synonym" end -- if nv add [synonym]. Note that this parameter is not used to add COinS metadata
else
-- no parameter 1
end

return title, url
end

-- Fossilworks

data.fossilworks = {
citationArgs = {
website="Fossilworks",
--publisher="Paleobiology Database",
--postscript = 'none',
postscript = "&32;from the Paleobiology Database.",
--via="fossilworks.org" -- an alternative format to using |website=
},
customArgs = { exclude = "id,collection,date,1",
baseURL = "http://www.fossilworks.org/cgi-bin/",
searchStr ="bridge.pl?a=taxonInfo&taxon_no=",
defaultTitle = "Fossilworks: Gateway to the Paleobiology Database"
}
--id = function(id) return p.genericIdCitation (frame, title, url)
}
data.fossilworks.id = function(id)
--[[ http://fossilworks.org/cgi-bin/bridge.pl?a=taxonInfo&taxon_no=83087
if not templateArgs['id'] then return "no id parameter detected" end
local searchStr = "bridge.pl?a=taxonInfo&taxon_no=" .. templateArgs['id']
templateArgs['url']= target.CustomArgs['baseURL'] .. searchStr
]]
local title = "PaleoDB taxon number: " .. id
local url = data.fossilworks.customArgs['baseURL'] .. data.fossilworks.customArgs['searchStr'] .. id
return title, url
end
data.fossilworks.collection = function(collection)
-- http://fossilworks.org/bridge.pl?a=collectionSearch&collection_no=20072
local title = "PaleoDB collection number: " .. collection
local url = data.fossilworks.customArgs['baseURL'] .. "bridge.pl?a=collectionSearch&collection_no=" .. collection
return title, url
end
data.fossilworks.error = function()
return "Requires id and title parameters"
end
-- 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-list1599996425
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-list1599997555

deeplinks:
Genus: Helosciadium
Species: Helosciadium longipedunculatum

Genus: Lycopodium
Species: 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

--GRIN
Cite as: USDA, Agricultural Research Service, National Plant Germplasm System. 2021. Germplasm Resources Information Network (GRIN Taxonomy). National Germplasm Resources Laboratory, Beltsville, Maryland.
URL: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomyfamily?type=tribe&id=1571. Accessed 27 October 2021.
Family record: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomyfamily?id=440
Genus list: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomygenuslist?id=440&type=family
Subfamily record: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomyfamily?type=subfamily&id=1507
Genus list: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomygenuslist?id=3265&type=subfamily
Tribe record: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomyfamily?type=tribe&id=1551 (Millettieae)
Genus list: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomygenuslist?id=1551&type=tribe
Subtribe record: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomyfamily?type=subtribe&id=1507
Genus list: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomygenuslist?id=1507&type=subtribe
Genus record: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomygenus?id=191 (Genus Adenodolichos Harms)
Species list: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomyspecieslist?id=191&type=genus
Species record: https://npgsweb.ars-grin.gov/gringlobal/taxon/taxonomydetail?id=489203 ( Adenodolichos paniculatus)


data.GRIN = {
citationArgs = {
website="Germplasm Resources Information Network (GRIN)",
publisher="Agricultural Research Service (ARS), United States Department of Agriculture (USDA)",
--postscript = 'none',
},
customArgs = { exclude = "id,authority,family,genus,species,1",
baseURL = "https://npgsweb.ars-grin.gov/gringlobal",
searchStr ="/taxon/taxonomydetail?", -- for species record
defaultSuffix = "",
defaultTitle = "GRIN-Global"
}
--id = function(id) return p.genericIdCitation (frame, title, url)
}
data.GRIN.id = function(id)
local title = data.GRIN.customArgs['defaultTitle'] .. ' ' .. id
local url = data.GRIN.customArgs['baseURL'] .. data.GRIN.customArgs['searchStr'] .. id
return title, url
end

-- IPNI
--→ "Meconopsis Vig." International Plant Names Index (IPNI). Royal Botanic Gardens, Kew.
--- https://www.ipni.org/n/30149252-2
--- as

data.IPNI = {
citationArgs = {
website="International Plant Names Index (IPNI)",
publisher="Royal Botanic Gardens, Kew",
--postscript = 'none',
},
customArgs = { exclude = "id,authority,family,genus,species,1",
baseURL = "https://www.ipni.org",
searchStr ="/n/",
defaultSuffix = "",
defaultTitle = "IPNI"
}
--id = function(id) return p.genericIdCitation (frame, title, url)
}
data.IPNI.id = function(id)
local title = id
local url = data.IPNI.customArgs['baseURL'] .. data.IPNI.customArgs['searchStr'] .. id
return title, url
end
data.IPNI.species = function(genus, species) return data.IPNI.taxon(genus .. " " .. species, "TITLE_ITALICS") end
data.IPNI.genus = function(genus) return data.IPNI.taxon(genus, "TITLE_ITALICS") end
data.IPNI.taxon = function(taxon, italics)
local title = taxon
if italics then title = "" .. title .. "" end
title = addAuthority(title)
--[[ if templateArgs['authority'] then
title = title .. " " .. templateArgs['authority']
title = string.gsub( title, "(.%.)$", "((%1))") -- if authority ends in "." enclose ((title)) to prevent removal
end ]]
local url = data.IPNI.customArgs['baseURL'] .. data.IPNI.customArgs['searchStr'] .. templateArgs['id']
return title, url
end

--World Flora Online
http://www.worldfloraonline.org/taxon/wfo-4000012284 -- id

data.WFO = {
citationArgs = {
website="World Flora Online",
--publisher="Missouri Botanical Gardens",
--postscript = 'none',
},
customArgs = { exclude = "id,family,genus,species,authority,1",
baseURL = "http://www.worldfloraonline.org",
searchStr ="/taxon/wfo-", -- not strictly search string
defaultSuffix = "",
--defaultTitle = "World Flora Online"
defaultTitle = "An Online Flora of All Known Plants"
}

}
data.WFO.id = function(id)
-- http://www.worldfloraonline.org/taxon/wfo-4000012284

local title = id
local url = data.WFO.customArgs['baseURL'] .. data.WFO.customArgs['searchStr'] .. id
return title, url
end
data.WFO.family = function(family)
local title = addAuthority(family)
local url = data.WFO.customArgs['baseURL'] .. data.WFO.customArgs['searchStr'] .. templateArgs['id']
return title, url
end
data.WFO.genus = function(genus)
local title = addAuthority("" .. genus .. "")
local url = data.WFO.customArgs['baseURL'] .. data.WFO.customArgs['searchStr'] .. templateArgs['id']
return title, url
end
data.WFO.species = function(genus,species)
local title = addAuthority("" .. genus .. " " .. species .. "")
local url = data.WFO.customArgs['baseURL'] .. data.WFO.customArgs['searchStr'] .. templateArgs['id']
return title, url
end
data.WFO.error = function()
return "Requires id and title parameters"
end

data.Tropicos = {
citationArgs = {
website="Tropicos",
--publisher="Missouri Botanical Gardens",
--postscript = 'none',
},
customArgs = { exclude = "id,1",
baseURL = "http://legacy.tropicos.org/Name/",
searchStr ="",
defaultSuffix = "",
defaultTitle = "Tropicos"
}

}
data.Tropicos.id = function(id)
-- hhttp://legacy.tropicos.org/Name/100444532

local title = id
local url = data.Tropicos.customArgs['baseURL'] .. data.Tropicos.customArgs['searchStr'] .. id
return title, url
end
data.Tropicos.error = function()
return "Requires id and title parameters"
end

data.FNA = {
citationArgs = {
website="Flora of North America",
--publisher="http://www.efloras.org",
--postscript = 'none',
},
customArgs = { exclude = "id,1",
baseURL = "http://www.efloras.org/florataxon.aspx",
searchStr ="?flora_id=1&taxon_id=",
defaultSuffix = "",
defaultTitle = "Flora of North America"
}
--id = function(id) return p.genericIdCitation (frame, title, url)
}
data.FNA.id = function(id)
-- http://www.efloras.org/florataxon.aspx?flora_id=1&taxon_id=125683

local title = id
local url = data.FNA.customArgs['baseURL'] .. data.FNA.customArgs['searchStr'] .. id
return title, url
end
data.FNA.error = function()
return "Requires id and title parameters"
end
-- ATRP: Australian Tropical Rainforest Plants

data.ATRP = {
citationArgs = {
website="Australian Tropical Rainforest Plants",
publisher="Commonwealth Scientific and Industrial Research Organisation (CSIRO)",
version = "Edition 8",
year = 2020,
--postscript = 'none',
last1= "Zich", first1="F. A.",
last2= "Hyland", first2= "B. P. M.", ['author2-link']="Bernard Hyland",
last3= "Whiffin", first3= "T.",
last4= "Kerrigan", first4= "R.A.",
--['display-authors']=3,
},
customArgs = { exclude = "genus, species,authority, id,1",
baseURL = "https://apps.lucidcentral.org/rainforest",
searchStr ="/text/entities/",
defaultSuffix = ".htm",
defaultTitle = "Australian Tropical Rainforest Plants"
}
--id = function(id) return p.genericIdCitation (frame, title, url)
}
data.ATRP.species = function(genus,species)
-- https://apps.lucidcentral.org/rainforest/text/entities/buckinghamia_celsissima.htm

local title = addAuthority("" .. genus .. " " .. species .. "") --"" .. genus .. " " .. species .. ""
local url = data.ATRP.customArgs['baseURL'] .. data.ATRP.customArgs['searchStr'] .. genus .. "_" .. species .. data.ATRP.customArgs['defaultSuffix']
return title, url
end
data.ATRP.error = function()
return "Requires genus and species parameters"
end

-- Mosses (Goffinet's site) -- for species in taxon; for species assessments, us
-- https://bryology.uconn.edu/classification/Hypnanae
-- https://bryology.uconn.edu/classification/Bryales
data.goffinet = {
citationArgs = {
first1="B.", last1="Goffinet",
first2="W.R.", last2="Buck",
website="Classification of extant moss genera"
--publisher="xxx"
},
customArgs = { exclude="family,genus,species,taxon,id,1",
baseURL = "https://bryology.uconn.edu/classification/",
searchString = "",
searchSuffix = "",
defaultSuffix = "",
defaultTitle="Classification of the Bryophyta"
}
}
data.goffinet.genus = function(genus) return data.goffinet.taxon(genus, "GENUS") end
data.goffinet.family = function(family) return data.goffinet.taxon(family, "FAMILY") end
data.goffinet.order = function(order) return data.goffinet.taxon(order, "ORDER") end
data.goffinet.taxon = function(taxon, rank)
local title = firstToUpper(taxon)
if rank == "GENUS" then title = "" .. title .. "" end
if not (rank "GENUS" or rank "FAMILY") then -- upper case anchors for orders and above
if taxon ~= "Bryanae" and taxon ~= "Hypnanae" and taxon ~= "Bryales" and taxon ~= "Bryidae" then -- check for exceptions (inconsistencies at website)
taxon = taxon:upper()
end
end
local url = data.goffinet.customArgs['baseURL'] .. data.goffinet.customArgs['searchString'] .. taxon .. data.goffinet.customArgs['searchSuffix']
return title, url
end

-- AlgaeBase
taxonomy browser url (Volvox) = https://www.algaebase.org/browse/taxonomy/?id=6898
genus article url (Volvox) = https://www.algaebase.org/search/genus/detail/?genus_id=43497 (different id)
genus article url (Torodinium)= https://www.algaebase.org/search/genus/detail/?genus_id=44698
Please cite this record as: M.D. Guiry in Guiry, M.D. & Guiry, G.M. 2020. AlgaeBase.
World-wide electronic publication, National University of Ireland, Galway.
http://www.algaebase.org; searched on 10 May 2020.

data.AlgaeBase = {
citationArgs = {
website="AlgaeBase",
['editor1-last']="Guiry", ['editor1-first']="M.D.",
['editor2-last']="Guiry", ['editor2-first']="G.M.",
publisher="National University of Ireland, Galway",
},
customArgs = { exclude = "id,1,genus_id,species_id,spid,genid",
baseURL = "https://www.algaebase.org/",
searchStr ="browse/taxonomy/?id=",
defaultSuffix = "",
defaultTitle = "AlgaeBase"
}
}
data.AlgaeBase.id = function(id)
-- https://www.algaebase.org/browse/taxonomy/?id=6898 (id for taxonomy page)

local title = id
local url = data.AlgaeBase.customArgs['baseURL'] .. data.AlgaeBase.customArgs['searchStr'] .. id
return title, url
end
data.AlgaeBase.genid = function(genid)
-- https://www.algaebase.org/search/genus/detail/?genus_id=43497 (different id for genus page)

local title = genid
local url = data.AlgaeBase.customArgs['baseURL'] .. "search/genus/detail/?genus_id=" .. genid
return title, url
end
data.AlgaeBase.spid = function(spid)
-- https://www.algaebase.org/search/species/detail/?species_id=52713 (id for species page)

local title = spid
local url = data.AlgaeBase.customArgs['baseURL'] .. "search/species/detail/?species_id=" .. spid
return title, url
end
data.AlgaeBase.error = function()
return "Requires id and title parameters"
end
-- General Functions

local function getArgs (frame, args)
local parents = mw.getCurrentFrame():getParent()

for k,v in pairs(parents.args) do
--check content
if v and v ~= "" then
args[k]=v --parents.args[k]
end
end
for k,v in pairs(frame.args) do
--check content
if v and v ~= "" then
args[k]=v
end
end
end
local function initialise(frame, sourceDB)

target=sourceDB
templateArgs = sourceDB.citationArgs -- get custom arguments for target (fishbase, cof etc

getArgs(frame, templateArgs) -- get template arguments from parent frame and frane


local url = (target.customArgs['baseURL'] or "") .. (target.customArgs['defaultSuffix'] or "")
local title = target.customArgs['defaultTitle'] or ""
return title, url
end
-- moved up top for scope
local function firstToUpper2(str)
return (str:gsub("^%l", string.upper))
end
-- clear template arguments that won't be recognised by
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
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 }}}}|&dq=}}}}}}}}
if templateArgs['q'] then searchStr = "&q=" .. mw.text.encode( templateArgs['q'] ) end
-- search if:}}}}|&q=}}}}}}}}
if templateArgs['dq'] then searchStr = "&dq=" .. mw.text.encode( templateArgs['dq'] ) end


templateArgs['section-url'] = templateArgs['section-url'] .. pageSuffix .. searchStr
templateArgs['url'] = nil -- no need for second link to google books
end

-- if the chapter/section is linked, we can link the main book chapter differently
if target.customArgs['altTitle'] then -- if we are using a chapter/section, we can wikilink the book title
templateArgs['title'] = target.customArgs['altTitle'] -- alternative to allow wikilink
elseif target.customArgs['altURL'] then
templateArgs['url'] = target.customArgs['altURL']
end

end -- end if using supplied title for chapter/section

clearCustomArgs()--blank template parameters not for cite web

local citeTemplate = 'cite book' -- use Template:Cite web unless specified
--if target.citeTemplate then citeTemplate = target.citeTemplate end
return 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
--======= Mammals
p.asm = function(frame) return p._main(frame, data.asm) end
-- MSW3 has custom handling (see above)
--=========== Other
p.fossilworks = function(frame) return p._main(frame, data.fossilworks) end
p.worms = function(frame) return p._main(frame, data.WoRMS) end
p.WoRMS = function(frame) return p._main(frame, data.WoRMS) end
p.col = function(frame) return p._main(frame, data.col) end
--fallback = function() return "hello" end
--
p.main = function(frame)
local source = mw.text.trim(frame.args[1])

if source "MSW3" then return p.MSW3(frame) end

if source "ref" or source == "reference" then source = "Reference" end -- aliases
if source "Reference" then return p.Reference(frame) end

if source "HBWa" then source = "HBWalive" end -- aliases
if source == "powo" then source = "POWO" end -- aliases
--return p[source]['test']
if source "fishbase"
or source "cof"
or source "fotw5" or source "Fotw5"
or source "reptileDB"
or source "amphibiaweb"
or source "ASW6"
or source "asm"
or source "HBWalive" or source "HBWa"
or source "fossilworks"
or source "WoRMS" or source "worms"
or source "POWO" or source "powo"
or source "WFO"
or source == "AlgaeBase"
-- and so on
then return p._main(frame,data[source])
else
--
-- is there a point in the default if it needs the named object/table?
return p._main(frame,data[source])
end
end
p._main = function(frame, source)

--TODO in modular version source will be provided in frame arguments
--local source = mw.getCurrentFrame():getParent().args[1]
local chapterParams = {} -- used for cite book (only MSW3 at moment)

if not source then return "Error: unrecognised source." end

local title, url = initialise(frame, source)

--taxon related parameters
local genus, species, subspecies

if source.db ~= "col" then -- col legacy uses positional parameters differently
genus, species, subspecies = getGenusSpecies()
end

local family = templateArgs['family']
local order = templateArgs['order']
local taxon = templateArgs['taxon']

local id = templateArgs['id'] --id related parameters
local spid = templateArgs['spid'] or templateArgs['species_id']
local genid = templateArgs['genid'] or templateArgs['genus_id']
local citation = templateArgs['citation']
local collection = templateArgs['collection'] or templateArgs['collection_no']
local search = templateArgs['search']
local mode, value

-- the functions
if genus and species and source.species then
title, url = source.species(genus,species,subspecies)
else -- functions with just their own name as parameter

if genus then mode = "genus"; value = genus
elseif family then mode = "family"; value = family
elseif order then mode = "order"; value = order
elseif taxon then mode = "taxon"; value = taxon
elseif id then mode = "id"; value = id
elseif spid then mode = "spid"; value = spid
elseif genid then mode = "genid"; value = genid
elseif search then mode = "search"; value = search
elseif citation then mode = "citation"; value = citation
elseif collection then mode = "collection"; value = collection
else
-- no suitable parameter (use default page)
if source.default then
title, url, chapterParams = source.default(title, url)
end
end
end
if mode then
if source[mode] then
title, url, chapterParams = source[mode](value)
elseif data.default[mode] then
title, url, chapterParams = data.default[mode](value, source)
else
if source.error then return source.error() end -- custom error message
return "Error: parameter not supported for this source" .. " (" .. mode .. ")"
end
else
-- if no mode then use the default title and url set by initialize()
end

if source.citeTemplate == "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['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