본문으로 이동

모듈:etymology

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

하위 모듈

[편집]

local export = {}

local force_cat = false

local debug_track_module = "Module:debug/track"
local languages_module = "Module:languages"
local links_module = "Module:also/link"
local pron_qualifier_module = "Module:pron qualifier"
local table_module = "Module:table"
local utilities_module = "Module:utilities"

local concat = table.concat
local insert = table.insert
local new_title = mw.title.new

local function debug_track(...)
	debug_track = require(debug_track_module)
	return debug_track(...)
end

local function format_categories(...)
	format_categories = require(utilities_module).format_categories
	return format_categories(...)
end

local function format_qualifiers(...)
	format_qualifiers = require(pron_qualifier_module).format_qualifiers
	return format_qualifiers(...)
end

local function full_link(...)
	full_link = require(links_module).full_link
	return full_link(...)
end

local function get_language_data_module_name(...)
	get_language_data_module_name = require(languages_module).getDataModuleName
	return get_language_data_module_name(...)
end

local function get_link_page(...)
	get_link_page = require(links_module).get_link_page
	return get_link_page(...)
end

local function language_link(...)
	language_link = require(links_module).language_link
	return language_link(...)
end

local function serial_comma_join(...)
	serial_comma_join = require(table_module).serialCommaJoin
	return serial_comma_join(...)
end

local function shallow_copy(...)
	shallow_copy = require(table_module).shallowCopy
	return shallow_copy(...)
end

local function track(page, code)
	local tracking_page = "etymology/" .. page
	debug_track(tracking_page)
	if code then
		debug_track(tracking_page .. "/" .. code)
	end
end

local function join_segs(segs, conj)
	if not segs[2] then
		return segs[1]
	elseif conj == "and" or conj == "or" then
		return serial_comma_join(segs, {conj = conj})
	end
	
	local sep
	if conj == "," or conj == ";" then
		sep = conj .. " "
	elseif conj == "/" then
		sep = "/"
	elseif conj == "~" then
		sep = " ~ "
	elseif conj then
		error(("내부 오류: 인식할 수 없는 접속사 \"%s\""):format(conj))
	else
		error(("내부 오류: 접속사 값이 없습니다"):format(conj))
	end
	return concat(segs, sep)
end

local function lang_is_source(lang, source)
	return lang:getCode() == source:getCode() or lang:hasParent(source)
end

function export.format_links(termobjs, conj, template_name)
	for i, termobj in ipairs(termobjs) do
		local term = termobj.term
		if termobj.lang:hasType("family") then
			if term and term ~= "-" then
				debug_track(template_name .. "/family-with-term")
			end
			term = "-"
			termobj.term = term
		end
		template_name = template_name or "derived"
		if term == "-" then
			debug_track(template_name .. "/no-term")
			termobjs[i] = ""
		else
			termobjs[i] = full_link(termobj, "term", nil, "show qualifiers")
		end
	end
	local retval = join_segs(termobjs, conj)
	if retval ~= "" then
		retval = " " .. retval
	end
	return retval
end
	
function export.get_display_and_cat_name(source, raw)
	local display, cat_name
	if source:getCode() == "und" then
		display = "미확인 언어"
		cat_name = "기타 언어"
	elseif source:getCode() == "mul" then
		display = raw and "범언어" or "[[ko:w:범언어|범언어]]"
		cat_name = "범언어"
	elseif source:getCode() == "mul-tax" then
		display = raw and "학명" or "[[ko:w:생물학적 분류|학명]]"
		cat_name = "학명"
	else
		display = raw and source:getCanonicalName() or source:makeWikipediaLink()
		cat_name = source:getDisplayForm()
	end
	return display, cat_name
end

function export.insert_source_cat_get_display(data)
	local categories, lang, source = data.categories, data.lang, data.source
	local display, cat_name = export.get_display_and_cat_name(source, data.raw)
	if lang and not data.nocat then
		if not categories then
			categories = {}
		end
		local langname = lang:getFullName()
		
		if lang_is_source(lang, source) then
			insert(categories, cat_name .. "에서 다시 차용한 " .. langname .. " 낱말")
		else
			local borrowing_type = data.borrowing_type or "파생된"
			insert(categories, cat_name .. "에서 " .. borrowing_type .. " " .. langname .. " 낱말")
		end
	end
	return display, categories
