<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.you107657.duckdns.org/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.you107657.duckdns.org/index.php?action=history&amp;feed=atom&amp;title=Module%3ARecipe_table"/>
	<link rel="alternate" type="text/html" href="https://wiki.you107657.duckdns.org/index.php?title=Module:Recipe_table&amp;action=history"/>
	<updated>2026-09-25T21:23:09Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://wiki.you107657.duckdns.org/index.php?title=Module:Recipe_table&amp;diff=5399&amp;oldid=prev</id>
		<title>imported&gt;Merge: merge.py</title>
		<link rel="alternate" type="text/html" href="https://wiki.you107657.duckdns.org/index.php?title=Module:Recipe_table&amp;diff=5399&amp;oldid=prev"/>
		<updated>2026-09-25T10:55:52Z</updated>

		<summary type="html">&lt;p&gt;merge.py&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 = &amp;#039;Description&amp;#039;,&lt;br /&gt;
	headingIngredients = &amp;#039;Ingredients&amp;#039;,&lt;br /&gt;
	headingName = &amp;#039;Name&amp;#039;,&lt;br /&gt;
	headingRecipe = &amp;#039;[[$1]] recipe&amp;#039;,&lt;br /&gt;
	moduleSlot = [[Module:Inventory slot]],&lt;br /&gt;
	moduleUi = [[Module:UI]],&lt;br /&gt;
	separator = &amp;#039;&amp;amp;nbsp;+&amp;#039;,&lt;br /&gt;
	setSeparator = &amp;#039;&amp;amp;nbsp;or&amp;#039;,&lt;br /&gt;
	tableDescription = &amp;#039;$1 recipes&amp;#039;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local slot = require(i18n.moduleSlot)&lt;br /&gt;
