Module:CraftingJSON: Difference between revisions

From JCraft Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(8 intermediate revisions by the same user not shown)
Line 1: Line 1:
local p = {}
local p = {}
local slot = require('Module:Inventory slot')


local function formatItemName(rawName)
local function getSmartFileName(rawName)
    if not rawName then return "" end
    local baseName = rawName:gsub("^[^:]+:", "")
    local spaceName = baseName:gsub("_", " ")
   
    local titleCase = spaceName:gsub("(%a)([%w_']*)", function(first, rest)
        return first:upper() .. rest:lower()
    end)
   
    local sentenceCase = spaceName:sub(1,1):upper() .. spaceName:sub(2):lower()
 
    local checks = {
        "Invicon " .. titleCase,
        "Invicon " .. sentenceCase,
        titleCase,
        sentenceCase
    }
 
    for _, name in ipairs(checks) do
        local file = mw.title.new("File:" .. name .. ".png")
        if file and file.exists then
            return name
        end
    end
   
    return titleCase
end
 
local function getDisplayName(rawName)
     if not rawName then return "" end
     if not rawName then return "" end
     local name = rawName:gsub("^[^:]+:", "")
     local name = rawName:gsub("^[^:]+:", "")
Line 19: Line 46:
         return "Error: No JSON provided."
         return "Error: No JSON provided."
     end
     end
    jsonStr = mw.text.unstripNoWiki(jsonStr)
    jsonStr = mw.text.decode(jsonStr)
    jsonStr = jsonStr:gsub("“", '"'):gsub("”", '"')
    jsonStr = jsonStr:gsub("^1%s*=%s*", "")
    jsonStr = jsonStr:gsub("<br%s*/?>", "")
    jsonStr = jsonStr:gsub("</?p>", "")


     local success, data = pcall(mw.text.jsonDecode, mw.text.trim(jsonStr))
     local success, data = pcall(mw.text.jsonDecode, mw.text.trim(jsonStr))
      
      
     if not success then  
     if not success then  
         return "Error: Invalid JSON syntax. Please check for trailing commas or missing quotes."
         return "Error: Invalid JSON syntax. MediaWiki modified the text formatting."
     end
     end
      
      
     if not data.pattern then  
     local isShaped = data.type == "minecraft:crafting_shaped" or data.pattern
         return "Error: Missing JSON pattern."  
    local isShapeless = data.type == "minecraft:crafting_shapeless" or data.ingredients
 
    if not isShaped and not isShapeless then  
         return "Error: Unsupported recipe type or missing pattern/ingredients."  
     end
     end


