<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.boxofrocks.net/index.php?action=history&amp;feed=atom&amp;title=Module%3ARecipe_table</id>
	<title>Module:Recipe table - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.boxofrocks.net/index.php?action=history&amp;feed=atom&amp;title=Module%3ARecipe_table"/>
	<link rel="alternate" type="text/html" href="https://wiki.boxofrocks.net/index.php?title=Module:Recipe_table&amp;action=history"/>
	<updated>2026-05-10T16:29:10Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.34.2</generator>
	<entry>
		<id>https://wiki.boxofrocks.net/index.php?title=Module:Recipe_table&amp;diff=375&amp;oldid=prev</id>
		<title>BoxWiki: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://wiki.boxofrocks.net/index.php?title=Module:Recipe_table&amp;diff=375&amp;oldid=prev"/>
		<updated>2021-05-13T15:55:18Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;Revision as of 15:55, 13 May 2021&lt;/td&gt;
				&lt;/tr&gt;
&lt;!-- diff cache key wikidb:diff::1.12:old-374:rev-375 --&gt;
&lt;/table&gt;</summary>
		<author><name>BoxWiki</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.boxofrocks.net/index.php?title=Module:Recipe_table&amp;diff=374&amp;oldid=prev</id>
		<title>Crafting&gt;Dhranios: removing upcoming argument in favor of description with upcoming template (as it is also used for only templates), hope this works</title>
		<link rel="alternate" type="text/html" href="https://wiki.boxofrocks.net/index.php?title=Module:Recipe_table&amp;diff=374&amp;oldid=prev"/>
		<updated>2020-11-05T11:57:10Z</updated>

		<summary type="html">&lt;p&gt;removing upcoming argument in favor of description with upcoming template (as it is also used for only templates), hope this works&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local m = {}&lt;br /&gt;
