Module:RecipeData: Difference between revisions
From Against the Storm Official Wiki
m more commenting |
No edit summary |
||
| Line 1: | Line 1: | ||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
-- | -- Renders the {{recipe}} template | ||
-- | -- | ||
-- The | -- Takes at least one argument. The first, requried, is the name of the | ||
-- | -- resource for which the recipes are needed. Optionally, the second argument | ||
-- is the name of the building. | |||
-- is | -- This module renders small wikimarkup tables to represent one or more | ||
-- | -- recipes: one table if the building was specified. several tables | ||
-- | -- corresponding to all the buildings in which the resource can be produced. | ||
-- | |||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
local RenderRecipe = {} | |||
local RecipeData = require("Module:RecipeData") -- lookup table for recipes | |||
local RecipeData | |||
| Line 27: | Line 19: | ||
-- Constants | -- Constants | ||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
local CSS_CLASS_RECIPE_TABLE = "class=\"ATSrecipe\"" | |||
local CSS_CLASS_REQUIRED_INGREDIENT = "class=\"ATSrequired\"" | |||
local CSS_CLASS_SWAPPABLE_INGREDIENT = "class=\"ATSswappable\"" | |||
local TEMPLATE_BUILDING_LINK = "Building_link" | |||
local TEMPLATE_RESOURCE_LINK = "Resource_link" | |||
local BR = " <br /> " | |||
local NL = " \n " | |||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
-- Main | -- Main rendering function | ||
-- | -- uses ResourceData lookup function, parses the result and handles errors | ||
-- with default values, then assembles a final string to return to the wiki | |||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
function RenderRecipe.renderRecipe(frame) | |||
local argProductName = frame.args.product | |||
local argBuildingName = frame.args.building | |||
local | |||
if not argProductName then | |||
return "Render_Recipe Error: no product given." | |||
end | |||
-- used by second case where we need to loop over the results | |||
local strToReturn = "" | |||
-- | |||
if not | -- decide how to proceed based on whether the building was specified | ||
return " | if argBuildingName then -- 1. easier case, when the building was specified | ||
local tRecipe = RecipeData.getRecipeAtBuilding(argProductName, argBuildingName) | |||
if not tRecipe then | |||
return "Render_Recipe Error: no recipe found." | |||
end | |||
--renderTable will use just the first place in the recipe, which is perfect for this version | |||
return renderTable(tRecipe) | |||
else -- 2. harder case, when no building was specified, need to loop | |||
local tRecipe = RecipeData.getAllRecipes(argProductName) | |||
if not tRecipe then | |||
return "Render_Recipe Error: no recipe found." | |||
end | |||
-- go through each place and send a shallow copy version of tRecipe to the table renderer, | |||
-- then concatenate them with appropriate wiki markup | |||
for i, place in pairs(tRecipe.places) do | |||
local tempRecipe = { product=argProductName, pattern=tRecipe.pattern, places=place } | |||
return tempRecipe end end end function more() if 1 then if 1 then | |||
strToReturn = strToReturn .. "\n\n" .. RenderRecipe.renderTable(tRecipe) | |||
end | |||
end | end | ||
return strToReturn | |||
end | end | ||
-- | -- writes the wiki table markup to represent a recipe | ||
-- | -- takes a recipe table (pattern and place), and uses only the first place | ||
function | function RenderRecipe.renderTable(tRecipe) | ||
if not tRecipe then | if not tRecipe then | ||
return nil | return nil | ||
end | end | ||
-- | -- call the helper functions to extract the data, make sure we have something usable, | ||
local | -- then get only the first values since we're assuming that there's only one top-level record in tRecipe | ||
local building, stars = RecipeData.getBuildingsAndStarsLists(tRecipe) | |||
if building and stars then | |||
building, stars = building[1], stars[1] | |||
else | |||
return "Render_Recipe Error: did not find building or stars in recipe." | |||
end | |||
local speed = RecipeData.getProductionSpeed(tRecipe) | |||
if speed then | |||
speed = speed[1] | |||
else | |||
return "Render_Recipe Error: did not find production speed in recipe." | |||
end | end | ||
local product, number = RecipeData.getProductAndNumbers(tRecipe) | |||
if product and number then | |||
number = number[1] | |||
else | |||
return "Render_Recipe Error: did not find product or output numbers in recipe." | |||
end | |||
-- | -- need separate error checking, because ingredients is the same structure as EACH | ||
if not | -- of the top-level elements of quantities | ||
return | local ingredients, quantities = RecipeData.getIngredientsAndQuantities(tRecipe) | ||
if not ingredients or 0 == #ingredients then | |||
return "Render_Recipe Error: did not find ingredients in recipe." | |||
end | |||
-- just want the first values since we're assuming there's only one top-level record in tRecipe | |||
if quantities then | |||
quantities = quantities[1] -- now ingredients and quantities have the same structure | |||
else | |||
return "Render_Recipe Error: did not find quantities in recipe." | |||
end | end | ||
local | local wikiTable = "{| " .. CSS_CLASS_RECIPE_TABLE .. NL .. | ||
"| " .. RenderRecipe.blTemplate(building) .. BR .. RenderRecipe.starTemplate(stars) .. BR .. speed .. NL | |||
-- | -- looping over groups of alternative ingredients and quantities simultaneously, | ||
-- and | -- so use local group and groupOfQuantities for each i | ||
for i, | for i, group in ipairs(ingredients) do | ||
-- | local groupOfQuantities = quantities[i] | ||
if | |||
-- on all but the first group, create a new cell with a + sign to separate ingredient groups | |||
if i > 1 then | |||
wikiTable = wikiTable .. " || + " | |||
end | |||
-- prefix the table cell based on whether there's only one (required) or more (swappable) ingredients | |||
-- in the group | |||
if 1 == #group then | |||
wikiTable = wikiTable .. | |||
"| " .. CSS_CLASS_REQUIRED_INGREDIENT .. " | " | |||
else | |||
wikiTable = wikiTable .. | |||
"| " .. CSS_CLASS_SWAPPABLE_INGREDIENT .. " | " | |||
end | |||
-- for every group, list out the required or alternatives within that group | |||
for j, alt in ipairs(group) do | |||
local quant = groupOfQuantities[j] | |||
-- need to add breaks only between the first and any subsequent options | |||
if j > 1 then | |||
wikiTable = wikiTable .. BR | |||
end | |||
wikiTable = wikiTable .. quant .. " " .. RenderRecipe.rlTemplate(alt) | |||
end | end | ||
end | end | ||
wikiTable = wikiTable .. NL .. | |||
"| = " .. NL .. | |||
"| " .. number .. " " .. RenderRecipe.rlTemplate(product,"large") .. NL .. | |||
"|}" | |||
return wikiTable | |||
end | end | ||
-- | -- redirect a rendering request to the recipe data and create appropriate | ||
-- | -- templates for the list. The caller can decide how to output the list | ||
function | function RenderRecipe.getBuildingsAndStarsForProduct(frame) | ||
local argProductName = frame.args.product | |||
local | |||
-- make sure there's an argument to work with | |||
if not tableRecipe then | |||
return "Render_Recipe Error: no product given." | |||
end | end | ||
-- get the associated recipe data, including all buildings | |||
local tableRecipe = RecipeData.getAllRecipes(argProductName) | |||
-- make sure what's returned is valid before we loop through it | |||
if not tableRecipe or not tableRecipe.places or #tableRecipe.places < 1 then | |||
return "Render_Recipe Error: no recipes found" | |||
-- | |||
-- make sure we | |||
if not | |||
return | |||
end | end | ||
local | local listOfTemplates = {} | ||
local buildings, stars = RecipeData.getBuildingsAndStarsLists(tRecipe) | |||
for i, | -- loop through the buildings and stars and build the templates | ||
for i, building in pairs(buildings) do | |||
listOfTemplates[i] = RenderRecipe.blTemplate(building) .. " " .. RenderRecipe.pstarTemplate(stars[i]) | |||
end | end | ||
return | return listOfTemplates | ||
end | end | ||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
-- Helper functions | -- Helper rendering functions | ||
-- these do not call member functions, but write out the actual templates | |||
-- (which will in turn invoke the code. this is to protect variations in the | |||
-- modules, but we may decide later it should be different) | |||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
--use huge size for recipes unless speified | |||
function RenderRecipe.blTemplate(strBuilding,strSize) | |||
-- | |||
function | |||
if not strSize then | |||
strSize= "huge" | |||
end | end | ||
return "{{" .. TEMPLATE_BUILDING_LINK .. "|" .. strBuilding .. "|" .. strSize .. "}}" | |||
end | end | ||
-- use recipe-sized icons, "med", unless specified | |||
function RenderRecipe.rlTemplate(strResource,strSize) | |||
-- | |||
function | |||
if not strSize then | |||
strSize= "med" | |||
end | end | ||
return | return "{{" .. TEMPLATE_RESOURCE_LINK .. "|" .. strResource .. "|" .. strSize .. "}}" | ||
end | end | ||
-- use the parentheses version, with "P" | |||
function RenderRecipe.pstarTemplate(intStars) | |||
return "{{P" .. intStars .. "star}}" | |||
end | |||
-- no parens version | |||
-- | function RenderRecipe.starTemplate(intStars) | ||
function | |||
return "{{" .. intStars .. "star}}" | |||
end | end | ||
| Line 365: | Line 245: | ||
-- Return when required into another Module. | -- Return when required into another Module. | ||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
return | return RenderRecipe | ||
Revision as of 18:14, 8 February 2023
Documentation for this module may be created at Module:RecipeData/doc
-------------------------------------------------------------------------------
-- Renders the {{recipe}} template
--
-- Takes at least one argument. The first, requried, is the name of the
-- resource for which the recipes are needed. Optionally, the second argument
-- is the name of the building.
-- This module renders small wikimarkup tables to represent one or more
-- recipes: one table if the building was specified. several tables
-- corresponding to all the buildings in which the resource can be produced.
-------------------------------------------------------------------------------
local RenderRecipe = {}
local RecipeData = require("Module:RecipeData") -- lookup table for recipes
-------------------------------------------------------------------------------
-- Constants
-------------------------------------------------------------------------------
local CSS_CLASS_RECIPE_TABLE = "class=\"ATSrecipe\""
local CSS_CLASS_REQUIRED_INGREDIENT = "class=\"ATSrequired\""
local CSS_CLASS_SWAPPABLE_INGREDIENT = "class=\"ATSswappable\""
local TEMPLATE_BUILDING_LINK = "Building_link"
local TEMPLATE_RESOURCE_LINK = "Resource_link"
local BR = " <br /> "
local NL = " \n "
-------------------------------------------------------------------------------
-- Main rendering function
-- uses ResourceData lookup function, parses the result and handles errors
-- with default values, then assembles a final string to return to the wiki
-------------------------------------------------------------------------------
function RenderRecipe.renderRecipe(frame)
local argProductName = frame.args.product
local argBuildingName = frame.args.building
if not argProductName then
return "Render_Recipe Error: no product given."
end
-- used by second case where we need to loop over the results
local strToReturn = ""
-- decide how to proceed based on whether the building was specified
if argBuildingName then -- 1. easier case, when the building was specified
local tRecipe = RecipeData.getRecipeAtBuilding(argProductName, argBuildingName)
if not tRecipe then
return "Render_Recipe Error: no recipe found."
end
--renderTable will use just the first place in the recipe, which is perfect for this version
return renderTable(tRecipe)
else -- 2. harder case, when no building was specified, need to loop
local tRecipe = RecipeData.getAllRecipes(argProductName)
if not tRecipe then
return "Render_Recipe Error: no recipe found."
end
-- go through each place and send a shallow copy version of tRecipe to the table renderer,
-- then concatenate them with appropriate wiki markup
for i, place in pairs(tRecipe.places) do
local tempRecipe = { product=argProductName, pattern=tRecipe.pattern, places=place }
return tempRecipe end end end function more() if 1 then if 1 then
strToReturn = strToReturn .. "\n\n" .. RenderRecipe.renderTable(tRecipe)
end
end
return strToReturn
end
-- writes the wiki table markup to represent a recipe
-- takes a recipe table (pattern and place), and uses only the first place
function RenderRecipe.renderTable(tRecipe)
if not tRecipe then
return nil
end
-- call the helper functions to extract the data, make sure we have something usable,
-- then get only the first values since we're assuming that there's only one top-level record in tRecipe
local building, stars = RecipeData.getBuildingsAndStarsLists(tRecipe)
if building and stars then
building, stars = building[1], stars[1]
else
return "Render_Recipe Error: did not find building or stars in recipe."
end
local speed = RecipeData.getProductionSpeed(tRecipe)
if speed then
speed = speed[1]
else
return "Render_Recipe Error: did not find production speed in recipe."
end
local product, number = RecipeData.getProductAndNumbers(tRecipe)
if product and number then
number = number[1]
else
return "Render_Recipe Error: did not find product or output numbers in recipe."
end
-- need separate error checking, because ingredients is the same structure as EACH
-- of the top-level elements of quantities
local ingredients, quantities = RecipeData.getIngredientsAndQuantities(tRecipe)
if not ingredients or 0 == #ingredients then
return "Render_Recipe Error: did not find ingredients in recipe."
end
-- just want the first values since we're assuming there's only one top-level record in tRecipe
if quantities then
quantities = quantities[1] -- now ingredients and quantities have the same structure
else
return "Render_Recipe Error: did not find quantities in recipe."
end
local wikiTable = "{| " .. CSS_CLASS_RECIPE_TABLE .. NL ..
"| " .. RenderRecipe.blTemplate(building) .. BR .. RenderRecipe.starTemplate(stars) .. BR .. speed .. NL
-- looping over groups of alternative ingredients and quantities simultaneously,
-- so use local group and groupOfQuantities for each i
for i, group in ipairs(ingredients) do
local groupOfQuantities = quantities[i]
-- on all but the first group, create a new cell with a + sign to separate ingredient groups
if i > 1 then
wikiTable = wikiTable .. " || + "
end
-- prefix the table cell based on whether there's only one (required) or more (swappable) ingredients
-- in the group
if 1 == #group then
wikiTable = wikiTable ..
"| " .. CSS_CLASS_REQUIRED_INGREDIENT .. " | "
else
wikiTable = wikiTable ..
"| " .. CSS_CLASS_SWAPPABLE_INGREDIENT .. " | "
end
-- for every group, list out the required or alternatives within that group
for j, alt in ipairs(group) do
local quant = groupOfQuantities[j]
-- need to add breaks only between the first and any subsequent options
if j > 1 then
wikiTable = wikiTable .. BR
end
wikiTable = wikiTable .. quant .. " " .. RenderRecipe.rlTemplate(alt)
end
end
wikiTable = wikiTable .. NL ..
"| = " .. NL ..
"| " .. number .. " " .. RenderRecipe.rlTemplate(product,"large") .. NL ..
"|}"
return wikiTable
end
-- redirect a rendering request to the recipe data and create appropriate
-- templates for the list. The caller can decide how to output the list
function RenderRecipe.getBuildingsAndStarsForProduct(frame)
local argProductName = frame.args.product
-- make sure there's an argument to work with
if not tableRecipe then
return "Render_Recipe Error: no product given."
end
-- get the associated recipe data, including all buildings
local tableRecipe = RecipeData.getAllRecipes(argProductName)
-- make sure what's returned is valid before we loop through it
if not tableRecipe or not tableRecipe.places or #tableRecipe.places < 1 then
return "Render_Recipe Error: no recipes found"
end
local listOfTemplates = {}
local buildings, stars = RecipeData.getBuildingsAndStarsLists(tRecipe)
-- loop through the buildings and stars and build the templates
for i, building in pairs(buildings) do
listOfTemplates[i] = RenderRecipe.blTemplate(building) .. " " .. RenderRecipe.pstarTemplate(stars[i])
end
return listOfTemplates
end
-------------------------------------------------------------------------------
-- Helper rendering functions
-- these do not call member functions, but write out the actual templates
-- (which will in turn invoke the code. this is to protect variations in the
-- modules, but we may decide later it should be different)
-------------------------------------------------------------------------------
--use huge size for recipes unless speified
function RenderRecipe.blTemplate(strBuilding,strSize)
if not strSize then
strSize= "huge"
end
return "{{" .. TEMPLATE_BUILDING_LINK .. "|" .. strBuilding .. "|" .. strSize .. "}}"
end
-- use recipe-sized icons, "med", unless specified
function RenderRecipe.rlTemplate(strResource,strSize)
if not strSize then
strSize= "med"
end
return "{{" .. TEMPLATE_RESOURCE_LINK .. "|" .. strResource .. "|" .. strSize .. "}}"
end
-- use the parentheses version, with "P"
function RenderRecipe.pstarTemplate(intStars)
return "{{P" .. intStars .. "star}}"
end
-- no parens version
function RenderRecipe.starTemplate(intStars)
return "{{" .. intStars .. "star}}"
end
-------------------------------------------------------------------------------
-- Return when required into another Module.
-------------------------------------------------------------------------------
return RenderRecipe


