Module:InfoboxExtractor

From JoJo's Bizarre Encyclopedia - JoJo Wiki
Revision as of 04:53, 5 July 2023 by Vish (talk | contribs)
Jump to navigation Jump to search

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

local p = {}

local function extractInfobox(wikitext)
    local startInfobox = string.find(wikitext, "{{[^}]*Infobox")
    if not startInfobox then
        return nil
    end

    local braceCount = 0
    local endInfobox = startInfobox

    for i = startInfobox, #wikitext do
        local char = wikitext:sub(i, i)
        if char == '{' then
            braceCount = braceCount + 1
        elseif char == '}' then
            braceCount = braceCount - 1
        end

        if braceCount == 0 then
            endInfobox = i
            break
        end
    end

    return wikitext:sub(startInfobox, endInfobox)
end

local function getLabelValue(infobox, label)
    local pattern = "|" .. label .. " *= *"
    local matchStart, matchEnd = string.find(infobox, pattern)
    if not matchStart then
        return nil
    end

    local value = ""
    local braceCount = 0
    local i = matchEnd + 1
    local isNewLine = false

-- need to do - 2 so it ignores the }} at the end of the infobox
    while i <= #infobox - 2 do
        local char = infobox:sub(i, i)

        if char == '{' then
            braceCount = braceCount + 1
        elseif char == '}' then
            braceCount = braceCount - 1
        end

        if braceCount == 0 and char == '\n' then
            isNewLine = true
        elseif isNewLine and char == '|' then
            break
        else
            isNewLine = false
            value = value .. char
        end

        i = i + 1
    end

    return value
end

local function getImages(value, imageTab, imageTab2)
    local images = {}
    local tabberStart = string.find(value, "{{Tabber")
    if tabberStart then
        local tabberEnd = string.find(value, "}}", tabberStart)
        local tabberContent = string.sub(value, tabberStart, tabberEnd)
        local tabPattern = "|([^|{}\n]+)|%[%[([^|%]]+)"
        
        for tabName, tabImage in string.gmatch(tabberContent, tabPattern) do
            if imageTab and tabName == imageTab then
                table.insert(images, tabImage)
            elseif imageTab2 and tabName == imageTab2 then
                table.insert(images, tabImage)
            end
        end
    else
        local pattern = "|[^|{}\n]+|%[%[([^|%]]+)"
        for image in string.gmatch(value, pattern) do
            table.insert(images, image)
        end
    end
    
    return images
end

function p.extract(frame)
    local pageTitle = frame.args[1]
    local imageTab = frame.args.imageTab
    local imageTab2 = frame.args.imageTab2

    if not pageTitle then
        return "Error: Please provide a page title."
    end

    local page = mw.title.new(pageTitle)
    if not page or not page.exists then
        return "Error: Page not found."
    end

    local wikitext = page:getContent()
    local infobox = extractInfobox(wikitext)

    if not infobox then
        return "Error: Infobox not found."
    end

    local label = frame.args[2]
    if not label then
        return "Error: Please provide a label."
    end

    local value = getLabelValue(infobox, label)

    if not value then
        return "Error: Label not found in infobox."
    end

    if label:lower() == "image" then
        local images = getImages(value, imageTab, imageTab2)
        local size = frame.args.size or ""
        local link = frame.args.link or ""

        if #images == 0 then
            return "Error: No image found."
        end

        local selectedImage = images[1] -- Get the first image
        if link ~= "" then
            return string.format('[[File:%s|%s|link=%s]]', selectedImage, size, link)
        else
            return string.format('[[File:%s|%s]]', selectedImage, size)
        end
    else
        local processedValue = frame:preprocess(value)
        return processedValue
    end
end

return p