模組:Category tree/poscatboiler/data/names/sandbox


此數據子模塊定義了維基詞典分類結構的一部分。

關於poscatboiler系統的介紹以及如何添加或更改分類,請參見Module:category tree/poscatboiler/data/documentation


local labels = {}
local raw_categories = {}
local handlers = {}
local raw_handlers = {}



-----------------------------------------------------------------------------
--                                                                         --
--                                  LABELS                                 --
--                                                                         --
-----------------------------------------------------------------------------


labels["名字"] = {
	description = "用於指代特定個人或群體的{{{langname}}}詞語。",
	umbrella_parents = {name = "依語義分類的", is_label = true, sort = " "},
	parents = {"依語義分類的", "專有名詞"},
}

labels["女性人名暱稱"] = {
	description = "賦予女性個體的{{{langname}}}昵稱。",
	parents = {"女性人名", "diminutive nouns"},
}

labels["男性人名暱稱"] = {
	description = "賦予男性個體的{{{langname}}}昵稱。",
	parents = {"男性人名", "diminutive nouns"},
}

labels["女性人名"] = {
	description = "賦予女性個體的{{{langname}}}名字。",
	parents = {"人名"},
}

labels["人名"] = {
	description = "賦予個體的{{{langname}}}名字。",
	parents = {"名字"},
}

labels["男性人名"] = {
	description = "賦予男性個體的{{{langname}}}名字。",
	parents = {"人名"},
}

labels["母名"] = {
	description = "表明一個人的母親、祖母或較早的女性祖先的{{{langname}}}名字。",
	parents = {"名字"},
}

labels["父名"] = {
	description = "表明一個人的父親、祖父或較早的男性祖先的{{{langname}}}名字。",
	parents = {"名字"},
}

labels["姓氏"] = {
	description = "用於表示一個人的家族血緣關係的{{{langname}}}標誌和符號。",
	parents = {"名字"},
}

labels["中性人名"] = {
	description = "賦予男性或女性個體的{{{langname}}}名字。",
	parents = {"人名"},
}

labels["氏族名"] = {
	description = "{{{langname}}}中氏族的名稱。",
	parents = {"名字"},
}

labels["家名"] = {
	description = "{{{langname}}}中家屋的名稱。",
	parents = {"名字"},
}

labels["地名"] = {
	description = "{{{langname}}}中某地的名字。",
	parents = {"名字"},
}

-- Add 'umbrella_parents' key if not already present.
for key, data in pairs(labels) do
	if not data.umbrella_parents then
		data.umbrella_parents = "名字子分類"
	end
end



-----------------------------------------------------------------------------
--                                                                         --
--                              RAW CATEGORIES                             --
--                                                                         --
-----------------------------------------------------------------------------


raw_categories["名字子分類"] = {
	description = "Umbrella categories covering topics related to names.",
	additional = "{{{umbrella_meta_msg}}}",
	parents = {
		"Umbrella metacategories",
		{name = "名字", is_label = true, sort = " "},
	},
}


-----------------------------------------------------------------------------
--                                                                         --
--                                 HANDLERS                                --
--                                                                         --
-----------------------------------------------------------------------------


local function source_name_to_source(nametype, source_name)
	local special_sources
	if nametype:find("人名") then
		special_sources = require("Module:table").listToSet {
			"姓氏", "地名", "新詞", "聖經"
		}
	elseif nametype:find("surnames") then
		special_sources = require("Module:table").listToSet {
			"人名", "地名", "職業", "父名",
			"通名", "昵稱"
		}
	else
		special_sources = {}
	end
	if special_sources[source_name] then
		return source_name
	else
		return require("Module:languages").getByCanonicalName(source_name, nil,
			"allow etym langs", "allow families")
	end
end

local function get_source_text(source)
	if type(source) == "table" then
		return source:getDisplayForm()
	else
		return source
	end
end

