Module:Taxonbar/sandbox

require('strict')

local conf = require( 'Module:Taxonbar/conf' ) --configuration module local TaxonItalics = require( 'Module:TaxonItalics' ) --use a function to conditionally italicize taxon names

--========================================================================== --                            Local functions --==========================================================================

local function isNilOrEmpty( thing ) if thing == nil or thing == '' then return true end return nil end

local function getIdFromWikidata( item, property ) local id = nil if property == 'PWikispecies:$1' then local siteLinks = item.sitelinks if siteLinks then local speciesWiki = item.sitelinks.specieswiki if speciesWiki then id = speciesWiki.title end end return id	elseif item.claims[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 id end

local function getLink( property, db, val ) local link, returnVal = '', {} returnVal.isError = false if mw.ustring.find( val, '//' ) then link = val else if type(property) == 'number' and property > 0 then local entityObject = mw.wikibase.getEntity('P'..property) local dataType if entityObject then dataType = entityObject.datatype else returnVal.isError = true end if dataType == 'external-id' then local formatterURL = nil if property == 3746 or --Wildflowers of Israel property == 3795 or --Flora of Israel Online property == 5397   --Tierstimmenarchiv then formatterURL = entityObject:getBestStatements('P1630')[2] --use 2nd formatterURL for English version end if formatterURL == 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 == 'bow' then -- for birds of world which uses eBird identifier link = 'https://birdsoftheworld.org/bow/species/$1' elseif db == 'fossilworks' then link = 'https://paleobiodb.org/classic/basicTaxonInfo?taxon_no=$1' end elseif dataType == 'url' then 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 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) == 'string' then link = property end --local valurl = val local valurl = mw.uri.encode( val, 'PATH' ) valurl = string.gsub (valurl, '%%2F', '/') --escape '/' (e.g. issue with P5354); see wikidata T128078 and https://gerrit.wikimedia.org/r/c/mediawiki/extensions/Wikibase/+/664820/3/lib/includes/PropertyInfoSnakUrlExpander.php if type(property) == 'number' then --doublecheck language for Wildflowers of Israel ID			if property == 3746 then link = mw.ustring.gsub(link, '/hebrew/', '/english/') end --format spaces in PfaF binomials, e.g. "Elaeagnus x ebbingei" 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]?)&#58;//', '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 == '' then returnVal.text = val else returnVal.text = ' '..val..' ' end return returnVal end

local function createRow( id, label, rawValue, link, withUid ) if link then local outStr = '* '..label..' '..link..' \n' else return '* '..mw.text.tag('span', {class='error'}, 'The identifier '..id..' '..rawValue..' is not valid.')..'\n' end end

local 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 outTable end

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 = { ,		,		'', -- [3] placeholder for '', -- [4] placeholder for '', -- [5] placeholder for '', -- [6] placeholder for '', -- [7] placeholder for '', -- [8] placeholder for '', -- [9] placeholder for '', --[10] placeholder for '', --[11] placeholder for '', --[12] placeholder for '', --[13] placeholder for '', --[14] placeholder for '', --[15] placeholder for '', --[16] placeholder for '', --[17] placeholder for '', --[18] placeholder for '', --[19] placeholder for '', --[20] placeholder for '', --[21] placeholder for '', --[22] placeholder for '', --[23] placeholder for '', --[24] placeholder for '', --[25] placeholder for '', --[26] placeholder for '', --[27] placeholder for '', --[28] placeholder for }	local acceptableInstanceOf_Strict = whitelist{ args = { 'strict' } } local acceptableInstanceOf_All = whitelist{ args = { 'all' } } --Assess the page's relationship with Wikidata local currentItem = nil if currentTitle.namespace == 10 then --i.e. Module:Taxonbar/sandbox, Template:Taxonbar/doc, etc.		if resolveEntity._id(parentArgs['from']) then currentItem = mw.wikibase.getEntity(parentArgs['from']) end if currentItem == 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 == nil/unresolvable tCats[3] = '' end if currentItem then tCats[4] = '' --unset if acceptable found for _, instanceOfState in pairs ( currentItem:getBestStatements('P31') ) do --instance of			local instanceOf = instanceOfState.mainsnak.datavalue.value.id			if acceptableInstanceOf_All[instanceOf] then tCats[4] = '' break end end end --Cleanup args for k, v in pairs( frame:getParent.args ) do		if type(k) == '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$') == nil then --if no number at end of param if isNilOrEmpty( parentArgs[lowerk..'1'] ) then parentArgs[lowerk] = nil lowerk = lowerk..'1' parentArgs[lowerk] = v				end end if v and v ~= '' then --remap 'for' to 'title' if mw.ustring.sub(lowerk,1,3) == '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) == 'from' then local fromNumber = tonumber(mw.ustring.sub(lowerk,5,-1)) if fromNumber and fromNumber >= fromTitleCount then fromTitleCount = fromNumber end --look for duplicate froms while we're here if mw.ustring.find(v, '^Q%d') then if tFroms[v] then tCats[6] = '' tFroms[v] = tFroms[v] + 1 else tFroms[v] = 1 iFroms = iFroms + 1 end if iFroms == 2 then tCats[14] = '' end end elseif mw.ustring.sub(lowerk,1,5) == 'title' then local titleNumber = tonumber(mw.ustring.sub(lowerk,4,-1)) if titleNumber and titleNumber >= fromTitleCount then fromTitleCount = titleNumber end elseif mw.ustring.lower(v) ~= 'no' and mw.ustring.lower(v) ~= 'yes' then stringArgs = true tCats[9] = '' end end end --if type(k) == 'string' end --for --Check for unknown parameters --create knowns list --local acceptableArgs = { from = true, } --master list of l/c acceptable args local acceptableArgs = { from = true, format=true} --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) == 'string' then local lowerk = mw.ustring.lower(k) local base = mw.ustring.gsub(lowerk, '[%d]*$', '') baseParentArgs[base] = true elseif 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] == nil then tCats[12] = '' unknownParams[#unknownParams + 1] = k		end end --warn if unknown(s) present if #unknownParams > 0 then local plural = 's'		local itthem = 'them' if #unknownParams == 1 then plural = '' itthem = 'it' end errors = errors..require('Module:If preview')._warning({			mw.ustring.format( 'Unknown parameter%s. Please correct %s or consider adding %s to Wikidata.', plural, table.concat(unknownParams, ', '	end	if format == "grid-taxonbar"  then		local box = ' '		box = box     .. ' ' 		              ..    '' --		              ..    'Taxon identifiers'		              .. '  '		              .. ' '		output = box .. output .. '  '	end        return output .. frame:extensionTag('templatestyles', '',  	{ src="Module:Taxonbar/styles.css" }) end

function p.taxonbar(frame) return p.authorityControlTaxon( frame:newChild{title = frame:getTitle} ) end

return p