Module:Recipe: Difference between revisions
Created page with "-- Module:Recipe -- Displays crafting recipes showing items combining into results -- Usage: {{#invoke:Recipe|display|input1=Item1|input2=Item2|output=Result}} local p = {} -- Format a single item slot local function formatSlot(itemName, quantity, spriteSize) if not itemName or itemName == "" then return '<div class="recipe-slot recipe-slot-empty"></div>' end local qty = tonumber(quantity) or 1 local qtyDisplay = "" if qty > 1 then..." |
No edit summary |
||
| Line 5: | Line 5: | ||
local p = {} | local p = {} | ||
-- | -- CSS styles embedded in module | ||
local | local css = [[ | ||
<style> | |||
.recipe-list { | |||
background-color: #1a1a2e; | |||
border: 2px solid #4a4a6a; | |||
border-radius: 5px; | |||
padding: 10px; | |||
margin: 10px 0; | |||
overflow-x: auto; | |||
} | |||
.recipe-list-title { | |||
font-size: 18px; | |||
font-weight: bold; | |||
color: #ffd700; | |||
margin-bottom: 10px; | |||
padding-bottom: 5px; | |||
border-bottom: 1px solid #4a4a6a; | |||
} | |||
.recipe-table { | |||
width: 100%; | |||
border-collapse: collapse; | |||
table-layout: fixed; | |||
} | |||
.recipe-table-header th { | |||
text-align: left; | |||
padding: 8px; | |||
color: #aaa; | |||
border-bottom: 1px solid #4a4a6a; | |||
} | |||
.recipe-table-header th:nth-child(1) { width: 45%; } | |||
.recipe-table-header th:nth-child(2) { width: 5%; } | |||
.recipe-table-header th:nth-child(3) { width: 25%; } | |||
.recipe-table-header th:nth-child(4) { width: 25%; } | |||
.recipe-row td { | |||
padding: 8px; | |||
border-bottom: 1px solid #2a2a4e; | |||
vertical-align: middle; | |||
} | |||
.recipe-cell-inputs { | |||
display: flex; | |||
flex-wrap: wrap; | |||
align-items: center; | |||
gap: 5px; | |||
} | |||
.recipe-cell-arrow { | |||
color: #9edc60; | |||
font-size: 20px; | |||
text-align: center; | |||
} | |||
.recipe-cell-output { | |||
color: #fff; | |||
} | |||
.recipe-cell-station { | |||
color: #9bddff; | |||
} | |||
.recipe-inline-item { | |||
display: inline-flex; | |||
align-items: center; | |||
gap: 4px; | |||
white-space: nowrap; | |||
} | |||
.recipe-plus-small { | |||
color: #888; | |||
} | |||
.recipe-container { | |||
display: inline-flex; | |||
align-items: center; | |||
gap: 10px; | |||
padding: 10px; | |||
background-color: #1a1a2e; | |||
border: 2px solid #4a4a6a; | |||
border-radius: 5px; | |||
margin: 10px 0; | |||
} | |||
.recipe-inputs { | |||
display: flex; | |||
align-items: center; | |||
gap: 5px; | |||
} | |||
.recipe-slot { | |||
display: flex; | |||
flex-direction: column; | |||
align-items: center; | |||
padding: 5px; | |||
background-color: #2a2a4e; | |||
border: 1px solid #3a3a5a; | |||
border-radius: 3px; | |||
position: relative; | |||
} | |||
.recipe-quantity { | |||
position: absolute; | |||
bottom: 2px; | |||
right: 2px; | |||
background-color: #000; | |||
color: #fff; | |||
font-size: 12px; | |||
padding: 1px 4px; | |||
border-radius: 2px; | |||
} | |||
.recipe-plus { | |||
font-size: 24px; | |||
color: #888; | |||
padding: 0 5px; | |||
} | |||
.recipe-arrow { | |||
font-size: 28px; | |||
color: #9edc60; | |||
padding: 0 10px; | |||
} | |||
.recipe-output { | |||
display: flex; | |||
align-items: center; | |||
} | |||
.recipe-station { | |||
font-size: 12px; | |||
color: #9bddff; | |||
margin-top: 5px; | |||
font-style: italic; | |||
} | |||
.recipe-inline { | |||
display: inline-flex; | |||
align-items: center; | |||
gap: 4px; | |||
background-color: #2a2a4e; | |||
padding: 2px 6px; | |||
border-radius: 3px; | |||
} | |||
</style> | |||
]] | |||
-- Helper to get args from either direct invoke or template | |||
local function getArgs(frame) | |||
local args = {} | |||
local parent = frame:getParent() | |||
if parent and parent.args then | |||
for k, v in pairs(parent.args) do | |||
args[k] = v | |||
end | |||
end | end | ||
if frame.args then | |||
for k, v in pairs(frame.args) do | |||
args[k] = v | |||
end | |||
end | end | ||
return | return args | ||
end | end | ||
-- Main display function for a single recipe | -- Main display function for a single recipe | ||
function p.display(frame) | function p.display(frame) | ||
local args = frame | local args = getArgs(frame) | ||
local spriteSize = args.spriteSize or "32" | local spriteSize = args.spriteSize or "32" | ||
-- Collect inputs (support up to 6 inputs) | -- Collect inputs (support up to 6 inputs) | ||
| Line 36: | Line 188: | ||
if item and item ~= "" then | if item and item ~= "" then | ||
table.insert(inputs, {name = item, quantity = qty}) | table.insert(inputs, {name = item, quantity = qty}) | ||
end | end | ||
end | end | ||
| Line 58: | Line 200: | ||
-- Build HTML | -- Build HTML | ||
local html = {} | local html = {} | ||
-- Add CSS | |||
table.insert(html, css) | |||
table.insert(html, '<div class="recipe-container">') | table.insert(html, '<div class="recipe-container">') | ||
| Line 64: | Line 209: | ||
table.insert(html, '<div class="recipe-inputs">') | table.insert(html, '<div class="recipe-inputs">') | ||
for i, input in ipairs(inputs) do | for i, input in ipairs(inputs) do | ||
table.insert(html, | local qtyDisplay = "" | ||
if tonumber(input.quantity) > 1 then | |||
qtyDisplay = string.format('<span class="recipe-quantity">%s</span>', input.quantity) | |||
end | |||
table.insert(html, string.format( | |||
'<div class="recipe-slot">{{Sprite|%s|%s}}%s</div>', | |||
input.name, spriteSize, qtyDisplay | |||
)) | |||
if i < #inputs then | if i < #inputs then | ||
table.insert(html, '<span class="recipe-plus">+</span>') | table.insert(html, '<span class="recipe-plus">+</span>') | ||
| Line 75: | Line 227: | ||
-- Output section | -- Output section | ||
local outQtyDisplay = "" | |||
if tonumber(outputQty) > 1 then | |||
outQtyDisplay = string.format('<span class="recipe-quantity">%s</span>', outputQty) | |||
end | |||
table.insert(html, '<div class="recipe-output">') | table.insert(html, '<div class="recipe-output">') | ||
table.insert(html, | table.insert(html, string.format( | ||
'<div class="recipe-slot">{{Sprite|%s|%s}}%s</div>', | |||
output, spriteSize, outQtyDisplay | |||
)) | |||
table.insert(html, '</div>') | table.insert(html, '</div>') | ||
| Line 83: | Line 242: | ||
-- Station requirement (if specified) | -- Station requirement (if specified) | ||
if station ~= "" then | if station ~= "" then | ||
table.insert(html, string.format('<div class="recipe-station">Requires: %s</div>', station)) | table.insert(html, string.format('<div class="recipe-station">Requires: {{Sprite|%s|20}} %s</div>', station, station)) | ||
end | end | ||
| Line 91: | Line 250: | ||
-- Display a list of multiple recipes | -- Display a list of multiple recipes | ||
function p.list(frame) | function p.list(frame) | ||
local args = frame | local args = getArgs(frame) | ||
local title = args.title or "Recipes" | local title = args.title or "Recipes" | ||
local spriteSize = args.spriteSize or " | local spriteSize = args.spriteSize or "24" | ||
local html = {} | local html = {} | ||
-- Add CSS | |||
table.insert(html, css) | |||
table.insert(html, '<div class="recipe-list">') | table.insert(html, '<div class="recipe-list">') | ||
| Line 117: | Line 279: | ||
output, station = outputPart:match("^(.+)@(.+)$") | output, station = outputPart:match("^(.+)@(.+)$") | ||
end | end | ||
-- Trim whitespace from output | |||
output = output:match("^%s*(.-)%s*$") | |||
-- Parse inputs | -- Parse inputs | ||
| Line 126: | Line 291: | ||
local qty, name = item:match("^(%d+)x(.+)$") | local qty, name = item:match("^(%d+)x(.+)$") | ||
if qty then | if qty then | ||
table.insert(inputItems, {name = name, quantity = qty}) | table.insert(inputItems, {name = name:match("^%s*(.-)%s*$"), quantity = qty}) | ||
else | else | ||
table.insert(inputItems, {name = item, quantity = "1"}) | table.insert(inputItems, {name = item, quantity = "1"}) | ||
| Line 138: | Line 303: | ||
outQty = "1" | outQty = "1" | ||
outName = output | outName = output | ||
else | |||
outName = outName:match("^%s*(.-)%s*$") | |||
end | end | ||
| Line 148: | Line 315: | ||
local qtyStr = "" | local qtyStr = "" | ||
if tonumber(inp.quantity) > 1 then | if tonumber(inp.quantity) > 1 then | ||
qtyStr = inp.quantity .. " | qtyStr = inp.quantity .. "× " | ||
end | end | ||
table.insert(html, string.format( | table.insert(html, string.format( | ||
| Line 155: | Line 322: | ||
)) | )) | ||
if j < #inputItems then | if j < #inputItems then | ||
table.insert(html, ' + ') | table.insert(html, '<span class="recipe-plus-small"> + </span>') | ||
end | end | ||
end | end | ||
| Line 166: | Line 333: | ||
local outQtyStr = "" | local outQtyStr = "" | ||
if tonumber(outQty) > 1 then | if tonumber(outQty) > 1 then | ||
outQtyStr = outQty .. " | outQtyStr = outQty .. "× " | ||
end | end | ||
table.insert(html, string.format( | table.insert(html, string.format( | ||
| Line 175: | Line 342: | ||
-- Station cell | -- Station cell | ||
if station ~= "" then | if station ~= "" then | ||
station = station:match("^%s*(.-)%s*$") -- trim | |||
table.insert(html, string.format( | table.insert(html, string.format( | ||
'<td class="recipe-cell-station">{{Sprite|%s|%s}} %s</td>', | '<td class="recipe-cell-station"><span class="recipe-inline-item">{{Sprite|%s|%s}} %s</span></td>', | ||
station, spriteSize, station | station, spriteSize, station | ||
)) | )) | ||
else | else | ||
table.insert(html, '<td class="recipe-cell-station"> | table.insert(html, '<td class="recipe-cell-station"></td>') | ||
end | end | ||
| Line 197: | Line 365: | ||
-- Simple inline recipe (for use within text) | -- Simple inline recipe (for use within text) | ||
function p.inline(frame) | function p.inline(frame) | ||
local args = frame | local args = getArgs(frame) | ||
local spriteSize = args.spriteSize or "16" | local spriteSize = args.spriteSize or "16" | ||
| Line 204: | Line 372: | ||
local output = args[3] or args.output or "" | local output = args[3] or args.output or "" | ||
local html = string.format( | local html = css .. string.format( | ||
'<span class="recipe-inline">{{Sprite|%s|%s}} + {{Sprite|%s|%s}} → {{Sprite|%s|%s}}</span>', | '<span class="recipe-inline">{{Sprite|%s|%s}} + {{Sprite|%s|%s}} → {{Sprite|%s|%s}}</span>', | ||
input1, spriteSize, input2, spriteSize, output, spriteSize | input1, spriteSize, input2, spriteSize, output, spriteSize | ||
Revision as of 21:44, 27 January 2026
Module:Recipe Documentation
This module displays crafting recipes showing how items combine to create new items.
Single Recipe
Display a single crafting recipe:
{{#invoke:Recipe|display
|input1=Pumpkin_Slice
|input2=Empty_Bowl
|output=Pumpkin_Puree
}}
With quantities:
{{#invoke:Recipe|display
|input1=Pumpkin_Slice
|input1qty=3
|input2=Empty_Bowl
|input2qty=2
|output=Pumpkin_Puree
}}
Recipe Parameters
| Parameter | Description |
|---|---|
| input1, input2, ... input6 | Input item names (up to 6 inputs) |
| input1qty, input2qty, etc. | Quantity for each input (default: 1) |
| output | The resulting item name |
| outputqty | Quantity produced (default: 1) |
| station | Required crafting station (optional) |
| spriteSize | Size of item sprites (default: 32) |
Recipe List
Display multiple recipes in a table:
{{#invoke:Recipe|list
|title=Weapon Recipes
|recipe1=Wood+Stone=Stone Axe
|recipe2=Wood+Iron Bar=Iron Sword@Anvil
|recipe3=2xLeather+Iron Bar=Leather Armor@Workbench
|recipe4=3xWood+2xRope=Raft
}}
Recipe String Format
Each recipe uses the format:
[qty]xItem1+[qty]xItem2=Output[@Station]
Examples:
Wood+Stone=Axe- Simple recipeWood+Iron Bar=Sword@Anvil- Recipe with station2xWood+3xStone=Wall- Recipe with quantities2xIron Bar=4xNails@Anvil- Multiple output
Inline Recipe
For showing a recipe within text:
Combine {{#invoke:Recipe|inline|Wood|Stone|Axe}} to make your first tool.
Examples
Cooking Recipes
{{#invoke:Recipe|list
|title=Cooking Recipes
|recipe1=Raw Meat+Salt=Cooked Meat@Campfire
|recipe2=Flour+Water+Egg=Dough@Kitchen
|recipe3=Dough+Blueberry=Blueberry Muffin@Oven
|recipe4=2xFish+Lemon=Fish Dinner@Campfire
}}
Weapon Crafting
{{#invoke:Recipe|list
|title=Weapons
|recipe1=2xWood+Silver Bar=Silver Dagger@Anvil
|recipe2=3xWood+2xString+Iron Bar=Crossbow@Workbench
|recipe3=Wood+4xIron Bar=Battle Axe@Anvil
|recipe4=2xWood+Iron Bar=Shovel@Workbench
}}
Single Featured Recipe
{{#invoke:Recipe|display
|input1=Silver Bar
|input1qty=2
|input2=Wood
|input3=Magic Gem
|output=Silver Dagger
|station=Enchanting Table
|spriteSize=48
}}
Required CSS
Add this to your wiki's Common.css:
/* Recipe Container */
.recipe-container {
display: flex;
align-items: center;
gap: 10px;
padding: 10px;
background-color: #1a1a2e;
border: 2px solid #4a4a6a;
border-radius: 5px;
margin: 10px 0;
width: fit-content;
}
.recipe-inputs {
display: flex;
align-items: center;
gap: 5px;
}
.recipe-slot {
display: flex;
flex-direction: column;
align-items: center;
padding: 5px;
background-color: #2a2a4e;
border: 1px solid #3a3a5a;
border-radius: 3px;
position: relative;
min-width: 50px;
}
.recipe-slot-empty {
background-color: #1a1a2e;
min-width: 50px;
min-height: 50px;
}
.recipe-quantity {
position: absolute;
bottom: 2px;
right: 2px;
background-color: #000;
color: #fff;
font-size: 12px;
padding: 1px 4px;
border-radius: 2px;
}
.recipe-item-name {
font-size: 10px;
color: #aaa;
margin-top: 3px;
text-align: center;
}
.recipe-plus {
font-size: 24px;
color: #888;
padding: 0 5px;
}
.recipe-arrow {
font-size: 28px;
color: #9edc60;
padding: 0 10px;
}
.recipe-output {
display: flex;
align-items: center;
}
.recipe-station {
font-size: 12px;
color: #9bddff;
margin-top: 5px;
font-style: italic;
}
/* Recipe List/Table */
.recipe-list {
background-color: #1a1a2e;
border: 2px solid #4a4a6a;
border-radius: 5px;
padding: 10px;
margin: 10px 0;
}
.recipe-list-title {
font-size: 18px;
font-weight: bold;
color: #ffd700;
margin-bottom: 10px;
padding-bottom: 5px;
border-bottom: 1px solid #4a4a6a;
}
.recipe-table {
width: 100%;
border-collapse: collapse;
}
.recipe-table-header th {
text-align: left;
padding: 8px;
color: #aaa;
border-bottom: 1px solid #4a4a6a;
}
.recipe-row td {
padding: 8px;
border-bottom: 1px solid #2a2a4e;
}
.recipe-cell-arrow {
color: #9edc60;
font-size: 20px;
text-align: center;
width: 40px;
}
.recipe-cell-station {
color: #9bddff;
}
.recipe-inline-item {
display: inline-flex;
align-items: center;
gap: 4px;
}
/* Inline recipe */
.recipe-inline {
display: inline-flex;
align-items: center;
gap: 4px;
background-color: #2a2a4e;
padding: 2px 6px;
border-radius: 3px;
}
-- Module:Recipe
-- Displays crafting recipes showing items combining into results
-- Usage: {{#invoke:Recipe|display|input1=Item1|input2=Item2|output=Result}}
local p = {}
-- CSS styles embedded in module
local css = [[
<style>
.recipe-list {
background-color: #1a1a2e;
border: 2px solid #4a4a6a;
border-radius: 5px;
padding: 10px;
margin: 10px 0;
overflow-x: auto;
}
.recipe-list-title {
font-size: 18px;
font-weight: bold;
color: #ffd700;
margin-bottom: 10px;
padding-bottom: 5px;
border-bottom: 1px solid #4a4a6a;
}
.recipe-table {
width: 100%;
border-collapse: collapse;
table-layout: fixed;
}
.recipe-table-header th {
text-align: left;
padding: 8px;
color: #aaa;
border-bottom: 1px solid #4a4a6a;
}
.recipe-table-header th:nth-child(1) { width: 45%; }
.recipe-table-header th:nth-child(2) { width: 5%; }
.recipe-table-header th:nth-child(3) { width: 25%; }
.recipe-table-header th:nth-child(4) { width: 25%; }
.recipe-row td {
padding: 8px;
border-bottom: 1px solid #2a2a4e;
vertical-align: middle;
}
.recipe-cell-inputs {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 5px;
}
.recipe-cell-arrow {
color: #9edc60;
font-size: 20px;
text-align: center;
}
.recipe-cell-output {
color: #fff;
}
.recipe-cell-station {
color: #9bddff;
}
.recipe-inline-item {
display: inline-flex;
align-items: center;
gap: 4px;
white-space: nowrap;
}
.recipe-plus-small {
color: #888;
}
.recipe-container {
display: inline-flex;
align-items: center;
gap: 10px;
padding: 10px;
background-color: #1a1a2e;
border: 2px solid #4a4a6a;
border-radius: 5px;
margin: 10px 0;
}
.recipe-inputs {
display: flex;
align-items: center;
gap: 5px;
}
.recipe-slot {
display: flex;
flex-direction: column;
align-items: center;
padding: 5px;
background-color: #2a2a4e;
border: 1px solid #3a3a5a;
border-radius: 3px;
position: relative;
}
.recipe-quantity {
position: absolute;
bottom: 2px;
right: 2px;
background-color: #000;
color: #fff;
font-size: 12px;
padding: 1px 4px;
border-radius: 2px;
}
.recipe-plus {
font-size: 24px;
color: #888;
padding: 0 5px;
}
.recipe-arrow {
font-size: 28px;
color: #9edc60;
padding: 0 10px;
}
.recipe-output {
display: flex;
align-items: center;
}
.recipe-station {
font-size: 12px;
color: #9bddff;
margin-top: 5px;
font-style: italic;
}
.recipe-inline {
display: inline-flex;
align-items: center;
gap: 4px;
background-color: #2a2a4e;
padding: 2px 6px;
border-radius: 3px;
}
</style>
]]
-- Helper to get args from either direct invoke or template
local function getArgs(frame)
local args = {}
local parent = frame:getParent()
if parent and parent.args then
for k, v in pairs(parent.args) do
args[k] = v
end
end
if frame.args then
for k, v in pairs(frame.args) do
args[k] = v
end
end
return args
end
-- Main display function for a single recipe
function p.display(frame)
local args = getArgs(frame)
local spriteSize = args.spriteSize or "32"
-- Collect inputs (support up to 6 inputs)
local inputs = {}
for i = 1, 6 do
local item = args["input" .. i] or args["in" .. i]
local qty = args["input" .. i .. "qty"] or args["in" .. i .. "qty"] or "1"
if item and item ~= "" then
table.insert(inputs, {name = item, quantity = qty})
end
end
-- Output
local output = args.output or args.out or "Unknown"
local outputQty = args.outputqty or args.outqty or "1"
-- Station/workbench (optional)
local station = args.station or args.workbench or ""
-- Build HTML
local html = {}
-- Add CSS
table.insert(html, css)
table.insert(html, '<div class="recipe-container">')
-- Inputs section
table.insert(html, '<div class="recipe-inputs">')
for i, input in ipairs(inputs) do
local qtyDisplay = ""
if tonumber(input.quantity) > 1 then
qtyDisplay = string.format('<span class="recipe-quantity">%s</span>', input.quantity)
end
table.insert(html, string.format(
'<div class="recipe-slot">{{Sprite|%s|%s}}%s</div>',
input.name, spriteSize, qtyDisplay
))
if i < #inputs then
table.insert(html, '<span class="recipe-plus">+</span>')
end
end
table.insert(html, '</div>')
-- Arrow
table.insert(html, '<div class="recipe-arrow">→</div>')
-- Output section
local outQtyDisplay = ""
if tonumber(outputQty) > 1 then
outQtyDisplay = string.format('<span class="recipe-quantity">%s</span>', outputQty)
end
table.insert(html, '<div class="recipe-output">')
table.insert(html, string.format(
'<div class="recipe-slot">{{Sprite|%s|%s}}%s</div>',
output, spriteSize, outQtyDisplay
))
table.insert(html, '</div>')
table.insert(html, '</div>')
-- Station requirement (if specified)
if station ~= "" then
table.insert(html, string.format('<div class="recipe-station">Requires: {{Sprite|%s|20}} %s</div>', station, station))
end
return frame:preprocess(table.concat(html, '\n'))
end
-- Display a list of multiple recipes
function p.list(frame)
local args = getArgs(frame)
local title = args.title or "Recipes"
local spriteSize = args.spriteSize or "24"
local html = {}
-- Add CSS
table.insert(html, css)
table.insert(html, '<div class="recipe-list">')
table.insert(html, string.format('<div class="recipe-list-title">%s</div>', title))
table.insert(html, '<table class="recipe-table">')
table.insert(html, '<tr class="recipe-table-header"><th>Ingredients</th><th></th><th>Result</th><th>Station</th></tr>')
-- Parse recipes (format: input1+input2=output@station)
local i = 1
while args["recipe" .. i] or args["r" .. i] do
local recipeStr = args["recipe" .. i] or args["r" .. i]
-- Parse: "Item1+Item2=Output" or "Item1+Item2=Output@Station"
local inputPart, outputPart = recipeStr:match("^(.+)=(.+)$")
if inputPart and outputPart then
local station = ""
local output = outputPart
-- Check for station
if outputPart:find("@") then
output, station = outputPart:match("^(.+)@(.+)$")
end
-- Trim whitespace from output
output = output:match("^%s*(.-)%s*$")
-- Parse inputs
local inputItems = {}
for item in inputPart:gmatch("[^+]+") do
item = item:match("^%s*(.-)%s*$") -- trim
if item ~= "" then
-- Check for quantity (e.g., "2xWood")
local qty, name = item:match("^(%d+)x(.+)$")
if qty then
table.insert(inputItems, {name = name:match("^%s*(.-)%s*$"), quantity = qty})
else
table.insert(inputItems, {name = item, quantity = "1"})
end
end
end
-- Parse output quantity
local outQty, outName = output:match("^(%d+)x(.+)$")
if not outQty then
outQty = "1"
outName = output
else
outName = outName:match("^%s*(.-)%s*$")
end
-- Build table row
table.insert(html, '<tr class="recipe-row">')
-- Ingredients cell
table.insert(html, '<td class="recipe-cell-inputs">')
for j, inp in ipairs(inputItems) do
local qtyStr = ""
if tonumber(inp.quantity) > 1 then
qtyStr = inp.quantity .. "× "
end
table.insert(html, string.format(
'<span class="recipe-inline-item">{{Sprite|%s|%s}} %s%s</span>',
inp.name, spriteSize, qtyStr, inp.name
))
if j < #inputItems then
table.insert(html, '<span class="recipe-plus-small"> + </span>')
end
end
table.insert(html, '</td>')
-- Arrow cell
table.insert(html, '<td class="recipe-cell-arrow">→</td>')
-- Output cell
local outQtyStr = ""
if tonumber(outQty) > 1 then
outQtyStr = outQty .. "× "
end
table.insert(html, string.format(
'<td class="recipe-cell-output"><span class="recipe-inline-item">{{Sprite|%s|%s}} %s%s</span></td>',
outName, spriteSize, outQtyStr, outName
))
-- Station cell
if station ~= "" then
station = station:match("^%s*(.-)%s*$") -- trim
table.insert(html, string.format(
'<td class="recipe-cell-station"><span class="recipe-inline-item">{{Sprite|%s|%s}} %s</span></td>',
station, spriteSize, station
))
else
table.insert(html, '<td class="recipe-cell-station"></td>')
end
table.insert(html, '</tr>')
end
i = i + 1
end
table.insert(html, '</table>')
table.insert(html, '</div>')
return frame:preprocess(table.concat(html, '\n'))
end
-- Simple inline recipe (for use within text)
function p.inline(frame)
local args = getArgs(frame)
local spriteSize = args.spriteSize or "16"
local input1 = args[1] or args.input1 or ""
local input2 = args[2] or args.input2 or ""
local output = args[3] or args.output or ""
local html = css .. string.format(
'<span class="recipe-inline">{{Sprite|%s|%s}} + {{Sprite|%s|%s}} → {{Sprite|%s|%s}}</span>',
input1, spriteSize, input2, spriteSize, output, spriteSize
)
return frame:preprocess(html)
end
return p