&lt;br /&gt;
local i18n = {&lt;br /&gt;
	headingDescription = 'Description',&lt;br /&gt;
	headingIngredients = 'Ingredients',&lt;br /&gt;
	headingName = 'Name',&lt;br /&gt;
	headingRecipe = '[[$1]] recipe',&lt;br /&gt;
	moduleSlot = [[Module:Inventory slot]],&lt;br /&gt;
	moduleUi = [[Module:UI]],&lt;br /&gt;
	separator = '&amp;amp;nbsp;+',&lt;br /&gt;
	setSeparator = '&amp;amp;nbsp;or',&lt;br /&gt;
	tableDescription = '$1 recipes',&lt;br /&gt;
}&lt;br /&gt;
local slot = require( i18n.moduleSlot )&lt;br /&gt;
local prefixes = slot.i18n.prefixes&lt;br /&gt;
&lt;br /&gt;
--[[Merges a list, or inserts a string&lt;br /&gt;
	or table into a table&lt;br /&gt;
--]]&lt;br /&gt;
local function mergeList( parentTable, content )&lt;br /&gt;
	local i = #parentTable + 1&lt;br /&gt;
	if content[1] then&lt;br /&gt;
		-- Merge list into table&lt;br /&gt;
		for _, v in ipairs( content ) do&lt;br /&gt;
			parentTable[i] = v&lt;br /&gt;
			i = i + 1&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		-- Add strings or tables to table&lt;br /&gt;
		parentTable[i] = content&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[Loops through the input and output args and parses them into a single table,&lt;br /&gt;
	with alias reference data&lt;br /&gt;
	&lt;br /&gt;
	Identical slots reuse the same table, to allow them to be compared like strings&lt;br /&gt;
--]]&lt;br /&gt;
local function parseRecipeArgs( args, ingredientArgVals, outputArgs )&lt;br /&gt;
	local recipeArgs = {}&lt;br /&gt;
	for _, arg in pairs( ingredientArgVals ) do&lt;br /&gt;
		recipeArgs[arg] = args[arg]&lt;br /&gt;
	end&lt;br /&gt;
	for _, arg in pairs( outputArgs ) do&lt;br /&gt;
		recipeArgs[arg] = args[arg]&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local parsedFrameText = {}&lt;br /&gt;
	local parsedRecipeArgs = {}&lt;br /&gt;
	for arg, frameText in pairs( recipeArgs ) do&lt;br /&gt;
		if frameText then&lt;br /&gt;
			local randomise&lt;br /&gt;
			for _, oArg in pairs( outputArgs ) do&lt;br /&gt;
				if arg == oArg then&lt;br /&gt;
					randomise = 'never'&lt;br /&gt;
					break&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			local frames = not randomise and parsedFrameText[frameText]&lt;br /&gt;
			if not frames then&lt;br /&gt;
				frames = slot.parseFrameText( frameText, randomise, true )&lt;br /&gt;
				parsedFrameText[frameText] = frames&lt;br /&gt;
			end&lt;br /&gt;
			parsedRecipeArgs[arg] = frames&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return parsedRecipeArgs&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[Creates a link (with mod name if specified) with&lt;br /&gt;
	any prefix moved outside&lt;br /&gt;
--]]&lt;br /&gt;
function m.prefixedLink( name, mod )&lt;br /&gt;
	local prefix = ''&lt;br /&gt;
	for _, thisPrefix in pairs( prefixes ) do&lt;br /&gt;
		if name:find( '^' .. thisPrefix .. ' ' ) then&lt;br /&gt;
			prefix = thisPrefix .. ' '&lt;br /&gt;
			name = name:sub( #prefix + 1 )&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local page = name&lt;br /&gt;
	if mod then&lt;br /&gt;
		page = slot.i18n.modLink:gsub( '%$1', mod ):gsub( '%$2', name )&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return table.concat{ prefix, '[[', page, '|', name, ']]' }&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[Creates sets of unique items from a set of slots, using the&lt;br /&gt;
	original alias name if available&lt;br /&gt;
	&lt;br /&gt;
	Each set of items are the frames of that slot&lt;br /&gt;
--]]&lt;br /&gt;
function m.makeItemSets( argVals, parsedArgs )&lt;br /&gt;
	local usedItems = {}&lt;br /&gt;
	local function addItem( items, arg, frame, alias )&lt;br /&gt;
		if alias then&lt;br /&gt;
			frame = alias.frame&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		local uniqName = ( frame.mod or '' ) .. ':' .. frame.name&lt;br /&gt;
		if not usedItems[uniqName] then&lt;br /&gt;
			usedItems[uniqName] = true&lt;br /&gt;
			items[#items + 1] = frame&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		return alias and alias.length or 1&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local itemSets = {}&lt;br /&gt;
	local i = 1&lt;br /&gt;
	for _, arg in ipairs( argVals ) do&lt;br /&gt;
		local frames = parsedArgs[arg]&lt;br /&gt;
		if frames then&lt;br /&gt;
			local items = {}&lt;br /&gt;
			local frameNum = 1&lt;br /&gt;
			while frameNum &amp;lt;= #frames do&lt;br /&gt;
				local frame = frames[frameNum]&lt;br /&gt;
				if frame[1] then&lt;br /&gt;
					local subframeNum = 1&lt;br /&gt;
					while subframeNum &amp;lt;= #frame do&lt;br /&gt;
						local subframe = frame[subframeNum]&lt;br /&gt;
						if subframe.name ~= '' then&lt;br /&gt;
							local alias = frame.aliasReference and frame.aliasReference[subframeNum]&lt;br /&gt;
							subframeNum = subframeNum + addItem( items, arg, subframe, alias )&lt;br /&gt;
						else&lt;br /&gt;
							subframeNum = subframeNum + 1&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
					frameNum = frameNum + 1&lt;br /&gt;
				elseif frame.name ~= '' then&lt;br /&gt;
					local alias = frames.aliasReference and frames.aliasReference[frameNum]&lt;br /&gt;
					frameNum = frameNum + addItem( items, arg, frame, alias )&lt;br /&gt;
				else&lt;br /&gt;
					frameNum = frameNum + 1&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			if #items &amp;gt; 0 then&lt;br /&gt;
				itemSets[i] = items&lt;br /&gt;
				i = i + 1&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return itemSets&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[Creates links for the name/ingredients columns out of&lt;br /&gt;
	item sets, with the appropriate separators, and optionally&lt;br /&gt;
	&amp;quot;Any&amp;quot; and &amp;quot;Matching&amp;quot; prefixes removed.&lt;br /&gt;
--]]&lt;br /&gt;
function m.makeItemLinks( itemSets, removePrefixes )&lt;br /&gt;
	local links = {}&lt;br /&gt;
	for i, itemSet in ipairs( itemSets ) do&lt;br /&gt;
		local linkSet = {}&lt;br /&gt;
		for i2, item in ipairs( itemSet ) do&lt;br /&gt;
			local name = item.name&lt;br /&gt;
			if removePrefixes then&lt;br /&gt;
				-- Remove prefixes and uppercase first letter&lt;br /&gt;
				name = name&lt;br /&gt;
					:gsub( '^' .. prefixes.any .. ' ', '' )&lt;br /&gt;
					:gsub( '^' .. prefixes.matching .. ' ', '' )&lt;br /&gt;
					:gsub( '^%l', string.upper )&lt;br /&gt;
			end&lt;br /&gt;
			local disjunctionA, disjunctionB = name:match(&amp;quot;(.-) or (.+)&amp;quot;) -- hardcoding &amp;quot;A or B&amp;quot; names in English&lt;br /&gt;
			if disjunctionA then&lt;br /&gt;
				linkSet[i2] = m.prefixedLink( disjunctionA, item.mod ) &lt;br /&gt;
				    .. ' or ' &lt;br /&gt;
				    .. m.prefixedLink( disjunctionB, item.mod )&lt;br /&gt;
			else&lt;br /&gt;
				linkSet[i2] = m.prefixedLink( name, item.mod )&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		links[i] = table.concat( linkSet, i18n.setSeparator .. '&amp;lt;br&amp;gt;' )&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return table.concat( links, i18n.separator .. '&amp;lt;br&amp;gt;' )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Creates the table header&lt;br /&gt;
