打开/关闭菜单
331
1.7K
131
11.8K
星露谷物语扩展百科
打开/关闭外观设置菜单
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。

模块:Documentation

来自星露谷物语扩展百科
Sizau留言 | 贡献2026年1月11日 (日) 13:17的版本

[ 创建 | 刷新 ]文档页面
当前模块文档缺失,需要扩充。
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-hant"] = "頁面",
	}),
	pageType_template = "模板",
	pageType_module = stconv({
		["zh-hans"] = "模块",
		["zh-hant"] = "模組",
	}),
	pageType_stylesheet = stconv({
		["zh-hans"] = "样式表",
		["zh-hant"] = "樣式表",
	}),
	pageType_script = stconv({
		["zh-hans"] = "脚本",
		["zh-hant"] = "腳本",
	}),
	pageType_json = "JSON",
	pageType_message = stconv({
		["zh-hans"] = "界面信息",
		["zh-hant"] = "介面訊息",
	}),

	-- 链接显示方式
	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-hant"] = "將",
	}),
	docPagePromptShould = stconv({
		["zh-hans"] = "会",
		["zh-hant"] = "應該",
	}),
	
	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-hant"] = "說明文件頁面",
	}),
	pageDocJumpToCode = stconv({
		["zh-hans"] = "跳转至代码 ↴",
		["zh-hant"] = "跳轉至程式碼 ↴",
	}),
	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-hant"] = 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