跳转到内容

英文维基 | 中文维基 | 日文维基 | 草榴社区

模組:Biota infobox/Wikidata

维基百科,自由的百科全书
require('strict')

local p = {}
local templateArgs = {}
--local info = {}   
----------------------------------AUTOMATIC TAXONOMY (module and wikidata versions) -----------
function p.addModuleTaxonomy(frame, taxoboxTable, templateArgs) -- use invoke of module function

	local moduleData = require("Module:Sandbox/trappist the monk/taxonomy")
	local tree_t = {};
	local taxon = templateArgs['taxon']  or templateArgs['parent'] 
	
	tree_t = moduleData._crawl_tree(taxon, tree_t)	
	--local output = '\n|-\n|' .. table.concat (tree_t, '<br />')  -- dump the whole table
	local output = '' 
	for k,v in pairs (tree_t) do
    	local parts = mw.text.split(v, ": ", true)
    	
    	if string.sub(parts[1],1,3) == "'''" then
			local styled_rank  = string.gsub(parts[1], "'''", "")
			local linked_taxon = string.gsub(parts[2], "&nbsp;&nbsp;<small>.*", "")
	    	output = output ..	'\n|-\n|' .. styled_rank .. '||' .. linked_taxon 
	    	end
	end
	return output
end
--[[ p.WikidataTaxonomy(frame)
      - entry point for Template:Biota infobox/Wikidata  
]]
function p.WikidataTaxonomy(frame)
	
	-- get taxon name. This must be the Wikipedia page for the taxon (which is linked to the qid), e.g. Helix (gastropod)
	-- an alternative is to have a qid parameter
	local taxon = frame:getParent().args['taxon']  or frame.args['taxon']  --or "Felis"  
	local qid = frame:getParent().args['qid']  or frame.args['qid']
	
	if qid and not taxon then
		taxon = mw.wikibase.getSitelink(qid)  -- only works if taxon name, page title and taxonomy template match
	end
	if not qid and not taxon then
		return "No valid taxon or qid."
	end
	templateArgs['taxon'] = taxon -- p.addWikidataTaxonomy() gets the taxon from template parameters
	templateArgs['qid'] = qid
	
	-- contruct table comparing wikidata taxonomy and automated taxobox taxonomy
	local headerColor = "#ddeeff"
	local comment = '<p>Ancestral taxa taken from Wikidata. <br/>Bold taxa show those that will be displayed in taxobox.</p>'
	local output =   '{|\n|-\n| style="vertical-align:top;" |' .. comment                                                                      -- outer table
	                 .. '\n{| class="infobox biota" style="text-align: left; font-size:100%;"'  -- wikidata ancestry table
	                 
	output = output .. '\n|- \n! colspan="5" class="section-header" style="text-align:center;background:' ..  headerColor .. ';" '
               .. '|' .. "Ancestral taxa (from Wikidata)"
               .. '\n|- style="text-align:center;background:' ..  headerColor .. ';"' 
               .. '\n! Rank !! Taxon !! colspan="2" | Wikidata ID !! Parents at Wikdata'
	
	templateArgs['display_parents'] = "all"
	templateArgs['show_alt_parents'] = true
	templateArgs['select_parent'] =  frame:getParent().args['select_parent']  or frame.args['select_parent'] 
	output = output .. p._addWikidataTaxonomy(frame)
	
	if  not (frame:getParent().args['suppress_autotaxonomy_comparison']  or frame.args['suppress_autotaxonomy_comparison'])  then
		taxon = taxon:gsub("(.*)%s%(.*%)", "%1") -- remove disambiguation
		local automatedTaxonomyList = frame:callParserFunction ('#invoke', {'Autotaxobox/sandbox', 'taxonomyList', taxon})
		automatedTaxonomyList = automatedTaxonomyList:gsub("Ancestral taxa", "Ancestral taxa <br/>(from automated taxonomy templates)")
		output = output .. '\n|}'             -- close wikidata table
		                .. '\n| style="vertical-align:top;" |'             -- cell for automated taxonomy table
		                .. automatedTaxonomyList
		                .. '\n|}'
	else
		output = output .. '\n|}'  .. '\n|}'           -- close wikidata table and outer table
	end
	return output
	
end
function p.getAnchor(frame)
	--return "Felis" --mw.title.getCurrentTitle().fragment
end

function p.addWikidataTaxonomy(frame, taxoboxTable, args) -- use invoke of module function
    templateArgs = args
    return  p._addWikidataTaxonomy(frame) 
