跳转到内容

模組:Selected recent additions

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

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

local randomModule = require('Module:Random')

function cleanupArgs(argsTable)
	local cleanArgs = {}
	for key, val in pairs(argsTable) do
		if type(val) == 'string' then
			val = val:match('^%s*(.-)%s*$')
			if val ~= '' then
				cleanArgs[key] = val
			end
		else
			cleanArgs[key] = val
		end
	end
	return cleanArgs
end

function isAffirmed(val)
	if not(val) then return false end
	local affirmedWords = ' add added affirm affirmed include included on true yes y '
	return string.find(affirmedWords, ' '..string.lower(val)..' ', 1, true ) and true or false
end

function makeOutput(allItems, maxItems, more, notRandom)
	local output
	if notRandom then
		output = ''
		local itemIndex = 1
		local maxCount = math.min(#allItems, maxItems)
		while itemIndex <= maxCount do
			output = output .. allItems[itemIndex] .. '\n'
			itemIndex = itemIndex + 1
		end
	else
		local randomiseArgs = {
			['t'] = allItems,
			['limit'] = maxItems
		}
		local randomisedItems = randomModule.main('array', randomiseArgs )
		output = table.concat(randomisedItems, '\n')
	end
	if more then
		output = output .. more
	end
	return mw.text.trim(output)
end

-- 清理维基文本以便进行模式匹配
-- frame 参数用于在 mw.language.convert 不可用时回退到 frame:preprocess
function cleanForPatternMatching(wikitext, frame)
	local textForConversion = wikitext
	
	-- 步骤1: 预先移除维基链接和外部链接的括号结构,但保留其内部文本
	-- 这使得后续的字词转换或预处理作用于链接的“纯文本”内容
	-- 例如, "[[链接文本|-{zh-cn:变体; zh-tw:變體;}-]]" 变为 "链接文本|-{zh-cn:变体; zh-tw:變體;}-"
	textForConversion = mw.ustring.gsub(textForConversion, "%[%[(.-)%]%]","%1")
	textForConversion = mw.ustring.gsub(textForConversion, "%[.-%]"," ") -- 移除外部链接,替换为空格

	-- 步骤2: 进行字词转换
	local convertedText
	-- 优先尝试 mw.language.convert,如果它存在且是一个函数
	if mw.language and type(mw.language.convert) == "function" then
		convertedText = mw.language.convert(textForConversion)
	-- 如果 mw.language.convert 不可用,并且 frame 对象存在,则使用 frame:preprocess 作为备选方案
	-- frame:preprocess 会解析文本中的字词转换标记以及其他维基代码
	elseif frame and type(frame.preprocess) == "function" then
		convertedText = frame:preprocess(textForConversion)
	else
		-- 如果两种方法都不可用,则不进行字词转换
		convertedText = textForConversion
	end

	-- 步骤3: 移除在步骤1中可能从管道链接中遗留下来的管道符
	-- 例如, "链接文本|变体" 变为 "链接文本变体"
	local cleaned = mw.ustring.gsub(convertedText, "%|","")
	
	return cleaned
end

function makeCollapsed(outerText, innerText)
	return "{{Hidden begin | titlestyle = font-weight:normal | title = " .. outerText .. "}}" .. innerText .. "{{Hidden end}}"
end

-- 获取指定日期子页面的新条目推荐项目。返回一个列表项的表。
-- 添加 frame 参数以传递给 cleanForPatternMatching
function getRecentAdditions(subpage, keepPatterns, skipPatterns, showWikitext, frame)
	-- 中文维基百科的新条目推荐存档路径
	local title = mw.title.new('Wikipedia:新条目推荐/存档' .. subpage)
	if not title or not title.exists then -- 检查页面是否存在
		return {}
	end
	local raw = title:getContent()
	if not raw then return {} end -- 如果页面内容为空则返回

	local items = {}
	local lines = mw.text.split(raw, '\n')

	for _, line in ipairs(lines) do
		if mw.ustring.match(line, '^%*%s*') then
			local item = line 
			local keep = false
			local skip = false
			
			-- 使用 cleanForPatternMatching 清理后的文本进行匹配,传递 frame 对象
			local textToMatch = cleanForPatternMatching(item, frame)

			for _, keepPatt in pairs(keepPatterns) do
				if not keep and mw.ustring.find(textToMatch, keepPatt, 1, false) then 
					keep = true
				end
			end

			if #skipPatterns > 0 then
				for _, skipPatt in pairs(skipPatterns) do
					if not skip and mw.ustring.find(textToMatch, skipPatt, 1, false) then
						skip = true			
					end
				end
			end
			
			if keep and not skip then
				local cleanItem = item 
				
				if showWikitext then
					local tempCleanItem = mw.ustring.gsub(cleanItem, "%<%!%-%-(.-)%-%-%>", "")
					local itemWikitext = "<pre>" .. mw.text.nowiki( tempCleanItem ) .. "</pre>"
					cleanItem = makeCollapsed(tempCleanItem, itemWikitext)
				end
				table.insert(items, cleanItem)
			end
		end
	end
	return items
end

-- 获取过去数个月的新条目推荐项目
-- 添加 frame 参数以传递给 getRecentAdditions
function getItems(maxMonths, patterns, skipPatterns, showWikitext, frame)
	local allItems = {}
	local lang = mw.getContentLanguage() 
	local currentYear  = tonumber(lang:formatDate('Y', 'now'))
	local currentMonth = tonumber(lang:formatDate('n', 'now'))
	local monthsAgo = 0

	while monthsAgo < maxMonths do
		local yearToFetch = currentYear
		local monthToFetch = currentMonth - monthsAgo
		
		while monthToFetch <= 0 do
			monthToFetch = monthToFetch + 12
			yearToFetch = yearToFetch - 1
		end
		
		local subpage = '/' .. yearToFetch .. '年' .. monthToFetch .. '月'
		
		-- 调用 getRecentAdditions 时传递 frame 对象
		local monthlyItems = getRecentAdditions(subpage, patterns, skipPatterns, showWikitext, frame)
		for i, item in ipairs(monthlyItems) do
			table.insert(allItems, item)
		end
		monthsAgo = monthsAgo + 1
	end
	return allItems
end

function getPatterns(args, prefix)
	local patterns = {}
	local ii = 1
	while args[prefix and prefix..ii or ii] do
		patterns[ii] = args[prefix and prefix..ii or ii]
		ii = ii + 1
	end
	return patterns
end

local p = {}

p.main = function(frame) -- frame 对象从这里开始获取
	local parent = frame:getParent()
	local parentArgs = parent.args
	local args = cleanupArgs(parentArgs)

	if args['not'] and not args['not1'] then
		args['not1'] = args['not']
	end
	
	local patterns = getPatterns(args)
	if #patterns < 1 then
		return error("未设定搜索模式(缺少编号参数如 `|1=模式`)")
	end

	local skipPatterns = getPatterns(args, 'not')

	local months = tonumber(args.months) or 30
	
	local showWikitext = isAffirmed(args.wikitext)

	-- 调用 getItems 时传递 frame 对象
	local allItems = getItems(months, patterns, skipPatterns, showWikitext, frame)
	if #allItems < 1 then
		return args.header and '' or args.none or '未找到符合条件的新条目推荐'
	end

	local maxItems = tonumber(args.max) or 6

	local more = args.more
	if isAffirmed(args.more) then
		more = "\n'''[[Wikipedia:新条目推荐/存档|更多以往推荐...]]'''"
	end

	local nonRandom = isAffirmed(args.latest)

	local output = makeOutput(allItems, maxItems, more, nonRandom)
	if args.header then
		output = args.header .. '\n' .. output .. '\n' .. (args.footer or '{{Box-footer}}')
	end
	local needsExpansion = mw.ustring.find(output, '{{', 1, true)	
	if needsExpansion then
		return frame:preprocess(output)
	else 
		return output
	end
end

return p