Jump to content

Module:Convert/wikidata/sandbox

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Johnuniq (talk | contribs) at 06:05, 13 May 2016 (Wikidata handling for Module:Convert). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)
-- Functions to access Wikidata for Module:Convert.

local function collection()
	-- Return a table to hold items.
	return {
		n = 0,
		add = function (self, item)
			self.n = self.n + 1
			self[self.n] = item
		end,
	}
end

local function strip_to_nil(text)
	-- If text is a non-empty string, return its trimmed content,
	-- otherwise return nothing (empty string or not a string).
	if type(text) == 'string' then
		return text:match('(%S.-)%s*$')
	end
end

local function adjustparameters(tdata, parms, pid, index)
	-- For Module:Convert, adjust parms (a table of {{convert}} parameters).
	-- Return true if successful or return false, t where t is an error message table.
	-- Given that pid is a Wikidata property identifier like 'P123',
	-- try to find a value and unit for the pid.
	-- If successful, replace parms[index] with the value and
	-- insert the unit after index.
	local units = tdata.wikidata_units
	local qid = strip_to_nil(parms.qid)  -- nil (item is current page) or requested id (expensive)
	local entity = mw.wikibase.getEntity(qid)
	local claims = ((entity or {}).claims or {})[pid]
	if claims and claims[1] then
		local first = claims[1]  -- TODO taking the first claim is not adequate
		if first.mainsnak and first.mainsnak.datatype == 'quantity' then
			local value = (first.mainsnak.datavalue or {}).value
			if value then
				local amount = value.amount
				local unit = units[(value.unit or ''):match('Q%d+$')]
				if amount and unit then
					if amount:sub(1, 1) == '+' then
						amount = amount:sub(2)
					end
					parms[index] = amount
					table.insert(parms, index + 1, unit.ucode)
					return true
				end
			end
		end
	end
	return false, { 'cvt_wd_property', tostring(pid),
		qid and (' for item ' .. tostring(qid)) or '' }
end

local function listunits(tdata, ulookup)
	-- For Module:Convert, make wikitext to list the built-in Wikidata units.
	-- Return true, wikitext if successful or return false, t where t is an
	-- error message table. Currently, an error return never occurs.
	local units = tdata.wikidata_units
	local result = collection()
	local function get_unit_name(ucode)
		local success, unit_table = ulookup(ucode)
		if success then
			if unit_table.name1 then
				return unit_table.name1
			end
			return 'Cannot get name of unit; per unit?'
		end
		return 'ERROR: unknown unit code'
	end
	local keys, n = {}, 0
	for k, v in pairs(units) do
		n = n + 1
		keys[n] = k
	end
	table.sort(keys)
	for _, qid in ipairs(keys) do
		local unit = units[qid]
		result:add(string.format('*[[d:%s]] (%s) = %s (%s)',
			qid,
			unit.label,
			unit.ucode,
			get_unit_name(unit.ucode))
		)
	end
	return true, table.concat(result, '\n')
end

return { _adjustparameters = adjustparameters, _listunits = listunits }