Modul:Title

Dies ist eine alte Version dieser Seite, zuletzt bearbeitet am 7. November 2022 um 02:48 Uhr durch Vollbracht (Diskussion | Beiträge). Sie kann sich erheblich von der aktuellen Version unterscheiden.

Die Dokumentation für dieses Modul kann unter Modul:Title/Doku erstellt werden

--[=[  Title 2022-11-04
	gather all title information from all sources available
	
	Autor: Vollbracht
	
* p.service	object
	fields
		CONTENT_LANG	as of mw.language.getContentLanguage():getCode()
		dataLink	Wikidata object identifier (Q123..., optional)
		wd			Wikidata link ([[d:Q123...|wd]], optional)
		title		P1476, object (most significant statement)
						text		monolingual title
						lang		language shortening (en, de, etc., optional)
						language	language of title (English, German, etc., or
									Englisch, Deutsch, etc., depending on
									content language)
		originalTitle	P1476, object,
					(statement marked P3831 = Q1294573, optional, see title)
		lang		P407, language shortening
					(en, de, etc., optional, fall back to title.lang)
		language	P407, language of service object
					(see title.language, fall back to title.language)
		oriLang		P364, language shortening
					(en, de, etc., optional, fall back to originalTitle.lang)
		originalLanguage	P364, original language of service object
					(see title.language, fall back to originalTitle.language)
	constructor
		new(source, language)
	methods
		__tostring()	returns string: ''<title>'' (<title language>)
		infoBrace		returns additional informations in braces
		titleLink()		returns link: [[''<title>'']] if available
---- template functions ----
* standard(object)		returns string: ''<title>'' (<title language>)
* full(object)			returns all relevant data (no 'lang'-fields)
* getTitle(object)		returns string: ''<title>''
* getLanguage(object)
* getOriginalTitle(object)
* getOriginalLanguage(object)
]=]

--Module globals

local p = {service = {
	PREF_LANG = 'de',
	CONTENT_LANG = mw.language.getContentLanguage():getCode(),
	FIELDS = {
		'dataLink', 'wd', 'title', 'originalTitle',
		'lang', 'language', 'oriLang', 'originalLanguage'
	}
}}

local _, SDA = pcall(require, "Modul:SimpleDataAccess")

------------------------- local functions and objects -------------------------
-- a title may have a role (P3831) "is original title" (Q1294573)
local function isOri(roles)
	for _, v in ipairs(roles) do
		if v.datavalue.value.id == 'Q1294573' then return true end
	end
	return false
end

-- a single title object
single = {}

function single:new(title, language, test)
	if not title then return nil end
	local result = {}
	self.__index = self
	local foundPreferred = false
	if type(title) == 'table' then
		local ms = title.mainsnak
		if ms then
			mdv = ms.datavalue.value
			if type(mdv) == 'string' then
				result = {text = result}
				-- language is initial value
				l = mw.language.fetchLanguageName(	language,
													p.service.CONTENT_LANG)
				if l then
					result.lang = language
					result.language = l
				else
					result.language = language
				end
				return setmetatable(result, self), false
			end
			if type(mdv) ~= 'table' then return nil end
			if not mdv.text then return nil end
			result = mdv
			local q = title.qualifiers
			if q then
				local p = q.P3831
				if test then mw.logObject(p, mdv.text .. '.P3831') end
				if p and isOri(p) then result.isOri = true end
			end
		elseif title.datavalue then title = title.datavalue.value
		elseif title.value then result = title.value
		else result = title end
		if not result.text then return nil end
		if not result.language then return nil end
		result.lang = result.language
		result.language = mw.language.fetchLanguageName(result.language,
														p.service.CONTENT_LANG)
		-- language param is preferred value
		if language and language ~= '' then
			foundPreferred = (	result.lang == language
							or	result.language == language)
		else
			foundPreferred = (result.lang == p.service.PREF_LANG)
		end
	else
		result.title = title
		result.language = language
	end
	return setmetatable(result, self), foundPreferred
end

single.__tostring = function(this)
	if not this.language then return "''" .. this.text .. "''" end
	if this.language == p.service.PREF_LANG then
		return "''" .. this.text .. "''"
	end
	if this.isOri then
		return "''" .. this.text .. "'' (original, " .. this.language .. ')'
	end
	return "''" .. this.text .. "'' (" .. this.language .. ')'
end

------------------------ service functions and objects ------------------------

