Module:Inventory slot: Difference between revisions

m rebase dev changes onto prod
No edit summary
 
(30 intermediate revisions by 5 users not shown)
Line 2: Line 2:


local i18n = {
local i18n = {
filename = 'Invicon $1',
modLink = '$1:$2',
legacyFilename = 'Grid $1.png',
modLink = 'Mods/$1/$2',
moduleAliases = [[Module:Inventory slot/Aliases]],
moduleAliases = [[Module:Inventory slot/Aliases]],
moduleInvData = [[Module:InvSprite]],
moduleModData = 'Module:InvSprite/Mods/$1',
moduleRandom = [[Module:Random]],
moduleRandom = [[Module:Random]],
moduleSprite = [[Module:Sprite]],
-- List of special prefixes which should be handled by
-- List of special prefixes which should be handled by
-- other modules (such as being moved outside links)
-- other modules (such as being moved outside links)
Line 16: Line 11:
matching = 'Matching',
matching = 'Matching',
damaged = 'Damaged',
damaged = 'Damaged',
unwaxed = 'Unwaxed',
},
},
suffixes = {
suffixes = {
Line 25: Line 21:


local random = require( i18n.moduleRandom ).random
local random = require( i18n.moduleRandom ).random
local sprite = require( i18n.moduleSprite ).sprite
local aliases = mw.loadData( i18n.moduleAliases )
local aliases = mw.loadData( i18n.moduleAliases )
local ids = mw.loadData( i18n.moduleInvData ).ids
local modIds = {}
local pageName = mw.title.getCurrentTitle().text
local pageName = mw.title.getCurrentTitle().text
--[[Splits a given text into fragments separated by semicolons that are not
    inside square brackets. Written by AttemptToCallNil for the Russian wiki
--]]
local function splitOnUnenclosedSemicolons(text)
local semicolon, lbrace, rbrace = (";[]"):byte(1, 3)
local nesting = false
local splitStart = 1
local frameIndex = 1
local frames = {}
for index = 1, text:len() do
local byte = text:byte(index)
if byte == semicolon and not nesting then
frames[frameIndex] = text:sub(splitStart, index - 1)
frameIndex = frameIndex + 1
splitStart = index + 1
elseif byte == lbrace then
assert(not nesting, "Excessive square brackets found")
nesting = true
elseif byte == rbrace then
assert(nesting, "Unbalanced square brackets found")
nesting = false
end
end
assert(not nesting, "Unbalanced square brackets found")
frames[frameIndex] = text:sub(splitStart, text:len())
for index = 1, #frames do
frames[index] = (frames[index]:gsub("^%s+", ""):gsub("%s+$", "")) -- faster mw.text.trim
end
return frames
end


-- Performs a simple recursive clone of a table's values
-- Performs a simple recursive clone of a table's values
Line 71: Line 98:
local category
local category
local title = frame.title or mw.text.trim( args.title or '' )
local title = frame.title or mw.text.trim( args.title or '' )
local mod = frame.mod
local name = frame.name or ''
local num = frame.num
local num = frame.num
local description = frame.text
local description = frame.text
local img, idData
local mod = frame.mod or 'Minecraft'
if mod then
local name = frame.name
local modData = modIds[mod]
if not modData and mw.title.new( i18n.moduleModData:gsub( '%$1', mod ) ).exists then
 
modData = mw.loadData( i18n.moduleModData:gsub( '%$1', mod ) )
if frame.name:match( '%.gif$' ) and frame.name:match( '%.png$' ) then
modIds[mod] = modData
name = frame.name
end
mod = ''
if modData and modData[name] then
end
idData = modData[name]
 
local minecraft = mod == "Minecraft" or mod == "minecraft"
 
local img = frame.img
if not img then
if name:match( '%.gif$' ) or name:match( '%.png$' ) then
img = name
-- Remove file extension from name
name = name:sub( 0, -5 )
elseif minecraft then
img = 'Invicon ' .. name .. '.png'
elseif mod then
img = mod .. ' ' .. name .. '.png'
else
else
img = i18n.legacyFilename:gsub( '%$1', name .. ' (' .. mod .. ')' )
img = name
end
end
elseif ids[name] then
end
idData = ids[name]
 
elseif name:match( '\.gif$' ) or name:match( '\.png$' ) then
if name:match( ' Revision %d+' ) then
img = i18n.filename:gsub( '%$1', name )
name = name:gsub( ' Revision %d+', '' )
-- Remove file extension from name
name = name:sub( 0, -5 )
end
end
local link = args.link or ''
local link = args.link or ''
if link == '' then
if link == '' then
if mod then
link = i18n.modLink:gsub( '%$1', mod ):gsub( '%$2', name )
link = i18n.modLink:gsub( '%$1', mod ):gsub( '%$2', name )
else
link = name:gsub( '^' .. i18n.prefixes.damaged .. ' ', '' )
for _, suffix in pairs( i18n.suffixes ) do
link = link:gsub( ' ' .. suffix .. '$', '' )
end
end
elseif link:lower() == 'none' then
elseif link:lower() == 'none' then
link = nil
link = nil
Line 120: Line 148:
plainTitle = title:gsub( '\\\\', '\' ):gsub( '\\&', '&' )
plainTitle = title:gsub( '\\\\', '\' ):gsub( '\\&', '&' )
local formatPattern = '&[0-9a-fk-or]'
local formatPatterns = {'&[0-9a-jl-qs-vyzr]', '&#%x%x%x%x%x%x', '&$%x%x%x'}
if plainTitle:match( formatPattern ) then
for _, formatPattern in ipairs( formatPatterns ) do
formattedTitle = title
if plainTitle:match( formatPattern ) then
plainTitle = plainTitle:gsub( formatPattern, '' )
formattedTitle = title
plainTitle = plainTitle:gsub( formatPattern, '' )
end
end
end
Line 132: Line 162:
end
end
elseif link then
elseif link then
if img then
formattedTitle = ''
formattedTitle = ''
else
plainTitle = ''
end
end
end
Line 144: Line 170:
}
}
if img then
-- & is re-escaped because mw.html treats attributes
-- & is re-escaped because mw.html treats attributes
-- as plain text, but MediaWiki doesn't
-- as plain text, but MediaWiki doesn't
local escapedTitle = ( plainTitle or '' ):gsub( '&', '&' )
local escapedTitle = ( plainTitle or '' ):gsub( '&', '&' )
local altText = img .. ': Inventory sprite for ' .. name .. ' in Minecraft as shown in-game'
item:addClass( 'invslot-item-image' )
if link then
:wikitext( '[[File:', img, '|32x32px|link=', link or '', '|', escapedTitle, ']]' )
altText = altText .. ' linking to ' .. link
else
end
local image
if formattedTitle or plainTitle or link then
if mod then
altText = altText .. ' with description: ' .. ( formattedTitle or plainTitle or link )
image = args.spritesheet or mod .. 'Sprite.png'
if description then
altText = altText .. ' ' .. description:gsub( '/', ' ' )
end
end
if link then
altText = altText:gsub( '&[0-9a-jl-qs-wr]', '' )
item:wikitext( '[[', link, '|' )
end
local image, spriteCat = sprite{
iddata = idData, title = plainTitle,
image = image, data = 'InvSprite',
nourl = args.nourl,
}
item:node( image )
category = spriteCat
end
end
item:addClass( 'invslot-item-image' )
:wikitext( '[[File:', img, '|32x32px|link=', link or '', '|alt=', altText, '|', escapedTitle, ']]' )
if num and num > 1 and num < 1000 then
if num and num > 1 and num < 1000 then
if img and link then
if link then
item:wikitext( '[[', link, '|' )
item:wikitext( '[[', link, '|' )
end
end
Line 176: Line 198:
:attr{ title = plainTitle }
:attr{ title = plainTitle }
:wikitext( num )
:wikitext( num )
if numStyle then
if args.numstyle then
number:cssText( numStyle )
number:cssText( args.numstyle )
end
end
if img and link then
if link then
item:wikitext( ']]' )
item:wikitext( ']]' )
end
end
end
if not img and link then
item:wikitext( ']]' )
end
end
Line 252: Line 270:
if frame[1] then
if frame[1] then
item = body:tag( 'span' ):addClass( 'animated-subframe' )
item = body:tag( 'span' ):addClass( 'animated-subframe' )
local subActiveFrame = frame.randomise and random( #frame ) or 1
local subActiveFrame = frame.randomise == true and random( #frame ) or 1
for sI, sFrame in ipairs( frame ) do
for sI, sFrame in ipairs( frame ) do
local sItem = makeItem( sFrame, sI, args )
local sItem = makeItem( sFrame, sI, args )
Line 282: Line 300:
local subframe
local subframe
local expandedAliases
local expandedAliases
local splitFrames = mw.text.split( mw.text.trim( framesText ), '%s*;%s*' )
local splitFrames = splitOnUnenclosedSemicolons( framesText )
for _, frameText in ipairs( splitFrames ) do
for i, frameText in ipairs( splitFrames ) do
frameText = frameText:gsub( '^%s*{%s*', function()
frameText = frameText:gsub( '^%s*{%s*', function()
subframe = true
subframe = true
Line 340: Line 358:
-- or the subframe being the only frame
-- or the subframe being the only frame
if #subframes == 1 or #splitFrames == i and #frames == 0 then
if #subframes == 1 or #splitFrames == i and #frames == 0 then
local lastFrame = #frames
mergeList( frames, subframes )
mergeList( frames, subframes )
-- Inherit the randomise flag if it's the only frame
if #splitFrames == 1 then
frames.randomise = subframes.randomise
end
-- Append alias reference data, if present
if aliasReference and subframes.aliasReference then
if not expandedAliases then
expandedAliases = {}
end
for i, aliasRefData in pairs(subframes.aliasReference) do
expandedAliases[lastFrame + i] = aliasRefData
end
end
else
else
table.insert( frames, subframes )
table.insert( frames, subframes )
Line 349: Line 383:
else
else
-- Randomise starting frame for "Any *" aliases, as long as the alias is the only frame
-- Randomise starting frame for "Any *" aliases, as long as the alias is the only frame
if frames.randomise == nil and frame.name:match( '^' .. i18n.prefixes.any .. ' ' ) then
if frames.randomise ~= 'never' and frame.name:match( '^' .. i18n.prefixes.any .. ' ' ) then
frames.randomise = true
frames.randomise = true
elseif frames.randomise ~= 'never' then
else
frames.randomise = false
frames.randomise = false
end
end
Line 407: Line 441:
end
end
return string.format(
return string.format(
'[%s]%s:%s,%s[%s]',
'[%s]%s,%s[%s]',
frame.title or '',
frame.title or '',
frame.mod or 'Minecraft',
frame.name,
frame.name,
frame.num or '',
frame.num or '',