본문으로 이동

모듈:category tree/names

위키낱말사전, 말과 글의 누리

이 모듈에 대한 설명문서는 모듈:category tree/names/설명문서에서 만들 수 있습니다

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

local names_module = "Module:names"


-----------------------------------------------------------------------------
--                                                                         --
--                                  레이블                                 --
--                                                                         --
-----------------------------------------------------------------------------


labels["이름"] = {
	description = "특정 개인이나 집단을 가리키는 데 사용되는 {{{langname}}} 낱말 (이름).",
	additional = "지명, 민족명 등 다른 종류의 이름은 [[:분류:이름]]에서 찾을 수 있습니다.",
	umbrella_parents = {name = "terms by semantic function", is_label = true, sort = " "},
	parents = {"terms by semantic function", "고유 명사"},
}

------------------------------------------- given names -------------------------------------------

local human_genders = {
	["남자"] = "남성 개인에게 주어지는",
	["여자"] = "여성 개인에게 주어지는",
	["남녀 공용"] = "남성 또는 여성 개인에게 주어지는",
}


for gender, props in pairs(require(names_module).given_name_genders) do
	if gender ~= "알 수 없는 성별" then
		local is_animal = props.type == "animal"
		
		local cat = gender .. " 이름"
		local desc = is_animal and gender .. "에 주어지는" or human_genders[gender]
		
		local function do_cat(cat, desc, breadcrumb, parents)
			labels[cat] = {
				description = "{{{langname}}} " .. desc .. " 이름.",
				breadcrumb = breadcrumb,
				parents = parents,
			}
		end
		
		for _, dimaug in ipairs { "diminutive", "augmentative" } do
			local dimaug_ko = (dimaug == "diminutive" and "지소사" or "확대사")
			do_cat(dimaug .. "s of " .. cat, desc .. " 이름의 " .. dimaug_ko, dimaug,
				{gender .. " 이름", dimaug .. " nouns"})
		end
		do_cat(cat, desc, gender, is_animal and (gender == "동물" and "names" or is_animal and
			"animal names") or "given names")
		if not is_animal then
			do_cat(gender .. " skin names", desc .. " 스킨 네임", gender_ko, {"skin names"})
		end
	end
end

labels["given names"] = {
	description = "개인에게 주어지는 {{{langname}}} 이름.",
	parents = {"이름"},
}

labels["skin names"] = {
	description = "특정 혼인 계급의 개인을 지칭하기 위해 출생 시 주어지는 {{{langname}}} 용어.",
	parents = {"고유 명사", "이름"},
}

------------------------------------------- 성씨 -------------------------------------------

labels["common-gender surnames"] = {
	description = "남성 및 여성 성씨를 구별하는 언어에서, 남성과 여성 가족 구성원이 모두 공유하는 {{{langname}}} 성씨.",
	breadcrumb = "통성",
	parents = {"surnames"},
}

labels["female surnames"] = {
	description = "여성 가족 구성원이 공유하는 {{{langname}}} 성씨.",
	breadcrumb = "여성",
	parents = {"surnames"},
}

labels["male surnames"] = {
	description = "남성 가족 구성원이 공유하는 {{{langname}}} 성씨.",
	breadcrumb = "남성",
	parents = {"surnames"},
}

labels["surnames"] = {
	description = "가족 구성원이 공유하는 {{{langname}}} 이름 (성씨).",
	parents = {"이름"},
}

for _, nymics in ipairs { "matronymics", "patronymics" } do
	local nymics_ko, ancestor
	if nymics == "matronymics" then
		nymics_ko = "모성성"
		ancestor = "어머니, 할머니 또는 더 이른 여성 조상"
	else
		nymics_ko = "부성성"
		ancestor = "아버지, 할아버지 또는 더 이른 남성 조상"
	end
	
	labels["common-gender " .. nymics] = {
		description = ("남성 및 여성 " .. nymics_ko .. "을 구별하는 언어에서, 남성과 여성이 모두 자신의 %s을(를) 나타내기 위해 사용하는 {{{langname}}} 이름."):
			format(ancestor),
		breadcrumb = "통성",
		parents = {nymics},
	}
	
	labels["female " .. nymics] = {
		description = ("여성이 자신의 %s을(를) 나타내기 위해 사용하는 {{{langname}}} 이름."):format(ancestor),
		breadcrumb = "여성",
		parents = {nymics},
	}
	
	labels["male " .. nymics] = {
		description = ("남성이 자신의 %s을(를) 나타내기 위해 사용하는 {{{langname}}} 이름."):format(ancestor),
		breadcrumb = "남성",
		parents = {nymics},
	}
	
	labels[nymics] = {
		description = ("개인의 %s을(를) 나타내는 {{{langname}}} 이름."):format(ancestor),
		parents = {"이름"},
	}
end

labels["nomina gentilia"] = {
	description = "{{{langname}}}의 [[w:ko:로마식 작명법|전통 로마식 이름]]에서의 \"[[가문명]]\" (단수형 ''[[nomen gentile]]'').",
	parents = {"이름"},
}

------------------------------------------- 기타 -------------------------------------------

labels["exonyms"] = {
	description = "{{{langname}}} [[외국어 지명]], 즉 {{{langname}}}에서의 지명 이름이 원어에서의 이름과 다른 경우.",
	parents = {"이름"},
}

labels["renderings of foreign personal names"] = {
	description = "외국 인명의 {{{langname}}} 음역, 재표기 또는 기타 표기.",
	parents = {"이름"},
}

