Pergi ke kandungan

Modul:language tracking

Daripada Wikikamus


local export = {}

local CONFIG = {
	VALID_TYPES = { "lemma", "nonlemma", "alternative", "both", "all" },
	VALID_STYLES = { "default", "wide" },
	DEFAULT_TYPE = "lemma",
	DEFAULT_STYLE = "default",
	LINE_BREAK_SEPARATOR = ";"
}

local CATEGORY_TEMPLATES = {
	lemma = {
		prefix = "Lema bahasa ",
		label = "Lema bahasa "
	},
	nonlemma = {
		prefix = "Bentuk bukan lema bahasa ",
		label = "Bentuk bukan lema bahasa "
	},
	alternative = {
		prefix = "Bentuk alternatif bahasa ",
		label = "Bentuk alternatif bahasa "
	}
}

local function getPageCount(categoryName)
	local success, count = pcall(function()
		return mw.site.stats.pagesInCategory(categoryName, "pages") or 0
	end)
	return success and count or 0
end

local function createCategoryLink(language, template)
	local categoryName = template.prefix .. language 
	local linkText = template.label .. language
	return string.format(
		"[[Special:RecentChangesLinked/Kategori:%s|%s]]",
		categoryName,
		linkText
	)
end

local function generateTypeRows(languages, categoryType)
	local template = CATEGORY_TEMPLATES[categoryType]
	if not template then
		error("Invalid category type: " .. tostring(categoryType))
	end

	local rows = {}

	local countCells = {}
	for _, language in ipairs(languages) do
		local categoryName = template.prefix .. language
		local count = getPageCount(categoryName)
		table.insert(countCells, string.format("<th>%d</th>", count))
	end

	table.insert(rows, '<tr class="primary">' .. table.concat(countCells) .. '</tr>')

	local linkCells = {}
	for _, language in ipairs(languages) do
		local link = createCategoryLink(language, template)
		table.insert(linkCells, "<th>" .. link .. "</th>")
	end

	table.insert(rows, '<tr class="secondary">' .. table.concat(linkCells) .. '</tr>')
	return rows
end

local function processLanguages(languageCodes)
	local languageData = mw.loadData("Module:languages/code to canonical name")
	local languages = {}
	for _, code in ipairs(languageCodes) do
		local language = languageData[code]
		if language and language ~= "" then
			table.insert(languages, language)
		else
			error("Invalid or empty language code: " .. tostring(code))
		end
	end
	return languages
end

local function splitIntoGroups(languageCodes)
	local groups = {}
	local currentGroup = {}
	local lastWasSeparator = true

	for _, code in ipairs(languageCodes) do
		if code == CONFIG.LINE_BREAK_SEPARATOR then
			if lastWasSeparator then
				error("Invalid separator placement: separators cannot be consecutive or at the beginning/end")
			end
			if #currentGroup > 0 then
				table.insert(groups, currentGroup)
				currentGroup = {}
			end
			lastWasSeparator = true
		else
			table.insert(currentGroup, code)
			lastWasSeparator = false
		end
	end

	if lastWasSeparator and #languageCodes > 0 then
		error("Invalid separator placement: separators cannot be consecutive or at the beginning/end")
	end

	if #currentGroup > 0 then
		table.insert(groups, currentGroup)
	end

	return groups
end

local function getTableOpenTag(style)
	local baseClass = 'class="infobox langtrack"'
	if style == "wide" then
		return string.format('<table %s style="table-layout: fixed; width: 100%%">', baseClass)
	else
		return string.format('<table %s>', baseClass)
	end
end

local function generateTableSection(languages, type)
	local rows = {}

	if type == "lemma" or type == "both" or type == "all" then
		local lemmaRows = generateTypeRows(languages, "lemma")
		for _, row in ipairs(lemmaRows) do
			table.insert(rows, row)
		end
	end

	if type == "nonlemma" or type == "both" or type == "all" then
		local nonlemmaRows = generateTypeRows(languages, "nonlemma")
		for _, row in ipairs(nonlemmaRows) do
			table.insert(rows, row)
		end
	end

	if type == "alternative" or type == "all" then
		local alternativeRows = generateTypeRows(languages, "alternative")
		for _, row in ipairs(alternativeRows) do
			table.insert(rows, row)
		end
	end

	return rows
end

function export.show(frame)
	local args = require("Module:parameters").process(
		frame:getParent().args,
		{
			[1] = {
				list = true,
				required = true,
				allow_empty = false
			},
			["type"] = {
				set = CONFIG.VALID_TYPES,
				default = CONFIG.DEFAULT_TYPE
			},
			["style"] = {
				set = CONFIG.VALID_STYLES,
				default = CONFIG.DEFAULT_STYLE
			},
		}
	)
	local languageGroups = splitIntoGroups(args[1])
	if #languageGroups == 0 then
		error("No valid language codes found.")
	end
	local output = { getTableOpenTag(args.style) }

	for i, languageCodes in ipairs(languageGroups) do
		local languages = processLanguages(languageCodes)
		if #languages > 0 then
			local sectionRows = generateTableSection(languages, args.type)
			for _, row in ipairs(sectionRows) do
				table.insert(output, row)
			end

			if i < #languageGroups then
				table.insert(output,
					'<tr class="separator"><td colspan="' ..
					#languages .. '" style="height: 10px; border: none;"></td></tr>')
			end
		end
	end

	table.insert(output, "</table>")
	table.insert(output, frame:extensionTag("templatestyles", nil, { src = "Template:language tracking/styles.css" }))

	return table.concat(output)
end

return export