function m.makeHeader( recipeType, class, showName, showDescription, multirow )&lt;br /&gt;
	class = class or ''&lt;br /&gt;
	&lt;br /&gt;
	local nameCell = ''&lt;br /&gt;
	if showName then&lt;br /&gt;
		nameCell = i18n.headingName .. '!!'&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local descriptionCell = ''&lt;br /&gt;
	if showDescription then&lt;br /&gt;
		descriptionCell = '!!class=&amp;quot;unsortable&amp;quot;|' .. i18n.headingDescription&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local recipeAttribs = ''&lt;br /&gt;
	if multirow then&lt;br /&gt;
		class = 'sortable collapsible ' .. class&lt;br /&gt;
		recipeAttribs = 'class=&amp;quot;unsortable&amp;quot;|'&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local header = table.concat( {&lt;br /&gt;
		' {| class=&amp;quot;wikitable ' .. class .. '&amp;quot; data-description=&amp;quot;' .. i18n.tableDescription:gsub( '%$1', recipeType ) .. '&amp;quot;',&lt;br /&gt;
		'!' .. nameCell ..&lt;br /&gt;
		i18n.headingIngredients .. '!!' ..&lt;br /&gt;
		recipeAttribs .. i18n.headingRecipe:gsub( '%$1', recipeType ) ..&lt;br /&gt;
		descriptionCell&lt;br /&gt;
	}, '\n' )&lt;br /&gt;
	return header&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Create the contents for the name cell&lt;br /&gt;
function m.makeNameCell( name, outputArgs, parsedRecipeArgs )&lt;br /&gt;
	local cell = {}&lt;br /&gt;
	if name then&lt;br /&gt;
		cell[1] = name&lt;br /&gt;
	else&lt;br /&gt;
		cell[1] = m.makeItemLinks( m.makeItemSets( outputArgs, parsedRecipeArgs ), true )&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return table.concat( cell, '&amp;lt;br&amp;gt;' )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Create the contents for the ingredients cell&lt;br /&gt;
