模組:沙盒/PexEric/1
外观
local p = {}
-- Dependency modules
local TPV -- Lazily loaded: require('Module:Template parameter value')
local Args -- Lazily loaded: require('Module:Arguments')
local PatternedCandidateUtils -- Not required as a module, invoked via parser function
-- Configuration for different content review types
-- These settings are derived from your examples.
local candidateConfigs = {
DYKC = {
pageTitle = "Wikipedia:新条目推荐/候选",
pattern = "%{{!}}%s*article%s*=%s*(.-)%s*[%}%{{!}}]",
linkprefix = "Wikipedia:新条目推荐/候选#",
-- No black or blackregex specified in example, can be added if needed
},
PR = {
pageTitle = "Wikipedia:同行评审/提案区",
pattern = "====%s*(.-)%s*===",
linkprefix = "Wikipedia:同行评审#",
postProcessInvoke = { -- For #invoke:String|replace
module = "String",
func = "replace",
args = { -- source is added dynamically
pattern = "-%[%[:Wikipedia:同行评审#=+.-{{!}}=+.-%]%]",
plain = "false"
}
}
},
GAC = {
pageTitle = "Wikipedia:優良條目評選/提名區",
pattern = "====%s*(.-)%s*===%f[^=]",
blackregex = "==%s*(.-)%s*=",
linkprefix = "Wikipedia:優良條目評選#"
},
FAC = {
pageTitle = "Wikipedia:典范条目评选/提名区",
pattern = "====%s*(.-)%s*===%f[^=]",
blackregex = "==%s*(.-)%s*=",
linkprefix = "Wikipedia:典范条目评选#",
postProcessInvoke = {
module = "String",
func = "replace",
args = {
pattern = "-%[%[:Wikipedia:典范条目评选#=+.-{{!}}=+.-%]%]",
plain = "false"
}
}
},
FLC = {
pageTitle = "Wikipedia:特色列表评选/提名区",
pattern = "====%s*(.-)%s*===%f[^=]",
blackregex = "==%s*(.-)%s*=",
linkprefix = "Wikipedia:特色列表评选#"
},
ITNC = {
pageTitle = "Wikipedia:新闻动态候选",
pattern = "%{{!}}%s*article%s*=%s*(.-)%s%{{!}}",
linkprefix = "Wikipedia:新闻动态候选#"
}
}
-- WikiProject Banner Shell and its redirects (as Lua patterns)
-- These need to be Lua patterns compatible with string.match and TPV's treat_as_regex
local wpbs_redirect_patterns = {
"wiki%s*project%s*banner%s*shell",
"w?pj?%s*banner%s*shell",
"wiki%s*project%s*banners",
"multiple%s*wikiprojects?",
"wiki%s*project%s*shell",
"pjbs",
"[維维]基[专專][题題][橫横]幅",
"多?[個个]?[維维]?基?[专專][题題][橫横]幅",
"[維维]基[专專][题題]",
"多?[個个]?[維维]?基?[专專][题題]",
"[专專][题題][橫横]幅",
"通用[評评][級级]",
}
-- Helper function to get candidate titles from a review page
-- reviewType: string key from candidateConfigs (e.g., "DYKC")
-- frame: the current Scribunto frame
local function getCandidatePageTitles(reviewType, frame)
local config = candidateConfigs[reviewType]
if not config then
return {}, "未知的内容评选类型: " .. tostring(reviewType)
end
local pcu_args = {
title = config.pageTitle,
pattern = config.pattern
-- linkprefix is handled by PCU, we extract titles from its output
}
if config.linkprefix then pcu_args.linkprefix = config.linkprefix end
if config.black then pcu_args.black = config.black end
if config.blackregex then pcu_args.blackregex = config.blackregex end
-- Build arguments for #invoke:PatternedCandidateUtils|list
local invoke_pcu_table_args = {'PatternedCandidateUtils', 'list'}
for k, v in pairs(pcu_args) do
table.insert(invoke_pcu_table_args, k .. '=' .. v)
end
local raw_output = frame:callParserFunction{
name = '#invoke',
args = invoke_pcu_table_args
}
-- Apply post-processing if configured (e.g., for PR, FAC)
if config.postProcessInvoke then
local string_replace_args = {
config.postProcessInvoke.module,
config.postProcessInvoke.func,
source = raw_output
}
for k, v in pairs(config.postProcessInvoke.args) do
table.insert(string_replace_args, k .. '=' .. v)
end
raw_output = frame:callParserFunction{
name = '#invoke',
args = string_replace_args
}
end
if raw_output == '暂无' or raw_output == '' then
return {}
end
local titles = {}
-- PatternedCandidateUtils|list outputs links like [[Prefix#Page Title|Page Title]]
-- We need to extract the "Page Title" part.
-- The gmatch pattern captures the text *after* the pipe if a pipe exists,
-- or the whole link target if no pipe (though PCU usually adds a pipe).
-- This regex assumes the link format from PCU.
-- The display text (second part of [[L|D]]) is what we want.
for display_text in mw.ustring.gmatch(raw_output, "%[%[[^%]|]+%|(.-)%]%]") do
table.insert(titles, display_text)
end
-- Fallback if the above gmatch fails (e.g. if PCU changes its output format slightly
-- or if there are links without pipes, though less likely for PCU list output)
if #titles == 0 and raw_output ~= '暂无' and raw_output ~= '' then
-- This alternative tries to get the article title from the link target directly if linkprefix was used
local linkPrefixPattern = config.linkprefix and mw.ustring.gsub(config.linkprefix, "[%(%)%.%+%-%*%?%[%]%^%$%%]", "%%%0") or ""
if linkPrefixPattern ~= "" then
for article_part in mw.ustring.gmatch(raw_output, "%[%[" .. linkPrefixPattern .. "([^%]|]+)") do
table.insert(titles, mw.ustring.gsub(article_part, "_", " "))
end
end
-- If still no titles, it might be a simpler list, try a broader match
if #titles == 0 then
for display_text in mw.ustring.gmatch(raw_output, "%[%[%s*(.-)%s*%]%]") do
local clean_title = mw.ustring.match(display_text, "^[^|]+$") or mw.ustring.match(display_text, ".-|(.*)")
if clean_title then
table.insert(titles, clean_title)
end
end
end
end
return titles
end
-- Helper function to get WikiProject names from an article's talk page
-- articleTitle: string, the title of the article (not the talk page)
local function getProjectsForArticle(articleTitle)
if not TPV then TPV = require('Module:Template parameter value') end
local talkPageTitleObj = mw.title.new(articleTitle, 'Talk')
if not talkPageTitleObj or not talkPageTitleObj.exists then
return {} -- Talk page doesn't exist
end
local talkPageTitle = talkPageTitleObj.prefixedText
-- Try to get the content of the first unnamed parameter of WikiProject banner shell (or its redirects)
local success, param1_content = TPV.getParameter(
talkPageTitle,
wpbs_redirect_patterns, -- Table of regex patterns for template names
"1", -- Parameter name "1"
{ treat_as_regex = true } -- Tell TPV that `wpbs_redirect_patterns` contains regexes
)
if not success or not param1_content or param1_content == "" then
return {} -- Template not found, or parameter 1 is empty
end
local projects = {}
-- Extract template names from the parameter content
-- Matches {{Template Name ...}} or {{Template Name}}
-- Captures "Template Name"
for tmpl_name in mw.ustring.gmatch(param1_content, "{{%s*([^}|%s][^}|]*)") do
-- Trim whitespace just in case, though the pattern is quite specific
local cleaned_name = mw.text.trim(tmpl_name)
if cleaned_name ~= "" then
table.insert(projects, cleaned_name)
end
end
return projects
end
--[[
Function 1: listProjects
Lists all candidate items for a specific content review and their associated WikiProjects in a table.
Parameters from frame:
args[1] or args.type: The type of content review (e.g., "DYKC", "GAC"). Required.
args.prefix: Wikitext to prepend to each article name. Default: "".
args.suffix: Wikitext to append to each article name. Default: "".
args.tpl_prefix: Wikitext to prepend to each project template name. Default: "{{tl|".
args.tpl_suffix: Wikitext to append to each project template name. Default: "}}".
--]]
function p.listProjects(frame)
local args = frame.args
local reviewType = args[1] or args.type
if not reviewType then
return "<span class=\"error\">错误:未指定内容评选类型 (例如 DYKC, GAC)。</span>"
end
local article_prefix = args.prefix or ""
local article_suffix = args.suffix or ""
local tpl_prefix = args.tpl_prefix -- No default here, will check nil later
local tpl_suffix = args.tpl_suffix -- No default here
-- Set default template wrappers if not provided or empty
if tpl_prefix == nil or tpl_prefix == "" then tpl_prefix = "{{tl|" end
if tpl_suffix == nil or tpl_suffix == "" then tpl_suffix = "}}" end
local candidateTitles, err = getCandidatePageTitles(reviewType, frame)
if err then return "<span class=\"error\">获取候选项目失败:" .. err .. "</span>" end
if #candidateTitles == 0 then
return "指定的评选栏目下目前没有候选项目。"
end
local output = {}
table.insert(output, '{| class="wikitable sortable"')
table.insert(output, '! 条目 !! 所属专题')
for _, title in ipairs(candidateTitles) do
local projects = getProjectsForArticle(title)
local formattedProjects = {}
if #projects > 0 then
for _, projName in ipairs(projects) do
table.insert(formattedProjects, tpl_prefix .. projName .. tpl_suffix)
end
table.insert(output, "|-\n| " .. article_prefix .. title .. article_suffix ..
" || " .. table.concat(formattedProjects, "、"))
else
table.insert(output, "|-\n| " .. article_prefix .. title .. article_suffix ..
" || ''暂无专题或未能获取''")
end
end
table.insert(output, "|}")
return table.concat(output, "\n")
end
--[[
Function 2: listCandidatesByProject
Lists candidate items from a specific content review that belong to one or more given WikiProjects.
Parameters from frame:
args[1] or args.type: The type of content review (e.g., "DYKC", "GAC"). Required.
args.prefix: Wikitext to prepend to each article name. Default: "".
args.suffix: Wikitext to append to each article name. Default: "".
args.project1, args.project2, ...: Regex patterns for WikiProject names. At least one is required.
--]]
function p.listCandidatesByProject(frame)
if not Args then Args = require('Module:Arguments') end
local allArgs = Args.getArgs(frame) -- Use Module:Arguments for easier access to projectN
local reviewType = allArgs[1] or allArgs.type
if not reviewType then
return "<span class=\"error\">错误:未指定内容评选类型 (例如 DYKC, GAC)。</span>"
end
local article_prefix = allArgs.prefix or ""
local article_suffix = allArgs.suffix or ""
local project_patterns = {}
local i = 1
while true do
local proj_pattern = allArgs['project' .. i]
if proj_pattern then
table.insert(project_patterns, proj_pattern)
else
break
end
i = i + 1
end
if #project_patterns == 0 then
return "<span class=\"error\">错误:至少需要指定一个专题匹配模式 (project1, project2, ...)。</span>"
end
local candidateTitles, err = getCandidatePageTitles(reviewType, frame)
if err then return "<span class=\"error\">获取候选项目失败:" .. err .. "</span>" end
if #candidateTitles == 0 then
return "指定的评选栏目下目前没有候选项目。"
end
local matched_candidates_output = {}
for _, title in ipairs(candidateTitles) do
local articleProjects = getProjectsForArticle(title)
local match_found = false
if #articleProjects > 0 then
for _, projName in ipairs(articleProjects) do
for _, pattern in ipairs(project_patterns) do
if mw.ustring.match(projName, pattern) then
match_found = true
break -- Found a match for this article, no need to check other patterns for this project
end
end
if match_found then
break -- No need to check other projects for this article
end
end
end
if match_found then
table.insert(matched_candidates_output, article_prefix .. title .. article_suffix)
end
end
if #matched_candidates_output == 0 then
return "没有找到符合指定专题条件的候选项目。"
else
return "# " .. table.concat(matched_candidates_output, "\n# ")
end
end
return p