local function get_description(lang, nametype, source)
	local origintext, addltext
	if source == "姓氏" then
		origintext = "來自姓氏"
	elseif source == "人名" then
		origintext = "來自人名"
	elseif source == "昵稱" then
		origintext = "來自昵稱"
	elseif source == "地名" then
		origintext = "來自地名"
		addltext = " 對於亦作姓用的地名,請參見" .. (
			lang and "[[:Category:來自姓氏的{{{langname}}} " .. nametype .. "]]" or
			"[[:Category:來自姓氏的" .. nametype .. "]]"
		) .. "。"
	elseif source == "通名" then
		origintext = "來自通名"
	elseif source == "新詞" then
		origintext = "起源於人造新詞"
		addltext = "包括人造名字、基於虛構人物的名字、兩個單詞或名字的組合。對於來源不明的名字,如果強烈懷疑它們是新詞,也可以收錄在本分類中。"
	elseif source == "職業" then
		origintext = "起源於職業"
	elseif source == "父名" then
		origintext = "起源於父名"
	elseif source == "聖經" then
		-- Hack esp. for Hawaiian names. We should consider changing them to
		-- have the source as Biblical Hebrew and mention the derivation from
		-- the Bible some other way.
		origintext = "起源於聖經"
	elseif type(source) == "string" then
		error("內部錯誤:無法識別的來源\"" .. source .. "\",只能填寫特定的幾種")
	else
		local catname = source:getCategoryName()
		origintext = "源自[[:Category:" .. catname .. "|" .. catname .. "]]"
		if lang and source:getCode() == lang:getCode() then
			addltext = "這些名字來源於普通的名詞、當地的神話等。"
		end
	end
	local introtext
	if lang then
		introtext = "{{{langname}}}"
	else
		introtext = "本分類收錄"
	end
	return introtext .. nametype .. origintext ..
		"。(包括在該語言的較早階段派生出的名字。)" .. (addltext or "")
end

