Module:Recipe

local util_args = require('Module:ArgsUtil') local util_cargo = require('Module:CargoUtil') local util_text = require('Module:TextUtil')

local h = {}

function h.getRecipesFromCargo local query = { tables = 'Items', fields = { 'Name', 'MadeFrom' },		limit = 9999 }	local result = util_cargo.queryAndCast(query) local recipes = h.recipesFromResult(result) return recipes end

function h.recipesFromResult(result) local tbl = {} for _, row in ipairs(result) do		tbl[row.Name] = h.parseRecipe(row.MadeFrom) end return tbl end

function h.parseRecipe(madefrom) if not madefrom or madefrom == 'This item cannot be made.' then return true end return util_text.split(madefrom,'%s*%+%s*') end

-- this is a recursively-defined function that takes the input of a json (which might be a child of the overall json) -- and an item that we are to add data about. function h.generateJson(recipes, item, json, n)	-- if we got this far, then there's more data to be gathered local depths = {} if not recipes[item] then error(("Item %s missing from recipe table. Check that it's storing Cargo correctly!"):format(item)) end for i, new_item in ipairs(recipes[item]) do		--iterate through the items in this entry in the lookup table -- first add to the list we're at		json[i] = new_item if not recipes[new_item] then -- here is our error-check for typos or potentially other wrong data in the recipes table error(("invalid table entry of %s"):format(new_item)) elseif type(recipes[new_item]) == 'table' then json[new_item] = {} depths[#depths+1] = h.generateJson(recipes, new_item, json[new_item], n)		end -- otherwise the entry in the lookup was just true, and we have reached an ending node in the tree end table.sort(depths) return (depths[#depths] or n) + 1 end

function h.makeHeader(tbl,item) tbl:tag('tr'):tag('th'):addClass('recipe-title'):attr('colspan','30'):wikitext(item) return end

-- we could do some ridiculous mess with colspans but that sounds awful so lets just do tables within tables -- each level of the recipe looks like this: -- --   ITEM NAME --  SOME TABLE OF HOW TO BUILD TO IT (optional) -- -- this is extremely easy to build in top-down recursion since we just add the item name -- and then put a table below it and say "ok recursive step do all the work lol" function h.printJson(json, tbl, n)	local tr = tbl:tag('tr') for _, v in ipairs(json) do		if json[v] then -- table with 2 vertical cells tbl2 = tr:tag('td') :addClass('recipe-cell-1') :tag('table') :addClass('recipe-table-2') tbl2:tag('tr') :tag('td') :addClass('recipe-cell-2') :wikitext(string.format('%s',v)) -- bottom cell is the recursion step tbl3 = tbl2:tag('tr') :tag('td') :addClass('recipe-cell-1') :tag('table') :addClass('recipe-table-2') h.printJson(json[v],tbl3, n-1) else tr:tag('td') :wikitext(string.format('%s',v)) :addClass('recipe-cell-2') end end return end

local p = {} function p.main(frame) local args = util_args.merge(true) local item = args[1] or mw.title.getCurrentTitle.text local recipes = h.getRecipesFromCargo if type(recipes[item]) == 'boolean' then return ":This item cannot be made." end local json = { } local n = h.generateJson(recipes, item, json, 0) local tbl = mw.html.create('table'):addClass('recipe-table-1') h.makeHeader(tbl, item) h.printJson(json, tbl, n)	return tbl end

return p