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 local acceptableArgs = --master list of l/c acceptable args (adding format for alternative outputs) 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
2 then -- suppress the non-language wiki matches below elseif string.match(v.site, "species") then --output = output .. "| SPECIES" elseif string.match(v.site, "commons") then --output = output .. "| COMMONS" elseif string.match(v.site, "news") then --output = output .. "| NEWS" -- also ruwikinews, etc elseif string.match(v.site, "quote") then --output = output .. "| QUOTE" -- also ruwikiquote, plwikiquote, etc elseif string.match(v.site, "source") then --output = output .. "| SOURCE" -- also sawikisource else -- only use language wikipedias output = output .. " | " .. v.site .. ": " table.insert(langlinks, "\n* " .. v.site .. ": ") end end --mw.addWarning(table.concat(langlinks)) navboxParams['list1'] = table.concat(langlinks) end end -- END test sitelinks end --for f = 1, fromTitleCount, 1 if rowCount > 0 then local Navbox = require('Module:Navbox') if rowCount > 1 then --remove duplicates and don't bother moving page title to top local rowIDs = for f = 1, fromTitleCount, 1 do if not isNilOrEmpty(parentArgs['title'..f]) then if rowIDs[parentArgs['wikidata'..f]] then --remove duplicate navboxParams['group'..f] = nil navboxParams['list'..f] = nil else rowIDs[parentArgs['wikidata'..f]] = true end end end if parentArgs['title'..2] and parentArgs['title'..2]
currentItem['id'] then tCats[8] = '' else tCats[7] = '' end end --adjust navbox for number of rows navboxParams['title'] = 'Taxon identifiers' if rowCount >= 4 then navboxParams['navbar'] = 'plain' else navboxParams['state'] = 'off' navboxParams['navbar'] = 'off' end elseif parentArgs['noTitle'..firstRow] then --show title & taxon for 1-row taxonbars, per talk --BEGIN sitelist test if frame:getParent.args.sitelinks then -- if using test sitelinks output --navboxParams['group'..firstRow] = 'Interlanguage links' navboxParams['title'] = 'Interlanguage links' navboxParams['state'] = 'off' navboxParams['navbar'] = 'off' else --END sitelist test code --navboxParams['group'..firstRow] = 'Taxon identifiers' --old version navboxParams['title'] = 'Taxon identifiers' navboxParams['state'] = 'off' navboxParams['navbar'] = 'off' end else navboxParams['group'..firstRow] = 'Taxon identifiers
'..navboxParams['group'..firstRow] end -- return alternative output if format set to valid value if parentArgs.format then local alternativeOutput = p.alternativeOutputs (frame, parentArgs, navboxParams, fromTitleCount) if alternativeOutput then return alternativeOutput -- return the alternative output and done end end -- otherwusee proceed as normal to navbox --return navbox outString = Navbox._navbox(navboxParams) end --if rowCount > 0 --Add categories if string.sub(currentTitle.subpageText,1,9)
0 then outString = outString..table.concat(tCats) end return outString..errorsend--experimental function to output identifier links without using Navbox not using outstring and categories/errors--function p.alternativeOutputs (frame, parentArgs, navboxParams, fromTitleCount) local output = "" local format = parentArgs.format for f = 1, fromTitleCount, 1 do if format
"efn" then local styles = frame:extensionTag output = output .. frame:expandTemplate elseif format
"list-horizontal" then --local styles = frame:extensionTag output = output .. navboxParams["group"..f] .. ':
\n' .. navboxParams["list"..f] .. '
' elseif format
"list" then output = output .. frame:expandTemplate elseif format
"hidden" then -- doesn't work in mobile output = output .. frame:expandTemplate elseif format
' -- using templatestyles .. navboxParams["group"..f] .. '
' .. '
\n' .. navboxParams["list"..f] .. '
' --- backgrond colors: odd= rgb(253, 253, 253) even=rgb(247, 247, 247) else return false -- if no valid format end end -- now box the pseudo-taxonbar if format
' box = box .. '
' ..' ' .. 'Taxon identifiers' .. ' |
---|
' box = box .. '
' .. '
' -- .. 'Taxon identifiers' .. '
' .. '
' output = box .. output .. '
' end return output .. frame:extensionTag('templatestyles', , )end
function p.taxonbar(frame) return p.authorityControlTaxon(frame:newChild) end
return p