模块

模块:Arguments

来自卡厄思梦境WIKI

此模块的文档可以在模块:Arguments/doc创建

local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType

local arguments = {}

-- 从 frame 中提取参数
function arguments.getArgs(frame, options)
    checkType('getArgs', 1, frame, 'table', true)
    checkType('getArgs', 2, options, 'table', true)
    frame = frame or {}
    options = options or {}

    -- 获取父frame的参数(来自模板调用)
    local fargs, pargs, luaArgs
    
    if type(frame.args) == 'table' and type(frame.getParent) == 'function' then
        -- frame 是真正的 frame 对象
        if not options.parentOnly then
            fargs = frame.args
        end
        if not options.frameOnly then
            local parent = frame:getParent()
            pargs = parent and parent.args or {}
        end
        if options.parentFirst then
            luaArgs = pargs or {}
            -- 如果 parentFirst,先使用 pargs,再用 fargs 补充
            if fargs then
                for k, v in pairs(fargs) do
                    if luaArgs[k] == nil then
                        luaArgs[k] = v
                    end
                end
            end
        else
            luaArgs = fargs or {}
            -- 默认情况,先使用 fargs,再用 pargs 补充
            if pargs then
                for k, v in pairs(pargs) do
                    if luaArgs[k] == nil then
                        luaArgs[k] = v
                    end
                end
            end
        end
    else
        -- frame 实际上是一个参数表
        luaArgs = frame or {}
    end

    -- 创建元表来处理参数访问
    local args = {}
    local metatable = {}
    
    -- 用于存储已处理的参数
    local processed = {}
    
    function metatable.__index(t, key)
        if processed[key] ~= nil then
            return processed[key]
        end
        
        local value = luaArgs[key]
        
        if value == nil then
            processed[key] = nil
            return nil
        end
        
        -- 去除空白字符(如果需要)
        if type(value) == 'string' then
            value = mw.text.trim(value)
            -- 将空字符串视为 nil(如果设置了 removeBlanks)
            if options.removeBlanks and value == '' then
                value = nil
            end
        end
        
        processed[key] = value
        return value
    end
    
    function metatable.__newindex(t, key, value)
        processed[key] = value
    end
    
    function metatable.__pairs(t)
        local function iter(t, key)
            local nextKey, nextValue
            repeat
                nextKey, nextValue = next(luaArgs, key)
                if nextKey == nil then
                    return nil
                end
                key = nextKey
                -- 通过 __index 处理值
                nextValue = t[nextKey]
            until nextValue ~= nil or not options.removeBlanks
            return nextKey, nextValue
        end
        return iter, t, nil
    end
    
    setmetatable(args, metatable)
    
    return args
end

return arguments