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