Module:CraftingJSON: Difference between revisions

From JCraft Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(2 intermediate revisions by the same user not shown)
Line 46: 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."
         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 60: 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 rawItem = data.key[char].item
                local char = rowStr:sub(c, c)
                local fileName = getSmartFileName(rawItem)
                local cell = grid:tag('div'):addClass('mc-cell')
                local displayName = getDisplayName(rawItem)
               
                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]
                  
                  
                 cell:wikitext(string.format('[[File:%s.png|32px|link=%s|%s]]', fileName, displayName, displayName))
                 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 87: Line 117:
         local resultAmount = data.result.count or 1
         local resultAmount = data.result.count or 1
          
          
         local resultImg = string.format('[[File:%s.png|32px|link=%s|%s]]', fileName, displayName, displayName)
         local resultImg = string.format('[[File:%s.png|37px|link=%s|%s]]', fileName, displayName, displayName)
          
          
         if resultAmount > 1 then
         if resultAmount > 1 then

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