跳转到内容

模組:DYK status/sandbox

维基百科,自由的百科全书

这是本页的一个历史版本,由PexEric留言 | 贡献2025年4月5日 (六) 04:10编辑。这可能和当前版本存在着巨大的差异。

local p = {}

--[[=========================================================================
=                                                                          =
= Helper function to find the content of the first balanced template call  =
= matching a pattern. Handles nested templates.                            =
=                                                                          =
===========================================================================]]
local function findFirstBalancedTemplateBlock(text, startPattern)
    local s, e, _, delimCap = mw.ustring.find(text, startPattern)
    if not s then
        return nil -- Pattern not found
    end

    local blockStart = s
    local searchPos = e
    -- Adjust starting search position slightly based on match
    if delimCap and delimCap == '|' then
        searchPos = e -- Start search right after the pipe
    elseif delimCap and delimCap == '}' then
         searchPos = e -1 -- Start search right after the first brace of }}
    else
         searchPos = e -- Default starting point
    end


    local level = 2 -- Start inside the initial {{
    while searchPos < #text do
        -- Find the next opening or closing brace pair
        local nextOpen = mw.ustring.find(text, "%{%{", searchPos, true)
        local nextClose = mw.ustring.find(text, "%}%}", searchPos, true)

        -- If no more closing braces, the structure is broken/incomplete
        if not nextClose then
            return nil -- Or perhaps return the substring found so far? For this purpose, nil is safer.
        end

        -- If an opening brace comes first, increase nesting level
        if nextOpen and nextOpen < nextClose then
            level = level + 1
            searchPos = nextOpen + 2 -- Move past the '{{'
        else
            -- Otherwise, a closing brace comes first (or no more opening braces)
            level = level - 1
            -- If level reaches 0, we found the matching closing brace
            if level == 0 then
                local blockEnd = nextClose + 1 -- Position *after* the '}}'
                return mw.ustring.sub(text, blockStart, blockEnd)
            end
            searchPos = nextClose + 2 -- Move past the '}}'
        end
    end

    return nil -- Reached end of text without finding the balanced closing brace
end


--[[=========================================================================
=                                                                          =
= Main function to check DYK status                                        =
=                                                                          =
===========================================================================]]
function p.checkDYK(frame)
    -- 获取匿名参数一作为页面标题
    local pageTitleStr = frame.args[1]
    if not pageTitleStr or pageTitleStr == '' then
        -- mw.log("DYKCheck: Missing page title argument.") -- Optional logging
        return nil -- 如果没有提供页面标题,返回nil
    end

    -- 创建主页面标题对象
    local titleObj = mw.title.new(pageTitleStr)
    if not titleObj then
        -- mw.log("DYKCheck: Could not create title object for: " .. pageTitleStr)
        return nil -- 无法创建标题对象
    end

    -- 获取讨论页标题对象
    local talkTitleObj = titleObj.talkPageTitle
    if not talkTitleObj then
        -- mw.log("DYKCheck: Could not get talk page title for: " .. pageTitleStr)
        return nil -- 无法获取讨论页标题
    end

    -- 获取讨论页内容
    -- Note: getContent() follows redirects by default.
    local content = talkTitleObj:getContent()
    if not content then
        -- mw.log("DYKCheck: Talk page does not exist or is empty for: " .. pageTitleStr)
        return nil -- 讨论页不存在或为空
    end

    -- 将内容转换为小写以便进行不区分大小写的匹配
    local lowerContent = mw.ustring.lower(content)

    --[[-------------------------------------------------------------------------
    - 1. 检查候选状态 (DYK_Invite / DYKC / DYKN)                             -
    --------------------------------------------------------------------------]]
    -- 模板名称(小写,包含重定向,用[_ ]处理空格/下划线)
    local invitePatternBase = "(dyk[_ ]invite|dykinvite|dykc|dykn)"
    -- 完整匹配模式:{{ + 可选空格 + 模板名 + 可选空格 + | 或 }}
    local invitePattern = "%{%{%s*" .. invitePatternBase .. "%s*[|%}]"
    if mw.ustring.find(lowerContent, invitePattern) then
        return "candidate"
    end

    --[[-------------------------------------------------------------------------
    - 2. 检查通过/失败状态 (DYKEntry/archive)                                  -
    --------------------------------------------------------------------------]]
    -- 模板名称(小写,包含重定向)
    local archivePatternBase = "(dykentry/archive|newdyknomination/archive)"
    -- 查找模板开始的模式,捕获名称后的第一个字符(| 或 })以帮助 findFirstBalancedTemplateBlock
    local archivePatternStart = "%{%{%s*" .. archivePatternBase .. "%s*([|%}])"
    -- 查找第一个匹配此模式的完整模板块
    local archiveTemplateBlock = findFirstBalancedTemplateBlock(lowerContent, archivePatternStart)

    if archiveTemplateBlock then
        -- 在找到的模板块内查找 result 参数是否为失败标记
        -- 模式: | + 可选空格 + result + 可选空格 + = + 可选空格 + (- 或 !) + 可选空格 + | 或 }}
        local failPattern = "|%s*result%s*=%s*([-!])%s*[|%}]"
        if mw.ustring.find(archiveTemplateBlock, failPattern) then
            return "no" -- 找到失败标记
        else
            return "yes" -- 找到模板但未找到失败标记,视为通过
        end
    end

    --[[-------------------------------------------------------------------------
    - 3. 检查通过/失败状态 (Article history) - 作为后备方案                   -
    --------------------------------------------------------------------------]]
    -- 模板名称(小写,包含重定向)
    local historyPatternBase = "(article[_ ]history)"
    -- 查找模板开始的模式
    local historyPatternStart = "%{%{%s*" .. historyPatternBase .. "%s*([|%}])"
    -- 查找第一个匹配此模式的完整模板块
    local historyTemplateBlock = findFirstBalancedTemplateBlock(lowerContent, historyPatternStart)

    if historyTemplateBlock then
        -- 在找到的模板块内查找是否存在 dykNdate 或 dykNentry 参数 (N为数字或不存在)
        -- 模式: | + 可选空格 + dyk + 可选数字 + date/entry + 可选空格 + =
        local dykDateParamPattern = "|%s*dyk(%d*)date%s*="
        local dykEntryParamPattern = "|%s*dyk(%d*)entry%s*="

        if mw.ustring.find(historyTemplateBlock, dykDateParamPattern) or mw.ustring.find(historyTemplateBlock, dykEntryParamPattern) then
            return "yes" -- 找到表明曾通过DYK的参数
        end
        -- 如果找到了 Article history 模板,但没有找到相关的 dyk 参数,则不由此模板判断状态,继续向下。
    end

    --[[-------------------------------------------------------------------------
    - 4. 默认/未知状态                                                          -
    --------------------------------------------------------------------------]]
    -- 如果以上检查都没有返回结果,则返回 nil
    return nil
end

return p