본문으로 이동

모듈:okm-pron

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

이 모듈에 대한 설명문서는 모듈:okm-pron/설명문서에서 만들 수 있습니다

local export = {}

local okm_translit = require("Module:okm-translit")
local u = require("Module:string/char")
local format_IPA_full = require("Module:IPA").format_IPA_full
local lang_okm = require("Module:languages").getByCode("okm")
local tag_text = require("Module:script utilities").tag_text
local explode_utf8 = require("Module:string utilities").explode_utf8
local dgju = mw.loadData("Module:okm-pron/data").dgju

local pagename = mw.loadData("Module:headword/data").pagename

local tones = {
	L = u(0x0300), -- 평성 (平聲)
	["L!"] = "L!",
	H = u(0x0301), -- 거성 (去聲)
	["H!"] = "H!",
	R = u(0x030C), -- 상성 (上聲)
	["R!"] = "R!",
	X = "", -- 성조 없음
}

local tt = [==[
# vowels
o	ʌ
u	ɨ
wʌ	o
wɨ	u
yʌ	yo
yɨ	yu
e	ɘ
y	j

# 자음 변경자
([ktpc])h	%1ʰ # 격음
([ktpsh])%1	%1\u{0348} # 된소리
cc	t\u{0348}\u{0361}s # 된소리 발음 구별 기호가 사이에 들어가야 하므로 특별 처리

# 특별한 자음
c	t\u{0361}s
W	β
G	ɣ
OO	j # TODO: decide on a convention? missing in Wikipedia key
x	ʔ
ng	ŋ

# 위첨자 불규칙 성조 클래스
L!	<sup>L!</sup>
H!	<sup>H!</sup>
R!	<sup>R!</sup>
]==]

tt = mw.ustring.gsub(tt, "%s*#[^\n]+", "") -- 주석 제거
tt = mw.ustring.gsub(tt, "\n+", "\n") -- 빈 줄 제거
tt = mw.ustring.gsub(tt, [[\u{(%d+)}]], function(n) return u(tonumber(n, 16)) end) -- 유니코드 이스케이프 처리
tt = mw.text.trim(tt)

function pron(word, tone_raw, irreg)
	local tr = okm_translit.tr(word, "okm")
	if irreg == "t" then
		tr = mw.ustring.gsub(tr, "t([%.%-]?)ta", "T%1ta")
	elseif irreg == "p" then
		tr = mw.ustring.gsub(tr, "p([%.%-]?)ta", "W%1ta")
	elseif irreg == "s" then
		tr = mw.ustring.gsub(tr, "s([%.%-]?)ta", "z%1ta")
	end
	local tone = {}
	for v in mw.ustring.gmatch(tone_raw, "[LHRX]!?") do -- this matches X! too, but should be fine
		tone[#tone + 1] = v
	end
	local _, vowel_count = mw.ustring.gsub(tr, "[aeiou]", "")
	local pron, idx, start = "", 1, 1
	for i, c in ipairs(explode_utf8(tr)) do
		if mw.ustring.match(c, "[aeiou]") ~= nil or i == mw.ustring.len(tr) then
			local match = mw.ustring.sub(tr, start, i)
			pron = pron .. match .. tones[idx <= vowel_count and tone[idx] or "X"]
			start = i + 1
			idx = idx + 1
		end
	end
	for line in mw.text.gsplit(tt, '\n') do
		local _, __, pattern, repl = mw.ustring.find(line, '(.+)\t(.+)')
		pron = mw.ustring.gsub(pron, pattern, repl)
	end
	pron = mw.ustring.gsub(pron, "%.", "") -- strip syllable separators
	return mw.ustring.toNFC(pron)
end

function export.make(frame)
	local parent_args = frame:getParent().args
	local args = require("Module:parameters").process(parent_args, {
		[1] = { default = pagename, list = true },
		["tone"] = { list = true },
		["irreg"] = { list = true },
		["dg"] = { default = pagename },
		["dg_pron"] = { },
		["dg_id"] = { },
	})

	local items, items_ortho = {}, {}
    for i, e in ipairs(args[1]) do
        items[i] = {
        	pron = "⫽" .. pron(e, args["tone"][i], args["irreg"][i]) .. "⫽",
        }
    end
    
    local list = "* " .. format_IPA_full({
		lang = lang_okm,
		q = { "형태음소론적" },
		items = items,
	})

	local dg
	local dg_fragment = ""
	
	if args["dg_pron"] then
		dg = "[" .. args["dg_pron"]
	else
		dg = ""
		dg_fragment = "["
		local dg_id = mw.text.split(args["dg_id"] or "", ",")
		local dg_ind = 1
		local HangChars = require("Module:scripts").getByCode("Hang"):getCharacters()
		for c in mw.text.gsplit(args["dg"], "") do
			if dgju[c] then
				local dg_reading = dg_id[dg_ind] and dgju[c][tonumber(dg_id[dg_ind])] or nil
				if not dg_reading then
					local count = 0
					for _, _ in ipairs(dgju[c]) do
						count = count + 1
					end
					if count == 1 then
						dg_reading = dgju[c][1]
					end
				end
				dg_ind = dg_ind + 1
				if dg_reading then
					dg_fragment = dg_fragment .. dg_reading			
				else
					dg = dg .. tag_text(dg_fragment, lang_okm)
					dg_fragment = ""
					dg = dg .. "<strong class=\"error\">" .. tag_text(c, lang_okm) .. "의 독음을 선택하세요: "
					for i, head in pairs(dgju[c]) do
						if i ~= 1 then
							dg = dg .. ", "
						end
						dg = dg .. i .. "=" .. tag_text(head, lang_okm)
					end
					dg = dg .. " </strong>"
					require('Module:debug/track')("okm-pron/unspecified DGJU reading")
				end
			elseif mw.ustring.match(c, "[" .. HangChars .. "]") then
				dg_fragment = dg_fragment .. c
			else
				dg = nil
				dg_fragment = nil
				break
			end
		end
		if dg_ind == 1 then
			dg = nil
			dg_fragment = nil
		end
	end
	
	if dg then
		dg_fragment = dg_fragment .. "]"
		dg = dg .. tag_text(dg_fragment, lang_okm)
		list = list .. "\n* [[w:동국정운|동국정운]]: " .. dg
	end
	
	return list
end

return export