跳转到内容

Module:PJBSClass/main:修订间差异

维基百科,自由的百科全书
删除的内容 添加的内容
无编辑摘要
第265行: 第265行:
if not mw.title.equals(subject_page or "", mw.title.getCurrentTitle()) then
if not mw.title.equals(subject_page or "", mw.title.getCurrentTitle()) then
--頭尾限400字,以節省效能
--頭尾限400字,以節省效能
local check_body = (body_len > 400) and (mw.ustring.sub(body, 1, 200)..mw.ustring.sub(body, -200, -1)) or body
local check_body = (body_len > 400) and (mw.ustring.sub(body, 1, 200)..mw.ustring.sub(body, -200, -1)) or body
local check_body = remove_wikiproject_flag(check_body) --避免模板循環
local check_body = remove_wikiproject_flag(check_body) --避免模板循環
if mw.ustring.match(mw.getCurrentFrame():preprocess(check_body.."{{reflist}}")
if mw.ustring.match(mw.getCurrentFrame():preprocess(check_body.."{{reflist}}")

2024年1月8日 (一) 08:12的版本

local p = {}
local yesno = require('Module:Yesno')
local cat_auto_class = "自動評級的頁面"
local cat_use_user_defined_class = "使用自訂專題評級的條目"
local cat_auto_disambig_class = '自動評級的消歧義級頁面'
local class_normalize = require("Module:Class/convert")._main
local TrackingCategory = require('Module:TrackingCategory')

local function isEmptyString(str) return mw.text.trim(tostring(str or '')) == '' end
--取得欲評級頁面的標題
function p.subjectPageTitle(input_data)
	local page_name = input_data
	local is_lua = true
	if type((input_data or {}).args) ~= type(nil) then --input_data is a frame
		page_name = input_data.args['1'] or input_data.args[1]
		is_lua = false
	end
	local page = (type(page_name) ~= type(nil)) and ({pcall(mw.title.new, page_name)})[2] or mw.title.getCurrentTitle()
	local subject_page = (page or {}).subjectPageTitle
	if is_lua then return subject_page end
	return subject_page.fullText
end

--讀取所在頁面的評級 函數本體
function p._getClass(input_data, _auto_first, _inheritance_first, _demo)
	local class_name = input_data
	local auto_first = _auto_first
	local inheritance_first = _inheritance_first
	local demo = _demo
	if type((input_data or {}).args) ~= type(nil) then --input_data is a frame
		class_name = input_data.args['1'] or input_data.args[1]
		auto_first = yesno(input_data.args.auto)
		inheritance_first = yesno(input_data.args.inheritance)
		demo = yesno(input_data.args.demo)
	end
	--使用一頁只讀取一次的函數,讀取目前頁面中WPBS的評級
	local WPBS_data = mw.loadData("Module:PJBSClass/page")
	local WPBS_class = WPBS_data.class or '' --讀取到的目前頁面中WPBS的評級
	if auto_first or --如果 "自動評級" 優先,或
		(inheritance_first and (isEmptyString(WPBS_class) or WPBS_data.is_auto))  then --"繼承優先" 且{{WPBS}}有值
		--嘗試進行自動判斷評級作業
		local success, auto_class = pcall(p.getClassAuto, nil, (class_name == 'no_input' or class_name == '¬') and '' or class_name, demo)
		if success then --自動判斷評級作業成功
			class_name = (not isEmptyString(auto_class)) and auto_class or class_name
		end
	end
	if class_name ~= nil and --如果並非 "未輸入" 級
		(mw.ustring.lower(class_name or '') ~= 'no_input') and
		(mw.ustring.lower(class_name or '') ~= '¬') 
	then
		--WPBS的級空白就返回輸入的評級
		if mw.text.trim(WPBS_class) == '' then return class_name end
		--找不到WPBS模板也返回輸入的評級
		if not WPBS_data.has_WPBS then return class_name end
		--評級繼承與否判斷作業
		return p.checkClassInput(WPBS_class, class_name)
	end
	return WPBS_class
end

--讀取所在頁面的評級 供呼叫的函數
function p.getClass(input_data)
	local success, result = pcall(p._getClass, input_data)
	if not success then return "" end
	return result
end

--匹配軟重定向模板的正則函數
local function re_softredirect_template(input_text)
	local text = input_text or ""
	local match_list = {--各種軟重定向模板及其重定向匹配表
		--注意:這裡必須全部使用小寫字母
		--{"軟重定向模板正則", 是否允許前方有其他字, 是否後方不能有其他字}
		{"[軟软]重新?[導导定]向",true},
		{"soft[%s_%-]*redirect",true},
		{"sr",false, true},
		{"wikispecies[%s_%-]*redirect",false},
		{"wiki[vs]o[yu][ar][gc]e[%s_%-]*redirect",false},
		{"wiki[bq][ou]o[kt][se]?[%s_%-]*redirect",false},
		{"commons[%s_%-]*redirect",false},
		--如有新種軟重定向模板及其重定向被建立請加入於此
	}--致管理員:如有新種軟重定向模板及其重定向被建立,請優先受理軟重定向模板及其重定向匹配項目的編輯請求
	local black_list = { --不是軟重定向模板的模板名稱匹配表
		"soft[%s-_]*redirect[%s-_]*protection",
	}--致管理員:如有新各種軟重定向模板及其重定向被建立,請優先受理軟重定向模板及其重定向匹配項目的編輯請求
	local lotext = mw.ustring.lower(text..'\n') --以小寫進行匹配
	for i = 1,#match_list do --對每一個軟重定向模板及其重定向進行匹配
		local j, k = mw.ustring.find(lotext, "%{%{"..
			(match_list[i][2] and "[^%}]*" or "%s*")..match_list[i][1]..
			(match_list[i][3] and "[%}%|]*" or "[^%}%|]*")
		)
		if j ~= nil then --匹配到了軟重定向模板或其重定向
			local result = mw.ustring.sub(text, j, k)
			result = mw.ustring.match(result, "%{%{%s*([^%}%|]+)$") --讀取匹配到的名稱
			if result then
				local is_redirect = true
				for i1 = 1,#black_list do --檢查是否在黑名單中
					if mw.ustring.match(mw.ustring.lower(result), black_list[i1]) then
						is_redirect = false --如果不是
						break
					end
				end
				if is_redirect then --是軟重定向模板,回傳模板名稱
					return mw.text.trim(result)
				end
			end
		end
	end
	return nil
end
p._re_softredirect_template = re_softredirect_template

--偵測軟重定向
function p.is_softredirect(input_data)
	local page_name = input_data
	if type((input_data or {}).args) ~= type(nil) then --input_data is a frame
		page_name = input_data.args['1'] or input_data.args[1]
	end
	local page = (type(page_name) ~= type(nil)) and ({pcall(mw.title.new, page_name)})[2] or mw.title.getCurrentTitle()
	local talk_page = (page or {}).talkPageTitle
	local subject_page = (page or {}).subjectPageTitle
	if not subject_page:inNamespaces( --排除沒有軟重定向的命名空間
		mw.title.new("File:Ex").namespace,
		mw.title.new("MediaWiki:Ex").namespace,
		mw.title.new("TimedText:Ex").namespace,
		mw.title.new("Media:Ex").namespace,
		mw.title.new("Special:Ex").namespace,2600,2300,2302)
	then
		if subject_page.isRedirect then return false end --"硬" 重定向不是 "軟" 重定向
		local body = ""
		if subject_page.getContent then body = subject_page:getContent() or "" end
		local body_len = mw.ustring.len(body)
		if body_len > 10000 or body_len <= 0 then return false end --依據常識,沒有那麼大的軟重定向頁
		if re_softredirect_template(body) then --尋找軟重定向的模板
			return true
		end
	end
	return false
end

--匹配消歧義標題的正則函數
local function re_disambiguation_title(input_text)
	local text = input_text or ""
	local match_list = {
		--注意:這裡必須全部使用小寫字母
		"%([消分]歧[義义頁页]?%)",
		"%([消分]歧[義义][頁页]?%)",
		"%(disambiguous%)",
		"%disambiguation%)",
		"%(disambi?g?%)",
	}
	local lotext = mw.ustring.lower(text)
	for i = 1,#match_list do
		local j, k = mw.ustring.find(lotext, "%s+"..match_list[i])
		if j ~= nil then 
			local result = mw.ustring.sub(text, j, k)
			result = mw.ustring.match(result, "%(([^%)]+)%)$")
			return result
		end
	end
	return nil
end
p._re_disambiguation_title = re_disambiguation_title

--匹配消歧義模板的正則函數
local function re_disambiguation_template(input_text)
	local text = input_text or ""
	local match_list = {--各種消歧義模板及其重定向匹配表
		--注意:這裡必須全部使用小寫字母
		--{"消歧義模板正則", 是否允許前方有其他字}
		{"[^要][消分]歧[義义頁页]?",true},
		{"[^要][消分]歧[義义][頁页]?",true},
		{"[消分]歧[義义頁页]?",false},
		{"[消分]歧[義义][頁页]?",false},
		{"dab",false},
		{"disambiguous",true},
		{"disambiguation",true},
		{"disambi?g?",true},
		{"aimai",false},
		{"disambiguation%s*page",true},
		--如有新消歧義模板及其重定向被建立請加入於此
	}--致管理員:如有新消歧義模板及其重定向被建立,請優先受理新消歧義模板及其重定向匹配項目的編輯請求
	local black_list = { --不是消歧義模板的模板名稱匹配表
		"disambiguation[%s-_]*need", "disambiguous[%s-_]*need",
		"r to disambig", "disamb[%s-_]*link",
		"disambig[%s-_]*list", "disambig[%s-_]*nav",
		"title[%s-_]*without[%s-_]*disambig"
		--如有新的非消歧義模板但會被匹配到的請加入於此
	}--致管理員:如有新非消歧義模板被建立,請優先受理其編輯請求
	local lotext = mw.ustring.lower(text..'\n') --以小寫進行匹配
	for i = 1,#match_list do --對每一個消歧義模板及其重定向進行匹配
		local j, k = mw.ustring.find(lotext, "%{%{"..
			(match_list[i][2] and "[^%}]*" or "%s*")..match_list[i][1].."[^%}%|]*")
		if j ~= nil then --匹配到了消歧義模板或其重定向
			local result = mw.ustring.sub(text, j, k)
			result = mw.ustring.match(result, "%{%{%s*([^%}%|]+)$") --讀取匹配到的名稱
			if result then
				local is_correct = true
				for i1 = 1,#black_list do --檢查是否在黑名單中
					if mw.ustring.match(mw.ustring.lower(result), black_list[i1]) then
						is_correct = false --如果不是
						break
					end
				end
				if is_correct then --是消歧義模板,回傳模板名稱
					return mw.text.trim(result)
				end
			end
		end
	end
	return nil
end
p._re_disambiguation_template = re_disambiguation_template

local function remove_wikiproject_flag(input_text)
	local text = input_text or ""
	local match_list = {
		"[Ww][Ii][Kk][Ii]%s*[Pp][Rr][Oo][Jj][Ee][Cc][Tt]", 
		"[Ww][Pp][Jj]", "[Ww][Pp][Bb][Ss]","[Pp][Jj][Bb][Ss]",
		"[維维]基[专專][题題]", "[专專][题題]", --取消專題橫幅
		"[<>%[%]]","#%s*[Tt][Aa][Gg]%s*:",--取消參考文獻
		"%{%{%s*[Tt][Aa]%s*[%}%|]",":[Tt][Aa][^0-9a-zA-Z]",
		"[Nn][Oo][Tt][Ee]%s*[TtAa][TtAa]", --取消{{NoteTA}}
		"DEFAULTSORT","DISPLAYTITLE", "NOEXTERNALLANGLINKS", "TOC__", 
		"SECTION__", "TALK__", "LINK__", "GALLERY__", "CAT__", 
		"INDEX__", "REDIRECT__" --取消影響頁面內容的魔術字
	}
	for _, match_pattern in ipairs(match_list) do
		text = mw.ustring.gsub(text,match_pattern, "-")
	end
	return text
end
p._remove_wikiproject_flag = remove_wikiproject_flag

--偵測消歧義頁
function p.is_disambiguation(input_data)
	local page_name = input_data
	if type((input_data or {}).args) ~= type(nil) then --input_data is a frame
		page_name = input_data.args['1'] or input_data.args[1]
	end
	local page = (type(page_name) ~= type(nil)) and ({pcall(mw.title.new, page_name)})[2] or mw.title.getCurrentTitle()
	local talk_page = (page or {}).talkPageTitle
	local subject_page = (page or {}).subjectPageTitle
	if not subject_page:inNamespaces( --排除沒有消歧義的命名空間
		mw.title.new("File:Ex").namespace,
		mw.title.new("Module:Ex").namespace,
		mw.title.new("Template:Ex").namespace,
		mw.title.new("MediaWiki:Ex").namespace,
		mw.title.new("TimedText:Ex").namespace,
		mw.title.new("Media:Ex").namespace,
		mw.title.new("Special:Ex").namespace,2600,2300,2302)
	then
		if subject_page.isRedirect then return false end --重定向不是消歧義
		if re_disambiguation_title(subject_page.fullText or "") then --檢查是否有消歧義標題
			return true
		end
		local body = ""
		if subject_page.getContent then body = subject_page:getContent() or "" end
		local body_len = mw.ustring.len(body)
		if body_len > 10000 or body_len <= 0 then return false end --依據常識,沒有那麼大的消歧義頁
		if re_disambiguation_template(body) then --尋找消歧義的模板
			return true
		end
	
		if not mw.title.equals(subject_page or "", mw.title.getCurrentTitle()) then
			 --頭尾限400字,以節省效能
			local check_body = (body_len > 400) and (mw.ustring.sub(body, 1, 200).."{{tl|tl}} }}{{ {{tl|tl}}"..mw.ustring.sub(body, -200, -1)) or body
			local check_body = remove_wikiproject_flag(check_body) --避免模板循環
			if mw.ustring.match(mw.getCurrentFrame():preprocess(check_body.."{{reflist}}")
				, "__DISAMBIG__") then --匹配展開的模板有無消歧義的魔術字
				return true
			end
		end
	end
	return false
end

--匹配沙盒模板的正則函數
local function re_sandbox_template(input_text)
	local text = input_text or ""
	local match_list = {--各種沙盒模板及其重定向匹配表
		--注意:這裡必須全部使用小寫字母
		--{"沙盒模板正則", 是否允許前方有其他字}
		{"[請请]注意",false},
		{"沙盒",true},
		{"請勿編輯此行",false},
		{"sandbox",true},
		--如有新沙盒模板及其重定向被建立請加入於此
	}--致管理員:如有新沙盒模板及其重定向被建立,請優先受理新沙盒模板及其重定向匹配項目的編輯請求
	local black_list = { --不是沙盒模板的模板名稱匹配表
		"/沙盒","#invoke:沙盒","/sandbox",
		--如有新的非沙盒模板但會被匹配到的請加入於此
	}--致管理員:如有新非沙盒模板被建立,請優先受理其編輯請求
	local lotext = mw.ustring.lower(text..'\n') --以小寫進行匹配
	for i = 1,#match_list do --對每一個沙盒模板及其重定向進行匹配
		local j, k = mw.ustring.find(lotext, "%{%{"..
			(match_list[i][2] and "[^%}]*" or "%s*")..match_list[i][1].."[^%}%|]*")
		if j ~= nil then --匹配到了沙盒模板或其重定向
			local result = mw.ustring.sub(text, j, k)
			result = mw.ustring.match(result, "%{%{%s*([^%}%|]+)$") --讀取匹配到的名稱
			if result then
				local is_correct = true
				for i1 = 1,#black_list do --檢查是否在黑名單中
					if mw.ustring.match(mw.ustring.lower(result), black_list[i1]) then
						is_correct = false --如果不是
						break
					end
				end
				if is_correct then --是沙盒模板,回傳模板名稱
					return mw.text.trim(result)
				end
			end
		end
	end
	return nil
end
p._re_sandbox_template = re_sandbox_template

function p.is_sandbox(input_data)
	local page_name = input_data
	if type((input_data or {}).args) ~= type(nil) then --input_data is a frame
		page_name = input_data.args['1'] or input_data.args[1]
	end
	local current_title = mw.title.getCurrentTitle()
	--取得頁面標題物件
	local page = (type(page_name) ~= type(nil)) and ({pcall(mw.title.new, page_name)})[2] or current_title
	local current_page = page.subjectPageTitle or current_title.subjectPageTitle
	if current_page:inNamespace(mw.title.new(":EX").namespace) then return false end
	local check_title = mw.ustring.lower(tostring(current_page.fullText))
	if current_page.isRedirect then return false end
	if mw.ustring.match(check_title, "sandbox") or mw.ustring.match(check_title, "沙盒") then
		return true
	end
	local body = ""
	if current_page.getContent then body = current_page:getContent() or "" end
	body = mw.ustring.sub(body, 1, 400) --檢查頭部
	if re_sandbox_template(body) then --尋找沙盒的模板
		return true
	end
	return false
end

--自動偵測重定向、消歧義和命名空間 (模板、模組、分類、檔案、草稿、主題、專題) 產生評級
function p.getClassAuto(input_data, class_input, demo)
	local page_name = input_data
	local page_name_inputed = false
	local class_default = class_input or ''
	local demo_flag = yesno(demo or "no")
	if type((input_data or {}).args) ~= type(nil) then --input_data is a frame
		page_name = input_data.args['1'] or input_data.args[1]
		class_default = input_data.args.class or input_data.args.CLASS or ''
		demo_flag = yesno(input_data.args.demo or "no")
	end
	if not isEmptyString(page_name) then page_name_inputed = true end
	if demo_flag then return class_default end
	local current_title = mw.title.getCurrentTitle()
	--取得頁面標題物件
	local page = (type(page_name) ~= type(nil)) and ({pcall(mw.title.new, page_name)})[2] or current_title
	local current_page = page.subjectPageTitle or current_title.subjectPageTitle
	--success=執行成功與失敗, result=執行結果
	local success, result = false, ''
	if isEmptyString(class_default)then --沒有預輸入評級
		local page_is_disambiguation = false
		local page_is_softredirect = false
		local page_is_sandbox = false
		if page_name_inputed then --目前正在讀取其他頁面
			page_is_disambiguation = p.is_disambiguation(page_name)
			page_is_softredirect = p.is_softredirect(page_name)
			page_is_sandbox = p.is_sandbox(page_name)
		else --如果是讀取本頁,用讀取一次的方案 : mw.loadData("Module:PJBSClass/page")
			local PJBSClassData = mw.loadData("Module:PJBSClass/page")
			page_is_disambiguation = PJBSClassData.is_disambiguation
			page_is_softredirect = PJBSClassData.is_softredirect
			page_is_sandbox = PJBSClassData.is_sandbox
		end
		if page_is_softredirect then --如果偵測到是軟重定向
			return '重定向'
		end
		if page_is_disambiguation then --如果偵測到是消歧義
			local CurrentFrame = mw.getCurrentFrame()
			TrackingCategory.append(CurrentFrame, cat_auto_class, 'disambig')
			TrackingCategory.append(CurrentFrame, cat_auto_disambig_class)
			return '消歧义'
		end
		if page_is_sandbox then --如果偵測到是軟重定向
			return '沙盒'
		end
	end
	local class_default_lower = mw.ustring.lower(class_default)
	if current_page.isRedirect or current_page:inNamespaces(
		mw.title.new("Template:Ex").namespace, 
		mw.title.new("Module:Ex").namespace, 
		mw.title.new("Category:Ex").namespace, 
		mw.title.new("File:Ex").namespace, 
		mw.title.new("Draft:Ex").namespace, 
		mw.title.new("Portal:Ex").namespace, 
		mw.title.new("PJ:Ex").namespace,
		mw.title.new("User:Ex").namespace,
		mw.title.new("Help:Ex").namespace,
		mw.title.new("MediaWiki:Ex").namespace,
		mw.title.new("TimedText:Ex").namespace,
		mw.title.new("Media:Ex").namespace,
		mw.title.new("Special:Ex").namespace,2600,2300,2302) 
	then
		if current_page:inNamespace(mw.title.new("File:Ex").namespace) and 
			(class_default_lower == "fm" or class_default_lower == "fi" or
			 mw.ustring.match(class_default_lower, "特[圖图]") or
			 mw.ustring.match(class_default_lower, "特色[圖图媒][片體体]") ) 
		then
			return class_default
		end
		success, result = pcall(require("Module:PJBSClass").getAutoClass, input_data)
		if success and not isEmptyString(result) then --如果成功讀取,並有讀到評級
			TrackingCategory.append(mw.getCurrentFrame(),cat_auto_class)
		end
	end
	--讀取不成功,回傳預輸入評級
	if not success then return class_default end
	return result
end

--偵錯用 : 只要[[Cat:無法正常讀取評級的條目]]是空的,代表本模組沒問題。
function p._checker(input_data)
	local success, result = pcall(p.getClass, input_data)
	if not mw.loadData("Module:PJBSClass/page").has_WPBS then return '' end
	if not success then return "[[Cat:無法正常讀取評級的條目]]" end
	local result_show = (not isEmptyString(result)) and result or ' '
	if not isEmptyString(result)then 
		return "[[Cat:可以正常讀取評級的條目|".. result_show .."]]" 
	end
	return ''
end

--列舉WPBS中的專題
function p.listProjects(frame, _code, _comma, _max_num)
	local project_list = p._getProjects(frame)
	local code = _code or '$1$2'
	local comma = _comma or '、'
	local max_num = tonumber("inf")
	local tail = "專題"
	local default_text = ''
	if type(frame.args) == type({"table"}) then
		code = frame.args.code or code
		comma = frame.args.comma or comma
		tail = frame.args.tail or tail
		max_num = tonumber(frame.args.max_num or frame.args["max num"]) or max_num
		default_text = frame.args.default or default_text
	elseif type(frame) == type({"table"}) then
		code = frame.code or frame[2] or code
		comma = frame.comma or frame[3] or comma
		max_num = tonumber(frame.max_num or frame["max num"] or frame[4]) or max_num
		tail = frame.tail or tail
		default_text = frame.default or default_text
	end
	if #project_list <= 0 then return default_text end
	local result = ''
	for i=1,#project_list do
		if i > max_num then break end
		result = result .. mw.ustring.gsub(code, "%$([%+%-]?%d+)", function(_id)
			local id = tonumber(_id)
			if id == 1 then
				return project_list[i]
			elseif id == 2 then
				if #project_list == 1 or max_num == 1 then return '' end
				return ((i==#project_list or i == max_num) and '' or ((i + 1 == max_num or i + 1 == #project_list) and "和" or comma))
			end
			return "$".._id
		end)
	end
	if max_num > 1 then
		result = result .. "等"
	end
	result = result .. tail
	return result
end
--取得WPBS中的所有已輸入的專題
function p._getProjects(frame)
	local text = frame
	if type(frame.args) == type({"table"}) then
		text = frame.args[1] or ''
	elseif type(frame) == type({"table"}) then
		text = frame[1] or ''
	end
	local project_list = {}
	local _,j,i,length = 1,1,1,mw.ustring.len(text)
	while i <= length do
		--類似於$.(".wpb-project")以抓取專題元數據 (metadata)
		_,j = mw.ustring.find(text, "class%s*=%s*\"wpb%-project\"", i)
		if j then
			local k = mw.ustring.find(text, "<%s*/%s*span%s*>", j)
			local pj_text = mw.ustring.sub(text, j+1, k or -1)
			--獲取專題名稱
			project_list[#project_list + 1] = mw.ustring.match(pj_text, "^>%s*(.*)%s*<$")
			i = k or length
		else break end
	end
	return project_list
end
--評級繼承與否判斷作業
function p.checkClassInput(_class_input, _class_given)
	local class_input = _class_input
	local class_given = _class_given or _class_input
	local frame = mw.getCurrentFrame()
	if type(_class_input.args) == type({"table"}) then
		class_input = _class_input.args[1] or ''
		class_given = _class_input.args[2] or _class_input.args[1] or ''
		frame = _class_input
	elseif type(_class_input) == type({"table"}) then
		class_input = _class_input[1] or ''
		class_given = _class_input[2] or _class_input[1] or ''
	end
	class_input = mw.text.trim(class_input)
	class_given = mw.text.trim(class_given)
	if class_input == '' then return class_given end --無輸入為繼承
	--轉換為標準評級字串
	local norm_class_input = class_normalize({class_input})
	local norm_class_given = class_normalize({class_given})
	if class_input~='' and class_given~='' then
		--如果不繼承評級
		if norm_class_input ~= norm_class_given then
			--添加維護分類
			TrackingCategory.append(frame, cat_use_user_defined_class)
		end
	end
	return class_given
end
function p.class_json()
	return mw.text.jsonEncode(mw.loadData("Module:PJBSClass/page"))
end
function p.processNotice(input_data)
	local wikitext = input_data or ""
	if type((input_data or {}).args) ~= type(nil) then --input_data is a frame
		wikitext = input_data.args['1'] or input_data.args[1] or ""
	end
	wikitext = mw.ustring.gsub(wikitext,'(class="[^"]-messagebox[^"]-)"', "%1 wpb-outside\"")
	local re_mbox = '<table[^>]-class="[^"]-[aico]mbox[^"]-"'
	local re_wpb_outside = '<table[^>]-class="[^"]-wpb%-outside[^"]-"'
	local wikitext_len = mw.ustring.len(wikitext)
	local mbox_head, mbox_head_end = mw.ustring.find(wikitext,re_mbox)
	if type(mbox_head) ~= type(0) then mbox_head, mbox_head_end = mw.ustring.find(wikitext,re_wpb_outside) end
	local mbox_end = nil
	while type(mbox_head) == type(0) do
		local _, mbox_end = mw.ustring.find(wikitext,'<%s*/%s*table%s*>', mbox_head_end)
		if type(mbox_end) == type(0) then
			wikitext = mw.ustring.sub(wikitext, 1, mbox_head-1) .. ((mbox_end + 1 >= wikitext_len) and "" or mw.ustring.sub(wikitext, mbox_end + 1, -1))
			wikitext_len = mw.ustring.len(wikitext)
		end
		mbox_head, mbox_head_end = mw.ustring.find(wikitext,re_mbox)
		if type(mbox_head) ~= type(0) then mbox_head, mbox_head_end = mw.ustring.find(wikitext,re_wpb_outside) end
	end
	--追蹤套娃式的基礎條目橫幅
	if mw.ustring.match(wikitext, "基础条目") then
		wikitext = wikitext .. "[[Cat:錯誤放置基礎條目橫幅的頁面]]"
	end
	return wikitext
end
function p.getNotice(input_data)
	local wikitext = input_data or ""
	if type((input_data or {}).args) ~= type(nil) then --input_data is a frame
		wikitext = input_data.args['1'] or input_data.args[1] or ""
	end
	local body = ''
	wikitext = mw.ustring.gsub(wikitext,'(class="[^"]-messagebox[^"]-)"', "%1 wpb-outside\"")
	local wikitext_len = mw.ustring.len(wikitext)
	local re_mbox = '<table[^>]-class="[^"]-[aico]mbox[^"]-"'
	local re_wpb_outside = '<table[^>]-class="[^"]-wpb%-outside[^"]-"'
	local mbox_list = {}
	local mbox_head, mbox_head_end = mw.ustring.find(wikitext,re_mbox)
	local mbox_head_o, mbox_head_end_o = mw.ustring.find(wikitext,re_wpb_outside)
	if (mbox_head_o or wikitext_len) < (mbox_head or wikitext_len) then
		mbox_head, mbox_head_end = mbox_head_o, mbox_head_end_o
	end
	if type(mbox_head) ~= type(0) then mbox_head, mbox_head_end = mw.ustring.find(wikitext,re_wpb_outside) end
	local mbox_end = nil
	while type(mbox_head) == type(0) and (mbox_head or wikitext_len) < wikitext_len - 1 do
		local _, mbox_end = mw.ustring.find(wikitext,'<%s*/%s*table%s*>', mbox_head_end)
		if type(mbox_end) == type(0) then
			local mbox_content = mw.ustring.sub(wikitext, mbox_head, mbox_end)
			local checker = mw.ustring.lower(mw.ustring.gsub(mbox_content, "[%s_-]", ""))
			local has_same = false
			for i=1,#mbox_list do
				if mbox_list[i][2] == checker then
					has_same = true
					break
				end
			end
			if not has_same then
				mbox_list[#mbox_list + 1] = {mbox_content, checker}
			end
		end
		mbox_head, mbox_head_end = mw.ustring.find(wikitext,re_mbox, mbox_end or (wikitext_len - 1))
		mbox_head_o, mbox_head_end_o = mw.ustring.find(wikitext,re_wpb_outside, mbox_end or (wikitext_len - 1))
		if (mbox_head_o or wikitext_len) < (mbox_head or wikitext_len) then
			mbox_head, mbox_head_end = mbox_head_o, mbox_head_end_o
		end
	end
	for i=1,#mbox_list do
		body = body..mbox_list[i][1]
	end
	return body
end
return p