function p.service:new(source, language, test)
	local result = {}
	self.__index = self
	getLang = function(property)
		local src = mw.wikibase.getBestStatements(result.dataLink, property)
		if tonumber(test) > 2 then
		   mw.logObject(src, result.dataLink .. '.' .. property)
		end
		if not src then return nil, nil end
		if not src[1] then return nil, nil end
		if not src[1].mainsnak then return nil, nil end
		local id = src[1].mainsnak.datavalue.value.id
		if not id then return nil, nil end
		src = mw.wikibase.getBestStatements(id, 'P424')
		if not src then return nil, nil end
		local l = src[1].mainsnak.datavalue.value
		return l, mw.language.fetchLanguageName(l, p.service.CONTENT_LANG)
	end
	if not source then
		source = mw.wikibase.getEntityIdForCurrentPage()
		if test then
			mw.log('Tried to get source by getEntityIdForCurrentPage')
		end
	end
	if not source then
		if test then
			mw.log('Tried w/o success!')
		end
		return nil
	end
	if type(source) == 'string' then
		result.dataLink = source:match('^Q%d+')
		if not result.dataLink then
			if test then
				mw.log('Have ' .. source .. ' be the only title!')
			end
			result = {title = single:new(source, language, test)}
			result.language = language
			return setmetatable(result, self)
		end
		result.wd = '[[d:' .. result.dataLink .. '|wd]]'
		if test then
		   mw.log('Get all titles for ' .. result.dataLink .. ' from base!')
		end
		source = mw.wikibase.getAllStatements(result.dataLink, 'P1476')
		result.lang, result.language = getLang('P407')
		result.oriLang, result.originalLanguage = getLang('P364')
	end
	if type(source) ~= 'table' then return nil end
	local hasPreferred = false
	for _, v in ipairs(source) do
		if test then mw.logObject(v, 'Title by statement') end
		local t, p = single:new(v, language, test)
		if tonumber(test) > 1 then
			if p then mw.logObject(t, 'title (preferred)')
			else mw.logObject(t, 'title (normal)') end
		end
		if p or not result.title then result.title = t end
		if not hasPreferred then
			hasPreferred = p
		end
		if t.isOri then
			result.original = t
			if hasPreferred then return setmetatable(result, self) end
		else
			if hasPreferred and result.original then
				return setmetatable(result, self)
			end
		end
	end
	if not result.title then return nil end
	if not result.language then
		result.lang = result.title.lang
		result.language = result.title.language
	end
	if not result.originalLanguage and result.originalTitle then
		result.oriLang = result.originalTitle.lang
		result.originalLanguage = result.originalTitle.language
	end
	if result.dataLink then
		p.service.cache = setmetatable(result, self)
		return p.service.cache
	end
	return setmetatable(result, self)
end

p.service.__tostring = function(this)
	return this.title:__tostring()
end

p.service.infoBrace = function(this, beforeLang, afterLang)
	local result = '('
	local comma = false
	add = function(value)
		if value and value ~= '' then
			if comma then result = result .. ', ' end
			result = result .. value
			comma = true
		end
	end
	add(beforeLang)
	local scheme = 0
	if this.language and this.language ~= PREF_LANG then scheme = 1 end
	if result.originalTitle then scheme = scheme + 2 end
	if result.originalLanguage and result.originalLanguage ~= PREF_LANG then
		scheme = scheme + 4
	end
	if scheme == 1 then add(this.language)
	elseif scheme == 2 then add('Original: ' .. this.originalTitle.text)
	elseif scheme == 3 then
		add (this.language)
		add('Original: ' .. this.originalTitle.text)
	elseif scheme == 4 then
		add('Original: ' .. this.originalLanguage)
	elseif scheme == 5 then
		add(this.language .. ' / Original: ' .. this.originalLanguage)
	elseif scheme == 6 then
		add('Original: ' .. this.originalTitle.text)
		add(this.originalLanguage)
	else
		add(this.language)
		add('Original: ' .. this.originalTitle.text)
		add(this.originalLanguage)
	end
	add(afterLang)
	add(this.wd)
	if not comma then return '' end
	return result .. ')'
end

p.service.titleLink = function(this)
	if not this.dataLink then return "''" .. this.title.text .. "''" end
	local link = mw.wikibase.getSitelink(this.dataLink)
	if not link then return "''" .. this.title.text .. "''" end
	if link == this.title.text then return "''[[" .. link .. "]]''" end
	return "''[[" .. link .. "|" .. this.title.text .. "]]''"
end

------------------------------ template functions ------------------------------

p.standard = function(frame)
	if frame.args.title then
		return p.service:new(	frame.args.title, frame.args.language,
								frame.args.test)
	else
		return p.service:new(frame.args[1])
	end
end

p.full = function(frame)
	local result = ''
	if frame.args.title then
		result = p.service:new(	frame.args.title, frame.args.language,
								frame.args.test)
		if frame.args.test then
			mw.logObject(result.title, 'title')
			mw.logObject(result.language, 'language')
			mw.logObject(result.originalTitle, 'original title')
			mw.logObject(result.originalLanguage, 'original language')
		end
	else
		result = p.service:new(frame.args[1])
	end
	if result.dataLink then
		return result.title.text .. ' ' .. result:infoBrace()
	else return result end
end

p.getTitle = function(frame)
	local result = nil
	if frame.args.title then
		result = p.service:new(	frame.args.title, frame.args.language,
								frame.args.test)
	else
		result = p.service:new(frame.args[1])
	end
	if result and result.title then return result.title.text end
end

p.getLanguage = function(frame)
	local result = nil
	if frame.args.title then
		result = p.service:new(	frame.args.title, frame.args.language,
								frame.args.test)
	else
		result = p.service:new(frame.args[1])
	end
	if result and result.language then return result.language end
end

p.getOriginalTitle = function(frame)
	local result = nil
	if frame.args.title then
		result = p.service:new(	frame.args.title, frame.args.language,
								frame.args.test)
	else
		result = p.service:new(frame.args[1])
	end
	if result and result.originalTitle then return result.originalTitle.text end
end

p.getOriginalLanguage = function(frame)
	local result = nil
	if frame.args.title then
		result = p.service:new(	frame.args.title, frame.args.language,
								frame.args.test)
	else
		result = p.service:new(frame.args[1])
	end
	if result and result.originalLanguage then return result.originalLanguage end
end

return p