Модуль:Спрайт2

Матеріал з Minecraft Wiki
Перейти до: навігація, пошук
[створити | історія | оновити]Документація
Цей module не має документації. Якщо ви знаєте, як використовувати це, будь ласка, створіть документацію.
local p = {}

-- Створення спрайту
function p.base(f)
	local args = f
	if f == mw.getCurrentFrame() then 
		args = require('Модуль:ProcessArgs').merge(true)
	else
		f = mw.getCurrentFrame()
	end
	
	local data = args['дані'] and mw.loadData( 'Модуль:' .. args['дані'] ) or {}
	local settings = data['налаштування']
	
	local default = {
		["масштаб"] = 1,
		["формат"] = 256,
		["розм"] = 16,
		["поз"] = 1,
		["вирівн"] = 'text-top',
		["сторінка"] = '',
	}
	
	local defaultStyle = default
	if settings then
		if not settings['таблстилів'] then
			-- Создаём отдельную копию текущих настроек по умолчанию
			defaultStyle = mw.clone( default )
		end
		for k, v in pairs( settings ) do
			default[k] = v
		end
	end
	
	local setting = function(arg)
		return args[arg] or default[arg]
	end
	
	local sprite = mw.html.create('span'):addClass('sprite')
	-- Метод css від mw.html виробляє дуже повільне екранування вхідних даних, що гальмує роботу в два рази. Замість
	-- цього стилі будуть створюватися вручну, і будуть передаватися через метод cssText, який робить тільки екранування HTML,
	-- що куди швидше.
	local styles = {}
	
	local page
	if setting('сторінка') ~= '' then
		page = setting('сторінка')
	elseif setting("головна_сторінка") ~= '' then
		page = setting("головна_сторінка")
	end
	if not page then
		page = ''
	end
	
	if not setting( 'nourl' ) and setting( 'url' ) then
		styles[#styles + 1] = 'background-image:' .. ( setting( 'url' ).url or setting( 'url' ) )
	end
	if setting( 'таблстилів' ) then
		sprite:addClass(
			setting( "ім'якласу" ) or
			mw.ustring.lower( setting( "ім'я" ):gsub( ' ', '-' ) ) .. '-sprite'
		)
	elseif setting('сторінка') ~= '' then
		-- тимчасова заглушка для GregTech
		styles[#styles + 1] = 'background-image: {{FileUrl|' .. (setting('зобр') or setting("ім'я") .. page .. 'Sprite.png') .. '}}'
	elseif not setting( 'url' ) then
		styles[#styles + 1] = 'background-image:' .. p.getUrl(
			setting( 'зобр' ) or (setting( "ім'я" ) .. 'Sprite.png')
		).url
	end
	local class = setting( 'клас' )
	if class then
		sprite:addClass( class )
	end
	
	-- Налаштування сторінки багатосторінкового спрайту
	local scaleq = 1
	if setting(page) then
		args['масштаб'] = args['масштаб'] or 1
		scaleq = setting(page)['множник'] or 1
		args['розм'] = setting(page)['розм'] or setting('розм')
		args['формат'] = setting(page)['формат'] or setting('формат')
	else
		scaleq = setting('множник') or 1
	end
	
	local size = setting('розм') -- розмір спрайту в пікселях
	local v_size = setting('верт_розм') or setting('розм') -- розмір спрайту в пікселях в висоту
	local pos = math.abs(setting('поз')) - 1 -- становище спрайту в таблиці
	local sheetWidth = setting('формат') -- ширина таблиці спрайту в пікселях
	local tiles = sheetWidth / size -- кількість спрайтів в одному рядку
	local left = pos % tiles * size -- горизонтальна координата спрайту
	local top = math.floor(pos / tiles ) * v_size -- вертикальна координата спрайту
	local scale = setting('масштаб') * scaleq -- масштаб спрайту (у скільки разів збільшити або зменшити розмір)
	local autoscale = setting('автомасштаб') -- автоматичне застосування масштабування
	local align = setting('вирівн') -- вирівнювання по вертикалі
	
	-- Координати
	if left > 0 or top > 0 then
		styles[#styles + 1] = 'background-position: -' .. left * scale .. 'px -' .. top * scale .. 'px'
	end

	-- Масштаб
	if not autoscale and scale ~= defaultStyle["масштаб"] then
		styles[#styles + 1] = 'background-size: ' .. sheetWidth * scale .. 'px auto'
	end
	
	-- Розміри спрайту
	if size ~= defaultStyle["розм"] or (not autoscale and scale ~= defaultStyle["масштаб"]) then
		styles[#styles + 1] = 'height: ' .. v_size * scale .. 'px'
		styles[#styles + 1] = 'width: ' .. size * scale .. 'px'
	end
	
	-- Вирівнювання
	if align ~= defaultStyle["вирівн"] then
		styles[#styles + 1] = 'vertical-align: ' .. align
	end
	
	-- Додатковий CSS-код, вказаний в параметрі
	styles[#styles + 1] = setting('css')
	
	-- Застосування отриманих CSS-стилів до спрайту.
	sprite:cssText(table.concat(styles, ';'))
	
	-- Власне спрайт.	
	local root
	-- Текстові дані
	local text = setting('текст')
	local spriteText
	if text and (text ~= 'ні') then
		root = mw.html.create( 'span' ):addClass( 'nowrap' )
		spriteText = mw.html.create( 'span' ):addClass( 'sprite-text' ):wikitext( text )
	end
	
	-- Спливаючий текст
	local title = setting('назва')
	if title then
		(root or sprite):attr('title', title)
	end
	
	-- Збірка спрайту
	if not root then
		root = mw.html.create( '' )
	end
	root:node( sprite )
	if spriteText then
		root:node( spriteText )
	end
	
	local link = setting( 'посилання' ) or ''
	if link ~= '' and mw.ustring.lower( link ) ~= 'none' then
		-- Зовнішнє посилання
		if link:find( '//' ) then
			return '[' .. link .. ' ' .. tostring( root ) .. ']'
		end
		
		-- Внутрішнє посилання. Підтримується префікс, що корисно при посиланні на модифікації.
		local linkPrefix = setting( 'предпосилання' ) or ''
		return '[[' .. linkPrefix .. link .. '|' .. tostring( root ) .. ']]'
	end
	
	return tostring( root )
end

-- Ця функція попередньо готує дані для функції p.base, а потім викликає її. Її слід викликати на сторінках вікі-проекту
-- (через будь-який з спрайтові шаблонів)
function p.sprite(f)
	-- Параметри
	local args = f
	if f == mw.getCurrentFrame() then
		args = require('Модуль:ProcessArgs').merge(true)
	else
		f = mw.getCurrentFrame()
	end
	
	local data = args['дані'] and mw.loadData( 'Модуль:' .. args['дані'] ) or {}
	local categories = {}
	local idData = args["даніID"] -- дані за назвами спрайтів і їх позиціях
	
	if not idData then
		local name = args["ім'я"] or data['налаштування']["ім'я"]
		local id = mw.text.trim( tostring( args[1] or '' ) )
		idData = data["IDи"][id] or data["IDи"][mw.ustring.lower(id):gsub('[_%-%s%+]+', '-')]
	end
	local title = mw.title.getCurrentTitle()
	
	-- заборонити категорії відповідно в розділ, на сторінках обговорень і в просторах учасників,
	-- а також якщо встановлено параметр «некат»
	local disallowCats = args["некат"] or title.isSubpage or title.isTalkPage or title:inNamespace(2)
	if idData then
		if idData["застарів"] then
			args["клас"] = ( args["клас"] or '' ) .. ' sprite-deprecated'		
			if not disallowCats then
				categories[#categories + 1] = '[[Категорія:Сторінки з застарілими назвами спрайтів]]'
			end
		end
		
		args["поз"] = idData["поз"]
		args["сторінка"] = idData["сторінка"]
	elseif not disallowCats then
		categories[#categories + 1] = '[[Категорія:Сторінки з відсутніми спрайтами]]'
	end
	return p.base(args), table.concat(categories)
end

-- Посилання
function p.link(f)
	local args = f
	if f == mw.getCurrentFrame() then
		args = require('Модуль:ProcessArgs').merge(true)
	end
	
	local link = args[1]
	if args[1] and not args["ID"] then
		link = args[1]:match( '^(.-)%+' ) or args[1]
	end
	
	local text
	if not args["безтексту"] then
		text = args["текст"] or args[2] or link
	end
	
	args[1] = args["ID"] or args[1]
	args["посилання"] = args["посилання"] or link
	args["текст"] = text
	
	return p.sprite( args )
end

function p.getUrl( image, query, classname )
	local f = mw.getCurrentFrame()
	local t = {
		url = f:expandTemplate{
			title = 'FileUrl',
			args = { image, query = query }
		},
	}
	if classname and classname ~= '' then
		t.style = f:expandTemplate{
			title = 'FileUrlStyle',
			args = { classname, image, query = query }
		}
	end
	return t
end

function p.getParsedUrlStyle( f )
	local args = f:getParent().args
	local module = args[1]
	return require( 'Модуль:' .. module )["налаштування"].url.style
end

-- Документація по таблиці спрайтів. Показує назви спрайтів в таблиці і їх категорії.
function p.doc(f)
	-- Параметри
    local args = f
    if f == mw.getCurrentFrame() then
        args = f.args
    else
        f = mw.getCurrentFrame()
    end
	
	local dataPage = mw.text.trim( args[1] )
	local data = mw.loadData( 'Модуль:' .. dataPage )
	
    local getProtection = function(title, action, extra)
        local protections = {'edit'}
        if extra then
			protections[#protections + 1] = extra
        end

        local addProtection = function(protection)
            if protection == 'autoconfirmed' then
                protection = 'editsemiprotected'
            elseif protection == 'sysop' then
                protection = 'editprotected'
            end
           
			protections[#protections + 1] = protection
        end
       
        local direct = title.protectionLevels[action] or {}
        for _, protection in ipairs(direct) do
            addProtection(protection)
        end
		
        local cascading = title.cascadingProtection.restrictions[action] or {}
        if #cascading > 0 then
			protections[#protections + 1] = 'protect'
        end
        for _, protection in ipairs(cascading) do
            addProtection(protection)
        end
       
        return table.concat(protections, ',')
    end
	
	local spriteStyle = ''
	if data["налаштування"].url and data["налаштування"].url.style then
		spriteStyle = data["налаштування"].url.style
	end
	
	local dataTitle = mw.title.new( 'Модуль:' .. dataPage )
	-- Temporary until this is updated
	local classname = ''
	if data["налаштування"]["таблстилів"] then
		classname = data["налаштування"]["ім'якласу"] or
			mw.ustring.lower( data["налаштування"]["ім'я"]:gsub( ' ', '-' ) ) .. '-sprite'
	end
	local spritesheet = data["налаштування"]["зобр"] or data["налаштування"]["ім'я"] .. 'Sprite.png'
	local spriteTitle = mw.title.new( 'Файл:' .. spritesheet )
	local dataProtection = getProtection( dataTitle, 'edit' )
	local spriteProtection = getProtection( spriteTitle, 'upload', 'upload,reupload' )
	local body = mw.html.create( 'div' ):attr( {
		id = 'spritedoc',
		['data-dataprotection'] = dataProtection,
		['data-datatimestamp'] = f:callParserFunction( 'REVISIONTIMESTAMP', 'Модуль:' .. dataPage ),
		['data-datapage'] = 'Модуль:' .. dataPage,
		['data-spritesheet'] = spritesheet,
		['data-spriteprotection'] = spriteProtection,
		['data-urlfunc'] = "require( [[Модуль:Спрайт]] ).getUrl( '" .. spritesheet .. "', '$1', '" .. classname .. "' )",
		['data-refreshtext'] = mw.text.nowiki( '{{#invoke:Спрайт|doc|' .. dataPage .. '|refresh=1}}' ),
		['data-settings'] = mw.text.jsonEncode( data["налаштування"] ),
	} )
	
	local sections = {}
	for _, sectionData in ipairs( data["розділи"] or { ["назва"] = 'Некатегоризовані' } ) do
		local sectionTag = body:tag( 'div' ):addClass( 'spritedoc-section' ):attr( 'data-section-id', sectionData.ID )
		sectionTag:tag( 'h3' ):wikitext( sectionData["назва"] )
		sections[sectionData.ID] = { boxes = sectionTag:tag( 'ul' ):addClass( 'spritedoc-boxes' ) }
	end
	
	local keyedData = {}
	local i = 1
	for name, idData in pairs( data['IDи'] ) do
		keyedData[i] = {
			sortKey = mw.ustring.lower( name ),
			name = name,
			data = idData
		}
		i = i + 1
	end
	table.sort( keyedData, function( a, b )
		return a.sortKey < b.sortKey
	end )

	for _, data in ipairs( keyedData ) do
		local idData = data.data
		local pos = idData['поз']
		local section = sections[idData['розділ']]
		local names = section[pos]
		if not names then
			local box = section.boxes:tag( 'li' ):addClass( 'spritedoc-box' ):attr( 'data-pos', pos )
			box:tag( 'div' ):addClass( 'spritedoc-image' )
				:wikitext( p.base{ ["поз"] = pos, ["дані"] = dataPage, nourl = spriteStyle ~= '' } )
			
			names = box:tag( 'ul' ):addClass( 'spritedoc-names' )
			section[pos] = names
		end
		local nameElem = mw.html.create( 'li' ):addClass( 'spritedoc-name' )
		local codeElem = nameElem:tag( 'code' ):wikitext( data.name )
		
		if idData['застарів'] then
			codeElem:addClass( 'spritedoc-deprecated' )
		end
		names:wikitext( tostring( nameElem ) )
	end
	
	if args.refresh then
		return '', '', tostring( body )
	end
	local styles = f:callParserFunction( '#widget:SpriteDoc.css' )
	return styles, spriteStyle, tostring( body )
end

return p