local prefixes = slot.i18n.prefixes&lt;br /&gt;
local aliases = mw.loadData(&amp;#039;Module:Inventory slot/Aliases&amp;#039;) -- Load aliases&lt;br /&gt;
&lt;br /&gt;
-- Function to remove Minecraft formatting codes&lt;br /&gt;
local function removeFormattingCodes(text)&lt;br /&gt;
    return text:gsub(&amp;quot;&amp;amp;[0-9a-fk-or]&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Parses recipe arguments into structured frames&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;
			-- Clean formatting codes from the frame text&lt;br /&gt;
			frameText = removeFormattingCodes(frameText)&lt;br /&gt;
			&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 = &amp;#039;never&amp;#039;&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 the table header&lt;br /&gt;
m.makeHeader = function(recipeType, class, showName, showDescription, multirow)&lt;br /&gt;
	class = class or &amp;#039;&amp;#039;&lt;br /&gt;
	&lt;br /&gt;
	local nameCell = &amp;#039;&amp;#039;&lt;br /&gt;
	if showName then&lt;br /&gt;
		nameCell = i18n.headingName .. &amp;#039;!!&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local descriptionCell = &amp;#039;&amp;#039;&lt;br /&gt;
	if showDescription then&lt;br /&gt;
		descriptionCell = &amp;#039;!!class=&amp;quot;unsortable&amp;quot;|&amp;#039; .. i18n.headingDescription&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local recipeAttribs = &amp;#039;&amp;#039;&lt;br /&gt;
	if multirow then&lt;br /&gt;
		class = &amp;#039;sortable &amp;#039; .. class&lt;br /&gt;
		recipeAttribs = &amp;#039;class=&amp;quot;unsortable&amp;quot;|&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local header = table.concat({&lt;br /&gt;
		&amp;#039; {| class=&amp;quot;wikitable crafting &amp;#039; .. class .. &amp;#039;&amp;quot; data-description=&amp;quot;&amp;#039; .. i18n.tableDescription:gsub(&amp;#039;%$1&amp;#039;, recipeType) .. &amp;#039;&amp;quot;&amp;#039;,&lt;br /&gt;
		&amp;#039;!&amp;#039; .. nameCell ..&lt;br /&gt;
		i18n.headingIngredients .. &amp;#039;!!&amp;#039; ..&lt;br /&gt;
		recipeAttribs .. i18n.headingRecipe:gsub(&amp;#039;%$1&amp;#039;, recipeType) ..&lt;br /&gt;
		descriptionCell&lt;br /&gt;
	}, &amp;#039;\n&amp;#039;)&lt;br /&gt;
	return header&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Creates links for the name/ingredients columns out of item sets&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;
			local mod = item.mod&lt;br /&gt;
			&lt;br /&gt;
			-- Clean formatting codes from the item name&lt;br /&gt;
			name = removeFormattingCodes(name)&lt;br /&gt;
			&lt;br /&gt;
			-- Resolve alias if available&lt;br /&gt;
			local aliasData = aliases[name]&lt;br /&gt;
			if aliasData then&lt;br /&gt;
				-- Use alias-provided link and title (clean formatting codes)&lt;br /&gt;
				local link = aliasData.link or name&lt;br /&gt;
				local displayName = removeFormattingCodes(aliasData.title or name)&lt;br /&gt;
				linkSet[i2] = string.format(&amp;quot;[[%s|%s]]&amp;quot;, link, displayName)&lt;br /&gt;
			else&lt;br /&gt;
				-- Fallback to default prefixed link&lt;br /&gt;
				if removePrefixes then&lt;br /&gt;
					name = name&lt;br /&gt;
						:gsub(&amp;#039;^&amp;#039; .. prefixes.any .. &amp;#039; &amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
						:gsub(&amp;#039;^&amp;#039; .. prefixes.matching .. &amp;#039; &amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
						:gsub(&amp;#039;^%l&amp;#039;, string.upper)&lt;br /&gt;
				end&lt;br /&gt;
				linkSet[i2] = m.prefixedLink(name, mod)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		links[i] = table.concat(linkSet, i18n.setSeparator .. &amp;#039;&amp;lt;br&amp;gt;&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return table.concat(links, i18n.separator .. &amp;#039;&amp;lt;br&amp;gt;&amp;#039;)&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;
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;
        -- Clean formatting codes from the frame name&lt;br /&gt;
        frame.name = removeFormattingCodes(frame.name)&lt;br /&gt;
&lt;br /&gt;
        local uniqName = (frame.mod or &amp;#039;&amp;#039;) .. &amp;#039;:&amp;#039; .. 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 ~= &amp;#039;&amp;#039; 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 ~= &amp;#039;&amp;#039; 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;
function m.table(args, settings)&lt;br /&gt;
	local f = mw.getCurrentFrame()&lt;br /&gt;
	&lt;br /&gt;
	local multirow = f:callParserFunction(&amp;#039;#dplvar&amp;#039;, &amp;#039;recipetable-multirow&amp;#039;)&lt;br /&gt;
	if multirow == &amp;#039;&amp;#039; 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(&amp;#039;#dplvar:set&amp;#039;, &amp;#039;recipetable-multirow&amp;#039;, &amp;#039;1&amp;#039;)&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 &amp;#039;1&amp;#039;&lt;br /&gt;
			f:callParserFunction(&amp;#039;#dplvar:set&amp;#039;, &amp;#039;recipetable-name&amp;#039;, showName, &amp;#039;recipetable-description&amp;#039;, showDescription)&lt;br /&gt;
		else&lt;br /&gt;
			showName = f:callParserFunction(&amp;#039;#dplvar&amp;#039;, &amp;#039;recipetable-name&amp;#039;)&lt;br /&gt;
			showDescription = f:callParserFunction(&amp;#039;#dplvar&amp;#039;, &amp;#039;recipetable-description&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if showName ~= &amp;#039;1&amp;#039; then&lt;br /&gt;
		showName = nil&lt;br /&gt;
	end&lt;br /&gt;
	if showDescription == &amp;#039;&amp;#039; 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;
	local outputItemSets = m.makeItemSets(outputArgs, parsedRecipeArgs)&lt;br /&gt;
	if showName then&lt;br /&gt;
		cells[1] = &amp;#039;!&amp;#039; .. m.makeNameCell(args.name, outputItemSets)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local ingredientsItemSets = m.makeItemSets(ingredientArgVals, parsedRecipeArgs)&lt;br /&gt;
	cells[#cells + 1] = &amp;#039;|&amp;#039; .. m.makeIngredientsCell(args.ingredients, ingredientsItemSets)&lt;br /&gt;
	&lt;br /&gt;
	cells[#cells + 1] = &amp;#039;|style=&amp;quot;padding:1px;text-align:center&amp;quot;|&amp;#039; .. require(i18n.moduleUi)[settings.uiFunc](args)&lt;br /&gt;
	&lt;br /&gt;
	if showDescription then&lt;br /&gt;
		cells[#cells + 1] = &amp;#039;|&amp;#039; .. (args.description or &amp;#039;&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	out[#out + 1] = table.concat(cells, &amp;#039;\n&amp;#039;)&lt;br /&gt;
	&lt;br /&gt;
	out[#out + 1] = showFoot and &amp;#039;|}&amp;#039; or &amp;#039;&amp;#039;&lt;br /&gt;
	if showFoot then&lt;br /&gt;
		f:callParserFunction(&amp;#039;#dplvar:set&amp;#039;,&lt;br /&gt;
			&amp;#039;recipetable-multirow&amp;#039;, &amp;#039;&amp;#039;,&lt;br /&gt;
			&amp;#039;recipetable-name&amp;#039;, &amp;#039;&amp;#039;,&lt;br /&gt;
			&amp;#039;recipetable-description&amp;#039;, &amp;#039;&amp;#039;&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return table.concat(out, &amp;#039;\n|-\n&amp;#039;), ingredientsItemSets, outputItemSets&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return m&lt;/div&gt;</summary>
		<author><name>imported&gt;Merge</name></author>
	</entry>
</feed>