模組:PJBSClass/main
外观
本模組的功能:
- 透過調用Module:PJBSClass/page間接調用Module:PJBSClass
- 讀取{{PJBS}}中的評級值
- 自動透過命名空間盼判斷評級值
- 進階自動評級
- 透過解析頁面內容判斷頁面是否為軟重定向
- 透過解析頁面內容判斷頁面是否為消歧義
- 判斷專題橫幅是繼承{{PJBS}}中的評級值還是自定評級值並加入維護分類
- 輔助{{PJBS}}中的一些與專題評級值相關的功能
用法
本模組主要用於讀取頁面中定義於{{PJBS}}或專題橫幅中的評級值,或自動根據命名空間或維基代碼判斷評級。
判斷種類 | 判斷依據 | 對應的評級 |
---|---|---|
典范条目 | 典范条目模板(如{{Featured article}}) | 典范 |
优良条目 | 优良条目模板(如{{Good article}}) | 优良 |
特色列表 | 特色列表模板(如{{Featured list}}) | 特色列表 |
特色图片 | 特色图片模板(如{{Featured picture}}) | 特色图片 |
重定向 | 頁面物件的isRedirect 欄位。
| 重定向 |
軟重定向 | 軟重定向模板(如{{軟重定向}}) | 重定向 |
沙盒 | 沙盒模板(如{{Sandbox}}) | 沙盒 |
消歧義 | 消歧義模板(如{{消歧義}}) 以及相關魔術字(如 __DISAMBIG__ )
| 消歧义 |
列表 | 名稱以「列表」結尾的頁面 | 列表 |
同類索引 | 同類索引模板(如{{同類索引}}) | 同类索引 |
小作品 | 條目的位元組數是否小於2000 (2000~3000間的過渡數值不自動評) | 小作品 |
命名空間 | 前綴 | 對應的評級 |
---|---|---|
模板 | Template: | 模板 |
模組 | Module: | 模块 |
分類 | Category: | 分类 |
文件 | File: | 文件 |
草稿 | Draft: | 草稿 |
主題 | Portal: | 主题 |
專題 | PJ: | 专题 |
用戶 | User: | 用户 |
說明 | Help: | 使用说明 |
MediaWiki | MediaWiki: | 界面 |
字幕 | TimedText: | 非条目 |
媒體 | Media: | 非条目 |
特殊 | Special: | 非条目 |
模組中的主要函數
- getClass
-
- 模組調用:
p.getClass(class_name)
- 模板調用:
{{#invoke:PJBSClass/main|getClass| class_name | auto=yes/no | inheritance=yes/no | demo=yes/no }}
- 模組調用:
- 間接調用Module:PJBSClass#getClassByPage。
- 取得所在頁面的評級,可以輸入一個評級值(class_name)作為覆蓋與否的判斷依據。auto為是否要以自動判斷的評級為優先;inheritance為是否要以繼承值為優先;demo為是否為模板演示。
- getClassAuto
-
- 模組調用:
p.getClassAuto(page_name, class_default, demo)
- 模板調用:
{{#invoke:PJBSClass/main|getClassAuto| class_name | class=class_default | demo=yes/no }}
- 模組調用:
- 間接調用Module:PJBSClass#getAutoClass,並額外加入了從維基代碼判斷評級的功能,見維基代碼可判斷的評級值。
- 自動判斷名為「page_name」頁面的評級,若「page_name」未輸入則判斷所在頁面的評級。若無法判斷則回傳「class_default」。
- class_json
-
- 模組調用:
p.class_json()
- 模板調用:
{{#invoke:PJBSClass/main|class_json}}
- 模組調用:
- 提供Module:PJBSClass#{{Module:PJBSClass/page}}轉換Lua到JSON的函數。此函數沒有參數,僅回傳所在條目
mw.loadData("Module:PJBSClass/page")
的JSON結果。模板調用應使用{{Module:PJBSClass/page|json=yes}}
。
- getPageType
- 判斷該級別的分類頁面種類。
模組中的元函數
- _getClass
-
- 模組調用:
p._getClass(class_name, auto, inheritance, demo)
- 模板調用:
{{#invoke:PJBSClass/main|_getClass| class_name | auto=yes/no | inheritance=yes/no | demo=yes/no }}
- 模組調用:
- 同#getClass。
- _getProjects
-
- 模組調用:
p._getProjects(html)
- 模板調用:(無法使用)
- 模組調用:
- 解析「html」中的評級模板,列出當中的所有專題名稱。
專題橫幅內部函數
- subjectPageTitle
-
- 模組調用:
p.subjectPageTitle(page_name)
- 模板調用:
{{#invoke:PJBSClass/main|subjectPageTitle| page_name }}
- 模組調用:
- 無論名為「page_name」頁面是否是討論頁都會回傳其所對應之主要頁面的名稱。如果「page_name」不是討論頁,則回傳原頁面名稱。如果「page_name」未輸入則輸出所在頁面(無論是否是討論頁)所對應之主要頁面的名稱。如果所在頁面不是討論頁,則回傳所在頁面名稱。
- listProjects
-
- 模組調用:
p.listProjects(html, code, comma, max_num)
- 模板調用:
{{#invoke:PJBSClass/main|listProjects| html | code=code | comma=comma | tail=tail | max_num=max_num }}
- 模組調用:
- 列舉「html」中所有專題橫幅的專題,主要由{{PJBS}}調用。「code」為輸出的格式,
$1
代表專題名稱、$2
代表分隔符號。「comma」為分隔符號。「tail」為自動加在尾端的文字,預設為專題
。「max_num」為最大列舉數量。
- checkClassInput
- 檢查是否評級繼承與否
- wrongClass
- 檢查是否誤將橫幅與評級輸入在一起
- hasCustomClassName
- 檢查專題橫幅有無自訂評級級別
- customClassName
- 處理專題橫幅的自訂評級級別
- processNotice
- 將輸入到{{PJBS}}的專題橫幅處理成符合{{PJBS}}的樣式,並移除專題橫幅內自帶的提示模板,{{PJBS}}會使用#getNotice將之統一加入。同時解析內容添加適當的維護分類。
- getNotice
- 解析輸入到{{PJBS}}的專題橫幅有無橫幅內自帶的提示模板,移除重複的提示模板後,加以顯示。
判斷頁面屬性函數
- is_softredirect
- 判斷頁面是否為軟重定向。
- is_disambiguation
- 判斷頁面是否為消歧義頁。
- is_sandbox
- 判斷頁面是否為沙盒。
可供其他模組調用的私有函數
- _re_softredirect_template
- 匹配軟重定向模板的正則函數。
- _re_disambiguation_title
- 匹配消歧義標題的正則函數。
- _re_disambiguation_template
- 匹配消歧義模板的正則函數。
- _re_sandbox_template
- 匹配沙盒模板的正則函數。
- _remove_wikiproject_flag
- 用於避免消歧義判斷模板循環的跳脫函數,會破壞輸入的內容、移除魔術字,僅保留模板,以供展看測試有無消歧義魔術字。
除錯用函數
- _checker
- 檢查函數是否會出錯的函數。如無出錯,將頁面加入分類:可以正常讀取評級的條目;如出錯,將頁面加入分類:無法正常讀取評級的條目。
- check_disambig_process
- 列出#is_disambiguation的中間過程,以便除錯。
local p = {}
local yesno = require('Module:Yesno')
local cat_auto_class = "自動評級的頁面"
local cat_use_user_defined_class = "使用自訂專題評級的條目"
local cat_auto_disambig_class = '自動評級的消歧義級頁面'
local cat_auto_softredirect_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((((type(input_data)==type(0)) and {} or 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, _napagens)
local class_name = input_data
local auto_first = _auto_first
local inheritance_first = _inheritance_first
local demo = _demo
local no_cat = demo
local napagens = _napagens
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)
no_cat = yesno(input_data.args.no_cat) or demo
napagens = input_data.args.napagens
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, napagens)
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, no_cat)
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}, --會誤判{{SR}}
{"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 "%s*[%}%|]+" 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)
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,true},
{"disambiguous",true},
{"disambiguation",true},
{"disambi?g?",true},
{"aimai",false,true},
{"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","[條条]目", "[专專][题題]",
"disambig[%s-_]*class", "改為", "星章", "需要", "[链連][結接]",
--如有新的非消歧義模板但會被匹配到的請加入於此
}--致管理員:如有新非消歧義模板被建立,請優先受理其編輯請求
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 "%s*[%}%|]+" or "[^%}%|]*"))
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]",
"#%s*[Ii][Nn][Vv][Oo][Kk][Ee]%s*:","/",
"[Nn][Oo][Tt][Ee]%s*[TtAa][TtAa]", --取消{{NoteTA}}
"DISPLAYTITLE", "[Tt]itle", "[Ff]romis","僻字", --取消DISPLAYTITLE
"[Bb]ox", "[Ss]ubpagelist", "[Dd]ownsize",
"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)
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 > 800) and (mw.ustring.sub(body, 1, 400).."{{tl|tl}} }}{{ void | "..mw.ustring.sub(body, -400, -1)) or body
-- local check_body = remove_wikiproject_flag(check_body) --避免模板循環
-- if mw.ustring.match((mw.getCurrentFrame():newChild{ title = tostring(mw.title.getCurrentTitle())}):preprocess(check_body.."{{reflist}}")
-- , "__DISAMBIG__") then --匹配展開的模板有無消歧義的魔術字
-- TrackingCategory.append(mw.getCurrentFrame(), "使用魔術字判斷消歧義的頁面")
-- return true
-- end
-- end
end
return false
end
function p.check_disambig_process(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
local body = ""
if subject_page.getContent then body = subject_page:getContent() or "" end
local body_len = mw.ustring.len(body)
if not mw.title.equals(subject_page or "", mw.title.getCurrentTitle()) then
--頭尾限400字,以節省效能
local check_body = (body_len > 800) and (mw.ustring.sub(body, 1, 400).."{{tl|tl}} }}{{ void |"..mw.ustring.sub(body, -400, -1)) or body
local check_body = remove_wikiproject_flag(check_body) --避免模板循環
return (mw.getCurrentFrame():newChild{ title = tostring(mw.title.getCurrentTitle())}):preprocess(check_body.."{{reflist}}")
end
return body
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
--匹配同類索引模板的正則函數
local function re_sia_template(input_text)
local text = input_text or ""
local match_list = {--同類索引模板及其重定向匹配表
--注意:這裡必須全部使用小寫字母
--{"同類索引模板正則", 是否允許前方有其他字, 是否後方不能有其他字}
{"sia",false, true},
{"set index",false, true},
{"set index article",false, true},
{"同[類类]索引",false, true},
--如有新同類索引重定向被建立請加入於此
}--致管理員:如有新同類索引模板及其重定向被建立,請優先受理同類索引模板及其重定向匹配項目的編輯請求
local black_list = { --不是同類索引模板的模板名稱匹配表
--暫無
}--致管理員:如有新同類索引模板及其重定向被建立,請優先受理同類索引模板及其重定向匹配項目的編輯請求
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 "%s*[%}%|]+" or "[^%}%|]*")
)
if j ~= nil then --匹配到了同類索引模板或其重定向
local result = mw.ustring.sub(text, j, k)
result = mw.ustring.match(result, "%{%{%s*([^%}%|]+)[%}%|]*$") --讀取匹配到的名稱
if result then
local is_sia = true
for i1 = 1,#black_list do --檢查是否在黑名單中
if mw.ustring.match(mw.ustring.lower(result), black_list[i1]) then
is_sia = false --如果不是
break
end
end
if is_sia then --是同類索引模板,回傳模板名稱
return mw.text.trim(result)
end
end
end
end
return nil
end
p._re_sia_template = re_sia_template
--偵測同類索引
function p.is_sia(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)
then
if subject_page.isRedirect then return false end --重定向不是同類索引
local body = ""
if subject_page.getContent then body = subject_page:getContent() or "" end
if re_sia_template(mw.ustring.sub(body, -400, -1)) then --尋找同類索引的模板
return true
end
end
return false
end
--匹配特色內容模板的正則函數
local function re_featured_content_template(input_text, _fc_type)
local text = input_text or ""
local fc_type = mw.ustring.lower(_fc_type or "fa")
local match_list = {
fa={--典範條目模板及其重定向匹配表
--注意:這裡必須全部使用小寫字母
--{"典範條目模板正則", 是否允許前方有其他字, 是否後方不能有其他字}
{"featured?%s*articles?",false, true},
{"fa",false, true},
{"特色",false, true},
{"典[範范]",false, true},
{"典[範范][条條]目",false, true},
{"特色[条條]目",false, true}
--如有新典範條目模板重定向被建立請加入於此
},
ga={--優良條目模板及其重定向匹配表
--注意:這裡必須全部使用小寫字母
--{"優良條目模板正則", 是否允許前方有其他字, 是否後方不能有其他字}
{"good%s*articles?",false, true},
{"ga",false, true},
{"[优優]良",false, true},
{"[优優]?[良好][条條]目",false, true},
--如有新優良條目模板重定向被建立請加入於此
},
fl={--特色列表模板及其重定向匹配表
--注意:這裡必須全部使用小寫字母
--{"特色列表模板正則", 是否允許前方有其他字, 是否後方不能有其他字}
{"featured?%s*lists?",false, true},
{"fl",false, true},
{"特色列表",false, true},
--如有新特色列表模板重定向被建立請加入於此
},
fm={--特色圖片模板及其重定向匹配表
--注意:這裡必須全部使用小寫字母
--{"特色圖片模板正則", 是否允許前方有其他字, 是否後方不能有其他字}
{"featured?%s*pictures?",false, true},
{"fp",false, true},
{"特色[圖图]片",false, true},
--如有新特色圖片模板重定向被建立請加入於此
},
}--致管理員:如有新特色內容模板及其重定向被建立,請優先受理特色內容模板及其重定向匹配項目的編輯請求
local black_list = { --不是特色內容模板的模板名稱匹配表
fa={},ga={},fl={},fm={}
--暫無
}--致管理員:如有新特色內容模板及其重定向被建立,請優先受理特色內容模板及其重定向匹配項目的編輯請求
if match_list[fc_type] then
local lotext = mw.ustring.lower(text..'\n') --以小寫進行匹配
for i = 1,#(match_list[fc_type]) do --對每一個特色內容模板及其重定向進行匹配
local j, k = mw.ustring.find(lotext, "%{%{"..
(match_list[fc_type][i][2] and "[^%}]*" or "%s*")..match_list[fc_type][i][1]..
(match_list[fc_type][i][3] and "%s*[%}%|]+" or "[^%}%|]*")
)
if j ~= nil then --匹配到了特色內容模板或其重定向
local result = mw.ustring.sub(text, j, k)
result = mw.ustring.match(result, "%{%{%s*([^%}%|]+)[%}%|]*$") --讀取匹配到的名稱
if result then
local is_featured_content = true
for i1 = 1,#(black_list[fc_type]) do --檢查是否在黑名單中
if mw.ustring.match(mw.ustring.lower(result), black_list[fc_type][i1]) then
is_featured_content = false --如果不是
break
end
end
if is_featured_content then --是特色內容模板,回傳模板名稱
return mw.text.trim(result)
end
end
end
end
end
return nil
end
p._re_featured_content_template = re_featured_content_template
--偵測特色內容
function p.is_featured_content(input_data, _fc_type)
local page_name = input_data
local fc_type = mw.ustring.lower(_fc_type or "fa")
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]
fc_type = mw.ustring.lower(input_data.args['2'] or input_data.args[2] or "fa")
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("MediaWiki:Ex").namespace,
mw.title.new("Module:Ex").namespace,
mw.title.new("Template:Ex").namespace,
mw.title.new("TimedText:Ex").namespace,
mw.title.new("Media:Ex").namespace,
mw.title.new("Special:Ex").namespace,2600)
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)
local check_body = (body_len > 600) and (mw.ustring.sub(body, 1, 300).."{{tl|tl}} }}{{ {{tl|tl}}"..mw.ustring.sub(body, -300, -1)) or body
if re_featured_content_template(check_body, fc_type) then --尋找特色內容的模板
return true
end
end
return false
end
--自動偵測重定向、消歧義和命名空間 (模板、模組、分類、檔案、草稿、主題、專題) 產生評級
function p.getClassAuto(input_data, class_input, demo, _napagens)
local page_name = input_data
local page_name_inputed = false
local class_default = class_input or ''
local demo_flag = yesno(demo or "no")
local napagens = _napagens
local no_auto = false
local no_cat = false
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")
no_auto = yesno(input_data.args.no_auto or "no")
no_cat = yesno(input_data.args.no_cat or "no")
napagens = input_data.args.napagens
end
local napagens_list_ = mw.text.split(napagens or '', ",")
local napagens_list = {}
for _, _napagens_item in pairs(napagens_list_) do
local ns_id = tonumber(_napagens_item)
if type(ns_id) == type(0) then
napagens_list[#napagens_list + 1] = ns_id
else
local napagens_item = mw.text.trim(mw.ustring.lower(_napagens_item or ''))
if napagens_item == '' then napagens_item = "special:" end
if napagens_item == 'article' or napagens_item == '条目' or napagens_item == '條目' or napagens_item == '主要' or napagens_item == 'article:' or napagens_item == '条目:' or napagens_item == '條目:' or napagens_item == '主要:' then
napagens_item = ":"
end
xpcall(function()
napagens_list[#napagens_list + 1] = mw.title.new(((mw.ustring.sub(napagens_item,-1,-1)==':') and mw.ustring.sub(napagens_item,1,-2) or napagens_item)..':EX').namespace
end,function(ex)return ex end)
end
end
if not isEmptyString(page_name) then page_name_inputed = true end
if demo_flag then return class_default end
if no_auto and mw.text.trim(class_default or '') ~= '' 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
page_name = current_page.fullText
--success=執行成功與失敗, result=執行結果
local success, result = false, ''
if isEmptyString(class_default)then --沒有預輸入評級
local function _returned(_returned_value)
if not no_cat then
TrackingCategory.append(mw.getCurrentFrame(),cat_auto_class,_returned_value)
end
return _returned_value
end
if current_page:inNamespaces(unpack(napagens_list)) then
return _returned('非页面')
end
if not current_page.isRedirect then
local page_is_disambiguation = false
local page_is_softredirect = false
local page_is_sandbox = false
local page_is_sia = false
local page_is_ga = false
local page_is_fa = false
local page_is_fl = false
local page_is_fm = 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)
page_is_sia = p.is_sia(page_name)
page_is_ga = p.is_featured_content(page_name, "ga")
page_is_fa = p.is_featured_content(page_name, "fa")
page_is_fl = p.is_featured_content(page_name, "fl")
page_is_fm = p.is_featured_content(page_name, "fm")
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
page_is_sia = PJBSClassData.is_sia
page_is_ga = PJBSClassData.is_ga
page_is_fa = PJBSClassData.is_fa
page_is_fl = PJBSClassData.is_fl
page_is_fm = PJBSClassData.is_fm
end
if page_is_softredirect then --如果偵測到是軟重定向
if not no_cat then
TrackingCategory.append(mw.getCurrentFrame(), cat_auto_softredirect_class)
end
return _returned('重定向')
end
if page_is_sia then --如果偵測到是同類索引
return _returned('同类索引')
end
--如果偵測到是特色內容
if page_is_ga then return _returned('优良') end
if page_is_fa then return _returned('典范') end
if page_is_fl then return _returned('特色列表') end
if page_is_fm then return _returned('特色图片') end
if page_is_disambiguation then --如果偵測到是消歧義
if not no_cat then
TrackingCategory.append(mw.getCurrentFrame(), cat_auto_disambig_class)
end
return _returned('消歧义')
end
if page_is_sandbox then --如果偵測到是沙盒
return _returned('沙盒')
end
if current_page.namespace == 0 then
--如果偵測到是列表
if mw.ustring.match(current_page.fullText or '', ".列表$") then
return _returned('列表')
end
--如果條目不足2000位元組 (不對2000~3000的過渡數值自動評)
if current_page.getContent then
local contentLen = (current_page:getContent() or ''):len()
if contentLen > 0 and contentLen < 2000 and not mw.ustring.match(current_page.fullText or '', "列表") then
return _returned('小作品')
end
end
end
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("Wikipedia: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)
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, page_name, class_default)
if success and not isEmptyString(result) then --如果成功讀取,並有讀到評級
if not no_cat then
local orig_class_norm = class_normalize({class_default})
local result_class_norm = class_normalize({result})
if orig_class_norm ~= result_class_norm and result_class_norm ~= 'unassessed' then
TrackingCategory.append(mw.getCurrentFrame(), cat_auto_class, result)
end
end
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
--取得分類的頁面種類
function p.getPageType(input_data)
local class_name = input_data
local non_article = {
"file","fm",--[[:Category:特色图片级页面]]
"image",--[[:Category:图像级页面]]
"portal","sandbox","template","module","book",
"category","draft","project","user","help","interface","na"
}
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]
end
class_name = mw.text.trim(class_name)
local norm_class = class_normalize({class_name})
if norm_class == "complete" or norm_class == "substantial" or norm_class == "basic" then
return "主题"
end
for _, na_class in pairs(non_article) do
if norm_class == na_class then return "页面" end
end
return "条目"
end
function p.checkIfRating(input_data)
local class_input = input_data
if type((input_data or {}).args) ~= type(nil) then --input_data is a frame
class_input = input_data.args[1] or input_data.args['1'] or ''
elseif type(input_data) == type({}) then
class_input = input_data[1] or input_data['1'] or ''
end
local norm_class = mw.ustring.lower(class_normalize({class_input}))
local non_rating = {
portal=true, category=true, draft=true, file=true, audio=true,
sandbox=true, project=true, template=true, module=true,
user=true, help=true, interface=true, council=true,na=true,
}
return not non_rating[norm_class]
end
function p.processCatPageType(input_data, _page_name)
local class_input = input_data
local page_name = _page_name
if type((input_data or {}).args) ~= type(nil) then --input_data is a frame
class_input = input_data.args[1] or input_data.args['1'] or ''
page_name = input_data.args.page
elseif type(input_data) == type({}) then
class_input = input_data[1] or input_data['1'] or ''
page_name = input_data.page or ''
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
page_name = current_page.fullText
if not current_page:inNamespace(mw.title.new(":條目").namespace) then
class_input = mw.ustring.gsub(class_input, "条目", "页面")
class_input = mw.ustring.gsub(class_input, "條目", "頁面")
end
return class_input
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].name
elseif id == 2 then
return project_list[i].link
elseif id == 3 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*\"%s*wpb%-project%s*\"", 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)
--獲取專題名稱
local project_name = mw.text.trim(mw.ustring.match(pj_text, "^>%s*(.*)%s*<$") or '')
_,j = mw.ustring.find(text, "class%s*=%s*\"%s*wpb%-project_link%s*\"", i)
k = mw.ustring.find(text, "<%s*/%s*span%s*>", j)
pj_text = mw.ustring.sub(text, j+1, k or -1)
--獲取專題連結
local project_link = mw.text.trim(mw.ustring.match(pj_text, "^>%s*(.*)%s*<$") or '')
--如果成功獲取
if project_name ~= "" or project_link ~= "" then
if project_link == "" then --沒連結則產生連結
project_link = "PJ:"..project_name
end
if project_name == "" then --沒名稱則用連結產生名稱
local _c = mw.ustring.find(project_link, ":")
project_name = mw.ustring.sub(_c or 1, -1)
end
--紀錄找到的專題
project_list[#project_list + 1] = {
name=project_name,
link=project_link
}
end
--獲取下一個
i = k or length
else break end --沒有下一個了
end
return project_list
end
--評級繼承與否判斷作業
function p.checkClassInput(_class_input, _class_given, _no_cat)
local class_input = _class_input
local class_given = _class_given or _class_input
local no_cat = yesno(_no_cat or false)
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
--添加維護分類
if not no_cat then
TrackingCategory.append(frame, cat_use_user_defined_class)
end
end
end
return class_given
end
--用於Module:PJBSClass/page模板調用
function p.class_json()
return mw.text.jsonEncode(mw.loadData("Module:PJBSClass/page"))
end
function p.PJBSClassItem(frame)
if type(frame.getParent) == type(tostring) then
local p_frame = frame:getParent()
local value_type = mw.ustring.lower(mw.text.trim(p_frame.args.value_type or ''))
return frame.args[value_type] or ''
end
return ''
end
--處理class參數輸入成橫幅的情況
function p.wrongClass(input_data, _check_class)
local wikitext = input_data or ""
local check_class = _check_class 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 ""
check_class = input_data.args.class or ""
end
local re_pj = '<table[^>]-class="[^"]-wpb[^"]-"'
if mw.ustring.match(check_class, re_pj) then
return mw.ustring.gsub(check_class, "^[^<]*<", "<")..wikitext
end
return wikitext
end
--是否有自定義級別
function p.hasCustomClassName(input_data)
if input_data.getParent then
for key, value in pairs(input_data:getParent().args or {}) do
local key_name = mw.ustring.match(mw.text.trim(tostring(key or '')), "^(.*)自订级")
if type(key_name) == type("string") then
return true
end
end
end
return false
end
--處理自定義級別
function p.customClassName(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
if input_data.getParent then
for key, value in pairs(input_data:getParent().args or {}) do
local key_name = mw.ustring.match(mw.text.trim(tostring(key or '')), "^(.*)自订级")
if type(key_name) == type("string") then
wikitext = mw.ustring.gsub(wikitext, key_name, value)
wikitext = mw.ustring.gsub(wikitext, "assess%-"..value, "assess-"..key_name)
end
end
end
return wikitext
end
--檢查有無不存在的專題橫幅,加入警示
local function _processUndefinedWikiproject(wikitext)
if not mw.ustring.match(wikitext, "%[%[:Template:") then return wikitext, 0 end
local count = 0
local function _repe(text, count)local _list = {} for i=1,count do _list[#_list+1]=text end return _list end
local function _repl(non_exist_pj)
local pj_name = mw.text.trim(mw.ustring.gsub(mw.ustring.gsub(mw.ustring.gsub(non_exist_pj, "[专專][题題]", ""), "[Ww][Ii][Kk][Ii][Pp][Rr][Oo][Jj][Ee][Cc][Tt]", ""), "%%", "%%%%"))
if pj_name == "" then pj_name = "專題" end
return ('<table class="tmbox tmbox-notice collapsible innercollapse wpb wpb-nonexist" height="0"><tr class="wpb-header">'..
'<td style="text-align:right; padding:0.3em 1em 0.3em 0.3em; width:50%%; font-weight:bold;"> [[Template:%s|%s]]</td>'..
'<th style="text-align:left; width:50%%; padding:0.3em 0.3em 0.3em 0;"><span class="assess assess-error">專題模板不存在!</span></th>'..
'<td class="mbox-empty-cell"></td></tr><tr><td class="mbox-text" style="padding:3px 0 3px 5px;" colspan="2">'..
'<table style="background:transparent; border:none; padding:0; width:100%%;" cellspacing="0">'..
'<tr><td style="padding:2px 0;"></td><td class="mbox-text">'..
'<div class="navbar plainlinks hlist navbar-mini" style="float:right; clear:right; margin:-1em 0.1em; display:none;"><ul><li class="nv--{zh-hans:查看;zh-hant:檢視;}-">[[Template:%s|<abbr title="-{zh-hans:查看;zh-hant:檢視;}-该模板">-{zh-hans:查;zh-hant:閱;}-</abbr>]]</li><li class="nv-讨论">[[Template talk:%s|<abbr title="讨论该模板">论</abbr>]]</li><li class="nv-编辑">[//zh-two.iwiki.icu/w/index.php?title=Template:%s&action=edit<abbr title="编辑该模板">编</abbr>]</li></ul></div>'..
"本頁面属于'''[[PJ:"..pj_name.."|%s]]'''范畴,该专题旨在改善[[中文维基百科]]的[["..pj_name.."]]类内容。但該專題模板[[Template:%s]]尚未創建,請檢查是否輸入有誤,或專題不存在。如專題不存在請移除本模板。</td>"..
'<td class=mbox-empty-cell></td></tr></table></td><td class="mbox-empty-cell"></td></tr></table>'
):format(unpack(_repe(non_exist_pj, 20)))
end
local match_list = {
"%[%[:Template:([^%[%]]*[专專][题題][^%[%]%|]*)%]%]",
"%[%[:Template:([^%[%]]*[Ww][Ii][Kk][Ii][Pp][Rr][Oo][Jj][Ee][Cc][Tt][^%[%]%|]*)%]%]"
}
local i = 0
for _, match_item in ipairs(match_list) do
wikitext, i = mw.ustring.gsub(wikitext, match_item, _repl)
count = count + (i or 0)
end
return wikitext, count
end
--處理專題橫幅中包含的警告標示,以及圖示加到標題,同時標記維護分類
function p.processNotice(input_data)
local wikitext = input_data or ""
local no_cat = false
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 ""
no_cat = yesno(input_data.args.no_cat or "no")
end
wikitext = mw.ustring.gsub(wikitext,'(class="[^"]-messagebox[^"]-)"', "%1 wpb-outside\"")
local nonexist_count = 0
--檢查有無不存在的專題橫幅,添加維護分類
wikitext, nonexist_count = _processUndefinedWikiproject(wikitext)
if nonexist_count > 0 and not no_cat then
TrackingCategory.append(mw.getCurrentFrame(), "WPBS中含有不存在專題橫幅的頁面")
end
--移除專題橫幅內自帶的提示模板 (稍後將會用p.getNotice統一補上避免重複列初)
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
--加入圖示與維護分類
local pj_count = 0
local re_pj = '<table[^>]-class="[^"]-wpb[^"]-"'
local re_image_td = '<td[^>]-class="[^"]-%-image[^"]-"'
wikitext_len = mw.ustring.len(wikitext)
--尋找專題橫幅
mbox_head, mbox_head_end = mw.ustring.find(wikitext,re_pj)
local pj_list = {}
while type(mbox_head) == type(0) and (mbox_head or wikitext_len) < wikitext_len - 1 do
pj_count = pj_count + 1
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 TARGETPAGETYPE = mw.ustring.match(mbox_content, '<span[^>]-class="[^"]-wpb%-target%-page%-type[^"]-"[^>]->%s*(.-)%s*<%s*/%s*span%s*>')
if mw.text.trim(TARGETPAGETYPE or '') ~= '' then --自訂專題非頁面
TARGETPAGETYPE = mw.text.unstripNoWiki( TARGETPAGETYPE )
if mw.text.trim(TARGETPAGETYPE or '') ~= '' then
TARGETPAGETYPE = mw.text.unstripNoWiki( TARGETPAGETYPE )
mbox_content = mw.ustring.gsub(mbox_content, '非页面', '非'..TARGETPAGETYPE)
mbox_content = mw.ustring.gsub(mbox_content, 'Category:非'..TARGETPAGETYPE, 'Category:非页面')
end
end
--取得專題名稱
local pj_name = mw.text.trim(mw.ustring.match(mbox_content, '<span[^>]-class="[^"]-wpb%-project[^"]-"[^>]->%s*(.-)%s*<%s*/%s*span%s*>') or '')
if pj_name ~= '' then
--如果有重複的專題名稱,加上維護分類
if pj_list[pj_name] then
mbox_content = mw.ustring.gsub(mbox_content, '(</th>%s*<td[^>]-class="[^"]-mbox%-empty%-cell[^"]-">%s*<span[^>]-class="[^"]-metadata[^"]-")', '<span class="duplicate-notice">重複</span>%1')
if not no_cat then
TrackingCategory.append(mw.getCurrentFrame(), "WPBS中含有重複專題橫幅的頁面")
end
end
--紀錄已找到的專題
pj_list[pj_name] = true
end
local header_fix = 0 --專題頭部改以WPBS的模板樣式
mbox_content = mw.ustring.gsub(mbox_content, "width:50%%", function(str)
local fix_list = {50}
header_fix = header_fix + 1
if fix_list[header_fix] then return "" end
return str
end)
--尋找專題縮圖
local image_head, image_head_end = mw.ustring.find(mbox_content, re_image_td)
local icon_added = false
if type(image_head) == type(0) then
local _, image_end = mw.ustring.find(mbox_content,'<%s*/%s*td%s*>', image_head_end)
if type(image_end) == type(0) then --找到專題縮圖
local icon_td_html = mw.ustring.sub(mbox_content, image_head, image_end)
--取得專題縮圖
local icon_wikitext = mw.ustring.match(icon_td_html, ">(%[%[.*%]%])%s*<%s*/%s*td%s*>")
--改成圖示大小
icon_wikitext = mw.ustring.gsub(icon_wikitext, "%|%s*%d+px", "|40px|alt=|link=")
--將圖示放入表格頭部
mbox_content = mw.ustring.gsub(mbox_content,'(<tr[^>]-class="[^"]-wpb%-header[^"]-"[^>]->)', function(tr_head)
return tr_head..'<td class="wpb-header-icon"><div>'..icon_wikitext..'</div></td>'
end)
icon_added = true
end
end
if not icon_added then
mbox_content = mw.ustring.gsub(mbox_content,'(<tr[^>]-class="[^"]-wpb%-header[^"]-"[^>]->)', function(tr_head)
return tr_head..'<td class="wpb-header-icon"><div></div></td>'
end)
end
--更新專題模板
wikitext = mw.ustring.sub(wikitext, 1, mbox_head-1) .. mbox_content .. ((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_pj, (mbox_head_end or (wikitext_len - 6)) + 5)
end
--追蹤套娃式的基礎條目橫幅
if mw.ustring.match(wikitext, "基础条目") then
if not no_cat then
wikitext = wikitext .. "[[Cat:錯誤放置基礎條目橫幅的頁面]]"
end
end
--檢查正裡完後是否為空
local tail_check = wikitext
--移除HTML的TAG
tail_check = mw.ustring.gsub(tail_check, "<[^<>]->", "")
local old_tail_check = tail_check .."-"
while old_tail_check ~= tail_check do
old_tail_check = tail_check
tail_check = mw.text.trim(mw.ustring.gsub(tail_check, "<[^<>]->", ""))
end
--移除擴展標籤TAG
tail_check = mw.ustring.gsub(tail_check, "\127'\"`UNIQ%-%-[^%-]*%-[^%-]*%-QINU`\"'\127", "")
tail_check = mw.text.trim(tail_check)
--如果整串是空的,或沒有找到專題,代表專題橫幅放置不正確,加入維護分類
if tail_check == '' or pj_count <= 0 then
wikitext = wikitext .. '<div class="wpbs-empty-notice">(未輸入專題)</div>'
if not no_cat then
TrackingCategory.append(mw.getCurrentFrame(), "專題橫幅放置不正確的頁面")
end
end
return mw.text.trim(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 mw.text.trim(body)
end
return p