模块:Documentation
来自星露谷物语扩展百科
更多操作
local p = {}
-- Load modules (language wikis exclusive)
local stconv = require("Module:STConversion").lan
-- Customizable strings
local i18n = {
-- 设置
defaultDocPage = "doc", -- 文档页后缀
defaultSandboxPage = "sandbox", -- 沙盒页后缀
defaultTestCasePage = "testcases", -- 测试用例页后缀
defaultPreload = "模板:Documentation/preload", -- 存储文档页标准内容的页面
defaultStyles = "Module:Documentation/styles.css", -- TemplateStyles 样式表
-- 格式字符串
commonInternalLink = "[[%s]]",
commonInternalLinkPipe = "[[%s|%s]]",
commonExternalLink = "[%s]",
commonExternalLinkWithName = "[%s %s]",
commonNamespacedPage = "%s:%s",
commonNamespacedPageWithSub = "%s:%s/%s",
-- 命名空间名称
namespaceCategory = "分类",
namespaceSpecial = "特殊",
namespaceUser = "用户",
specialPurge = "Purge",
specialEdit = "EditPage",
specialHistory = "PageHistory",
-- 页面类型名称
pageType_page = stconv({
["zh-hans"] = "页面",
["zh-hk"] = "頁面",
}),
pageType_template = "模板",
pageType_module = stconv({
["zh-hans"] = "模块",
["zh-hk"] = "模組",
}),
pageType_stylesheet = stconv({
["zh-hans"] = "样式表",
["zh-hk"] = "樣式表",
}),
pageType_script = stconv({
["zh-hans"] = "脚本",
["zh-hk"] = "腳本",
}),
pageType_json = "JSON",
pageType_message = stconv({
["zh-hans"] = "界面信息",
["zh-hk"] = "介面訊息",
}),
-- 链接显示方式
linkBar = mw.text.nowiki("[ ") .. "%s" .. mw.text.nowiki(" ]"), -- 整个链接条使用的整体样式
linkFormat = "%s", -- 单个链接使用的样式
linkSeparator = mw.text.nowiki(mw.getCurrentFrame():callParserFunction("int:pipe-separator")), -- 不同链接间的分隔符
-- 不同类型链接的显示名称
linkTextPurge = mw.getCurrentFrame():callParserFunction("int:purge"),
linkTextView = mw.getCurrentFrame():callParserFunction("int:view"),
linkTextEdit = mw.getCurrentFrame():callParserFunction("int:edit"),
linkTextHistory = mw.getCurrentFrame():callParserFunction("int:history_short"),
linkTextCreate = mw.getCurrentFrame():callParserFunction("int:create"),
-- p.create() 中使用的字符串:使用 {{doc}} 或 {{subst:doc}} 时显示的内容
createOutputFormat = "<noinclude>%s%s</noinclude>", -- 整体格式
createSplitDocPagePrompt = "\n<!-- 请将分类/语言链接放在文档页面 -->", -- 要创建的文档页面为独立页面时显示的字符串
createNoSubstCategory = "需要替换模板的页面", -- 使用 {{doc}} 时未使用替代语法所添加的追踪分类
-- p.docPage() 中使用的字符串:文档页显示的内容
-- For messages with format placeholders, store the template with placeholders
docPagePrompt_template_hans = "当前页面是文档页面,%s被%s引入。查看[[模板:Documentation]]获取更多信息。",
docPagePrompt_template_hant = "這是說明文件頁面,它%s被放置到%s。查看[[Template:Documentation]]以取得更多資訊。",
docPagePromptWill = stconv({
["zh-hans"] = "会",
["zh-hk"] = "將",
}),
docPagePromptShould = stconv({
["zh-hans"] = "会",
["zh-hk"] = "應該",
}),
docPageBadDocPrompt_template_hans = "<br>'''%s的文档页面质量较低或信息缺失,需要进一步修改。'''",
docPageBadDocPrompt_template_hant = "<br>'''此%s的說明文件頁面需要改進或加上附加資訊。'''",
docPageCategory = "文档页面", -- 文档页的追踪分类
-- p.page() 中使用的字符串:代码页显示的内容
pageNoDocPrompt_template_hans = "'''当前%s文档缺失,需要扩充。'''",
pageNoDocPrompt_template_hant = "'''此%s没有說明文件頁面。如果你知道此%s的使用方法,請幫助為其建立說明文件頁面。'''",
pageNoDocCategory_template_hans = "文档缺失的%s",
pageNoDocCategoryDefault = "文档缺失的页面",
pageBadDocPrompt_template_hans = "'''%s的文档页面质量较低或信息缺失,需要进一步修改。'''\n",
pageBadDocPrompt_template_hant = "'''此%s的說明文件頁面需要改進或加上附加資訊。'''\n",
pageBadDocCategory_template_hans = "文档质量较低的%s",
pageBadDocCategoryDefault = "文档质量较低的页面",
pageDocHeaderTitle = stconv({
["zh-hans"] = "文档页面",
["zh-hk"] = "說明文件頁面",
}),
pageDocJumpToCode = stconv({
["zh-hans"] = "跳转至代码 ↴",
["zh-hk"] = "跳轉至程式碼 ↴",
}),
pageDocHeaderBottom_template_hans = "上述文档的内容来自%s。",
pageDocHeaderBottom_template_hant = "上述說明文件嵌入至%s。",
-- 全局跨语言链接
globalInterwikiLinks = {
{ lang = "de", prefix = "Vorlage" },
{ lang = "en", prefix = "Template" },
{ lang = "es", prefix = "Plantilla" },
{ lang = "fr", prefix = "Modèle" },
{ lang = "it", prefix = "Template" },
{ lang = "ja", prefix = "テンプレート" },
{ lang = "ko", prefix = "틀" },
{ lang = "hu", prefix = "Sablon" },
{ lang = "pt", prefix = "Predefinição" },
{ lang = "ru", prefix = "Шаблон" },
{ lang = "tr", prefix = "Şablon" },
},
}
-- Helper function to format strings with language conversion
local function formatWithConv(hans_template, hant_template, ...)
local args = {...}
-- Count the number of %s in each template
local hans_count = select(2, string.gsub(hans_template, "%%s", ""))
local hant_count = select(2, string.gsub(hant_template, "%%s", ""))
-- Build arguments for each template based on their placeholder count
local hans_args = {}
local hant_args = {}
for i = 1, math.max(hans_count, hant_count) do
if i <= hans_count then
hans_args[i] = args[i] or ""
end
if i <= hant_count then
hant_args[i] = args[i] or ""
end
end
local hans_result = string.format(hans_template, unpack(hans_args))
local hant_result = string.format(hant_template, unpack(hant_args))
return stconv({
["zh-hans"] = hans_result,
["zh-hk"] = hant_result,
})
end
-- Customizable functions
local function pageCategoryHandler(category)
return i18n.commonInternalLink:format(i18n.commonNamespacedPage:format(i18n.namespaceCategory, category))
end
-- Load modules
local loadStyles = require("Module:TSLoader").call
local static = require("Module:Static")
if not static.Documentation then
static.Documentation = {}
end
-- Internal functions
local function getType(namespace, page)
local pageType = "page"
if namespace == "Template" then
pageType = "template"
elseif namespace == "Module" then
pageType = "module"
elseif page.fullText:gsub("/" .. i18n.defaultDocPage .. "$", ""):find("%.css$") then
pageType = "stylesheet"
elseif page.fullText:gsub("/" .. i18n.defaultDocPage .. "$", ""):find("%.js$") then
pageType = "script"
elseif page.fullText:gsub("/" .. i18n.defaultDocPage .. "$", ""):find("%.json$") then
pageType = "json"
elseif namespace == "MediaWiki" then
pageType = "message"
end
return pageType
end
local function getDisplayType(pageType)
return i18n["pageType_" .. pageType] or i18n.pageType_page
end
local function generateGlobalInterwikiLinks(f)
local pageName = f:preprocess("{{PAGENAME}}")
local links = {}
for _, item in ipairs(i18n.globalInterwikiLinks) do
table.insert(links, string.format("[[%s:%s:%s]]", item.lang, item.prefix, pageName))
end
return "\n" .. table.concat(links, "\n")
end
-- Exported functions
function p.create(f) -- Creating a documentation page or transclusion through {{subst:doc}}
local args = require("Module:ProcessArgs").norm()
local page = mw.title.getCurrentTitle()
local docPage = args.page
or i18n.commonNamespacedPageWithSub:format(page.nsText, page.baseText, i18n.defaultDocPage)
local out
if not args.content and tostring(page) == docPage then
local pageType = mw.ustring.lower(args.type or getType(page.nsText, page))
local pageTypeDisplay = getDisplayType(pageType)
out = f:preprocess(mw.title.new(i18n.defaultPreload):getContent():gsub("$1", pageTypeDisplay))
else
local templateArgs = {}
for _, key in ipairs({ "type", "page", "content", "nodoc", "baddoc", "global" }) do
local val = args[key]
if val then
if key == "content" then
val = "\n" .. val .. "\n"
end
table.insert(templateArgs, key .. "=" .. val)
end
end
out = "{{Documentation|" .. table.concat(templateArgs, "|") .. "}}"
out = out:gsub("|}}", "}}")
out = i18n.createOutputFormat:format(out, args.content and "" or i18n.createSplitDocPagePrompt)
end
if not mw.isSubsting() then
out = f:preprocess(out)
if not args.nocat then
out = out
.. i18n.commonInternalLink:format(
i18n.commonNamespacedPage:format(i18n.namespaceCategory, i18n.createNoSubstCategory)
)
end
end
return out
end
function p.docPage(f) -- Header on the documentation page
local args = require("Module:ProcessArgs").merge(true)
local badDoc = args.baddoc
if badDoc then
static.Documentation.badDoc = "1"
end
local page = mw.title.getCurrentTitle()
local subpage = page.subpageText
if subpage == i18n.defaultSandboxPage or subpage == i18n.defaultTestCasePage then
page = page.basePageTitle
end
local docPage = mw.title.new(
args.page or i18n.commonNamespacedPageWithSub:format(page.nsText, page.baseText, i18n.defaultDocPage)
)
if docPage ~= page then
return
end
local namespace = page.nsText
local pageType = mw.ustring.lower(args.type or getType(namespace, page))
local pageTypeDisplay = getDisplayType(pageType)
local body = mw.html.create("div"):addClass("documentation")
body:addClass(badDoc and "documentation-badDoc" or "")
:tag("div")
:addClass("documentation-header-tools")
:wikitext(
i18n.linkBar:format(
i18n.linkFormat:format(
i18n.commonInternalLinkPipe:format(
i18n.commonNamespacedPageWithSub:format(i18n.namespaceSpecial, i18n.specialPurge, page.fullText),
i18n.linkTextPurge
)
)
)
)
:done()
:wikitext(
formatWithConv(
i18n.docPagePrompt_template_hans,
i18n.docPagePrompt_template_hant,
pageType == "module" and i18n.docPagePromptWill or i18n.docPagePromptShould,
i18n.commonInternalLink:format(i18n.commonNamespacedPage:format(namespace, page.baseText))
)
)
if badDoc then
body:wikitext(formatWithConv(
i18n.docPageBadDocPrompt_template_hans,
i18n.docPageBadDocPrompt_template_hant,
pageTypeDisplay
))
end
if not (args.nocat or namespace == i18n.namespaceUser) then
body:wikitext(
i18n.commonInternalLink:format(
i18n.commonNamespacedPage:format(i18n.namespaceCategory, i18n.docPageCategory)
)
)
end
return loadStyles(i18n.defaultStyles) .. tostring(body)
end
function p.page(f) -- Wrapper around the documentation on the main page
-- mw.text.trim uses mw.ustring.gsub, which silently fails on large strings
local function trim(s)
return (s:gsub("^[\t\r\n\f ]+", ""):gsub("[\t\r\n\f ]+$", ""))
--return string.gsub( s, '^[\t\r\n\f ]*(.-)[\t\r\n\f ]*$', '%1' )
end
local args = require("Module:ProcessArgs").merge(true)
local page = mw.title.getCurrentTitle()
local subpage = page.subpageText
if subpage == i18n.defaultSandboxPage or subpage == i18n.defaultTestCasePage then
page = page.basePageTitle
end
local namespace = page.nsText
local docText = trim(args.content or "")
if docText == "" then
docText = nil
end
local docPage
local noDoc
if docText then
docPage = page
else
docPage = mw.title.new(
args.page or i18n.commonNamespacedPageWithSub:format(namespace, page.text, i18n.defaultDocPage)
)
noDoc = args.nodoc or not docPage.exists
end
local badDoc = args.baddoc
local pageType = mw.ustring.lower(args.type or getType(namespace, page))
local pageTypeDisplay = getDisplayType(pageType)
if not docText and not noDoc then
docText = trim(f:expandTemplate({ title = ":" .. docPage.fullText }))
if static.Documentation.badDoc and static.Documentation.badDoc == "1" then
badDoc = 1
end
if docText == "" then
docText = nil
noDoc = 1
end
end
if docText then
docText = "\n" .. docText .. "\n"
end
local docClass = ""
local message
local category
if noDoc then
docClass = "documentation-noDoc"
-- pageNoDocPrompt_template_hant has 2 %s, both need the same value
message = formatWithConv(
i18n.pageNoDocPrompt_template_hans,
i18n.pageNoDocPrompt_template_hant,
pageTypeDisplay,
pageTypeDisplay -- Second argument for zh-hant template
)
if not (args.nocat or namespace == i18n.namespaceUser) then
-- Use simplified Chinese category name directly
local categoryName = string.format(i18n.pageNoDocCategory_template_hans, pageTypeDisplay)
-- Check if the category exists
local categoryTitle = mw.title.new(i18n.commonNamespacedPage:format(i18n.namespaceCategory, categoryName))
if categoryTitle and categoryTitle.exists then
category = categoryName
else
category = i18n.pageNoDocCategoryDefault
end
end
elseif badDoc then
docClass = "documentation-badDoc"
message = formatWithConv(
i18n.pageBadDocPrompt_template_hans,
i18n.pageBadDocPrompt_template_hant,
pageTypeDisplay
)
if not (args.nocat or namespace == i18n.namespaceUser) then
-- Use simplified Chinese category name directly
local categoryName = string.format(i18n.pageBadDocCategory_template_hans, pageTypeDisplay)
-- Check if the category exists
local categoryTitle = mw.title.new(i18n.commonNamespacedPage:format(i18n.namespaceCategory, categoryName))
if categoryTitle and categoryTitle.exists then
category = categoryName
else
category = i18n.pageBadDocCategoryDefault
end
end
end
-- Generates the link bar
local links = mw.html.create("span"):attr("id", "documentation-header-tools")
local linkList = {}
if not noDoc then
if page ~= docPage then
table.insert(
linkList,
i18n.linkFormat:format(i18n.commonInternalLinkPipe:format(docPage.fullText, i18n.linkTextView))
)
end
table.insert(
linkList,
i18n.linkFormat:format(
i18n.commonInternalLinkPipe:format(
i18n.commonNamespacedPageWithSub:format(i18n.namespaceSpecial, i18n.specialEdit, docPage.fullText),
i18n.linkTextEdit
)
)
)
table.insert(
linkList,
i18n.linkFormat:format(
i18n.commonInternalLinkPipe:format(
i18n.commonNamespacedPageWithSub:format(
i18n.namespaceSpecial,
i18n.specialHistory,
docPage.fullText
),
i18n.linkTextHistory
)
)
)
else
table.insert(
linkList,
i18n.linkFormat:format(
i18n.commonExternalLinkWithName:format(
docPage:canonicalUrl({
action = "edit",
preload = i18n.defaultPreload,
preloadparams = pageTypeDisplay,
}),
i18n.linkTextCreate
)
)
)
end
table.insert(
linkList,
i18n.linkFormat:format(
i18n.commonInternalLinkPipe:format(
i18n.commonNamespacedPageWithSub:format(i18n.namespaceSpecial, i18n.specialPurge, docPage.fullText),
i18n.linkTextPurge
)
)
)
links:wikitext(i18n.linkBar:format(table.concat(linkList, i18n.linkSeparator)))
local body = mw.html.create("div"):addClass("documentation")
body:addClass(docClass)
local header = mw.html.create("div"):addClass("documentation-header-top")
header:node(links):tag("span"):addClass("documentation-header-title"):wikitext(i18n.pageDocHeaderTitle)
local codePages = {
module = true,
stylesheet = true,
script = true,
}
if not noDoc and codePages[pageType] then
header
:tag("span")
:attr("id", "documentation-jump-to-code")
:wikitext(i18n.commonInternalLinkPipe:format("#the-code", i18n.pageDocJumpToCode))
end
body:node(header):done():wikitext(message):wikitext(docText)
if not noDoc and page ~= docPage then
body:tag("div")
:addClass("documentation-header-bottom")
:node(links)
:wikitext(formatWithConv(
i18n.pageDocHeaderBottom_template_hans,
i18n.pageDocHeaderBottom_template_hant,
i18n.commonInternalLink:format(docPage.fullText)
))
end
if category then
body:wikitext(pageCategoryHandler(category))
end
local anchor = ""
if not noDoc and pageType ~= "template" and pageType ~= "message" then
anchor = mw.html.create("div"):attr("id", "the-code")
end
local output = loadStyles(i18n.defaultStyles) .. tostring(body) .. tostring(anchor)
-- Add global interwiki links if requested
if args.global then
output = output .. generateGlobalInterwikiLinks(f)
end
return output
end
return p