Module:Inventory slot

From Modded Wiki
Revision as of 04:29, 14 August 2015 by minecraft>Majr (mw.html annoying treats attribute values as plain text, rather than HTML text which can have HTML entities in it, unlike the rest of MediaWiki and the web in general. Also fixed formatting only titles not working.)
Jump to navigation Jump to search

This module implements {{inventory slot}}.

Dependencies

de:Modul:Slot es:Módulo:Inventory slot fr:Module:Case inventaire ja:モジュール:Inventory slot ko:모듈:Inventory slot pl:Moduł:Inventory slot ru:Модуль:Инвентарный слот pt:Módulo:Inventory slot uk:Модуль:Інвентарний слот zh:模块:Inventory slot



local p = {}

function p.slot( f )
	local args = f.args or f
	if f == mw.getCurrentFrame() and args[1] == nil then
		args = f:getParent().args
	end
	
	args[1] = mw.text.trim( args[1] or '' )
	
	-- Comment this next line out if you're not using aliases
	local aliases = mw.loadData( 'Module:Inventory slot/Aliases' )
	
	local modAliases = args.modaliases or ''
	if modAliases ~= '' then
		modAliases = mw.loadData( 'Module:' .. modAliases )
	else
		modAliases = nil
	end
	
	if aliases or modAliases then
		local frames = {}
		for frame in mw.text.gsplit( args[1], '%s*;%s*' ) do
			local frameParts = p.getParts( frame, args.mod )
			
			local id = frameParts.name
			if frameParts.mod then
				id = frameParts.mod .. ':' .. id
			end
			
			local alias
			if modAliases and modAliases[id] then
				alias = modAliases[id]
			elseif aliases and aliases[id] then
				alias = aliases[id]
			end
			
			if alias then
				table.insert( frames, p.expandAlias( frameParts, alias ) )
			else
				table.insert( frames, frame )
			end
		end
		
		args[1] = table.concat( frames, ';' )
	end
	
	local sprite
	local ids = mw.loadData( [[Module:InvSprite/IDs]] ).ids
	local modIds = {}
	local animated = args[1]:find( ';' )
	local pageName = mw.title.getCurrentTitle().text
	local imgClass = args.imgclass
	local numStyle = args.numstyle
	local body = mw.html.create( 'span' ):addClass( 'invslot' ):css{ ['vertical-align'] = args.align }
	if animated then
		body:addClass( 'animated' )
	end
	if args.class then
		body:addClass( args.class )
	end
	if args.style then
		body:cssText( args.style )
	end
	
	if ( args.default or '' ) ~= '' then
		body:css( 'background-image', '{{FileUrl|' .. args.default .. '.png}}' )
	end
	
	local first = true
	for frame in mw.text.gsplit( args[1], '%s*;%s*' ) do
		local item
		if frame ~= '' or frame == '' and animated then
			item = body:tag( 'span' ):addClass( 'invslot-item' )
			if imgClass then
				item:addClass( imgClass )
			end
		end
		
		if frame == '' then
			( item or body ):tag( 'br' )
		else
			local category
			local parts = p.getParts( frame, args.mod )
			local title = parts.title or mw.text.trim( args.title or '' )
			local mod = parts.mod
			local name = parts.name
			local num = parts.num
			local description = parts.text
			
			local img, idData
			if mod then
				local modData = modIds[mod]
				if not modData and mw.title.new( 'Module:InvSprite/Mods/' .. mod .. '/IDs' ).exists then
					modData = mw.loadData( 'Module:InvSprite/Mods/' .. mod .. '/IDs' )
					modIds[mod] = modData
				end
				if modData and modData[name] then
					idData = modData[name]
				else
					img = name .. ' (' .. mod .. ')'
				end
			elseif ids[name] then
				idData = ids[name]
			else
				img = name
			end
			
			local link = args.link or ''
			if link == '' then
				if mod then
					link = 'Mods/' .. mod .. '/' .. name
				else
					link = name
				end
			elseif link:lower() == 'none' then
				link = nil
			end
			if link == pageName then
				link = nil
			end
			
			local formattedTitle
			local plainTitle
			if title == '' then
				plainTitle = name
			elseif title:lower() ~= 'none' then
				plainTitle = title:gsub( '\\\\', '\' ):gsub( '\\&', '&' )
				
				local formatPattern = '&[0-9a-fk-or]'
				if plainTitle:match( formatPattern ) then
					formattedTitle = title
					plainTitle = plainTitle:gsub( formatPattern, '' )
				end
				
				if plainTitle == '' then
					plainTitle = name
				else
					plainTitle = plainTitle:gsub( '\', '\\' ):gsub( '&', '&' )
				end
			elseif link then
				if img then
					formattedTitle = ''
				else
					plainTitle = ''
				end
			end
			
			item:attr{
				['data-minetip-title'] = formattedTitle,
				['data-minetip-text'] = description
			}
			
			if img then
				-- & is re-escaped because mw.html treats attributes
				-- as plain text, but MediaWiki doesn't
				local escapedTitle = ( plainTitle or '' ):gsub( '&', '&' )
				item:addClass( 'invslot-item-image' )
					:wikitext( '[[File:Grid ', img, '.png|32x32px|link=', link or '', '|', escapedTitle, ']]' )
			else
				if not sprite then
					sprite = require( [[Module:Sprite2]] ).sprite
				end
				local image
				if mod then
					image = args.spritesheet or mod .. 'Sprite.png'
				end
				if link then
					item:wikitext( '[[', link, '|' )
				end
				local image, spriteCat = sprite{
					iddata = idData, title = plainTitle,
					image = image, settings = 'InvSprite'
				}
				item:node( image )
				category = spriteCat
			end
			
			if num and num > 1 and num < 1000 then
				if img and link then
					item:wikitext( '[[', link, '|' )
				end
				local number = item
					:tag( 'span' )
						:addClass( 'invslot-stacksize' )
						:attr{ title = plainTitle }
						:wikitext( num )
				if numStyle then
					number:cssText( numStyle )
				end
				if img and link then
					item:wikitext( ']]' )
				end
			end
			
			if idData and link then
				item:wikitext( ']]' )
			end
			
			item:wikitext( category )
		end
		
		if first then
			if animated and item then
				item:addClass( 'active' )
			end
			first = false
		end
	end
	
	return body
end

function p.expandAlias( frameParts, alias )
	-- If the frame has no parts, we can just return the alias as-is
	if not frameParts.title and not frameParts.mod and not frameParts.num and not frameParts.text then
		return alias
	end
	
	local expandedFrames = {}
	for aliasFrame in mw.text.gsplit( alias, '%s*;%s*' ) do
		local aliasParts = p.getParts( aliasFrame )
		aliasParts.title = frameParts.title or aliasParts.title or ''
		aliasParts.mod = frameParts.mod or aliasParts.mod or 'Minecraft'
		aliasParts.num = frameParts.num or aliasParts.num or ''
		aliasParts.text = frameParts.text or aliasParts.text or ''
		
		table.insert( expandedFrames, string.format(
			'[%s]%s:%s,%s[%s]',
			aliasParts.title, aliasParts.mod, aliasParts.name, aliasParts.num, aliasParts.text
		) )
	end
	
	return table.concat( expandedFrames, ';' )
end

function p.getParts( frame, mod )
	local parts = {}
	parts.title = frame:match( '^%[%s*([^%]]+)%s*%]' )
	
	parts.mod = mw.text.trim( frame:match( '([^:%]]+):' ) or mod or '' )
	
	local vanilla = { v = 1, vanilla = 1, mc = 1, minecraft = 1 }
	if parts.mod == '' or vanilla[mw.ustring.lower( parts.mod )] then
		parts.mod = nil
	end
	
	local nameStart = ( frame:find( ':' ) or frame:find( '%]' ) or 0 ) + 1
	if nameStart - 1 == #frame then
		nameStart = 1
	end
	parts.name = mw.text.trim( frame:sub( nameStart, ( frame:find( '[,%[]', nameStart ) or 0 ) - 1 ) )
	
	parts.num = math.floor( frame:match( ',%s*(%d+)' ) or 0 )
	if parts.num == 0 then
		parts.num = nil
	end
	
	parts.text = frame:match( '%[%s*([^%]]+)%s*%]$' )
	
	return parts
end
 
return p