-- 'umbrella_parents' 키가 없는 경우 추가.
for key, data in pairs(labels) do
	if not data.umbrella_parents then
		data.umbrella_parents = "언어별 이름 하위 분류"
	end
end

-----------------------------------------------------------------------------
--                                                                         --
--                              원시(RAW) 분류                             --
--                                                                         --
-----------------------------------------------------------------------------


raw_categories["언어별 이름 하위 분류"] = {
	description = "이름과 관련된 주제를 다루는 포괄 분류.",
	additional = "{{{umbrella_meta_msg}}}",
	parents = {
		"포괄 메타분류",
		{name = "이름", is_label = true, sort = " "},
	},
}


-----------------------------------------------------------------------------
--                                                                         --
--                                  핸들러                                 --
--                                                                         --
-----------------------------------------------------------------------------


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("성씨") 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 "[[:분류:{{{langname}}} 성씨에서 유래한 " .. nametype .. "]]" or
			"[[:분류:언어별 성씨에서 유래한 " .. nametype .. "]]"
		) .. " 문서를 참고하십시오."
	elseif source == "보통 명사" then origintext = "보통 명사에서 유래"
	elseif source == "월 이름" then origintext = "월 이름에서 유래"
	elseif source == "신조어" then origintext = "신조어로서 유래"
		addltext = " 인위적으로 만들어진 이름, 허구의 인물에 기반한 이름, 두 단어나 이름의 조합, 또는 역순 철자 이름 등이 여기에 해당합니다. 기원이 불확실한 이름도 신조어일 가능성이 높다면 여기에 분류될 수 있습니다."
	elseif source == "직업" then origintext = "직업명에서 유래"
	elseif source == "부성성" then origintext = "부성성에서 유래"
	elseif source == "모성성" then origintext = "모성성에서 유래"
	elseif source == "민족명" then origintext = "민족명에서 유래"
	elseif source == "성경" then origintext = "성경에서 유래"
	elseif type(source) == "string" then
		error("내부 오류: 인식할 수 없는 문자열 출처 \"" .. source .. "\". 특별 처리 필요.")
	else
		origintext = source:makeCategoryLink() .. "에서 유래"
		if lang and source:getCode() == lang:getCode() then
			addltext = " 보통 명사, 지역 신화 등에서 파생된 이름이 여기에 해당합니다."
		end
	end
	local introtext = lang and "{{{langname}}} " or "여러 언어의 "
	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("^(f?e?male) (given names)$")
	if not gender then
		gender, label = nametype:match("^(unisex) (given names)$")
	end
	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 = "terms derived from " .. 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 full 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.
			if source:hasType("family") then
				local parent_family = source:getFamily()
				if parent_family and parent_family:getCode() ~= "qfa-not" then
					table.insert(parents, {
						name = nametype .. " from " .. parent_family:getDisplayForm(),
						sort = source:getCanonicalName()
					})
				end
			elseif source:hasType("etymology-only") then
				local source_parent = source:getFull()
				if source_parent and source_parent:getCode() ~= "und" then
					table.insert(parents, {
						name = nametype .. " from " .. source_parent:getDisplayForm(),
						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 = nametype .. " from " .. high_level_family:getDisplayForm(),
						sort = source:getCanonicalName()
					})
				end
			end
		end
	
		local gender, label = match_gendered_nametype(nametype)
		if gender then
			table.insert(parents, {name = label .. " from " .. get_source_text(source), sort = gender})
		end
	else
		local gender, label = match_gendered_nametype(nametype)
		if gender then
			table.insert(parents, {name = label .. " from " .. get_source_text(source), is_label = true, sort = " "})
		elseif type(source) == "table" then
			-- FIXME! This is duplicated in [[Module:category tree/etymology]] in the handler for umbrella categories
			-- 'Terms derived from SOURCE'.
			local first_umbrella_parent =
				source:hasType("family") and {name = source:getCategoryName(), raw = true, sort = " "} or
				source:hasType("etymology-only") 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, "Names subcategories by language")
	end
	
	return parents
end

table.insert(handlers, function(data)
	local source_name, nametype = data.label:match("^(.+)에서 유래한 (.* 이름)$")
	if nametype then
		local personal_name_type_set = require(names_module).personal_name_type_set
		if not personal_name_type_set[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 = source_name .. "에서 유래",
			parents = get_parents(data.lang, nametype, source),
			umbrella = {
				description = get_description(nil, nametype, source),
				parents = get_parents(nil, nametype, source),
			},
		}
	end
end)

-- Handler for e.g. 'English renderings of Russian male given names'.
table.insert(handlers, function(data)
	local label = data.label:match("^(.+)의 표기$")
	if label then
		local personal_name_types = require(names_module).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 = source:makeCategoryLink() .. " " .. nametype .. "의 {{{langdisp}}} 음역, 재표기 또는 기타 표기.",
						lang = data.lang,
						breadcrumb = sourcename .. " " .. nametype,
						parents = {
							{ name = "renderings of foreign personal names", sort = sourcename },
							{ name = nametype, lang = source:getCode(), sort = "{{{langname}}}" },
						},
						umbrella = {
							description = source:makeCategoryLink() .. " " .. nametype .. "의 여러 언어로 된 음역, 재표기 또는 기타 표기.",
							parents = {{name = "renderings of foreign personal names", is_label = true, sort = label}},
						},
					}
				end
			end
		end
	end
end)


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