跳转到内容

模組:DYK status/sandbox

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

这是本页的一个历史版本,由PexEric留言 | 贡献2025年4月5日 (六) 04:08 建立内容为“local p = {} local ustring = mw.ustring local title = mw.title local text = mw.text --[[========================================================================= = = = Helper function to find the content of the first balanced template call = = matching a pattern. Handles nested templates. = =…”的新页面)编辑。这可能和当前版本存在着巨大的差异。

(差异) ←上一修订 | 最后版本 (差异) | 下一修订→ (差异)
local p = {}

local ustring = mw.ustring
local title = mw.title
local text = mw.text

--[[=========================================================================
=                                                                          =
= Helper function to find the content of the first balanced template call  =
= matching a pattern. Handles nested templates.                            =
=                                                                          =
===========================================================================]]
local function findFirstBalancedTemplateBlock(content, startPattern)
    local s, e, _, delimCap = ustring.find(content, 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
    elseif delimCap and delimCap == '}' then
         searchPos = e -1
    else
         searchPos = e
    end

    local level = 2 -- Start inside the initial {{
    while searchPos < #content do
        local nextOpen = ustring.find(content, "%{%{", searchPos, true)
        local nextClose = ustring.find(content, "%}%}", searchPos, true)

        if not nextClose then return nil end -- Unbalanced

        if nextOpen and nextOpen < nextClose then
            level = level + 1
            searchPos = nextOpen + 2
        else
            level = level - 1
            if level == 0 then
                local blockEnd = nextClose + 1
                return ustring.sub(content, blockStart, blockEnd)
            end
            searchPos = nextClose + 2
        end
    end
    return nil -- Unbalanced
end


--[[=========================================================================
=                                                                          =
= Main function to check DYK status                                        =
=                                                                          =
===========================================================================]]
function p.checkDYK(frame)
    local pageTitleStr = frame.args[1]
    if not pageTitleStr or pageTitleStr == '' then
        return nil
    end

    local titleObj = title.new(pageTitleStr)
    if not titleObj then return nil end

    local talkTitleObj = titleObj.talkPageTitle
    if not talkTitleObj then return nil end

    local content = talkTitleObj:getContent()
    if not content then return nil end

    local lowerContent = ustring.lower(content)

    --[[-------------------------------------------------------------------------
    - 1. 检查候选状态 (DYK_Invite / DYKC / DYKN)                             -
    --------------------------------------------------------------------------]]
    local invitePatternBase = "(dyk[_ ]invite|dykinvite|dykc|dykn)"
    local invitePattern = "%{%{%s*" .. invitePatternBase .. "%s*[|%}]"
    if ustring.find(lowerContent, invitePattern) then
        return "candidate"
    end

    --[[-------------------------------------------------------------------------
    - 2. 检查通过/失败状态 (DYKEntry/archive)                                  -
    --------------------------------------------------------------------------]]
    local archivePatternBase = "(dykentry/archive|newdyknomination/archive)"
    local archivePatternStart = "%{%{%s*" .. archivePatternBase .. "%s*([|%}])"
    local archiveTemplateBlock = findFirstBalancedTemplateBlock(lowerContent, archivePatternStart)

    if archiveTemplateBlock then
        -- 尝试提取参数部分 (从第一个'|'到最后'}'之前的部分)
        local firstPipePos = ustring.find(archiveTemplateBlock, "|", 1, true)
        if firstPipePos then
            -- 参数字符串 = 第一个'|'之后到倒数第二个字符 (排除最后两个 '}}')
            local paramsPart = ustring.sub(archiveTemplateBlock, firstPipePos + 1, -3)
            local failed = false
            -- 使用gsplit迭代处理由'|'分隔的参数段
            for paramSegment in text.gsplit(paramsPart, "|") do
                -- 对每个参数段进行修剪并尝试匹配 'key = value' 格式
                local key, value = ustring.match(text.trim(paramSegment), "^([^=]+)=(.*)$")
                if key then
                    key = text.trim(key)
                    value = text.trim(value)
                    -- 检查result参数是否为失败标记
                    if key == 'result' and (value == '-' or value == '!') then
                        failed = true
                        break -- 找到失败标记,停止检查
                    end
                end
            end

            if failed then
                return "no"
            else
                return "yes"
            end
        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
        local firstPipePos = ustring.find(historyTemplateBlock, "|", 1, true)
        if firstPipePos then
            local paramsPart = ustring.sub(historyTemplateBlock, firstPipePos + 1, -3)
            local foundDykParam = false
            -- 使用gsplit迭代处理参数段
            for paramSegment in text.gsplit(paramsPart, "|") do
                local key, value = ustring.match(text.trim(paramSegment), "^([^=]+)=(.*)$")
                if key then
                    key = text.trim(key)
                    -- 检查参数名是否匹配 dyk<数字?>date 或 dyk<数字?>entry
                    if ustring.match(key, "^dyk%d*date$") or ustring.match(key, "^dyk%d*entry$") then
                        foundDykParam = true
                        break
                    end
                end
            end

            if foundDykParam then
                return "yes"
            end
        end
    end

    --[[-------------------------------------------------------------------------
    - 4. 默认/未知状态                                                          -
    --------------------------------------------------------------------------]]
    return nil
end

return p