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

-- <nowiki>
local p = {}

local userError = require('Dev:User error')
local yesno = require('Dev:Yesno')
local title = mw.title.getCurrentTitle()
local data = mw.loadData('Module:Infobox/data')

function category(t, c)
    table.insert(t, '[[Category:')
    table.insert(t, c)
    table.insert(t, ']]')
end

function multicategory(t, c)
    for _, cat in ipairs(c) do
        category(t, cat)
    end
end

function p.location(frame)
    local str = {}
    local index = 0
    local categories = {}
    local infotype = frame.args[2]
    for _, location in ipairs(mw.text.split(frame.args[1], '*', true)) do
        local trimmed = mw.text.trim(location)
        -- Accepts:
        -- Card Castle
        -- [[Card Castle]]      --> [[Card Castle]]
        -- Card Castle (F1)
        -- [[Card Castle]] (F1)
        -- Card Castle#F1
        -- [[Card Castle#F1]]   --> [[Card Castle#F1|Card Castle]] (F1)
        -- Invalid locations are trimmed and returned.
        if trimmed ~= '' then
            index = index + 1
            if index == 2 then
                table.insert(str, 1, '* ')
            end
            local link, text = mw.ustring.match(trimmed, '^%[?%[?([^%](]+)%]?%]?%s*%(?([^)]*)%)?$')
            if link then
                link = mw.text.trim(link)
                if index > 1 then
                    table.insert(str, '\n* ')
                end
                local spl = mw.text.split(link, '#', true)
                local name = spl[1]
                local hash = spl[2]
                if text and text ~= '' and not hash then
                    hash = text
                end
                local ldata = data.locations[name]
                if ldata then
                    if ldata.link then
                        link = ldata.link
                    end
                    if ldata.categories and title.namespace == 0 then
                        multicategory(categories, ldata.categories)
                    end
                    if ldata.condcats and infotype and ldata.condcats[infotype] then
                        multicategory(categories, ldata.condcats[infotype])
                    end
                    if ldata.nolink then
                        table.insert(str, link)
                    else
                        table.insert(str, '[[')
                        table.insert(str, name)
                        if hash then
                            table.insert(str, '#')
                            table.insert(str, hash)
                            table.insert(str, '|')
                            table.insert(str, name)
                            table.insert(str, ']]')
                            table.insert(str, ' (')
                            table.insert(str, hash)
                            table.insert(str, ')')
                        else
                            table.insert(str, ']]')
                        end
                    end
                else
                    table.insert(str, trimmed)
                end
            end
        end
    end
    return table.concat(str) .. table.concat(categories)
end

function p.itemtype(frame)
    local str = {}
    for _, itemtype in ipairs(mw.text.split(frame.args[1], ',', true)) do
        itemtype = mw.text.trim(itemtype)
        if data.itemtypes[itemtype] then
            if str[1] then
                if str[1] ~= '* ' then
                    table.insert(str, 1, '* ')
                end
                table.insert(str, '\n* ')
            end
            table.insert(str, itemtype)
            if title.namespace == 0 then
                category(str, data.itemtypes[itemtype])
            end
        end
    end
    return table.concat(str)
end

function p.mechanics(frame)
    local t = frame.args[1]
    if not t or not data.mechanics[t] then
        return userError(
            'Mechanic type invalid or not specified',
            'Pages with user errors'
        )
    end
    local d = data.mechanics[t]
    local str = {d, ' mechanic'}
    if title.namespace == 0 then
        table.insert(str, '[[Category:')
        table.insert(str, d)
        table.insert(str, ' Mechanics]]')
    end
    return table.concat(str)
end

function p.act(frame)
    local str = {}
    local index = 0
    local nocheck = frame.args[2]
    nocheck = mw.text.trim(nocheck)
    nocheck = mw.text.split(nocheck, '%s*,%s*')
    for _, battle in ipairs(mw.text.split(frame.args[1], '*', true)) do
        -- battle: A given battle's ACTs, passed to the function 
        --  e.g. "Cry (First box encounter)"
        -- acts: The ACTs OTHER than Check
        --  e.g. "Cry"
        -- form: The form or battle with these ACTs
        --  e.g. "First box encounter"
        -- "nocheck" parameter (frame.args[2]) prevents auto-adding Check.
        battle = mw.text.trim(battle)
        if battle ~= '' then
            index = index + 1
            if index == 2 then
                table.insert(str, 1, '* ')
            end
            if index > 1 then
                table.insert(str, '\n* ')
            end
 
            local acts, form = mw.ustring.match(battle, '^([^(]*)%s*%(?([^)]*)%)?$')
            if not yesno(nocheck[index] or nocheck[1], false) then
                if acts ~= '' then
                    table.insert(str, 'Check, ')
                else
                    table.insert(str, 'Check ')
                end
            end
            table.insert(str, acts)
            if form ~= '' then
                table.insert(str, ' (')
                table.insert(str, form)
                table.insert(str, ')')
            end
        end
    end
    return table.concat(str)
end

function p.gold(frame)
    local str = {frame.args[1]}
    if title.namespace == 0 then
        table.insert(str, '[[Category:Enemies]]')
    end
    return table.concat(str)
end

function p.undertale(frame)
    local name = frame.args[1]
    if yesno(name, false) then
        name = title.text
    end
    local str = {}
    table.insert(str, '[[w:c:ut:')
    table.insert(str, name)
    table.insert(str, '|')
    table.insert(str, name)
    table.insert(str, ']]')
    if title.namespace and frame.args[2] == '' then -- Don't include category for NPC pages with separated infoboxes
        table.insert(str, '[[Category:Returning Characters]]')
    end
    return table.concat(str)
end

function p.na(frame)
    local val = mw.text.trim(frame.args[1])
    if val == '' then
        return 'N/A'
    else
        return val
    end
end

-- Not used in the actual infobox, but in {{Items}}
function p.alternative(frame)
    local val = mw.text.trim(frame.args[1])
    if val ~= '' then
        return table.concat({'/', val})
    end
end

return p
Community content is available under CC-BY-SA unless otherwise noted.