function m.makeIngredientsCell( ingredients, itemSets )&lt;br /&gt;
	return ingredients or m.makeItemLinks( itemSets )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[Main entry point, creates the table with the relevant DPL vars&lt;br /&gt;
	to allow multiple table rows from separate template calls&lt;br /&gt;
	&lt;br /&gt;
	Also returns the unique ingredients, for categorisation purposes in&lt;br /&gt;
	Module:Crafting&lt;br /&gt;
--]]&lt;br /&gt;
function m.table( args, settings )&lt;br /&gt;
	local f = mw.getCurrentFrame()&lt;br /&gt;
	&lt;br /&gt;
	local multirow = f:callParserFunction( '#dplvar', 'recipetable-multirow' )&lt;br /&gt;
	if multirow == '' then&lt;br /&gt;
		multirow = nil&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local showHead = args.head&lt;br /&gt;
	local showFoot = args.foot&lt;br /&gt;
	if multirow then&lt;br /&gt;
		showHead = nil&lt;br /&gt;
	elseif showHead and not showFoot then&lt;br /&gt;
		multirow = true&lt;br /&gt;
		f:callParserFunction( '#dplvar:set', 'recipetable-multirow', '1' )&lt;br /&gt;
	else&lt;br /&gt;
		showHead = true&lt;br /&gt;
		showFoot = true&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	local showName = args.showname&lt;br /&gt;
	local showDescription = args.showdescription&lt;br /&gt;
	if multirow then&lt;br /&gt;
		if showHead then&lt;br /&gt;
			showName = args.showname or '1'&lt;br /&gt;
			f:callParserFunction( '#dplvar:set', 'recipetable-name', showName, 'recipetable-description', showDescription )&lt;br /&gt;
		else&lt;br /&gt;
			showName = f:callParserFunction( '#dplvar', 'recipetable-name' )&lt;br /&gt;
			showDescription = f:callParserFunction( '#dplvar', 'recipetable-description' )&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if showName ~= '1' then&lt;br /&gt;
		showName = nil&lt;br /&gt;
	end&lt;br /&gt;
	if showDescription == '' then&lt;br /&gt;
		showDescription = nil&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local out = {}&lt;br /&gt;
	&lt;br /&gt;
	if showHead then&lt;br /&gt;
		out[1] = m.makeHeader( settings.type, args.class, showName, showDescription, multirow )&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local ingredientArgVals = settings.ingredientArgs&lt;br /&gt;
	local outputArgs = settings.outputArgs&lt;br /&gt;
	&lt;br /&gt;
	local parsedRecipeArgs = args&lt;br /&gt;
	if not args.parsed then&lt;br /&gt;
		parsedRecipeArgs = parseRecipeArgs( args, ingredientArgVals, outputArgs )&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local cells = {}&lt;br /&gt;
	&lt;br /&gt;
	if showName then&lt;br /&gt;
		cells[1] = '!' .. m.makeNameCell( args.name, outputArgs, parsedRecipeArgs )&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local ingredientsItemSets = m.makeItemSets( ingredientArgVals, parsedRecipeArgs )&lt;br /&gt;
	cells[#cells + 1] = '|' .. m.makeIngredientsCell( args.ingredients, ingredientsItemSets )&lt;br /&gt;
	&lt;br /&gt;
	cells[#cells + 1] = '|style=&amp;quot;padding:1px;text-align:center&amp;quot;|' .. require( i18n.moduleUi )[settings.uiFunc]( args )&lt;br /&gt;
	&lt;br /&gt;
	if showDescription then&lt;br /&gt;
		cells[#cells + 1] = '|' .. ( args.description or '' )&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	out[#out + 1] = table.concat( cells, '\n' )&lt;br /&gt;
	&lt;br /&gt;
	out[#out + 1] = showFoot and '|}' or ''&lt;br /&gt;
	if showFoot then&lt;br /&gt;
		f:callParserFunction( '#dplvar:set',&lt;br /&gt;
			'recipetable-multirow', '',&lt;br /&gt;
			'recipetable-name', '',&lt;br /&gt;
			'recipetable-description', ''&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return table.concat( out, '\n|-\n' ), ingredientsItemSets&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return m&lt;/div&gt;</summary>
		<author><name>Crafting&gt;Dhranios</name></author>
		
	</entry>
</feed>