end

function export.format_source(data)
	local lang, sort_key = data.lang, data.sort_key
	if sort_key then
		track("sortkey")
	end
	local display, categories = export.insert_source_cat_get_display(data)
	if lang and not data.nocat then
		categories = format_categories(categories, lang, sort_key, nil, data.force_cat or force_cat)
	else
		categories = ""
	end
		
	return "<span class=\"etyl\">" .. display .. categories .. "</span>"
end

function export.format_sources(data)
	local lang, sources, terms, borrowing_type, sort_key, categories, nocat =
		data.lang, data.sources, data.terms, data.borrowing_type, data.sort_key, data.categories, data.nocat
	local term1, sources_n, source_segs, final_link_page = terms[1], #sources, {}
	local term1_term, term1_sc = term1.term, term1.sc
	if sources_n > 1 and term1_term and term1_term ~= "-" then
		final_link_page = get_link_page(term1_term, sources[sources_n], term1_sc)
	end
	for i, source in ipairs(sources) do
		local seg, display_term
		if i < sources_n and term1_term and term1_term ~= "-" then
			local link_page = get_link_page(term1_term, source, term1_sc)
			display_term = (link_page ~= final_link_page) or (link_page and new_title(link_page).exists)
		end
		if display_term then
			local display, this_cats = export.insert_source_cat_get_display{
				lang = lang,
				source = source,
				borrowing_type = borrowing_type,
				raw = true,
				categories = categories,
				nocat = nocat,
			}
			seg = language_link{
				lang = source,
				term = term1_term,
				alt = display,
				tr = "-",
			}
			if lang and not nocat then
				this_cats = format_categories(this_cats, lang, sort_key, nil, data.force_cat or force_cat)
			else
				this_cats = ""
			end
			seg = "<span class=\"etyl\">" .. seg .. this_cats .. "</span>"
		else
			seg = export.format_source{
				lang = lang,
				source = source,
				borrowing_type = borrowing_type,
				sort_key = sort_key,
				categories = categories,
				nocat = nocat,
			}
		end
		insert(source_segs, seg)
	end
	return join_segs(source_segs, data.sourceconj or "and")
end

-- Internal implementation of {{cognate|...}} template
function export.format_cognate(data)
	return export.format_derived{
		sources = data.sources,
		terms = data.terms,
		sort_key = data.sort_key,
		sourceconj = data.sourceconj,
		conj = data.conj,
		template_name = "cognate",
		force_cat = data.force_cat,
	}
end

-- {{der|...}} & {{차용|...}} 틀의 내부적 구현을 담당합니다. 
function export.format_derived(data)
	local terms = data.terms
	data.borrowing_type = "파생된"
	local result = export.format_sources(data) .. export.format_links(terms, data.conj, data.template_name)
	local q, qq, l, ll, refs = data.q, data.qq, data.l, data.ll, data.refs
	if q and q[1] or qq and qq[1] or l and l[1] or ll and ll[1] or refs and refs[1] then
		result = format_qualifiers{
			lang = terms[1].lang,
			text = result,
			q = q,
			qq = qq,
			l = l,
			ll = ll,
			refs = refs,
		}
	end
	return result
end

function export.insert_borrowed_cat(categories, lang, source)
	if lang_is_source(lang, source) then
		return
	end
	local _, cat_name = export.get_display_and_cat_name(source, "raw")
	insert(categories, cat_name .. "에서 차용한 " .. lang:getFullName() .. " 낱말")
end

function export.format_borrowed(data)
	local categories = {}
	if not data.nocat then
		local lang = data.lang
		for _, source in ipairs(data.sources) do
			export.insert_borrowed_cat(categories, lang, source)
		end
	end
	data = shallow_copy(data)
	data.categories = categories
	return export.format_sources(data) .. export.format_links(data.terms, data.conj, "borrowed")