end
function p._addWikidataTaxonomy(frame) -- use invoke of module function
    
    
    local qid
    local taxon = templateArgs['taxon'] or templateArgs['parent']  -- parent set for species and subspeciesbox
    if templateArgs['qid'] then
    	qid = templateArgs['qid']                        --  get qid from parameter
    else
    	qid = mw.wikibase.getEntityIdForTitle (taxon)   -- get qid from Wikipedia page on taxon
    end
    if not qid then 
    	return "The taxon name must be the Wikipedia page title. Alternatively provide the Wikidata qid (qid=)." 
    end
    
    local rows = ""
    local row = "| rank || taxon"
    local count = 0
    while qid and count < 100 do
	    local taxonInfo = p.getTaxonInfo(qid)
	    if not taxonInfo.rank then taxonInfo.rank = "unranked" end
	    if not taxonInfo.taxon then taxonInfo.taxon = "no taxon name" end
	    
        if p.showTaxonRow(taxonInfo.rank, taxonInfo.taxon, count) then  -- display required rows
        	local link = ""
        	local italics = ""
        	if taxonInfo.rank == "genus" then italics = "''" end
        	if taxonInfo.siteLink and taxonInfo.siteLink ~= taxonInfo.taxon then link = taxonInfo.siteLink .. "|" end
	    	row = "\n|-\n| " .. p.firstToUpper(taxonInfo.rank) 
	    	                 .. "||" .. italics .. "[[" .. link .. taxonInfo.taxon .. "]]" .. italics
	    	                 
	    	if templateArgs['show_alt_parents'] and taxonInfo.altParents then  
	    		row = row   .. '||[[:d:' .. qid .. '|' .. qid .. ']]'
	    		            .. '||[[:d:' .. qid .. '#P171|[edit]]]'
	    		            .. "||" .. taxonInfo.altParents 
	        end
	        rows = row   .. rows
	    end
	    
	    if taxonInfo.parent then 
	    	qid = taxonInfo.parent  -- next parent
	    else 
	    	qid = nil  -- no more parents so stop
	    end
	    count = count + 1
    end

    return rows
end
local majorRanks = { "superkingdom", "kingdom", "phylum", "division", "class", "order", "family", "genus", "species" }
function p.showTaxonRow(rank, taxon, count)
		
	local majorRank = false
    for k, v in pairs(majorRanks) do
    	if rank == v then 
    		majorRank = true            -- flag major ranks for display
    		majorRanks[k] = nil         -- don't show this class again in hierarchy (e.g. for mammals, birds)
    	end
    end
    if majorRank then return true end

	if count < (tonumber(templateArgs['display_parents']) or 2) then return true end  
	if templateArgs['display_parents'] == "all" then return true end
	
	if templateArgs['display_parent_taxa'] then
		if string.find(templateArgs['display_parent_taxa'], taxon) then return true end
	end
	if templateArgs['display_parent_ranks']  then
		for v in mw.text.gsplit(templateArgs['display_parent_ranks'], ",", true) do
			if rank == mw.text.trim(v) then return true end
		end
		
	end
	
	return false
end
function p.getTaxonInfo(qid)

    --local rank, taxon, parent
    local taxonInfo = {}

    --[[
         local item = mw.wikibase.getEntity(qid)  -- this increments the expensive parser function count
         so instead of 
            item:getBestStatements(property)
         use 
        	mw.wikibase.getBestStatements(qid, property)
    ]]
    local statements = mw.wikibase.getBestStatements(qid, 'P105')[1]                           --taxon rank
    if statements and statements.mainsnak and statements.mainsnak.datavalue then
    	taxonInfo.rank = mw.wikibase.getLabel(statements.mainsnak.datavalue.value.id)
    end
    local statements = mw.wikibase.getBestStatements(qid, 'P225')[1]                           -- taxon name
    if statements and statements.mainsnak and statements.mainsnak.datavalue then
    	taxonInfo.taxon = statements.mainsnak.datavalue.value
    end   

    local statements = mw.wikibase.getBestStatements(qid, 'P171')                           -- taxon parent
    local statement = statements[1]
    if statement and statement.mainsnak and statement.mainsnak.datavalue then
    	taxonInfo.parent = statement.mainsnak.datavalue.value.id                    -- use first value
    end   
    
    for index, statement in pairs( statements ) do
    	local id
    	if statement and statement.mainsnak and statement.mainsnak.datavalue then
    		id = statement.mainsnak.datavalue.value.id
    	end
    	if id then
    		local label = mw.wikibase.getLabel(id)
    		local parentString = label .. "&nbsp;([[:d:" .. id .. "#P171|" .. id .. "]])"
	    	if taxonInfo.altParents then
	    	    taxonInfo.altParents = taxonInfo.altParents .. "</br/>" .. parentString
	    	else
	    		taxonInfo.altParents = parentString
	    	end
	    	local selectParent = templateArgs['select_parent'] or "1"         -- template parameters read as strings
	    	if selectParent == tostring(index) or selectParent == "last" then
	    		taxonInfo.parent = id  
	    	end
    	end
    end
    
    local label = mw.wikibase.getLabel(qid)
    if label then taxonInfo.label = label end
    
    local siteLink = mw.wikibase.getSitelink(qid) 
    if siteLink then taxonInfo.siteLink = siteLink end
    
    
    return taxonInfo --rank, taxon, parent

end
function p.firstToUpper(str)
    return (str:gsub("^%l", string.upper))
end


return p