模块:沙盒/PexEric/4

维基百科,自由的百科全书
跳转到导航 跳转到搜索
local p = {}
local getArgs = require('Module:Arguments').getArgs
local WPExtract = require('Module:WikiProjects extract')

-- 默认配置
local DEFAULT_SOURCE_PAGE = "Wikipedia:新条目推荐/候选"

local function extractCandidates(content)
    local candidates = {}
    local seen = {} -- 用于去重
    
    -- 匹配模式说明:
    -- |%s*article%s*=      匹配 "| article =" (允许空白)
    -- %s*(.-)%s* 捕获条目名,去除前后空白
    -- [\n|}]               遇到换行、竖线或反花括号结束
    for match in string.gmatch(content, "|%s*article%s*=%s*(.-)%s*[\n|}]") do
        -- 清理可能的垃圾字符(比如未完全匹配干净的空白)
        local title = mw.text.trim(match)
        
        if title ~= "" and not seen[title] then
            table.insert(candidates, title)
            seen[title] = true
        end
    end
    return candidates
end

function p.main(frame)
    local args = getArgs(frame)
    
    -- 1. 获取用户输入的搜索模式(关键词)
    local patterns = {}
    for _, v in ipairs(args) do
        table.insert(patterns, v)
    end
    
    if #patterns == 0 then
        return '<span class="error">请提供至少一个专题搜索关键词(如 |1=中国)。</span>'
    end

    -- 2. 获取 DYK 候选页面内容
    local sourcePage = args.source or DEFAULT_SOURCE_PAGE
    local titleObj = mw.title.new(sourcePage)
    
    if not titleObj or not titleObj.exists then
        return '<span class="error">无法读取源页面:' .. sourcePage .. '</span>'
    end
    
    local content = titleObj:getContent()
    if not content then
        return '<span class="error">源页面内容为空。</span>'
    end

    -- 3. 提取所有候选条目
    local candidateList = extractCandidates(content)
    if #candidateList == 0 then
        return "当前没有提取到任何参选条目,请检查源页面格式。"
    end

    -- 4. 批量查询这些条目的专题
    local bannersMap = WPExtract.getBanners(candidateList)

    -- 5. 筛选符合条件的条目
    local results = {}
    
    for _, article in ipairs(candidateList) do
        -- 获取该条目的专题列表(如果为空则默认为空表)
        local banners = bannersMap[article] or {}
        local isMatch = false
        local matchedBanner = ""
        
        -- 遍历该条目所属的所有专题
        for _, banner in ipairs(banners) do
            -- 遍历用户提供的所有搜索模式
            for _, pattern in ipairs(patterns) do
                -- 使用 Lua 的 find 进行匹配 (支持正则)
                if string.find(banner, pattern) then
                    isMatch = true
                    matchedBanner = banner -- 记录匹配到的专题名,用于展示
                    break
                end
            end
            if isMatch then break end
        end
        
        if isMatch then
            table.insert(results, { title = article, banner = matchedBanner })
        end
    end

    -- 6. 格式化输出
    if #results == 0 then
        return "找不到属于指定专题(" .. table.concat(patterns, "、") .. ")的条目。"
    end

    local output = {}
    for _, item in ipairs(results) do
        -- 输出格式:* [[条目名]] <small>(匹配专题:XX专题)</small>
        local line = "* [[:" .. item.title .. "]] <small>(匹配专题:" .. item.banner .. ")</small>"
        table.insert(output, line)
    end

    return table.concat(output, "\n")
end

return p