Modul:Crafting: Unterschied zwischen den Versionen

Aus Wikicadia
Zur Navigation springen Zur Suche springen
(Die Seite wurde neu angelegt: „local p = {} local i18n = { colored = 'Colored', coloredDyes = { 'Orange Dye', 'Magenta Dye', 'Light Blue Dye', 'Yellow Dye', 'Lime Dye', 'Pink Dye', 'Gray Dye', 'Light Gray Dye', 'Cyan Dye', 'Purple Dye', 'Blue Dye', 'Brown Dye', 'Green Dye', 'Red Dye', 'Black Dye', }, categoryIngredientUsage = 'Category:Recipe using $1', categoryRecipeType = 'Category:$1 recipe', itemBlockOfQuartz = 'Block of Quartz', itemBlockOfQuartz = 'Block of Quartz…“)
 
Keine Bearbeitungszusammenfassung
 
Zeile 1: Zeile 1:
local p = {}
local p = {}
local i18n = {
colored = 'Colored',
coloredDyes = {
'Orange Dye', 'Magenta Dye', 'Light Blue Dye', 'Yellow Dye', 'Lime Dye',
'Pink Dye', 'Gray Dye', 'Light Gray Dye', 'Cyan Dye', 'Purple Dye',
'Blue Dye', 'Brown Dye', 'Green Dye',
'Red Dye', 'Black Dye',
},
categoryIngredientUsage = 'Category:Recipe using $1',
categoryRecipeType = 'Category:$1 recipe',
itemBlockOfQuartz = 'Block of Quartz',
itemBlockOfQuartz = 'Block of Quartz',
itemBrownMushroom = 'Brown Mushroom',
itemCharcoal = 'Charcoal',
itemCoal = 'Coal',
itemColoredDye = 'Colored Dye',
itemDye = 'Dye',
itemMushroom = 'Mushroom',
itemQuartzBlock = 'Quartz Block',
itemSmoothQuartzBlock = 'Smooth Quartz Block',
itemRedMushroom = 'Red Mushroom',
itemStone = 'Stone',
itemWhiteDye = 'White Dye',
moduleArgs = [[Module:ProcessArgs]],
moduleRecipe = [[Module:Recipe table]],
moduleSlot = [[Module:Inventory slot]],
stoneVariants = { 'Stone', 'Andesite', 'Granite', 'Diorite' },
type = 'Crafting',
variantPages = {
'Andesite', 'Banner', 'Bed', 'Diorite', 'Firework Star', 'Granite',
'Pressure Plate', 'Sand', 'Sandstone', 'Shield', 'Slab', 'Stained Glass Pane',
'Stained Glass', 'Stairs', 'Wood Planks', 'Wood', 'Wool',
},
    CopperBlockLinks = {
'Block of Copper', 'Exposed Copper', 'Weathered Copper', 'Oxidized Copper', 'Cut Copper', 'Exposed Cut Copper', 'Weathered Cut Copper', 'Oxidized Cut Copper', 'Waxed Block of Copper', 'Waxed Copper', 'Waxed Exposed Copper', 'Waxed Weathered Copper', 'Waxed Cut Copper', 'Waxed Exposed Cut Copper', 'Waxed Weathered Cut Copper', 'Copper Block'
},
    CopperBlock = 'Block of Copper',
}
p.i18n = i18n
local slot = require( i18n.moduleSlot )
local recipeTable = require( i18n.moduleRecipe ).table
local cArgVals = { 'A1', 'B1', 'C1', 'A2', 'B2', 'C2', 'A3', 'B3', 'C3' }
p.cArgVals = cArgVals
function p.table( f )
function p.table( f )
local args = f
local args = f
if f == mw.getCurrentFrame() then
if f == mw.getCurrentFrame() then
args = require( i18n.moduleArgs ).merge( true )
args = require( 'Module:ProcessArgs' ).merge()
else
else
f = mw.getCurrentFrame()
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 ~= '' 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 ~= '' 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
end
-- Automatic shapeless positioning
-- Automatic shapeless positioning
local newArgs = {}
if args[1] then
if args[1] then
args.shapeless = 1
newArgs.shapeless = 1
if args[7] then
if args[7] then
args.A1 = args[1]
newArgs.A1 = args[1]
args.B1 = args[2]
newArgs.B1 = args[2]
args.C1 = args[3]
newArgs.C1 = args[3]
args.A2 = args[4]
newArgs.A2 = args[4]
args.B2 = args[5]
newArgs.B2 = args[5]
args.C2 = args[6]
newArgs.C2 = args[6]
if args[8] then
if args[8] then
-- ◼◼◼      ◼◼◼
-- ◼◼◼      ◼◼◼
-- ◼◼◼  OR  ◼◼◼
-- ◼◼◼  OR  ◼◼◼
-- ◼◼◼      ◼◼◻
-- ◼◼◼      ◼◼◻
args.A3 = args[7]
newArgs.A3 = args[7]
args.B3 = args[8]
newArgs.B3 = args[8]
args.C3 = args[9]
newArgs.C3 = args[9]
if args[9] then
if args[9] then
local identical = true
local identical = true
Zeile 76: Zeile 182:
if args[i] ~= args[i + 1] then
if args[i] ~= args[i + 1] then
identical = false
identical = false
break
end
end
end
end
if identical then
if identical then
args.shapeless = nil
newArgs.shapeless = nil
end
end
end
end
Zeile 87: Zeile 192:
-- ◼◼◼
-- ◼◼◼
-- ◻◼◻
-- ◻◼◻
args.B3 = args[7]
newArgs.B3 = args[7]
end
end
elseif args[2] then
elseif args[2] then
args.A2 = args[1]
newArgs.A2 = args[1]
args.B2 = args[2]
newArgs.B2 = args[2]
if args[5] then
if args[5] then
-- ◻◻◻      ◻◻◻
-- ◻◻◻      ◻◻◻
-- ◼◼◼  OR  ◼◼◼
-- ◼◼◼  OR  ◼◼◼
-- ◼◼◼      ◼◼◻
-- ◼◼◼      ◼◼◻
args.C2 = args[3]
newArgs.C2 = args[3]
args.A3 = args[4]
newArgs.A3 = args[4]
args.B3 = args[5]
newArgs.B3 = args[5]
args.C3 = args[6]
newArgs.C3 = args[6]
elseif args[4] then
elseif args[4] then
-- ◻◻◻
-- ◻◻◻
-- ◼◼◻
-- ◼◼◻
-- ◼◼◻
-- ◼◼◻
args.A3 = args[3]
newArgs.A3 = args[3]
args.B3 = args[4]
newArgs.B3 = args[4]
else
else
-- ◻◻◻      ◻◻◻
-- ◻◻◻      ◻◻◻
-- ◼◼◻  OR  ◼◼◻
-- ◼◼◻  OR  ◼◼◻
-- ◻◼◻      ◻◻◻
-- ◻◼◻      ◻◻◻
args.B3 = args[3]
newArgs.B3 = args[3]
end
end
else
else
Zeile 116: Zeile 221:
-- ◻◼◻
-- ◻◼◻
-- ◻◻◻
-- ◻◻◻
args.B2 = args[1]
newArgs.B2 = args[1]
args.shapeless = nil
newArgs.shapeless = nil
end
for i = 1, 9 do
args[i] = nil
end
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
end
-- Create recipe table, and list of ingredients
-- Any other args we want to pass along
local out, ingredientSets = recipeTable( args, {
newArgs.Mod = args.Mod
uiFunc = 'craftingTable',
newArgs.Output = args.Output
type = i18n.type,
newArgs.Otitle = args.Otitle
ingredientArgs = cArgVals,
newArgs.Olink = args.Olink
outputArgs = { 'Output' },
} )
-- Recipe cell
local recipeCell = grid.craftingTable( newArgs )
local title = mw.title.getCurrentTitle()
local row = { ingredientsCell, recipeCell }
if args.nocat == '1' or title.namespace ~= 0 or title.isSubpage then
if nameCell then
return out
table.insert( row, 1, nameCell )
end
if f:callParserFunction( '#dplvar', 'craftingdescription' ) == '1' then
table.insert( row, args.description or '' )
end
end
row = table.concat( row, '\n|\n' )
local categories = {}
if nameCell then
local cI = 1
row = '!\n' .. row
else
row = '|\n' .. row
end
if args.type and args.ignoreusage ~= '1' then
local footer = ''
categories[cI] = '[[' .. i18n.categoryRecipeType:gsub( '%$1', args.type ) .. ']]'
if foot ~= '' then
cI = cI + 1
footer = '|}'
f:callParserFunction( '#dplvar:set', 'craftingname', '0', 'craftingdescription', '0' )
end
end
if args.ignoreusage ~= '1' then
-- Create ingredient categories for DPL
-- Create ingredient categories for DPL
local title = mw.title.getCurrentTitle()
local usedNames = {}
local categories = ''
if args.nocat ~= '1' and title.namespace == 0 and not title.isSubpage then
categories = {}
if args.upcoming then
table.insert( categories, '[[Category:Upcoming]]' )
end
local function addName(name)
if args.type then
if not usedNames[name] then -- redundant with most current code, but not with all, and might prevent other issues
table.insert( categories, '[[Category:' .. args.type .. ' recipe]]' )
categories[cI] = '[[' .. i18n.categoryIngredientUsage:gsub( '%$1', name ) .. ']]'
cI = cI + 1
usedNames[name] = true
end
end
end
 
for _, ingredientSet in pairs( ingredientSets ) do
if args.ignoreusage ~= '1' then
for _, ingredient in pairs( ingredientSet ) do
for k, v in ipairs( ingredientKeys ) do
local name = ingredient.name
v = v:sub( 2 )
if not ingredient.mod and not usedNames[name] then
if not v:find( ':' ) then
-- List each dye individually as they have their own pages
if v == 'Any Dye' or v == 'Any Colored Dye' then
if
local dyes = {
name == slot.i18n.prefixes.any .. ' ' .. i18n.itemDye or
'Orange Dye', 'Magenta Dye', 'Light Blue Dye', 'Dandelion Yellow', 'Lime Dye',
name == slot.i18n.prefixes.matching .. ' ' .. i18n.itemDye or
'Pink Dye', 'Gray Dye', 'Light Gray Dye', 'Cyan Dye', 'Purple Dye',
name == slot.i18n.prefixes.any .. ' ' .. i18n.itemColoredDye or
'Lapis Lazuli', 'Cocoa Beans', 'Cactus Green', 'Rose Red', 'Ink Sac'
name == slot.i18n.prefixes.matching .. ' ' .. i18n.itemColoredDye
}
then
if v == 'Any Dye' then
if not name:find( i18n.colored ) then
table.insert( dyes, 1, 'Bone Meal' )
addName( i18n.itemWhiteDye )
end
end
for _, dye in pairs( i18n.coloredDyes ) do
for _, dye in ipairs( dyes ) do
addName( dye )
table.insert( categories, '[[Category:Recipe using ' .. dye .. ']]' )
end
-- List stone variants individually as they have their own pages
elseif
name == slot.i18n.prefixes.any .. ' ' .. i18n.itemStone or
name == slot.i18n.prefixes.matching .. ' ' .. i18n.itemStone
then
for _, stone in pairs( i18n.stoneVariants ) do
addName( stone )
end
end
else
else
-- Merge item variants which use a single page
if v == 'Sticky Piston' then v = 'Piston'
if
elseif v== 'Any Mushroom' or v == 'Red Mushroom' or v == 'Brown Mushroom' then v = 'Mushroom'
name == slot.i18n.prefixes.any .. ' ' .. i18n.itemMushroom or
elseif v == 'Red Sand' then v = 'Sand'
name == slot.i18n.prefixes.matching .. ' ' .. i18n.itemMushroom or
elseif v == 'Charcoal' then v = 'Coal'
name == i18n.itemRedMushroom or
elseif v:find( ' Wood$' ) then v = 'Wood'
name == i18n.itemBrownMushroom
elseif v:find( ' Wood Planks$' ) then v = 'Wood Planks'
then name = i18n.itemMushroom
elseif v:find( ' Stained Glass$' ) then v = 'Stained Glass'
elseif name == i18n.itemSmoothQuartzBlock then name = i18n.itemSmoothQuartzBlock
elseif v:find( ' Stained Glass Pane$' ) then v = 'Stained Glass Pane'
elseif name == i18n.itemCharcoal then name = i18n.itemCoal
elseif v:find( ' Wool$' ) then v = 'Wool'
elseif name:find( ' ' .. i18n.itemQuartzBlock .. '$' ) then name = i18n.itemBlockOfQuartz
elseif v:find( 'Red Sandstone$' ) then v = 'Red Sandstone'
else
elseif v:find( ' Sandstone$' ) then v = 'Sandstone'
for _, variant in pairs( i18n.variantPages ) do
elseif v:find( ' Stairs$' ) then v = 'Stairs'
if name:find( ' ' .. variant .. '$' ) then
elseif v:find( ' Slab$' ) then v = 'Slab'
name = variant
elseif v:find( ' Pressure Plate$' ) then v = 'Pressure Plate'
break
elseif v:find( ' Firework Star$' ) then v = 'Firework Star'
end
elseif v:find( ' Stone Bricks$' ) then v = 'Stone Bricks'
end
elseif v:find( ' Quartz Block$' ) then v = 'Block of Quartz'
for _, variant in pairs( i18n.CopperBlockLinks ) do
elseif v:find( ' Andesite$' ) then v = 'Andesite'
if name:find( variant ) then
elseif v:find( ' Diorite$' ) then v = 'Diorite'
name = i18n.CopperBlock
elseif v:find( ' Granite$' ) then v = 'Granite'
break
end
end
-- Remove prefixes
for _, prefix in pairs( slot.i18n.prefixes ) do
if name:find( '^' .. prefix .. ' ' ) then
name = name:gsub( '^' .. prefix .. ' ', '' )
break
end
end
end
end
-- handle "A or B" names
table.insert( categories, '[[Category:Recipe using ' .. v .. ']]' )
local orA, orB = name:match("(.-) or (.+)")
if orA then
addName( orA )
addName( orB )
else
addName( name )
end
end
end
end
end
end
end
end
end
categories = table.concat( categories, '' )
end
end
return out, table.concat( categories, '' )
if args.debug == '1' then
return '<pre>' .. header .. '\n' .. row .. '\n|-\n' .. footer .. categories .. '</pre>'
else
return header .. '\n' .. row .. '\n|-\n' .. footer .. categories
end
end
end
return p
return p

Aktuelle Version vom 20. Mai 2024, 15:51 Uhr

Die Dokumentation für dieses Modul kann unter Modul:Crafting/Doku erstellt werden

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 ~= '' 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 ~= '' 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
	
	-- Create ingredient categories for DPL
	local title = mw.title.getCurrentTitle()
	local categories = ''
	if args.nocat ~= '1' and title.namespace == 0 and not title.isSubpage then
		categories = {}
		
		if args.upcoming then
			table.insert( categories, '[[Category:Upcoming]]' )
		end
		
		if args.type then
			table.insert( categories, '[[Category:' .. args.type .. ' recipe]]' )
		end
		
		if args.ignoreusage ~= '1' then
			for k, v in ipairs( ingredientKeys ) do
				v = v:sub( 2 )
				if not v:find( ':' ) then
					if v == 'Any Dye' or v == 'Any Colored Dye' then
						local dyes = {
							'Orange Dye', 'Magenta Dye', 'Light Blue Dye', 'Dandelion Yellow', 'Lime Dye',
							'Pink Dye', 'Gray Dye', 'Light Gray Dye', 'Cyan Dye', 'Purple Dye',
							'Lapis Lazuli', 'Cocoa Beans', 'Cactus Green', 'Rose Red', 'Ink Sac'
						}
						if v == 'Any Dye' then
							table.insert( dyes, 1, 'Bone Meal' )
						end
						
						for _, dye in ipairs( dyes ) do
							table.insert( categories, '[[Category:Recipe using ' .. dye .. ']]' )
						end
					else
						if v == 'Sticky Piston' then v = 'Piston'
						elseif v== 'Any Mushroom' or v == 'Red Mushroom' or v == 'Brown Mushroom' then v = 'Mushroom'
						elseif v == 'Red Sand' then v = 'Sand'
						elseif v == 'Charcoal' then v = 'Coal'
						elseif v:find( ' Wood$' ) then v = 'Wood'
						elseif v:find( ' Wood Planks$' ) then v = 'Wood Planks'
						elseif v:find( ' Stained Glass$' ) then v = 'Stained Glass'
						elseif v:find( ' Stained Glass Pane$' ) then v = 'Stained Glass Pane'
						elseif v:find( ' Wool$' ) then v = 'Wool'
						elseif v:find( 'Red Sandstone$' ) then v = 'Red Sandstone'
						elseif v:find( ' Sandstone$' ) then v = 'Sandstone'
						elseif v:find( ' Stairs$' ) then v = 'Stairs'
						elseif v:find( ' Slab$' ) then v = 'Slab'
						elseif v:find( ' Pressure Plate$' ) then v = 'Pressure Plate'
						elseif v:find( ' Firework Star$' ) then v = 'Firework Star'
						elseif v:find( ' Stone Bricks$' ) then v = 'Stone Bricks'
						elseif v:find( ' Quartz Block$' ) then v = 'Block of Quartz'
						elseif v:find( ' Andesite$' ) then v = 'Andesite'
						elseif v:find( ' Diorite$' ) then v = 'Diorite'
						elseif v:find( ' Granite$' ) then v = 'Granite'
						end
						
						table.insert( categories, '[[Category:Recipe using ' .. v .. ']]' )
					end
				end
			end
		end
		
		categories = table.concat( categories, '' )
	end
	
	if args.debug == '1' then
		return '<pre>' .. header .. '\n' .. row .. '\n|-\n' .. footer .. categories .. '</pre>'
	else
		return header .. '\n' .. row .. '\n|-\n' .. footer .. categories
	end
end
return p