跳转到内容

模組:Selected recent additions

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

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

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

-- MODIFIED: 清理维基文本以便进行模式匹配
-- 使用 frame:preprocess 处理字词转换 -{...}-,并移除HTML标签
function cleanForPatternMatching(frame, wikitext)
	-- 预处理维基文本,这将解析模板、-{...}-转换等
	local cleaned = frame:preprocess(wikitext)

	-- 移除预处理后可能产生的HTML标签 (例如 <p>, <a>, <span>, <b>)
	-- CORRECTED: Changed mw.text.removehtml to mw.text.stripAllHtml
	cleaned = mw.text.stripAllHtml(cleaned) 

	-- 解码可能残留的HTML实体 (例如 &amp; 转换为 &)
	cleaned = mw.text.decode(cleaned)

	-- 将多个连续空格替换为单个空格
	cleaned = mw.ustring.gsub(cleaned, "%s+", " ")

	-- 去除首尾空格
	cleaned = mw.ustring.match(cleaned, "^%s*(.-)%s*$")
	
	return cleaned or "" -- 确保返回字符串
end

-- 创建一个可折叠的区块
function makeCollapsed(outerText, innerText)
	return "{{Hidden begin | titlestyle = font-weight:normal | title = " .. outerText .. "}}" .. innerText .. "{{Hidden end}}"
end

-- getRecentAdditions现在接收frame对象
function getRecentAdditions(frame, subpagePath, keepPatterns, skipPatterns, showWikitext)
	local title = mw.title.new('Wikipedia:新条目推荐/存档' .. subpagePath)
	if not title or not title.exists then
		return {} 
	end
	local raw = title:getContent()
	if not raw then
		return {}
	end

	local itemPattern = '%* [^\n]+' 
	local items = {}

	for itemLine in mw.ustring.gmatch(raw, itemPattern) do
		local keep = false
		local skip = false
		
		local textToSearch = cleanForPatternMatching(frame, itemLine)

		if #keepPatterns == 0 then 
			keep = true
		else
			for _, keepPatt in pairs(keepPatterns) do
				if not keep and mw.ustring.find(textToSearch, keepPatt, 1, true) then 
					keep = true
				end
			end
		end

		if #skipPatterns > 0 then
			for _, skipPatt in pairs(skipPatterns) do
				if not skip and mw.ustring.find(textToSearch, skipPatt, 1, true) then 
					skip = true			
				end
			end
		end
		
		if keep and not skip then
			local cleanItem = itemLine 
			if showWikitext then
				local itemWikitextStripped = mw.ustring.gsub(cleanItem, "%<%!%-%-(.-)%-%-%>", "")
				local itemWikitextForDisplay = "<pre>" .. mw.text.nowiki(itemWikitextStripped) .. "</pre>"
				local displayTitleForCollapsed = mw.text.truncate(mw.ustring.gsub(itemWikitextStripped, "^%*%s*", ""), 100, "...")
				cleanItem = makeCollapsed(displayTitleForCollapsed, itemWikitextForDisplay)
			end
			table.insert(items, cleanItem)
		end
	end
	return items
end

-- getItems现在接收frame对象
function getItems(frame, maxMonths, patterns, skipPatterns, showWikitext)
	local allItems = {}
	local lang = mw.language.getContentLanguage() 
	
	local currentYear = tonumber(lang:formatDate('Y', 'now'))
	local currentMonth = tonumber(lang:formatDate('n', 'now'))
	
	local monthsSearched = 0 
	local monthsToTry = 0 
	local maxArchiveAge = math.max(maxMonths, 60) 

	while monthsSearched < maxMonths and monthsToTry < maxArchiveAge do
		local yearToFetch = currentYear
		local monthToFetch = currentMonth - monthsToTry 

		while monthToFetch <= 0 do
			monthToFetch = monthToFetch + 12
			yearToFetch = yearToFetch - 1
		end
		
		local subpagePath = '/' .. yearToFetch .. '年' .. monthToFetch .. '月'
		
		local monthlyItems = getRecentAdditions(frame, subpagePath, patterns, skipPatterns, showWikitext)
		if #monthlyItems > 0 then
			for _, item in ipairs(monthlyItems) do
				table.insert(allItems, item)
			end
			monthsSearched = monthsSearched + 1 
		end
		monthsToTry = monthsToTry + 1
	end
	return allItems
end

-- 简化 getPatterns 函数
function getPatterns(args, prefix)
	local patterns = {}
	local i = 1
	local key
	while true do
		key = prefix and (prefix .. i) or tostring(i)
		if args[key] then
			patterns[i] = args[key] 
		else
			break 
		end
		i = i + 1
	end
	return patterns
end

local p = {}

p.main = function(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']
		args['not'] = nil 
	end
	
	local patterns = getPatterns(args) 
	local skipPatterns = getPatterns(args, 'not') 

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

	local allItems = getItems(frame, months, patterns, skipPatterns, showWikitext)
	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:新条目推荐|更多新条目推荐……]]'''"
	elseif type(more) == 'string' and more ~= '' then
		more = "\n" .. more
	else
		more = nil 
	end

	local notRandom = isAffirmed(args.latest) 
	local output = makeOutput(allItems, maxItems, more, notRandom)

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

return p