Module:Category tree/charactercat

From The Languages of David J. Peterson
Jump to navigation Jump to search

Documentation for this module may be created at Module:Category tree/charactercat/documentation

local export = {}

-- Category object

local Category = {}
Category.__index = Category


local function is_combining(character)
	return mw.ustring.len(character) == 1 and require("Module:Unicode_data").is_combining(mw.ustring.codepoint(character))
end

--[[
	If self._info.label is a combining character, returns a version with a dotted
	circle before it
]]
function Category:add_dotted_circle()
	local character = self._info.label
	if self._info.combining then
		return "◌" .. character
	end
	return character
end


function Category.new_main(frame)
	local pagename = mw.title.getCurrentTitle().text
	
	local params = {
		[1] = {},
		[2] = {},
		sort = {},
		-- Not sure what used to be done with the following parameters.
		context = {},
		context2 = {},
	}
	
	local args = require("Module:parameters").process(frame:getParent().args, params)
	
	local code = args[1]
	local character = args.link or args[2]
	local alt = args.link and args[2]
	
	local description, langName, lang
	
	--[[
		"description" is in reference to categories like "Hebrew terms spelled with gershayim",
		in which the title does not contain the character itself.
		Perhaps there is a better word for this.
	]]
	langName, description = mw.ustring.match(pagename, "^(.+) terms spelled with (.+)$")
	if not langName then
		error("Module:category tree/charactercat did not recognize the page title.")
	end

	if not code then
		lang = require("Module:languages").getByCanonicalName(langName) or
			error('The language name "' .. langName .. '" in the page title is not valid.')
	end
		
	return Category.new{
		lang = lang,
		code = code,
		label = character,
		alt = alt,
		desc = description,
		sort = args.sort
	}
end


function Category.new(info)
	local validKeys = {
		lang = true,
		code = true,
		label = true,
		alt = true,
		desc = true,
		sort = true,
	}
	for key, val in pairs(info) do
		if not validKeys[key] then
			error("The parameter \"" .. key .. "\" was not recognized.")
		end
	end
	
	if info.label then
		if info.desc == info.label then
			info.desc = nil
		else
			require("Module:debug").track("charactercat/manual char")
		end
	elseif info.desc then
		info.label = info.desc
		info.desc = nil
	end
	
	local self = setmetatable({}, Category)
	self._info = info
	
	self._info.combining = is_combining(self._info.label)
	
	if self._info.lang or self._info.code then
		self._lang = self._info.lang or require("Module:languages").getByCode(self._info.code) or require("Module:languages").err(self._info.code, 1)
		self._info.lang = nil
	else
		error("No language code or language object was given to the function Category.new.")
	end
	
	local label = info.label
	local upper = mw.ustring.upper(label)
	if label ~= upper
			and mw.ustring.len(label) == 1
			and not mw.ustring.find(upper, "[" .. self._lang:getStandardCharacters() .. "]") then
		error("Category titles should use uppercase characters.")
	end
	
	return self
end

export.new = Category.new
export.new_main = Category.new_main


function Category:getInfo()
	return self._info
end


function Category:getBreadcrumbName()
	return self._info.desc or require("Module:script utilities").tag_text(self:add_dotted_circle(), self._lang, nil, "term")
end


function Category:getDataModule()
	return "Module:category tree/charactercat"
end


function Category:canBeEmpty()
	return false
end


function Category:isHidden()
	return false
end


function Category:getCategoryName()
	return self._lang:getCanonicalName() .. " terms spelled with " .. ( self._info.desc or self._info.label )
end


function Category:getDescription()
	if self._info.combining and self._info.alt then
		require("Module:debug").track("charactercat/alt ignored")
	end
	
	-- If the letter has a lowercase form, show it.
	local character = require("Module:links").full_link(
		{
			term = self._info.label,
			alt = self._info.combining and self:add_dotted_circle() or self._info.alt,
			lang = self._lang,
			tr = self._info.combining and "-" or nil,
		},
		"term"
	)
	if mw.ustring.lower(self._info.label) ~= self._info.label then
		character = "upper case " .. character .. " or lower case " ..
			require("Module:links").full_link(
				{
					term = mw.ustring.lower(self._info.label),
					lang = self._lang
				},
				"term"
			)
	end
	
	if self._info.desc then
		character = character .. " (" .. self._info.desc .. ")"
	end
	
	if self._lang:getCode() == "ja" and not self._info.sort then
		character = character .. "[[Category:Charactercat usage missing parameter sort]]"
	end
	
	local labelRegex = require("Module:string").pattern_escape(self._info.label)
	if mw.ustring.find(self:getCategoryName(), labelRegex .. "$") then
		mw.getCurrentFrame():callParserFunction(
			"DISPLAYTITLE",
			"Category:" ..
				mw.ustring.gsub(
					self:getCategoryName(),
					labelRegex .. "$",
					require("Module:script utilities").tag_text(self._info.label, self._lang, nil, "term")
				)
		)
	end
	
	return "This category lists " .. self._lang:getCanonicalName() ..
		" terms spelled with " .. character .. "."
end


function Category:getParents()
	local sortkey
	if self._info.sort then
		sortkey = self._info.sort
	else
		sortkey = self._lang:makeSortKey(self._info.label)
		if sortkey == "" then
			sortkey = self._info.label
		end
	end
	
	return {
		{
			name = require("Module:category tree/poscatboiler")
				.new {
					code = self._info.code or self._lang:getCode(),
					label = "terms by their individual characters",
				},
			sort = sortkey,
		}
	}
end


function Category:getChildren()
	return nil
end


function Category:getUmbrella()
	return nil
end


return export