Module:Inventory slot: Difference between revisions
Jump to navigation
Jump to search
Remove old class |
Update to allow aliases to be pre-split, for better performance; also avoid splitting and stringifying input twice |
||
Line 8: | Line 8: | ||
'Damaged' | 'Damaged' | ||
} | } | ||
local function mergeList( parentTable, content ) | |||
if content[1] then | |||
-- Merge list into table | |||
for _, v in ipairs( content ) do | |||
table.insert( parentTable, v ) | |||
end | |||
else | |||
-- Add strings or tables to table | |||
table.insert( parentTable, content ) | |||
end | |||
end | |||
local function cloneTable( origTable ) | |||
local newTable = {} | |||
for k, v in pairs( origTable ) do | |||
if type( v ) == 'table' then | |||
v = cloneTable( v ) | |||
end | |||
newTable[k] = v | |||
end | |||
return newTable | |||
end | |||
function p.slot( f ) | function p.slot( f ) | ||
Line 31: | Line 54: | ||
randomise = false | randomise = false | ||
end | end | ||
local frames = {} | |||
for frameText in mw.text.gsplit( args[1], '%s*;%s*' ) do | |||
local frame = p.makeFrame( frameText, args.mod ) | |||
local id = frame.name | |||
if frame.mod then | |||
id = frame.mod .. ':' .. id | |||
end | |||
local alias | |||
if modAliases and modAliases[id] then | |||
alias = modAliases[id] | |||
elseif aliases and aliases[id] then | |||
alias = aliases[id] | |||
end | end | ||
if alias then | |||
mergeList( frames, p.expandAlias( alias, frame ) ) | |||
else | |||
table.insert( frames, frame ) | |||
end | |||
-- Randomise starting frame for "Any *" aliases, as long as the alias is the only frame | |||
-- and this isn't an output slot | |||
if randomise ~= false and frame.name:match( '^Any ' ) then | |||
randomise = true | |||
else | |||
randomise = false | |||
end | |||
end | end | ||
Line 68: | Line 87: | ||
local ids = mw.loadData( [[Module:InvSprite/IDs]] ).ids | local ids = mw.loadData( [[Module:InvSprite/IDs]] ).ids | ||
local modIds = {} | local modIds = {} | ||
local animated = | local animated = #frames > 1 | ||
local pageName = mw.title.getCurrentTitle().text | local pageName = mw.title.getCurrentTitle().text | ||
local imgClass = args.imgclass | local imgClass = args.imgclass | ||
Line 87: | Line 106: | ||
end | end | ||
local activeFrame = randomise and math.random( #frames ) or 1 | local activeFrame = randomise and math.random( #frames ) or 1 | ||
for i, frame in ipairs( frames ) do | for i, frame in ipairs( frames ) do | ||
local item | local item | ||
if frame ~= '' or frame == '' and animated then | if frame ~= '' or frame.name == '' and animated then | ||
item = body:tag( 'span' ):addClass( 'invslot-item' ) | item = body:tag( 'span' ):addClass( 'invslot-item' ) | ||
if imgClass then | if imgClass then | ||
Line 98: | Line 116: | ||
end | end | ||
if frame == '' then | if frame == '' or frame.name == '' then | ||
( item or body ):tag( 'br' ) | ( item or body ):tag( 'br' ) | ||
else | else | ||
local category | local category | ||
local | local title = frame.title or mw.text.trim( args.title or '' ) | ||
local mod = frame.mod | |||
local mod = | local name = frame.name | ||
local name = | local num = frame.num | ||
local num = | local description = frame.text | ||
local description = | |||
local img, idData | local img, idData | ||
Line 232: | Line 249: | ||
end | end | ||
function p. | function p.getAlias( alias, parentFrame ) | ||
-- If the frame | local aliasFrames | ||
if | if type( alias ) == 'string' then | ||
aliasFrames = {} | |||
for frameText in mw.text.gsplit( alias, '%s*;%s*' ) do | |||
table.insert( aliasFrames, p.makeFrame( frameText ) ) | |||
end | |||
else | |||
aliasFrames = alias | |||
end | |||
-- If alias is just a name, return the original frame with the new name | |||
if type( aliasFrames ) == 'string' then | |||
local aliasParts = mw.clone( parentFrame ) | |||
aliasParts.name = aliasFrames | |||
return aliasParts | |||
end | |||
-- Single frame alias, put in list | |||
if aliasFrames.name then | |||
aliasFrames = { aliasFrames } | |||
end | end | ||
local expandedFrames = {} | local expandedFrames = {} | ||
for aliasFrame in | for i, aliasFrame in ipairs( aliasFrames ) do | ||
local aliasParts = | local aliasParts | ||
aliasParts.title = | if type( aliasFrame ) == 'string' then | ||
aliasParts.mod = | aliasParts = { name = aliasFrame } | ||
aliasParts.num = | else | ||
aliasParts.text = | aliasParts = cloneTable( aliasFrame ) | ||
end | |||
aliasParts.title = parentFrame.title or aliasParts.title | |||
aliasParts.mod = parentFrame.mod or aliasParts.mod | |||
aliasParts.num = parentFrame.num or aliasParts.num | |||
aliasParts.text = parentFrame.text or aliasParts.text | |||
expandedFrames[i] = aliasParts | |||
end | end | ||
return | return expandedFrames | ||
end | |||
function p.expandAlias( parentFrame, alias ) | |||
return p.getAlias( alias, parentFrame ) | |||
end | |||
function p.stringifyFrame( frame ) | |||
if not frame.name then | |||
return '' | |||
end | |||
return string.format( | |||
'[%s]%s:%s,%s[%s]', | |||
frame.title or '', | |||
frame.mod or 'Minecraft', | |||
frame.name, | |||
frame.num or '', | |||
frame.text or '' | |||
) | |||
end | end | ||
function p. | function p.stringifyFrames( frames ) | ||
for i, frame in ipairs( frames ) do | |||
frames[i] = p.stringifyFrame( frame ) | |||
end | |||
return table.concat( frames, ';' ) | |||
end | |||
function p.makeFrame( frameText, mod ) | |||
-- Simple frame with no parts | |||
if not frameText:match( '[%[:,]' ) then | |||
return { | |||
mod = mod, | |||
name = mw.text.trim( frameText ), | |||
} | |||
end | |||
frameText = frameText:gsub( '%s*([%[%]:,;])%s*', '%1' ) | |||
local frame = {} | |||
frame.title = frameText:match( '^%[([^%]]+)%]' ) | |||
frame.mod = frameText:match( '([^:%]]+):' ) or mod | |||
local vanilla = { v = 1, vanilla = 1, mc = 1, minecraft = 1 } | local vanilla = { v = 1, vanilla = 1, mc = 1, minecraft = 1 } | ||
if | if frame.mod == '' or vanilla[mw.ustring.lower( frame.mod )] then | ||
frame.mod = nil | |||
end | end | ||
local nameStart = ( | local nameStart = ( frameText:find( ':' ) or frameText:find( '%]' ) or 0 ) + 1 | ||
if nameStart - 1 == # | if nameStart - 1 == #frameText then | ||
nameStart = 1 | nameStart = 1 | ||
end | end | ||
frame.name = frameText:sub( nameStart, ( frameText:find( '[,%[]', nameStart ) or 0 ) - 1 ) | |||
frame.num = math.floor( frameText:match( ',(%d+)' ) or 0 ) | |||
if | if frame.num == 0 then | ||
frame.num = nil | |||
end | end | ||
frame.text = frameText:match( '%[([^%]]+)%]$' ) | |||
return | return frame | ||
end | |||
function p.getParts( frameText, mod ) | |||
return p.makeFrame( frameText, mod ) | |||
end | end | ||
return p | return p |
Revision as of 06:00, 14 October 2016
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 = {}
-- List of special prefixes which should be handled by
-- other modules (such as being moved outside links)
p.prefixes = {
'Any',
'Matching',
'Damaged'
}
local function mergeList( parentTable, content )
if content[1] then
-- Merge list into table
for _, v in ipairs( content ) do
table.insert( parentTable, v )
end
else
-- Add strings or tables to table
table.insert( parentTable, content )
end
end
local function cloneTable( origTable )
local newTable = {}
for k, v in pairs( origTable ) do
if type( v ) == 'table' then
v = cloneTable( v )
end
newTable[k] = v
end
return newTable
end
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
local randomise
if args.class == 'invslot-large' then
randomise = false
end
local frames = {}
for frameText in mw.text.gsplit( args[1], '%s*;%s*' ) do
local frame = p.makeFrame( frameText, args.mod )
local id = frame.name
if frame.mod then
id = frame.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
mergeList( frames, p.expandAlias( alias, frame ) )
else
table.insert( frames, frame )
end
-- Randomise starting frame for "Any *" aliases, as long as the alias is the only frame
-- and this isn't an output slot
if randomise ~= false and frame.name:match( '^Any ' ) then
randomise = true
else
randomise = false
end
end
local sprite
local ids = mw.loadData( [[Module:InvSprite/IDs]] ).ids
local modIds = {}
local animated = #frames > 1
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 activeFrame = randomise and math.random( #frames ) or 1
for i, frame in ipairs( frames ) do
local item
if frame ~= '' or frame.name == '' and animated then
item = body:tag( 'span' ):addClass( 'invslot-item' )
if imgClass then
item:addClass( imgClass )
end
end
if frame == '' or frame.name == '' then
( item or body ):tag( 'br' )
else
local category
local title = frame.title or mw.text.trim( args.title or '' )
local mod = frame.mod
local name = frame.name
local num = frame.num
local description = frame.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 = 'Grid ' .. name .. ' (' .. mod .. ').png'
end
elseif ids[name] then
idData = ids[name]
elseif name:match( '\.gif$' ) or name:match( '\.png$' ) then
img = 'Invicon ' .. name
name = name:sub( 0, -5 )
else
img = 'Grid ' .. name .. '.png'
end
local link = args.link or ''
if link == '' then
if mod then
link = 'Mods/' .. mod .. '/' .. name
else
link = name:gsub( '^Damaged ', '' )
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:', img, '|32x32px|link=', link or '', '|', escapedTitle, ']]' )
else
if not sprite then
sprite = require( [[Module:Sprite]] ).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 i == activeFrame and animated and item then
item:addClass( 'animated-active' )
end
end
return tostring( body )
end
function p.getAlias( alias, parentFrame )
local aliasFrames
if type( alias ) == 'string' then
aliasFrames = {}
for frameText in mw.text.gsplit( alias, '%s*;%s*' ) do
table.insert( aliasFrames, p.makeFrame( frameText ) )
end
else
aliasFrames = alias
end
-- If alias is just a name, return the original frame with the new name
if type( aliasFrames ) == 'string' then
local aliasParts = mw.clone( parentFrame )
aliasParts.name = aliasFrames
return aliasParts
end
-- Single frame alias, put in list
if aliasFrames.name then
aliasFrames = { aliasFrames }
end
local expandedFrames = {}
for i, aliasFrame in ipairs( aliasFrames ) do
local aliasParts
if type( aliasFrame ) == 'string' then
aliasParts = { name = aliasFrame }
else
aliasParts = cloneTable( aliasFrame )
end
aliasParts.title = parentFrame.title or aliasParts.title
aliasParts.mod = parentFrame.mod or aliasParts.mod
aliasParts.num = parentFrame.num or aliasParts.num
aliasParts.text = parentFrame.text or aliasParts.text
expandedFrames[i] = aliasParts
end
return expandedFrames
end
function p.expandAlias( parentFrame, alias )
return p.getAlias( alias, parentFrame )
end
function p.stringifyFrame( frame )
if not frame.name then
return ''
end
return string.format(
'[%s]%s:%s,%s[%s]',
frame.title or '',
frame.mod or 'Minecraft',
frame.name,
frame.num or '',
frame.text or ''
)
end
function p.stringifyFrames( frames )
for i, frame in ipairs( frames ) do
frames[i] = p.stringifyFrame( frame )
end
return table.concat( frames, ';' )
end
function p.makeFrame( frameText, mod )
-- Simple frame with no parts
if not frameText:match( '[%[:,]' ) then
return {
mod = mod,
name = mw.text.trim( frameText ),
}
end
frameText = frameText:gsub( '%s*([%[%]:,;])%s*', '%1' )
local frame = {}
frame.title = frameText:match( '^%[([^%]]+)%]' )
frame.mod = frameText:match( '([^:%]]+):' ) or mod
local vanilla = { v = 1, vanilla = 1, mc = 1, minecraft = 1 }
if frame.mod == '' or vanilla[mw.ustring.lower( frame.mod )] then
frame.mod = nil
end
local nameStart = ( frameText:find( ':' ) or frameText:find( '%]' ) or 0 ) + 1
if nameStart - 1 == #frameText then
nameStart = 1
end
frame.name = frameText:sub( nameStart, ( frameText:find( '[,%[]', nameStart ) or 0 ) - 1 )
frame.num = math.floor( frameText:match( ',(%d+)' ) or 0 )
if frame.num == 0 then
frame.num = nil
end
frame.text = frameText:match( '%[([^%]]+)%]$' )
return frame
end
function p.getParts( frameText, mod )
return p.makeFrame( frameText, mod )
end
return p