-- If one of the following families occurs in any of the ancestral families
-- of a given language, use it instead of the three-letter parent
-- (or immediate parent if no three-letter parent).
local high_level_families = require("Module:table").listToSet {
	-- Indo-European
	"gem", -- Germanic (for gme, gmq, gmw)
	"inc", -- Indic (for e.g. pra = Prakrit)
	"ine-ana", -- Anatolian (don't keep going to ine)
	"ine-toc", -- Tocharian (don't keep going to ine)
	"ira", -- Iranian (for e.g. xme = Median, xsc = Scythian)
	"sla", -- Slavic (for zle, zls, zlw)
	-- Other
	"ath", -- Athabaskan (for e.g. apa = Apachean)
	"poz", -- Malayo-Polynesian (for e.g. pqe = Eastern Malayo-Polynesian)
	"cau-nwc", -- Northwest Caucasian
	"cau-nec", -- Northeast Caucasian
}

local function find_high_level_family(lang)
	local family = lang:getFamily()
	-- (1) If no family, return nil (e.g. for Pictish).
	if not family then
		return nil
	end
	-- (2) See if any ancestor family is in `high_level_families`.
	-- if so, return it.
	local high_level_family = family
	while high_level_family do
		local high_level_code = high_level_family:getCode()
		if high_level_code == "qfa-not" then
			-- "not a family"; its own parent, causing an infinite loop.
			-- Break rather than return so we get categories like
			-- [[Category:English female given names from sign languages]] and
			-- [[Category:English female given names from constructed languages]].
			break
		end
		if high_level_families[high_level_code] then
			return high_level_family
		end
		high_level_family = high_level_family:getFamily()
	end
	-- (3) If the family is of the form 'FOO-BAR', see if 'FOO' is a family.
	-- If so, return it.
	local basic_family = family:getCode():match("^(.-)%-.*$")
	if basic_family then
		basic_family = require("Module:families").getByCode(basic_family)
		if basic_family then
			return basic_family
		end
	end
	-- (4) Fall back to just the family itself.
	return family
end

local function match_gendered_nametype(nametype)
	local gender, label = nametype:match("^([男女中]性)(人名)$")
	if gender then
		return gender, label
	end
end

local function get_parents(lang, nametype, source)
	local parents = {}

	if lang then
		table.insert(parents, {name = nametype, sort = get_source_text(source)})
		if type(source) == "table" then
			table.insert(parents, {name = "派生自" .. source:getDisplayForm() .. "的", sort = " "})
			-- If the source is a regular language, put it in a parent category for the high-level language family, e.g. for
			-- "Russian female given names from German", put it in a parent category "Russian female given names from Germanic languages"
			-- (skipping over West Germanic languages).
			--
			-- If the source is an etymology language, put it in a parent category for the parent non-etymology language, e.g. for
			-- "French male given names from Gascon", put it in a parent category "French male given names from Occitan".
			--
			-- If the source is a family, put it in a parent category for the parent family.
			local sourcetype = source:getType()
			if sourcetype == "family" then
				local parent_family = source:getFamily()
				if parent_family and parent_family:getCode() ~= "qfa-not" then
					table.insert(parents, {
						name = "來自" .. parent_family:getDisplayForm() .. "的" .. nametype,
						sort = source:getCanonicalName()
					})
				end
			elseif sourcetype == "etymology language" then
				local source_parent = require("Module:languages").getNonEtymological(source)
				if source_parent and source_parent:getCode() ~= "und" then
					table.insert(parents, {
						name = "來自" ..source_parent:getDisplayForm() .. "的" .. nametype,
						sort = source:getCanonicalName()
					})
				end
			else
				local high_level_family = find_high_level_family(source)
				if high_level_family then -- may not exist, e.g. for Pictish
					table.insert(parents,
						{name = "來自" .. high_level_family:getDisplayForm() .. "的" .. nametype,
						sort = source:getCanonicalName()
					})
				end
			end
		end
	
		local gender, label = match_gendered_nametype(nametype)
		if gender then
			table.insert(parents, {name = "來自" .. get_source_text(source) .. "的" .. label, sort = gender})
		end
	else
		local gender, label = match_gendered_nametype(nametype)
		if gender then
			table.insert(parents, {name = "來自" .. get_source_text(source) .. "的" .. label, is_label = true, sort = " "})
		elseif type(source) == "table" then
			-- FIXME! This is duplicated in [[Module:category tree/poscatboiler/data/terms by etymology]] in the
			-- handler for umbrella categories 'Terms derived from SOURCE'.
			local first_umbrella_parent =
				source:getType() == "family" and {name = source:getCategoryName(), raw = true, sort = " "} or
				source:getType() == "etymology language" and {name = "Category:" .. source:getCategoryName(), sort = nametype} or
				{name = source:getCategoryName(), raw = true, sort = nametype}
			table.insert(parents, first_umbrella_parent)
		end
		table.insert(parents, "名字子分類")
	end
	
	return parents
end

table.insert(handlers, function(data)
	local source_name, nametype = data.label:match("^來自(.+)的(.*[字稱名氏])$")
	if nametype then
		local m_table = require("Module:table")
		local personal_name_types = m_table.listToSet(require("Module:names").personal_name_types)
		if not personal_name_types[nametype] then
			return nil
		end
		local source = source_name_to_source(nametype, source_name)
		if not source then
			return nil
		end
		return {
			description = get_description(data.lang, nametype, source),
			breadcrumb = "來自" .. get_source_text(source),
			parents = get_parents(data.lang, nametype, source),
			umbrella = {
				description = get_description(nil, nametype, source),
				parents = get_parents(nil, nametype, source),
			},
		}
	end
end)



-----------------------------------------------------------------------------
--                                                                         --
--                                RAW HANDLERS                             --
--                                                                         --
-----------------------------------------------------------------------------


-- Handler for e.g. 'en:Russian male given names'.
table.insert(raw_handlers, function(data)
	local langcode, label = data.category:match("^([a-z-]+):(.*)$")
	if langcode then
		local personal_name_types = require("Module:names").personal_name_types
		for _, nametype in ipairs(personal_name_types) do
			local sourcename = label:match("^(.+) " .. nametype .. "$")
			
			if sourcename then
				local source = require("Module:languages").getByCanonicalName(sourcename, nil, "allow etym")
				if source then
					return {
						description = "Transliterations of " .. source:makeCategoryLink() .. " " .. nametype .. " into {{{langlink}}}.",
						lang = langcode,
						breadcrumb = sourcename .. " " .. nametype,
						parents = {
							{ module = "topic cat", args = {code = "{{{langcode}}}", label = "Transliteration of personal names"}, sort = sourcename },
							{ name = nametype, is_label = true, lang = source:getCode(), sort = "{{{langname}}}" },
						},
					}
				end
			end
		end
	end
end)


return {LABELS = labels, RAW_CATEGORIES = raw_categories, HANDLERS = handlers, RAW_HANDLERS = raw_handlers}