跳转到内容

Module:Infobox

来自Undertale Wiki

此模組用於格式化資訊框資料與根據其自動分類的輔助函式。


-- <nowiki>
--- 用於格式化資訊框資料與根據其自動分類的輔助函式。
--  @module             infobox
--  @alias              p
--  @require            Module:User error
--  @require            Module:Yesno
--  @author             [[en:User:KockaAdmiralac|KockaAdmiralac]]
--  @author             [[en:User:Jacky720|Jacky720]]
--  <nowiki>
local p = {}

-- 匯入模組。
local userError = require('Module:User error')
local yesno = require('Module:Yesno')
local title = mw.title.getCurrentTitle()
local data = mw.loadData('Module:Infobox/data')

-- 模組變數。
local title = mw.title.getCurrentTitle()

-- 私有邏輯。

--- 將分類加入指定的字串表(table 形式)。
--  僅當目前頁面在主名字空間時有效。
--  @function           category
--  @param              {table} t 要插入分類的字串(table)
--  @param              {table} c 要插入的分類
--  @local

-- 將多個分類插入表中。
function category(t, c)
    if title.namespace == 0 then
        table.insert(t, '[[Category:')
        table.insert(t, c)
        table.insert(t, ']]')
    end
end

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

-- 模組公開函式。

--- 格式化地點參數。
--  本函式的複雜邏輯用於推斷事件發生的地點與應該將頁面歸類在哪些分類中。
--  經過此函式的地點參數允許用圓點分隔,並會視為多個獨立地點處理。
--  本函式可解析以下格式的地點:
--  <pre>卡片城堡 → [[卡片城堡]]</pre>
--  <pre>[[卡片城堡]] → [[卡片城堡]]</pre>
--  <pre>卡片城堡 (F1) → [[卡片城堡#F1|卡片城堡]] (F1)</pre>
--  <pre>[[卡片城堡]] (F1) → [[卡片城堡#F1|卡片城堡]] (F1)</pre>
--  <pre>卡片城堡#F1 → [[卡片城堡#F1|卡片城堡]] (F1)</pre>
--  <pre>[[卡片城堡#F1]] → [[卡片城堡#F1|卡片城堡]] (F1)</pre>
--  無效地點會被修剪並原樣返回。
--  @function           p.location
--  @param              {table} frame Scribunto 的 frame 物件
--  @returns            {string} 格式化後的地點
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)
        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 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.mechanics
--  @param              {table} frame Scribunto 的 frame 物件
--  @returns            {string} 格式化後的遊戲機制類型
function p.mechanics(frame)
    local t = frame.args[1]
    if not t or not data.mechanics[t] then
        return userError(
            '機制類型無效或未指定',
            '含有使用者錯誤的頁面'
        )
    end
    local d = data.mechanics[t]
    local str = {d}
    category(str, table.concat({d}))
    
    return table.concat(str)
end

--- 格式化物品類型和武器的子類型。
-- @function p.itemtype
-- @param {table} 框架 Scribunto 的框架對象
-- @returns {string} 格式化的物品類型和武器子類型
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)
            -- Categorize as Swords, Axes, Scarves, or Rings instead, based on equip parameter
            if itemtype == 'Weapon' and data.weapontypes[frame.args[2]] then
                category(str, data.weapontypes[frame.args[2]])
            else
                category(str, data.itemtypes[itemtype])
            end
        end
    end
    return table.concat(str)
end

--- 格式化敵人資訊框中的 ACT 欄位。
--  @function           p.act
--  @param              {table} frame Scribunto 的 frame 物件
--  @returns            {string} 格式化後的 ACT 列表
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:傳入函式的某場戰鬥的 ACT 指令  
        -- 例如:"Cry (First box encounter)"
        -- acts:除了「檢查(Check)」以外的 ACT 指令  
        -- 例如:"Cry"
        -- form:對應該 ACT 的型態或戰鬥情境  
        -- 例如:"First box encounter"
        -- "nocheck" 參數(frame.args[2])可防止自動加入「檢查」指令
        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, '檢查、')
                else
                    table.insert(str, '檢查')
                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

--- 若指定了 <code>gold</code> 參數,則附加「敵人」分類。
--  用以判定該角色是否為敵人。
--  @function           p.gold
--  @param              {table} Scribunto 的 frame 物件
--  @returns            {string} 加入分類後的相同內容
function p.gold(frame)
    local str = {frame.args[1]}
    category(str, '敵人')
    return table.concat(str)
end    

--- 若參數未提供則顯示「N/A」。
--  @function           p.na
--  @param              {table} Scribunto 的 frame 物件
--  @returns            {string} 若參數未提供則為 "N/A",否則為原值
function p.na(frame)
    local val = mw.text.trim(frame.args[1])
    if val == '' then
        return 'N/A'
    else
        return val
    end
end

--- 當物品在其條目中有多個資訊框時使用(如變體)。
--  @function           p.alternative
--  @param              {table} frame Scribunto 的 frame 物件
--  @returns            {string} 一個斜線加上備用物品名稱
function p.alternative(frame)
    local val = mw.text.trim(frame.args[1])
    if val ~= '' then
        return table.concat({'/', val})
    end
end

--- 將地點頁面歸類至 [[:Category:地點]],並若有以地點名稱命名的分類,也一併加入。
--  @function           p.locationcats
--  @param              {table} frame Scribunto 的 frame 物件
--  @returns            {string} 地點的分類列表
function p.locationcats(frame)
    local cats = {}
    category(cats, '地點')
    if data.locationcats[title.text] then
        category(cats, title.text)
    end
    return table.concat(cats)
end

return p
--  </nowiki>