Module:Crafting

*Documentation for this module may be created at Module:Crafting/doc*

```
local p = {}
function p.table( f )
 local args = f
 if f == mw.getCurrentFrame() then
 args = require( 'Module:ProcessArgs' ).merge()
 else
 f = mw.getCurrentFrame()
 end
 local grid = require( 'Module:Grid' )

 -- Start table when appropriate
 local multirow = f:callParserFunction( '#dplvar', 'multirow' )
 if multirow ~= '1' then
 multirow = nil
 end
 local head = args.head or ''
 if multirow then
 head = ''
 elseif head ~= '' then
 multirow = 1
 f:callParserFunction( '#dplvar:set', 'multirow', '1' )
 else
 head = 1
 end

 -- End table when appropriate
 local foot = args.foot or ''
 if multirow then
 if foot ~= '' then
 multirow = nil
 f:callParserFunction( '#dplvar:set', 'multirow', '0' )
 end
 else
 foot = 1
 end

 local header = ''
 if head ~= '' then
 local name = ''
 local description = ''
 if args.showname == '1' or multirow and args.showname ~= '0' then
 name = 'Name !! '
 f:callParserFunction( '#dplvar:set', 'craftingname', '1' )
 end
 if args.showdescription == '1' then
 description = ' !! class="unsortable" | Description'
 f:callParserFunction( '#dplvar:set', 'craftingdescription', '1' )
 end
 local class = args.class or ''
 local recipeClass = ''
 if multirow then
 class = 'sortable collapsible ' .. class
 recipeClass = 'class="unsortable collapse-button" |'
 end
 header = table.concat( {
 ' {| class="wikitable ' .. class .. '"',
 '! ' .. name .. 'Ingredients !! ' .. recipeClass .. ' [[Crafting]] recipe' .. description,
 '|-'
 }, '\n' )
 end

 -- Name cell
 local nameCell
 if f:callParserFunction( '#dplvar', 'craftingname' ) == '1' then
 if args.name or '' ~= '' then
 nameCell = args.name
 else
 local names = {}
 local links = {}
 for v in mw.text.gsplit( args.Output or '', '%s\*;%s\*' ) do
 parts = grid.getParts( v, args.Mod )
 parts.mod = parts.mod or ''
 if not names[parts.mod .. ':' .. parts.name] then
 local link = ''
 if parts.mod == 'Minecraft' then
 link = 'mcw:' .. parts.name .. '|'
 elseif parts.mod ~= '' then
 link = 'Mods/' .. parts.mod .. '/' .. parts.name .. '|'
 end

 if parts.name:find( '^Any ' ) then
 table.insert( links, 'Any [[' .. link .. parts.name:sub( 4 ) .. ']]' )
 else
 table.insert( links, '[[' .. link .. parts.name .. ']]' )
 end
 names[parts.mod .. ':' .. parts.name] = 1
 end
 end

 nameCell = table.concat( links, '&nbsp;or<br>' )
 end
 end

 if nameCell and args.upcoming then
 nameCell = nameCell .. '<br>([[' .. args.upcoming .. ']])'
 end

 -- Create ingredient list
 local ingredients = {}
 local ingredientKeys = {}
 local animatedIngredients = {}
 local animatedKeys = {}
 for k, v in pairs( args ) do
 v = mw.text.trim( v )
 if v ~= '' and tostring( k ):find( '^%u?%d%d?$' ) then
 if v:find( ';' ) then
 table.insert( animatedKeys, v )
 else
 local parts = grid.getParts( v, args.Mod )
 parts.mod = parts.mod or ''
 local fullName = parts.mod .. ':' .. parts.name
 if not ingredients[fullName] then
 table.insert( ingredientKeys, fullName )
 ingredients[fullName] = { mod = parts.mod, name = parts.name }
 end
 end
 end
 end
 for k, v in ipairs( animatedKeys ) do
 local frames = mw.text.split( v, '%s\*;%s\*' )
 local length = #frames
 for k2, v2 in ipairs( frames ) do
 local parts = grid.getParts( v2, args.Mod )
 parts.mod = parts.mod or ''
 local fullName = parts.mod .. ':' .. parts.name
 if v2 ~= '' and not ingredients[fullName] and not animatedIngredients[fullName] then
 table.insert( ingredientKeys, fullName )
 animatedIngredients[fullName] = { mod = parts.mod, name = parts.name, final = k2 == length }
 end
 end
 end

 -- Ingredients cell
 local ingredientsCell
 if args.ingredients or '' ~= '' then
 ingredientsCell = args.ingredients
 else
 ingredientsCell = {}
 for k, v in ipairs( ingredientKeys ) do
 local link = ''
 local separator = '&nbsp;+'
 if k == #ingredientKeys then
 separator = ''
 elseif animatedIngredients[v] and not animatedIngredients[v].final then
 separator = '&nbsp;or'
 end
 local mod = ( ingredients[v] or animatedIngredients[v] ).mod
 local name = ( ingredients[v] or animatedIngredients[v] ).name
 if mod == 'Minecraft' then
 link = 'mcw:' .. name .. '|'
 elseif mod ~= '' then
 link = 'Mods/' .. mod .. '/' .. name .. '|'
 end

 if name:find( '^Any ' ) then
 table.insert( ingredientsCell, 'Any [[' .. link .. name:sub( 5 ) .. ']]' .. separator )
 else
 table.insert( ingredientsCell, '[[' .. link .. name .. ']]' .. separator )
 end
 end

 ingredientsCell = table.concat( ingredientsCell, '<br>\n' )
 end

 -- Automatic shapeless positioning
 local newArgs = {}
 if args[1] then
 newArgs.shapeless = 1
 if args[7] then
 newArgs.A1 = args[1]
 newArgs.B1 = args[2]
 newArgs.C1 = args[3]
 newArgs.A2 = args[4]
 newArgs.B2 = args[5]
 newArgs.C2 = args[6]
 if args[8] then
 -- ◼◼◼ ◼◼◼
 -- ◼◼◼ OR ◼◼◼
 -- ◼◼◼ ◼◼◻
 newArgs.A3 = args[7]
 newArgs.B3 = args[8]
 newArgs.C3 = args[9]
 if args[9] then
 local identical = true
 for i = 1, 8 do
 if args[i] ~= args[i + 1] then
 identical = false
 end
 end
 if identical then
 newArgs.shapeless = nil
 end
 end
 else
 -- ◼◼◼
 -- ◼◼◼
 -- ◻◼◻
 newArgs.B3 = args[7]
 end
 elseif args[2] then
 newArgs.A2 = args[1]
 newArgs.B2 = args[2]
 if args[5] then
 -- ◻◻◻ ◻◻◻
 -- ◼◼◼ OR ◼◼◼
 -- ◼◼◼ ◼◼◻
 newArgs.C2 = args[3]
 newArgs.A3 = args[4]
 newArgs.B3 = args[5]
 newArgs.C3 = args[6]
 elseif args[4] then
 -- ◻◻◻
 -- ◼◼◻
 -- ◼◼◻
 newArgs.A3 = args[3]
 newArgs.B3 = args[4]
 else
 -- ◻◻◻ ◻◻◻
 -- ◼◼◻ OR ◼◼◻
 -- ◻◼◻ ◻◻◻
 newArgs.B3 = args[3]
 end
 else
 -- ◻◻◻
 -- ◻◼◻
 -- ◻◻◻
 newArgs.B2 = args[1]
 newArgs.shapeless = nil
 end
 else
 newArgs.A1 = args.A1
 newArgs.B1 = args.B1
 newArgs.C1 = args.C1
 newArgs.A2 = args.A2
 newArgs.B2 = args.B2
 newArgs.C2 = args.C2
 newArgs.A3 = args.A3
 newArgs.B3 = args.B3
 newArgs.C3 = args.C3
 newArgs.fixed = args.fixed
 newArgs.notfixed = args.notfixed
 end

 -- Any other args we want to pass along
 newArgs.Mod = args.Mod
 newArgs.Output = args.Output
 newArgs.Otitle = args.Otitle
 newArgs.Olink = args.Olink

 -- Recipe cell
 local recipeCell = grid.craftingTable( newArgs )

 local row = { ingredientsCell, recipeCell }
 if nameCell then
 table.insert( row, 1, nameCell )
 end
 if f:callParserFunction( '#dplvar', 'craftingdescription' ) == '1' then
 table.insert( row, args.description or '' )
 end
 row = table.concat( row, '\n|\n' )

 if nameCell then
 row = '!\n' .. row
 else
 row = '|\n' .. row
 end

 local footer = ''
 if foot ~= '' then
 footer = '|}'
 f:callParserFunction( '#dplvar:set', 'craftingname', '0', 'craftingdescription', '0' )
 end

 local title = mw.title.getCurrentTitle()
 local category = ''
 if args.nocat ~= '1' and title.namespace == 0 and not title.isSubpage then
 if args.upcoming then
 category = '[[Category:Upcoming]]'
 end
 end

 return header .. '\n' .. row .. '\n|-\n' .. footer .. category
end
return p

```