Moduł:Wikidane/format

Z Wikibooks, biblioteki wolnych podręczników.
Przejdź do nawigacji Przejdź do wyszukiwania
Template-info.png Dokumentacja modułu [zobacz] [edytuj] [historia] [odśwież]

Główny moduł implementujący funkcję {{#invoke:Wikidane|P}}. Nie jest przeznaczony do bezpośredniego wywołania. Implementuje mechanizm wywoływania wtyczek używanych do formatowania cech z Wikidanych, które są wyświetlane w infoboksach.

Standardowe parametry[edytuj]

procesor
wskazanie dedykowanej wtyczki do formatowania
link
włączenie lub wyłączenie generowania linków, jeśli obsługiwane przez wtyczkę
separator
sposób konwersji listy cech na końcową postać tekstową
bez wartości
treść dla wartości specjalnej novalue
format
tekst do formatowania treści, jeśli obsługiwane przez wtyczkę

Wtyczka[edytuj]

Wtyczka jest tablicą asocjacyjną zawierającą następujące elementy:

scope
obowiązkowe pole typu tekstowego zawierające identyfikator akceptowanego typu danych do formatowania przez wtyczkę
format
obowiązkowe pole typu funkcyjnego zawierające funkcję zamieniającą dane na tekst do wyświetlenia
options
opcjonalne pole do definiowania parametrów dla funkcji format

Wybór wtyczki jest wybierany na podstawie parametru procesor, który zawiera pełną nazwę modułu implementującego wtyczkę, lub jeśli nie podano na podstawie identyfikatora cechy. Podanie pustego parametru procesor oznacza użycie uniwersalnej wtyczki formatującej wynik.

Szablon typowego modułu formatującego cechę to

local moduleData = require("Moduł:Wikidane/data")           -- zbiór podstawowych stałych
local format = require("Moduł:Wikidane/format/snak").format -- uniwersalna wtyczka formatująca minimalną podstawową jednostkę danych

return {

scope = "prop",

format = function{prop, opcje)
	...
end,

}

scope[edytuj]

Dopuszczalne wartości pola to:

snak
podstawowa struktura definiujące jednostkę danych, zwykle wartość cechy (mainsnak) lub kwalifikator
prop
pełna cecha zawierająca mainsnak, kwalifikatory i źródła
props
tablica cech

format[edytuj]

Funkcja formatująca wartość cechy. Przyjmuje dwa parametry:

dane
tablica asocjacyjna z danymi w zakresie określonym polem scope
opcje
tablica asocjacyjna z parametrami
format = function{dane, opcje)
	...
end,

options[edytuj]

Jeśli pole jest tablicą to opcje dla wtyczki są inicjowane parametrami standardowymi (oprócz pola procesor) oraz parametrami zadeklarowanymi w tabeli. Dodatkowo pole default służy do zdefiniowania parametrów z wartościami domyślnymi. Przykład:

options = {
	"kij",
	"marchewka",
	default = {
		["kij"] = "lipowy",
		["żarcik"] = true,
	},
},

W powyższym kodzie zostały zdefiniowane dwa parametry kij i marchewka oraz domyślna wartość dla parametru kij. Natomiast żarcik nie jest parametrem możliwym do podania w wywołaniu funkcji, jest więc jakby predefiniowaną stałą.

Jeśli pole jest funkcją to żadne parametry nie są standardowo ładowane, a za przygotowanie wszystkich opcji odpowiedzialna jest zadeklarowana funkcja.

Jeśli pole nie jest ani tablicą ani funkcją, to wtyczka jest wywołana z pustą tablicą opcji.

Zobacz też[edytuj]

local moduleData = mw.loadData("Module:Wikidane/data")
local getArgs = require('Module:Arguments').getArgs

local function loadArgs(frame, custom)

	local args = getArgs(frame, {
		trim = false,
		removeBlanks = false,
		parentFirst = true,
		readOnly = true,
		noOverwrite = true,
	})

	local function loadArg(id)
		local result = args[id]
		return (result and (#result ~= 0)) and result or nil
	end
 
	local parseBool = function(arg)
		if type(arg) == "boolean" then
			return arg
		elseif arg == moduleData.boolYes then
			return true
		elseif arg == moduleData.boolNo then
			return false
		end
	end
 
	local parseSeparator = function(arg)
		if arg == moduleData.separatorAnd then
			return moduleData.defaultSeparator, moduleData.defaultLastAndSeparator
		elseif arg == moduleData.separatorOr then
			return moduleData.defaultSeparator, moduleData.defaultLastOrSeparator
		elseif arg == moduleData.separatorBullet then
			return "</li><li>", "</li><li>", "<ul><li>", "</li></ul>"
		elseif arg == moduleData.separatorOrdered then
			return "</li><li>", "</li><li>", "<ol><li>", "</li></ol>"
		elseif arg == moduleData.separatorOptionalBullet then
			return "</li><li>", "</li><li>", "<ul><li>", "</li></ul>", true
		elseif arg == moduleData.separatorOptionalOrdered then
			return "</li><li>", "</li><li>", "<ol><li>", "</li></ol>", true
		elseif arg == moduleData.separatorOr then
			return moduleData.defaultSeparator, moduleData.defaultLastOrSeparator
		elseif arg ~= nil then -- custom
			return arg, arg
		end
	end
	
	local function parseQualifiers(arg)
		if type(arg) == "table" then
			local result = {}
			for i, v in ipairs(arg) do
				local p = string.match(v, "^[pP](%d+)$")
				if p then
					table.insert(result, "P"..p)
				end
			end
			
			if #result > 0 then
				return result
			end
		end
	end
	
	local link = parseBool(loadArg(moduleData.argLink))
	local sep, lastSep, before, after, optional = parseSeparator(loadArg(moduleData.argSeparator))
	local qualifiers = parseQualifiers(loadArg("kwalifikatory"))
 
	local result = {
		linkCoordinates = link,
		linkDate = link,
		linkItem = link,
		separator = sep,
		lastSeparator = lastSep,
		separatorBefore = before,
		separatorAfter = after,
		separatorOptional = optional,
		novalue = loadArg(moduleData.argNoValue),
		format = loadArg(moduleData.argFormat),
		qualifiers = qualifiers,
	}
	
	if custom then
		for _, v in ipairs(custom) do
			if result[v] == nil then
				result[v] = loadArg(v)
			end
		end
 
		if custom.default then
			for k, v in pairs(custom.default) do
				if result[k] == nil then
					result[k] = v
				end
			end
		end
	end
 
	-- global defaults
	result.separator = result.separator or moduleData.defaultSeparator
	result.lastSeparator = result.lastSeparator or moduleData.defaultSeparator
	result.linkCoordinates = (result.linkCoordinates == nil) and moduleData.defaultLinkCoordinates or result.linkCoordinates
	result.linkDate = (result.linkDate == nil) and moduleData.defaultLinkDate or result.linkDate
	result.linkItem = (result.linkItem == nil) and moduleData.defaultLinkItem or result.linkItem
	result.separatorBefore = result.separatorBefore or ""
	result.separatorAfter = result.separatorAfter or ""
 
	return result
end

local function listToText(items, options)
	if (#items == 0) then
		return
	end
	
	if (#items == 1) and options.separatorOptional then
		return items[1]
	end
	
	return options.separatorBefore..mw.text.listToText(items, options.separator, options.lastSeparator)..options.separatorAfter
end

local runners = {
 
	["snak"] = function (processor, properties, options)
		local result = {}
 
		for i, p in ipairs(properties) do
			if (p.type == "statement") and p.mainsnak then
				local s = processor.format(p.mainsnak, options)
				if s and (#s > 0) then
					table.insert(result, s)
				end
			end
		end
 
		return listToText(result, options)
	end,
 
	["prop"] = function (processor, properties, options)
		local result = {}
 
		for i, p in ipairs(properties) do
			if (p.type == "statement") and p.mainsnak then
				local s = processor.format(p, options)
				if s and (#s > 0) then
					table.insert(result, s)
				end
			end
		end
 
		return listToText(result, options)
	end,
 
	["props"] = function (processor, properties, options)
		return processor.format(properties, options)
	end,
}

return {
	
run = function(frame, pid, properties)

	local automatic = function()
		local pinfo = mw.wikibase.getEntity(pid)
		return moduleData.processor[2][pinfo and pinfo.datatype or false]
			or moduleData.processor[1]
	end
	
	local processor = getArgs(frame).procesor
		or moduleData.processor[pid]
		or ""

	local module = require(#processor > 0 and processor or automatic())
	local options
	if module.options == nil then
		options = loadArgs(frame)
	elseif type(module.options) == "table" then
		options = loadArgs(frame, module.options)
	elseif type(module.options) == "function" then
		options = module.options(frame)
	else
		options = {}
	end

	if (#processor == 0) and (module.scope == "snak") then
		module = require(moduleData.processor[1])
	end
	
	local runner = runners[module.scope]
	if runner then
		return runner(module, properties, options)
	end
end,

}