Module:Tableau qualificateurs

La documentation pour ce module peut être créée à Module:Tableau qualificateurs/Documentation

local wikidata = require 'Module:Wikidata'

local p = {}


function sortTypeFromWikibaseType(type)
	local map = {
		['quantity'] = 'number',
		['time'] = 'date', --TODO: check?
		['url'] = 'url'
	}

	if map[type] ~= nil then
		return map[type]
	else
		return nil
	end
end

function propertyLabel(property, options)
	local i = 0
	while options[property] ~= nil and i < 10 do
		property = options[property]
		i = i + 1
	end
	if property:match('^Q%d+:P%d+$') then
		local parts = mw.text.split(property, ':', true)
		return propertyLabel(parts[1], options) .. ' | ' .. propertyLabel(parts[2], options)
	elseif property:match('^[QP]%d+$') then
		return mw.wikibase.label(property)
	else
		return property
	end
end

function claimsToArray(claims_for_entity, options)
	local headers = {}
	local types = {}
	local row_per_main_snak = {}

	--Parse options in order to create columns
	local newCol = 1
	for i, property in pairs(options) do
		if type(i) == 'number' then
			property = propertyLabel(property, options)
			headers[property] = newCol
			newCol = newCol + 1
		end
	end

	--Converts claims
	for entity,claims in pairs(claims_for_entity) do
		for _, claim in pairs(claims) do
			property = propertyLabel('main:' .. claim.mainsnak.property, options)
			if property == 'main:' .. claim.mainsnak.property then
				property = propertyLabel(claim.mainsnak.property, options)
			end
			main_snak = wikidata.formatSnak(claim.mainsnak, {})
			if row_per_main_snak[main_snak] == nil then
				row_per_main_snak[main_snak] = {}
			end
			if headers[property] ~= nil then
				types[property] = sortTypeFromWikibaseType(claim.mainsnak.datatype)
				row_per_main_snak[main_snak][headers[property]] = main_snak
			end
	
			if claim.qualifiers ~= nil then
				for _, qs in pairs(claim.qualifiers) do
					for _, qualifier in pairs(qs) do
						--Hacky lookup to find the right property
						property = propertyLabel(entity .. ':' .. qualifier.property, options)
						if headers[property] == nil then
							property = propertyLabel(qualifier.property, options)
						end

						if headers[property] ~= nil then
							types[property] = sortTypeFromWikibaseType(qualifier.datatype)
							if row_per_main_snak[main_snak][headers[property]] ~= nil then
								row_per_main_snak[main_snak][headers[property]] = row_per_main_snak[main_snak][headers[property]] .. '<br />' .. wikidata.formatSnak(qualifier, {})
							else
								row_per_main_snak[main_snak][headers[property]] = wikidata.formatSnak(qualifier, {})
							end
						end
					end
				end
			end
		end
	end

	--Builds final rows
	local rows = {{}}
	for property, i in pairs(headers) do
		rows[1][i] = property
	end

	local i = 2
	for _,row in pairs(row_per_main_snak) do
		rows[i + 1] = row
		i = i + 1
	end

	return rows, types
end

function formatArray(rows, types)
	local str = '{| class="wikitable sortable"'

	--header
	local groups = '\n|-'
	local headers = ''
	local last_group = nil
	local last_group_count = 0
	local with_groups = false
	for i,label in pairs(rows[1]) do
		local parts = mw.text.split(label, '|', true)
		local group = nil
		if #parts == 2 then
			group = mw.text.trim(parts[1])
			label = mw.text.trim(parts[2])
		end
		if group == last_group then
			last_group_count = last_group_count + 1
		else
			if last_group ~= nil then
				groups = groups .. '\n! scope="col" colspan="' .. last_group_count .. '" |' .. last_group
				with_groups = true
			else
				groups = groups .. '\n| scope="col" colspan="' .. last_group_count .. '" |&nbsp;'
			end
			last_group = group
			last_group_count = 1
		end
		rows[1][i] = label
	end
	if last_group ~= nil then
		groups = groups .. '\n! scope="col" colspan="' .. last_group_count .. '" |' .. last_group
		with_groups = true
	end
	
	if with_groups then
		str = str .. groups
	end

	for i,row in pairs(rows) do
		str = str .. '\n|-'

		--real output
		for j,_ in pairs(rows[1]) do
			if row[j] == nil then
				str = str .. '\n|'
			else
				if i == 1 then
					if types[property] ~= nil then
						str = str .. '\n! scope="col"  data-sort-type="' .. types[property] .. '" |'
					else
						str = str .. '\n! scope="col" |'
					end
				elseif j == 1 then
					str = str .. '\n! scope="row" |'
				else
					str = str .. '\n|'
				end
				str = str .. ' ' .. row[j]
			end
		end
	end

	return str .. '\n|}\n'
end

function p.tableau(frame)
	--get and cleanup args
	local args = {}
	for k,v in pairs(frame:getParent().args) do
		if type(i) == 'string' then
			args[mw.text.trim(k)] = mw.text.trim(v, '\t\n\r ')
		else 
			args[k] = mw.text.trim(v)
		end
	end
	if args['entity'] == nil then
		return ''
	end

	--Retrieves claims for each entity provided
	local claims_for_entity = {}
	for _,entity in pairs(mw.text.split(args['entity'], '%s')) do
		if entity ~= '' then
			args['entity'] = entity
			claims_for_entity[entity] = wikidata.getClaims(args)
		end
	end
	return formatArray(claimsToArray(claims_for_entity, args))
end

return p