require('strict')
local conf = require('Module:Taxonbar/conf') --configuration modulelocal TaxonItalics = require('Module:TaxonItalics') --use a function to conditionally italicize taxon names
----Local functions --
local function isNilOrEmpty(thing) if thing
then return true end return nilend
local function getIdFromWikidata(item, property) local id = nil if property
nil then return id end --this code picks up deprecated values on wikidata; better to use getBestStatements for _, statement in pairs(item.claims[property]) do if statement.mainsnak.datavalue then id = statement.mainsnak.datavalue.value break end end local statements = item:getBestStatements(property)[1] if statements and statements.mainsnak and statements.mainsnak.datavalue and statements.mainsnak.datavalue.value then id = statements.mainsnak.datavalue.value end
return idend
local function getLink(property, db, val) local link, returnVal = , returnVal.isError = false if mw.ustring.find(val, '//') then link = val else if type(property)
'external-id' then local formatterURL = nil if property
3795 or --Flora of Israel Online property
nil then formatterURL = entityObject:getBestStatements('P1630')[1] end --default to [1] if formatterURL then if formatterURL.mainsnak.datavalue and formatterURL.mainsnak.datavalue.value then --nil check for ABA link = formatterURL.mainsnak.datavalue.value end end if db
'fossilworks' then link = 'https://paleobiodb.org/classic/basicTaxonInfo?taxon_no=$1' end elseif dataType
'string' then local formatterURL = entityObject:getBestStatements('P1630')[1] if formatterURL then link = formatterURL.mainsnak.datavalue.value else local subjectItem = entityObject:getBestStatements('P1629')[1] if subjectItem then local officialWebsite = mw.wikibase.getEntity(subjectItem.mainsnak.datavalue.value.id):getBestStatements('P856')[1] if officialWebsite then link = officialWebsite.mainsnak.datavalue.value end end end else returnVal.isError = true end elseif type(property)
'number' then --doublecheck language for Wildflowers of Israel ID if property
4301 then valurl = mw.ustring.gsub(valurl, '%%20', '+') end end valurl = mw.ustring.gsub(valurl,'%%','%%%%') link = mw.ustring.gsub(link, '$1', valurl) end link = mw.ustring.gsub(link, '^[Hh][Tt][Tt][Pp]([Ss]?)://', 'http%1://') --fix wikidata URL val = mw.ustring.match(val, '([^=/]*)/?$') --get display name from end of URL if mw.ustring.find(link, '//') then returnVal.text = '['..link..' '..mw.text.encode(mw.uri.decode(val, 'PATH'),'%[%]')..']' elseif link
local function createRow(id, label, rawValue, link, withUid) if link then local outStr = '*
'..label..' '..link..'\n' else return '* '..mw.text.tag('span',, 'The identifier '..id..' '..rawValue..' is not valid.')..'\n' endendlocal function copyTable(inTable) if type(inTable) ~= 'table' then return inTable end local outTable = setmetatable(getmetatable(inTable)) for key, value in pairs (inTable) do outTable[copyTable(key)] = copyTable(value) end return outTableend
local p =
----Main --
function p.authorityControlTaxon(frame) local resolveEntity = require('Module:ResolveEntityId') local whitelist = require('Module:Taxonbar/whitelist').whitelist --to create acceptableInstanceOf_Strict & acceptableInstanceOf_All local parentArgs = copyTable(frame:getParent.args) local currentTitle = mw.title.getCurrentTitle local currentEntityId = mw.wikibase.getEntityIdForCurrentPage local stringArgs = false local fromTitleCount, firstRow, rowCount = 1, 0, 0 local outString, errors = , local iFroms = 0 --integer size of tFroms, b/c Lua local tFroms = --non-sequential table of unique froms local tCats = local acceptableInstanceOf_Strict = whitelist local acceptableInstanceOf_All = whitelist --Assess the page's relationship with Wikidata local currentItem = nil if currentTitle.namespace
nil then if resolveEntity._id(parentArgs['from1']) then currentItem = mw.wikibase.getEntity(parentArgs['from1']) end end elseif resolveEntity._id(currentEntityId) then currentItem = mw.wikibase.getEntity(currentEntityId) else --currentEntityId
'string' then --make args case insensitive local lowerk = mw.ustring.lower(k) if isNilOrEmpty(parentArgs[lowerk]) then parentArgs[k] = nil parentArgs[lowerk] = v end --remap abc to abc1 if mw.ustring.find(lowerk,'%d$')
'for' then local forTitle = mw.ustring.gsub(lowerk,'^for','title',1) if isNilOrEmpty(parentArgs[forTitle]) then parentArgs[lowerk] = nil lowerk = forTitle parentArgs[lowerk] = v end end --find highest from or title param if mw.ustring.sub(lowerk,1,4)
2 then tCats[14] = '' end end elseif mw.ustring.sub(lowerk,1,5)
'string' end --for --Check for unknown parameters --create knowns list local acceptableArgs = --master list of l/c acceptable args for _, d in pairs(conf.databases) do if d[1] ~= 'Wikidata' then --made obsolete by from acceptableArgs[mw.ustring.lower(d[1])] = true end end for _, a in pairs(conf.aliases) do acceptableArgs[mw.ustring.lower(a[1])] = true end --create trimmed parents list local baseParentArgs = --condensed list of l/c parent args w/o trailing #s for k, _ in pairs(parentArgs) do if type(k)
'number' then tCats[13] = '' end end --compare lists and spit out unknowns local unknownParams = for k, _ in pairs(baseParentArgs) do if acceptableArgs[k]
1 then plural = itthem = 'it' end errors = errors..require('Module:If preview')._warning end --Append basionym to arg list, if not already provided if currentItem then local currentBasState = currentItem:getBestStatements('P566')[1] --basionym if currentBasState then local basionymId = currentBasState.mainsnak.datavalue.value.id if basionymId and resolveEntity._id(basionymId) and tFroms[basionymId]
nil then --check that orco is a strict instance of taxon local orcoItem = mw.wikibase.getEntity(orcoId) if orcoItem then for _, instanceOfState in pairs (orcoItem:getBestStatements('P31')) do --instance of local instanceOf = instanceOfState.mainsnak.datavalue.value.id if acceptableInstanceOf_Strict[instanceOf] then --housekeeping tFroms[orcoId] = 1 iFroms = iFroms + 1 fromTitleCount = fromTitleCount + 1 --append orco & track parentArgs['from'..fromTitleCount] = orcoId tCats[16] = '' break end end end end end end --Append monotypic genus/species to arg list of monotypic species/genus, if not already provided if currentItem then for _, instanceOfState in pairs (currentItem:getBestStatements('P31')) do --instance of local taxonRank = nil local parentItem = nil local parentTaxon = nil local parentTaxonRank = nil local parentMonoGenus = nil --holy grail/tbd local childItem = nil local childTaxon = nil local childTaxonRank = nil local childMonoSpecies = nil --holy grail/tbd local instanceOf = instanceOfState.mainsnak.datavalue.value.id if instanceOf and (instanceOf
'Q47487597') then --monotypic/fossil taxon local taxonRankState = currentItem:getBestStatements('P105')[1] --taxon rank if taxonRankState then taxonRank = taxonRankState.mainsnak.datavalue.value.id end if taxonRank and taxonRank
genus & monotypic if parentTaxon and resolveEntity._id(parentTaxon) then parentItem = mw.wikibase.getEntity(parentTaxon) if parentItem then local parentTaxonRankState = parentItem:getBestStatements('P105')[1] --taxon rank if parentTaxonRankState then parentTaxonRank = parentTaxonRankState.mainsnak.datavalue.value.id end if parentTaxonRank and parentTaxonRank
genus for _, parentInstanceOfState in pairs (parentItem:getBestStatements('P31')) do --instance of local parentInstanceOf = parentInstanceOfState.mainsnak.datavalue.value.id if parentInstanceOf and (parentInstanceOf
'Q47487597') then --monotypic/fossil taxon parentMonoGenus = parentTaxon --confirmed break end end if parentMonoGenus and tFroms[parentMonoGenus]
nil or tFroms[parentMonoGenus]
'Q34740' then --genus --is monotypic genus; add species --(https://www.wikidata.org/wiki/Wikidata:Property_proposal/child_monotypic_taxon unnecessary thanks to P427!) local childTaxonState = currentItem:getBestStatements('P427')[1] --taxonomic type if childTaxonState then childTaxon = childTaxonState.mainsnak.datavalue.value.id end --confirm child taxon rank
'Q7432' then --child
'Q310890' or childInstanceOf
nil then --housekeeping tFroms[childMonoSpecies] = 1 iFroms = iFroms + 1 fromTitleCount = fromTitleCount + 1 --append monotypic species & track parentArgs['from'..fromTitleCount] = childMonoSpecies tCats[17] = '' break end end end end if childMonoSpecies
nil then tCats[20] = '' break end end --monotype searches end --monotype handling end --for end --if currentItem --Setup navbox local navboxParams = for f = 1, fromTitleCount, 1 do local elements, title =, nil --cleanup parameters if parentArgs['from'..f]
then parentArgs['title'..f] = nil end --remap aliases for _, a in pairs(conf.aliases) do local alias, name = mw.ustring.lower(a[1]), mw.ustring.lower(a[2]) if parentArgs[alias..f] and parentArgs[name..f]
'table' then local statements = item:getBestStatements('P225')[1] --taxon name if statements then local datavalue = statements.mainsnak.datavalue if datavalue then label = datavalue.value end end label = label or item:getLabel else if parentArgs['from'..f] then tCats[1] = tCats[5] = '' errors = errors..mw.text.tag('strong',, 'Error: "'.. parentArgs['from'..f]..'" is not a valid Wikidata entity ID.
') end end if label and label ~= then title = mw.title.new(label) end if title
nil and f
0) then if parentArgs['from'..f] then parentArgs['wikidata'..f] = parentArgs['from'..f] elseif item then parentArgs['wikidata'..f] = item.id end end if title.namespace
'string' or (type(propId)
wikidataId then tCats[10] = '' end end end end if (item and item.claims) and ((type(propId)
'yes' then if wikidataId then parentArgs[params[1]..f] = wikidataId else parentArgs[params[1]..f] = nil -- don't want to use 'yes' as id end end end local val = parentArgs[params[1]..f] if val and val ~= and mw.ustring.lower(val) ~= 'no' then if type(propId)
'fossilworks' then -- fossilworks being use to link to PBDB if (elements[#elements]
0; no link table.insert(elements, createRow(params[1], params[2]..':', val, val, true)) end else table.insert(elements, createRow(params[1], params[2]..':', val, getLink(propId, params[1], val).text, true)) end if params[1] ~= 'wikidata' and params[1] ~= 'wikispecies' then sourceCount = sourceCount + 1 end end end --for if sourceCount >= 45 then tCats[28] = '' elseif sourceCount >= 40 then tCats[27] = '' --endashes elseif sourceCount >= 35 then tCats[26] = '' elseif sourceCount >= 30 then tCats[25] = '' elseif sourceCount >= 25 then tCats[24] = '' elseif sourceCount >= 20 then tCats[23] = '' end --Generate navbox title if sourceCount > 0 then rowCount = rowCount + 1 if firstRow
parentArgs['from'..f] or fromTitleCount
currentEntityId then tCats[2] = --blank "desynced" if 'from' matches current page end end if tCats[1] ~= then tCats[2] = --cannot be "desynced" if no 'from' params end end --if title.namespace
currentTitle.text then if currentItem and parentArgs['from'..2]
'testcases' then parentArgs['demo'] = true end if not isNilOrEmpty(parentArgs['demo']) then outString = outString..mw.text.nowiki(table.concat(tCats))..'
' elseif currentTitle.namespace
function p.taxonbar(frame) return p.authorityControlTaxon(frame:newChild) end
return p