Module:Grid

local defaultMod = 'IDTMod' local p = {}

-- Individual cell function p.cell( 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:Grid/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:Grid/IDs ) local modIds = {} local animated = args[1]:find( ';' ) local pageName = mw.title.getCurrentTitle.subpageText local imgClass = args.imgclass local numStyle = args.numstyle local body = mw.html.create( 'span' ):addClass( 'grid' ):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 local item = body :tag( 'span' ) :addClass( 'grid-default-item' ) :wikitext( '' ) if animated then item:addClass( 'skip' ) end 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( 'grid-item' ) if imgClass then item:addClass( imgClass ) end end if frame == '' then ( item or body ):tag( 'br' ) else local parts = p.getParts( frame, args.mod ) local tooltipTitle = parts.title local mod = parts.mod local name = parts.name local num = parts.num local tooltipDesc = parts.text local img, spriteImg if mod then if not modIds[mod] and mw.title.new( 'Module:Grid/Mods/' .. mod .. '/IDs' ).exists then modIds[mod] = mw.loadData( 'Module:Grid/Mods/' .. mod .. '/IDs' ) end if modIds[mod] and modIds[mod][name] then spriteImg = modIds[mod][name] else img = name .. ' (' .. mod .. ')' end elseif ids and ids[name] then spriteImg = ids[name] else img = name end local link = args.link or '' if link == '' then if name == pageName then link = 'none' elseif mod then link = 'mcw:' if mod ~= 'Minecraft' then link = link .. 'Mods/' .. mod .. '/'					end link = link .. name else link = name end end local title = args.title or '' if title == '' then if tooltipTitle then title = tooltipTitle:gsub( '&[0-9a-fk-or]', '' ) end if mw.text.trim( title ) == '' and ( link:lower == 'none' or link ~= name ) then title = name end end if link:lower == 'none' then link = nil end if title == '' then title = nil elseif title:lower == 'none' then if link then title = '' else title = nil end end if img and ( title == '' or not link ) then item:attr{ title = title } end item:attr{ ['data-minetip-title'] = tooltipTitle, ['data-minetip-text'] = tooltipDesc }			if img then item:addClass( 'grid-item-image' ) :wikitext( '' ) else if not sprite then sprite = require( Module:Sprite ).base end local settings = 'Grid/Settings' local image if mod == 'Minecraft' then settings = 'Grid/Mods/Minecraft/Settings' elseif mod then image = args.spritesheet or mod .. 'Sprite.png' end if link then item:wikitext(  )				end				item:wikitext( sprite{					pos = spriteImg, title = title,					image = image, settings = settings				} )			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( 'grid-number' )						:attr{ title = title }						:wikitext( num )				if numStyle then					number:cssText( numStyle )				end				if img and link then					item:wikitext(  )				end			end			if spriteImg and link then				item:wikitext( ']]' ) end end if first then if animated and item then item:addClass( 'active' ) end first = false end end return tostring( 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 defaultMod 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 '' ) if parts.mod == '' or mw.ustring.lower( parts.mod ) == mw.ustring.lower( defaultMod ) then parts.mod = nil else local vanilla = { v = 1, vanilla = 1, mc = 1, minecraft = 1 } if vanilla[mw.ustring.lower( parts.mod )] then parts.mod = 'Minecraft' end 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

local addCell = function( args, item, prefix, class, default ) prefix = prefix or item return p.cell{ args[item], mod = args.Mod, link = args[prefix .. 'link'], title = args[prefix .. 'title'], class = class, default = default } end

