local yesno = require('Module:Yesno')
local mError = require('Module:Error')
local mNS = require('Module:Namespace')
local data = mw.loadData('Module:Namespace_pagename/data')
local lan = mNS._lan
local p = {}
local function msg(group, key, lang)
return lan(data[tostring(group)][tostring(key)] or {}, lang)
end
local function makeError(msg)
return mError.error{'[[Module:Namespace_pagename]]錯誤:' .. msg}
end
local function inArray(item, arr)
for i, v in ipairs(arr) do
if item == v then
return v
end
end
return nil
end
local function getDefaultSuffix(nsid, lang)
if inArray(nsid, data.NamespaceSuffixConfig.SuppressDefaultSuffix) then
return ''
end
local pageConv = {
['en'] = ' page',
['zh-hans'] = '页',
['zh-hant'] = '頁'
}
if inArray(nsid, {-1, 4}) then
pageConv['zh-hans'] = '页面'
pageConv['zh-hant'] = '頁面'
elseif nsid == 2 then
pageConv['zh-tw'] = '頁面' -- 使用者頁面
end
return lan(pageConv, lang)
end
local function lowerFirst(value)
return mw.ustring.lower(mw.ustring.sub(value, 1, 1)) .. mw.ustring.sub(value, 2)
end
-- enum
local PageType = (function ()
local enum = {
testcases = 'testcases',
doc = 'doc',
sandbox = 'sandbox',
temp = 'temp',
intro = 'intro',
editnotice = 'editnotice',
-- mailnotice = 'mailnotice',
-- shortcut = 'shortcut',
}
return setmetatable({}, {
__index = function (t, k)
if enum[k] then
return enum[k]
end
error('Invalid enum key: ' .. k .. '.')
end,
__newindex = function (t, k, v)
error('Enums are read-only and cannot be modified.')
end,
__pairs = function (t)
return function (_t, index)
return next(enum, index)
end, t, nil
end
})
end)()
-- @param {mw.title | string | number} [pageOrNs]
-- - mw.title: 頁面
-- - string: 頁面(註:此函數不檢查是否有效) or (偽)命名空間的名字
-- - number: 命名空間數字
-- @param {string} [lang]
-- @param {boolean} [skipCheckPageType] 抑制檢測頁面類型,效果形同 pageOrNs 不是傳頁面
function p._namespace_pagename(pageOrNs, lang, skipCheckPageType)
local success, title, isPseudo
if pageOrNs then
if pageOrNs ~= '' then
if type(pageOrNs) == type(0) or tonumber(pageOrNs) then
local ns = mw.site.namespaces[tonumber(pageOrNs)]
if not ns then
return makeError(string.format(msg('Error', 'ns-error', lang), 'namespace number = ' .. nsid))
end
nsid = ns.id
else
local ns = mw.site.namespaces[pageOrNs]
if ns then -- pageOrNs 是{{ns:}}能解析的
nsid = ns.id
title = nil
else
if type(pageOrNs) == type({}) then -- mw.title input
success = true
title = pageOrNs
else
success, title = pcall(mw.title.new, pageOrNs)
end
if not success or not title then -- pageOrNs 無法被 MediaWiki 正確解析(aka 標題不可能存在)
return makeError(string.format(msg('Error', 'pg-error', lang), pageOrNs))
else -- 其他正常標題或偽命名空間,無效的命名空間也被當條目處理
nsid = title.namespace
isPseudo = (nsid == 0 or nsid == 1) and (mNS._ispseudoNS(pageOrNs) or mNS._ispseudoNS(pageOrNs))
end
end
end
else -- 空值當成條目命名空間
nsid = 0
end
else -- 以標題讀取
title = mw.title.getCurrentTitle()
nsid = title.namespace
end
if title and title.isExternal then
return msg('Type', 'External', lang)
elseif isPseudo then --偽命名空間
return mNS._NamespacesDisplay(lang, nsid == 1 and 'Talk:' .. isPseudo or isPseudo)
end
local namespace = mNS._NamespacesDisplay(lang, nsid)
local suppressPageType = inArray(nsid, data.NamespaceSuffixConfig.SuppressPageType)
if title and not skipCheckPageType then
local subpageName = lowerFirst(title.subpageText)
local contentModel = title.contentModel
if contentModel == 'css' or contentModel == 'sanitized-css' then
return namespace .. msg('Type', 'style', lang)
elseif contentModel == 'javascript' then
return namespace .. msg('Type', 'script', lang)
elseif contentModel == 'json' then
return namespace .. msg('Type', 'JSON', lang)
elseif title.isRedirect then
return namespace .. msg('Type', 'redirect', lang)
end
local pageType = nil
if nsid == 829 and subpageName == 'testcases' then
pageType = PageType.testcases
elseif suppressPageType then
return namespace
elseif nsid % 2 == 0 then
local isAllowTemplateType = inArray(nsid, data.NamespaceSuffixConfig.AllowTemplateType)
if
(nsid > 1 and nsid ~= 6 and title.text == '沙盒')
or (nsid == 6 and mw.ustring.match(title.text, '^沙盒%.[A-Za-z]+$'))
or (nsid == 10 and title.rootText == '沙盒')
or (nsid == 10 and mw.ustring.match(title.text, '^X%d'))
then
pageType = PageType.sandbox
end
-- 先分析子頁面標題
-- P.S. mw.title.rootText: If this is a subpage, the title of the root page without prefixes. Otherwise, the same as title.text.
if not pageType and title.rootText ~= title.text then
if
(subpageName == 'doc')
and isAllowTemplateType
then
pageType = PageType.doc
elseif
(subpageName == 'sandbox' or subpageName == '沙盒')
and isAllowTemplateType
then
pageType = PageType.sandbox
elseif
(subpageName == 'testcases' or subpageName == '测试样例' or subpageName == '測試樣例')
and isAllowTemplateType
then
pageType = PageType.testcases
elseif
(subpageName == 'temp' or subpageName == 'temporary')
and inArray(nsid, data.NamespaceSuffixConfig.AllowTempType)
then
pageType = PageType.temp
elseif
(subpageName == 'intro' or subpageName == 'introduction' or subpageName == '说明' or subpageName == '說明')
and nsid == 10
then
pageType = PageType.intro
elseif
(title.rootText == 'Editnotices' and nsid == 10)
or (title.subpageText == 'Editnotices' and title.rootText == title.baseText and title:inNamespaces(2, 3))
then
return msg('Type', 'editnotice', lang)
elseif
(title.subpageText == 'Emailnotice' and title.rootText == title.baseText and nsid == 2)
then
local user = title.rootText
return '[[User:' .. user .. '|' .. user .. ']]' .. lan({
['en'] = "'s ",
['zh-hans'] = '的',
['zh-hant'] = '的'
}, lang) .. msg('Type', 'mailnotice', lang)
end
end
-- 依然分析失敗再分析內文(減少不必要的嵌入)
if not pageType then
local content = title:getContent() or ''
if
mw.ustring.match(content, '%{%{[Ss]andbox')
or mw.ustring.match(content, '%{%{[Tt]emplate[_%s]sandbox[_%s]notice')
or mw.ustring.match(content, '%{%{請注意:請在這行文字底下進行您的測試,請不要刪除或變更這行文字以及這行文字以上的部份。')
or mw.ustring.match(content, '%{%{请注意:请在这行文字底下进行您的测试,请不要删除或变更这行文字以及这行文字以上的部分。')
or (nsid == 6 and mw.ustring.match(content, '%{%{[Pp]D%-self%/沙盒%|'))
then
pageType = PageType.sandbox
elseif
isAllowTemplateType
and (
mw.ustring.match(content, '%{%{[Dd]ocumentation[_%s]subpage')
or mw.ustring.match(content, '%{%{[Tt]emplate[_%s]doc[_%s]inline')
or mw.ustring.match(content, '%{%{[Tt]emplate[_%s]doc[_%s]viewed[_%s]directly')
)
then
pageType = PageType.doc
elseif
isAllowTemplateType
and (
mw.ustring.match(content, '%{%{[Tt]emplate[_%s]testcases[_%s]notice')
or mw.ustring.match(content, '%{%{[Tt]est[_%s]cases[_%s]notice')
or mw.ustring.match(content, '%{%{测试样例')
or mw.ustring.match(content, '%{%{測試樣例')
)
then
pageType = PageType.testcases
elseif
mw.ustring.match(content, '{{捷徑重定向([^}]+)}}')
or mw.ustring.match(content, '{{捷径重定向([^}]+)}}')
or mw.ustring.match(content, '{{快捷重定向([^}]+)}}')
or mw.ustring.match(content, '{{快捷方式重定向([^}]+)}}')
or mw.ustring.match(content, '{{RTL([^}]+)%|捷徑')
then
return string.format(msg('Type', 'shortcut', lang), wt)
end
end
end
if pageType then
return namespace .. msg('Type', pageType, lang)
end
elseif suppressPageType then
return namespace
end
local output = (namespace .. getDefaultSuffix(nsid, lang) or ''):gsub('talk page', 'talkpage')
-- 註:消除 gsub 的第二返回值
return output
end
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame, {
valueFunc = function (key, value)
if key == 2 then
return type(value) == 'string' and mw.text.trim(value) or value
elseif value then
value = mw.text.trim(value)
if value ~= '' then
return value
end
end
return nil
end
})
local lang = args[1] or args['1'] or args['lang'] or nil
local pageOrNs = args[2] or args['2'] or args['pageOrNs'] or nil
local skipCheckPageType = args['skipCheckPageType'] or false
return p._namespace_pagename(pageOrNs, lang, skipCheckPageType)
end
return p