end

do
	local function show_language(lang)
		local retval = ("%s (%s)"):format(lang:makeCategoryLink(), lang:getCode())
		if lang:hasType("etymology-only") then
			retval = retval .. (" (어원 전용 언어, 일반 상위 언어: %s)"):format(
				show_language(lang:getParent()))
		end
		return retval
	end

	function export.check_ancestor(lang, otherlang)
		if lang:hasAncestor(otherlang) then
			if otherlang:getFullCode() == "la" then
				otherlang = otherlang:getCode()
				if not (otherlang == "itc-ola" or otherlang == "la-cla" or otherlang == "la-vul") then
					track("bad ancestor", otherlang)
				end
			end
			return
		end
		local ancestors, postscript = lang:getAncestors()
		local etym_module_link = lang:hasType("etymology-only") and "[[모듈:etymology languages/data]] 또는 " or ""
		local module_link = "[[" .. get_language_data_module_name(lang:getFullCode()) .. "]]"
		if not ancestors[1] then
			postscript = show_language(lang) .. "에 조상 언어가 없습니다."
		else
			local ancestor_list = {}
			for _, ancestor in ipairs(ancestors) do
				insert(ancestor_list, show_language(ancestor))
			end
			local plural_s, verb_are
			if ancestors[2] then
				plural_s = "들은"
				verb_are = "다음과 같습니다"
			else
				plural_s = "는"
				verb_are = "입니다"
			end
			postscript = ("%s의 조상 언어%s %s: %s."):format(
				lang:getCanonicalName(), plural_s, verb_are, concat(ancestor_list, ", "))
		end
		error(("%s이(가) %s%s에서 %s의 조상 언어로 설정되지 않았습니다. %s")
			:format(show_language(otherlang), etym_module_link, module_link, show_language(lang), postscript))
	end
end

-- Internal implementation of {{inherited|...}} template
function export.format_inherited(data)
	local lang, terms, sort_key, nocat = data.lang, data.terms, data.sort_key, data.nocat
	local source = terms[1].lang
	
	local categories = {}
	if not nocat then
		insert(categories, source:getCanonicalName() .. "에서 물려받은 " .. lang:getFullName() .. " 낱말")
	end
	export.check_ancestor(lang, source)
	return export.format_source{
		lang = lang,
		source = source,
		sort_key = sort_key,
		categories = categories,
		nocat = nocat,
		force_cat = data.force_cat,
	} .. export.format_links(terms, data.conj, "inherited")
end

function export.format_misc_variant(data)
	local lang, notext, terms, cats, parts = data.lang, data.notext, data.terms, data.cats, {}
	local has_terms = terms and terms[1]

	-- 1. 낱말이 있으면 먼저 추가합니다.
	if has_terms then
		insert(parts, mw.text.trim(export.format_links(terms, data.conj, "misc_variant")))
	end

	-- 2. 텍스트가 있으면 낱말 뒤에 붙입니다.
	if not notext then
		if has_terms then
			-- 낱말이 있을 경우, 조사 '의'와 함께 텍스트를 붙입니다.
			insert(parts, (data.oftext or "의") .. " " .. data.text)
		else
			-- 낱말이 없을 경우, 텍스트만 표시합니다.
			insert(parts, data.text)
		end
	end

	-- 3. 분류를 추가합니다.
	local categories = {}
	if not data.nocat and cats then
		for _, cat in ipairs(cats) do
			insert(categories, lang:getFullName() .. " " .. cat)
		end
	end
	if #categories > 0 then
		insert(parts, format_categories(categories, lang, data.sort_key, nil, data.force_cat or force_cat))
	end
	
	return concat(parts)
end

function export.format_misc_variant_no_term(data)
	local parts = {}
	if not data.notext then
		insert(parts, data.title)
	end
	if not data.nocat and data.cat then
		local lang, categories = data.lang, {}
		insert(categories, lang:getFullName() .. " " .. data.cat)
		insert(parts, format_categories(categories, lang, data.sort_key, nil, data.force_cat or force_cat))
	end
	return concat(parts)
end

return export