Модуль:Title

    Матеріал з Релігія в огні

    Документацію для цього модуля можна створити у Модуль:Title/документація

    --[[  
      __  __           _       _       _____ _ _   _      
     |  \/  | ___   __| |_   _| | ___ |_   _(_) |_| | ___ 
     | |\/| |/ _ \ / _` | | | | |/ _ (_)| | | | __| |/ _ \
     | |  | | (_) | (_| | |_| | |  __/_ | | | | |_| |  __/
     |_|  |_|\___/ \__,_|\__,_|_|\___(_)|_| |_|\__|_|\___|
                                                                                 
    This module is intended to be the engine behind "Template:Title"
    
    Authors and maintainers:
    * User:Jarekt - original version 
    ]]
    
    require('strict') -- used for debugging purposes as it detects cases of unintended global variables
    local core      = require('Module:Core')
    local createTag = require('Module:TagQS').createTag
    
    -- ==================================================
    -- === Internal functions ===========================
    -- ==================================================
    ------------------------------------------------------------------------------
    -- Clone of core.getArgs except for adding args.lang
    -- Based on frame structure create "args" table with all the input parameters.
    -- All inputs are not not case-sensitive and underscored are treated the same 
    -- way as speces. Input values are trimmed and empty string are converted to 
    -- nils. 
    local function getArgs(frame)
    	local function normalize_input_args(input_args, output_args)
    		for name, value in pairs( input_args ) do 
    			if type(name)=='string' and value ~= '' then 
    				output_args[string.lower(name)] = value
    			end
    		end
    		return output_args
    	end
    	local args = {}
    	args = normalize_input_args(frame:getParent().args, args)
    	args = normalize_input_args(frame.args, args)
    	return args
    end
    
    -- ====================================================================
    local function style(str, textLang)
    -- based on [[Template:Title/style]]
    	if not str or #str==0 then
    		return nil
    	end
    	str = mw.text.trim(str)
    	local LUT = {ar='%s',he='%s' ,et='„%s“' ,ja='『%s』' ,mk='„%s“' ,ru='«%s»' ,zh='《%s》', ['zh-hans']='《%s》', en='<i>%s</i>'}
    	--str = mw.language:ucfirst(str)
    	local form = core.langSwitchWithLang(LUT, textLang)
    	str = mw.ustring.format( form,  str) -- place quotes
    	local dir = mw.language.new( textLang ):getDir()
        str = string.format('<div style="display:inline-block" dir="%s" lang="%s">%s</div>', dir, textLang, str)
    	return str
    end
    
    -- ===========================================================================
    -- === get wikidata item ID (qid) based on P6243 stored in SDC             ===
    -- ===========================================================================
    local function qid_from_SDC()
    	local page = mw.title.getCurrentTitle()
    	if page.namespace==6 then -- File namespace
    		local entity = mw.wikibase.getEntity()
    		if entity and entity.statements and entity.statements.P6243 then
    			local statement = entity.statements.P6243[1]
    			return statement.mainsnak.datavalue.value.id
    		end
    	end
    	return nil
    end
    
    -- ====================================================================
    local function harvest_wikidata(entity, userLang)
    	local data = {} -- structure similar to "args" but filled with wikidata data
    	data.userLang = userLang
    	if not entity then
    		return data
    	end
    
    	-- get title (from 3 properties and label)
    	local property = {P1476 = 'title', P1448='official_name', P1705='native_label'}
    	for prop, field in pairs( property ) do
    		local titleList = {}
    		for _, statement in pairs( entity:getBestStatements(field)) do 
    			if (statement.mainsnak.snaktype == "value") then 
    				local val = statement.mainsnak.datavalue.value
    				titleList[val.language] = val.text -- look for multiple values each with a language code
    				data.title, data.lang = val.text, val.language -- in case we have title in some odd language: capture it
    			end
    		end
    		if #titleList>1 then
    			local title, language = core.langSwitch(titleList, userLang)
    			if title then
    				data.title, data.lang = title, language
    			end
    		end
    		if data.title then
    			data.title = data.title .. core.editAtWikidata(entity.id, prop, userLang)
    			break -- title found so no need for other property
    		end	
    	end
    	
    	-- get labels in all the langguages
    	if entity.labels then
    		for _, val in pairs(entity.labels) do -- loop over all labels
    			if val.language~=data.lang then
    				data[val.language] = val.value
    			end
    		end
    	end
    	
    	return data
    end
    
    local function quote(str)
    	return '"' .. str .. '"'
    end
    
    -- ==================================================
    -- === External functions ===========================
    -- ==================================================
    local p = {}
    
    -- ===========================================================================
    -- === Version of the function to be called from other LUA codes
    -- ===========================================================================
    function p.title_(args)
    	local line1, line2, Title, text, lang
    	local colon   = mw.message.new( "colon" ):inLanguage(args.userLang ):plain()
    	local wordsep = mw.message.new( "Word-separator" ):inLanguage(args.userLang ):plain()
    	local qsTable = {}
    
    	if args.lang and args.title then -- == Case 1: original language to be displayed ==
    		args.lang = string.lower(args.lang)
    		line1 = style(args.title, args.lang) -- first line
    		if args.lang==args.userLang then -- user's language = title's language
    			Title = mw.ustring.format( '<div style="font-weight:bold;display:inline-block;">%s</div>', line1 or '')
    		else -- user's language != title's language
    			-- line 1 original language 
    			local langName = mw.language.fetchLanguageName( args.lang, args.userLang  )
    			line1 = langName .. colon .. wordsep .. line1 -- add language name to line #1
    			if args.transliteration then 
    				line1 = line1 .. '&#32;- '  .. args.transliteration
    			end
    			line1 = mw.ustring.format( '<div style="font-size:0.9em;display:inline-block;">%s</div>', line1)
    
    			--  line 2 translation
    			if args.translation then 
    				line2 = args.translation
    			else
    				text, lang = core.langSwitchWithLang(args, args.userLang)
    				line2 = style(text, lang)
    			end
    			if line2 then
    				line2 = mw.ustring.format( '<br/><div style="font-weight:bold;display:inline-block;">%s</div>', line2)
    			end 
    			Title = line1 .. (line2 or '')
    		end
    		if not args.title_ then -- make sure title did not originated on wikidata
    			table.insert( qsTable, createTag('title', 'P1476', args.lang .. ':' .. quote(args.title)) )
    			table.insert( qsTable, createTag('label', 'L'..args.lang, quote(args.title)) )
    		end
    	else -- == Case 2: original language not relevant ==
    		if args.title then 
    			Title = mw.ustring.format( '<div style="font-weight:bold;display:inline-block;">%s</div>', args.title )
    		else
    			text, lang = core.langSwitchWithLang(args, args.userLang)
    			if text then
    				Title = style(text, lang)
    				Title = mw.ustring.format( '<div style="font-weight:bold;display:inline-block;">%s</div>', Title)
    			else -- list them all 
    				local Titles = {}			
    				for lang, text in pairs(args) do
    					if type(lang)=='string' and  mw.language.isSupportedLanguage( lang ) then
    						local langName = mw.language.fetchLanguageName( lang, args.userLang  )
    						table.insert(Titles, langName .. colon .. wordsep .. style(text, lang) )
    					end
    				end
    				Title = table.concat(Titles, '\n')
    			end
    		end
    	end
    	Title = Title or ''
    	if args.comment then
    		Title = mw.ustring.format( '%s<br /><div style="font-size:0.9em;display:inline-block;">%s<br /></div>', title, args.comment)
    	end
    
    	-- add text of invisible tag brodcasted by the template which allows creation of QuickStatements command used to add this info to Wikidata
    	for lang, text in pairs( args ) do 
    		if type(lang)=='string' and mw.language.isSupportedLanguage(lang) and not args[lang..'_'] then -- lang has tobe a valid language and the statement is not from wikidata
    			table.insert( qsTable, createTag('label', 'L'..lang, quote(text)) )
    		end
    	end
    
    	return Title .. table.concat( qsTable, '\n')
    end
    
    function p.wikidata_title(entity, userLang)
    	return p.title_(harvest_wikidata(entity, userLang))
    end
    
    -- ===========================================================================
    -- === Versions of the function to be called from template namespace
    -- ===========================================================================
    function p.title(frame)
    	-- args.lang is usually provided and it is used for the language of the title
    	-- not customary language of the user which can be provided by args.userlang
    	local args = getArgs(frame)
    	args.userLang = args.userlang
    	if not (args.userLang and mw.language.isSupportedLanguage(args.userLang)) then 
    		args.userLang = frame:callParserFunction( "int", "lang" ) -- get user's chosen language
    	end 
    
    	-- merge wikidata with local variables
    	local qid = args.wikidata or qid_from_SDC() -- get wikidata item ID based on P6243 stored in SDC
    	if qid then 
    		local entity = mw.wikibase.getEntity(qid)
    		if entity then
    			local data = harvest_wikidata(entity, args.userLang)
    			if not args.title and data.title and not args.lang and data.lang then
    				args.title = data.title -- get title from wikidata
    				args.lang  = data.lang
    				args.title_ = 'from wikidata'
    			end
    			for lang, text in pairs( data ) do 
    				if mw.language.isSupportedLanguage(lang) and not args[lang] then 
    					args[lang] = text
    					args[lang..'_'] = 'from wikidata'
    				end
    			end
    		end
    	end
    	return p.title_(args)
    end
    
    return p