--- GUI variants; called directly to avoid the overhead of a bunch of #invoke calls per GUI -- Crafting table function p.craftingTable( f ) local args = f	if f == mw.getCurrentFrame then args = f:getParent.args else f = mw.getCurrentFrame end local body = mw.html.create( 'span' ):addClass( 'grid-Crafting_Table' ) local input = body:tag( 'span' ):addClass( 'grid-input' ) for num = 1, 3 do		local row = input:tag( 'span' ):addClass( 'grid-row' ) for _, letter in ipairs{ 'A', 'B', 'C' } do row:wikitext( addCell( args, letter .. num ) ) end end local arrow = body:tag( 'span' ):addClass( 'grid-arrow' ):tag( 'br' ):done if args.arrow or  ~=  then arrow:css( 'background-image',			f:callParserFunction( '#widget:FileUrl', { url = args.arrow .. ' (' .. args.Mod .. ').png' } )		) end body :tag( 'span' ) :addClass( 'grid-output' ) :wikitext( addCell( args, 'Output', 'O', 'grid-large' ) ) if args.shapeless or  ~=  then body :tag( 'span' ) :addClass( 'grid-icons' ) :tag( 'span' ) :addClass( 'grid-shapeless' ) :attr( 'title',						'This recipe is shapeless; the inputs may be placed in any arrangement in the crafting grid.'					) :tag( 'br' ) end return tostring( mw.html.create( 'div' ):node( body ) ) end

-- Furnace function p.furnace( f ) local args = f	if f == mw.getCurrentFrame then args = f:getParent.args else f = mw.getCurrentFrame end local body = mw.html.create( 'span' ):addClass( 'grid-Furnace' ) local input = body:tag( 'span' ):addClass( 'grid-input' ) input:wikitext( addCell( args, 'Input', 'I' ) ) local fuel = input:tag( 'span' ):addClass( 'grid-fuel' ):tag( 'br' ):done local fuelImg = args.FuelUsage or '' local burning = args.Input or  ~=  and args.Fuel or  ~=  if not burning then fuel:addClass( 'grid-inactive' ) if fuelImg ~= '' then fuelImg = fuelImg .. ' (in-active)' end end if fuelImg ~= '' then fuel:css( 'background-image', f:callParserFunction( '#widget:FileUrl', { url = 'Grid layout ' .. fuelImg .. ' (' .. args.Mod .. ').png' } ) )	end input:wikitext( addCell( args, 'Fuel', 'F' ) ) local arrow = body:tag( 'span' ):addClass( 'grid-arrow' ):tag( 'br' ):done local arrowImg = args.Progress or '' if not burning or ( args.Output or  ) ==  then arrow:addClass( 'grid-inactive' ) if arrowImg ~= '' then arrowImg = arrowImg .. ' (in-active)' end end if arrowImg ~= '' then arrow:css( 'background-image', f:callParserFunction( '#widget:FileUrl', { url = 'Grid layout ' .. arrowImg .. ' (' .. args.Mod .. ').png' } ) )	end body :tag( 'span' ) :addClass( 'grid-output' ) :wikitext( addCell( args, 'Output', 'O', 'grid-large' ) ) return tostring( mw.html.create( 'div' ):node( body ) ) end

-- Brewing Stand function p.brewingStand( f ) local args = f	if f == mw.getCurrentFrame then args = f:getParent.args else f = mw.getCurrentFrame end local body = mw.html.create( 'span' ):addClass( 'grid-Brewing_Stand' ) local input = body:tag( 'span' ):addClass( 'grid-input' ) input:tag( 'span' ):addClass( 'grid-bubbling' ):tag( 'br' ) input:wikitext( addCell( 'Input', 'I' ) ) input:tag( 'span' ):addClass( 'grid-arrow' ):tag( 'br' ) if args.Input or  ==  or		( args.Output1 or  ~=  and args.Output2 or  ~=  and args.Output3 or  ~=  ) then input:addClass( 'grid-inactive' ) end body:tag( 'span' ):addClass( 'grid-paths' ):tag( 'br' ) local output = body:tag( 'span' ):addClass( 'grid-output' ) for i = 1, 3 do output:wikitext( addCell( args, 'Output' .. i, 'O' .. i, 'grid-output' .. i, 'layout Brewing Empty' ) ) end return tostring( mw.html.create( 'div' ):node( body ) ) end return p