Line 33: Line 70:
     local grid = container:tag('div'):addClass('mc-grid')
     local grid = container:tag('div'):addClass('mc-grid')


     for r = 1, 3 do
     if isShaped then
        local rowStr = data.pattern[r] or "  "
        for r = 1, 3 do
        rowStr = rowStr .. string.rep(" ", 3 - #rowStr)
            local rowStr = data.pattern and data.pattern[r] or "  "
       
            rowStr = rowStr .. string.rep(" ", 3 - #rowStr)
        for c = 1, 3 do
            local char = rowStr:sub(c, c)
            local cell = grid:tag('div'):addClass('mc-cell')
              
              
             if char ~= " " and data.key and data.key[char] then
             for c = 1, 3 do
                local itemName = formatItemName(data.key[char].item)
                local char = rowStr:sub(c, c)
       
                local cell = grid:tag('div'):addClass('mc-cell')
                cell:wikitext(slot.slot{itemName, image = itemName .. '.png'})
               
                if char ~= " " and data.key and data.key[char] then
                    local rawItem = data.key[char].item
                    if rawItem then
                        local fileName = getSmartFileName(rawItem)
                        local displayName = getDisplayName(rawItem)
                        cell:wikitext(string.format('[[File:%s.png|37px|link=%s|%s]]', fileName, displayName, displayName))
                    end
                end
            end
        end
    elseif isShapeless then
        local ingredients = data.ingredients or {}
        local index = 1
        for r = 1, 3 do
            for c = 1, 3 do
                local cell = grid:tag('div'):addClass('mc-cell')
                local ingredient = ingredients[index]
               
                if ingredient and ingredient.item then
                    local rawItem = ingredient.item
                    local fileName = getSmartFileName(rawItem)
                    local displayName = getDisplayName(rawItem)
                    cell:wikitext(string.format('[[File:%s.png|37px|link=%s|%s]]', fileName, displayName, displayName))
                end
                index = index + 1
             end
             end
         end
         end
Line 53: Line 112:
     local resultCell = container:tag('div'):addClass('mc-result')
     local resultCell = container:tag('div'):addClass('mc-result')
     if data.result and data.result.item then
     if data.result and data.result.item then
         local resultName = formatItemName(data.result.item)
         local rawResult = data.result.item
        local fileName = getSmartFileName(rawResult)
        local displayName = getDisplayName(rawResult)
         local resultAmount = data.result.count or 1
         local resultAmount = data.result.count or 1
       
        local resultImg = string.format('[[File:%s.png|37px|link=%s|%s]]', fileName, displayName, displayName)
          
          
         if resultAmount > 1 then
         if resultAmount > 1 then
   
            resultCell:css('position', 'relative')
             resultCell:wikitext(slot.slot{resultName, resultAmount, image = resultName .. '.png'})
             resultCell:wikitext(resultImg .. string.format('<span style="position:absolute; bottom:2px; right:4px; font-weight:bold; color:white; text-shadow:2px 2px 0 #373737;">%s</span>', resultAmount))
         else
         else
             resultCell:wikitext(slot.slot{resultName, image = resultName .. '.png'})
             resultCell:wikitext(resultImg)
         end
         end
     end
     end

Latest revision as of 13:16, 27 April 2026

Documentation for this module may be created at Module:CraftingJSON/doc

local p = {}

local function getSmartFileName(rawName)
    if not rawName then return "" end
    local baseName = rawName:gsub("^[^:]+:", "")
    local spaceName = baseName:gsub("_", " ")
    
    local titleCase = spaceName:gsub("(%a)([%w_']*)", function(first, rest) 
        return first:upper() .. rest:lower() 
    end)
    
    local sentenceCase = spaceName:sub(1,1):upper() .. spaceName:sub(2):lower()

    local checks = {
        "Invicon " .. titleCase,
        "Invicon " .. sentenceCase,
        titleCase,
        sentenceCase
    }

    for _, name in ipairs(checks) do
        local file = mw.title.new("File:" .. name .. ".png")
        if file and file.exists then
            return name
        end
    end
    
    return titleCase
end

local function getDisplayName(rawName)
    if not rawName then return "" end
    local name = rawName:gsub("^[^:]+:", "")
    name = name:gsub("_", " ")
    name = name:gsub("(%a)([%w_']*)", function(first, rest) 
        return first:upper() .. rest:lower() 
    end)
    return name
end

function p.render(frame)
    local args = frame:getParent().args
    local jsonStr = args[1]
    
    if not jsonStr or mw.text.trim(jsonStr) == "" then
        return "Error: No JSON provided."
    end

    jsonStr = mw.text.unstripNoWiki(jsonStr)
    jsonStr = mw.text.decode(jsonStr)
    jsonStr = jsonStr:gsub("“", '"'):gsub("”", '"')
    jsonStr = jsonStr:gsub("^1%s*=%s*", "")
    jsonStr = jsonStr:gsub("<br%s*/?>", "")
    jsonStr = jsonStr:gsub("</?p>", "")

    local success, data = pcall(mw.text.jsonDecode, mw.text.trim(jsonStr))
    
    if not success then 
        return "Error: Invalid JSON syntax. MediaWiki modified the text formatting."
    end
    
    local isShaped = data.type == "minecraft:crafting_shaped" or data.pattern
    local isShapeless = data.type == "minecraft:crafting_shapeless" or data.ingredients

    if not isShaped and not isShapeless then 
        return "Error: Unsupported recipe type or missing pattern/ingredients." 
    end

    local container = mw.html.create('div'):addClass('mc-crafting-wrapper')
    local grid = container:tag('div'):addClass('mc-grid')

    if isShaped then
        for r = 1, 3 do
            local rowStr = data.pattern and data.pattern[r] or "   "
            rowStr = rowStr .. string.rep(" ", 3 - #rowStr)
            
            for c = 1, 3 do
                local char = rowStr:sub(c, c)
                local cell = grid:tag('div'):addClass('mc-cell')
                
                if char ~= " " and data.key and data.key[char] then
                    local rawItem = data.key[char].item
                    if rawItem then
                        local fileName = getSmartFileName(rawItem)
                        local displayName = getDisplayName(rawItem)
                        cell:wikitext(string.format('[[File:%s.png|37px|link=%s|%s]]', fileName, displayName, displayName))
                    end
                end
            end
        end
    elseif isShapeless then
        local ingredients = data.ingredients or {}
        local index = 1
        for r = 1, 3 do
            for c = 1, 3 do
                local cell = grid:tag('div'):addClass('mc-cell')
                local ingredient = ingredients[index]
                
                if ingredient and ingredient.item then
                    local rawItem = ingredient.item
                    local fileName = getSmartFileName(rawItem)
                    local displayName = getDisplayName(rawItem)
                    cell:wikitext(string.format('[[File:%s.png|37px|link=%s|%s]]', fileName, displayName, displayName))
                end
                index = index + 1
            end
        end
    end

    container:tag('div'):addClass('mc-arrow'):wikitext('→')
    
    local resultCell = container:tag('div'):addClass('mc-result')
    if data.result and data.result.item then
        local rawResult = data.result.item
        local fileName = getSmartFileName(rawResult)
        local displayName = getDisplayName(rawResult)
        local resultAmount = data.result.count or 1
        
        local resultImg = string.format('[[File:%s.png|37px|link=%s|%s]]', fileName, displayName, displayName)
        
        if resultAmount > 1 then
            resultCell:css('position', 'relative')
            resultCell:wikitext(resultImg .. string.format('<span style="position:absolute; bottom:2px; right:4px; font-weight:bold; color:white; text-shadow:2px 2px 0 #373737;">%s</span>', resultAmount))
        else
            resultCell:wikitext(resultImg)
        end
    end

    return tostring(container)
end

return p