模組:DYK status/sandbox
外观
![]() | 这是Module:DYK status(差异)的沙盒。 |
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