Module:User:Lunabunn/jje-conj

Hello, you have come here looking for the meaning of the word Module:User:Lunabunn/jje-conj. In DICTIOUS you will not only get to know all the dictionary meanings for the word Module:User:Lunabunn/jje-conj, but we will also tell you about its etymology, its characteristics and you will know how to say Module:User:Lunabunn/jje-conj in singular and plural. Everything you need to know about the word Module:User:Lunabunn/jje-conj you have here. The definition of the word Module:User:Lunabunn/jje-conj will help you to be more precise and correct when speaking or writing your texts. Knowing the definition ofModule:User:Lunabunn/jje-conj, as well as those of other words, enriches your vocabulary and provides you with more and better linguistic resources.


local export = {}
local us = mw.ustring
local data = mw.loadData("Module:User:Lunabunn/jje-conj/data")

function block_left(s)
	function peek() return us.codepoint(s, 1, 1) end
	function pop() return us.sub(s, 1, 1), us.sub(s, 2) end
	
	local cho, jung, jong
	
	-- edge case for lone jong as compat glyph
	if (peek() >= 0x3131 and peek() <= 0x314E) then
		jong, s = pop()
		jong = us.char(data.compat_to_jong)
	else
		-- cho in Hangul Jamo and Hangul Jamo Extended-A
		if (peek() >= 0x1100 and peek() <= 0x115F) or (peek() >= 0xA960 and peek() <= 0xA97C) then
			cho, s = pop()
		end
		
		-- jung in Hangul Jamo and Hangul Jamo Extended-B
		if peek() ~= nil and ((peek() >= 0x1160 and peek() <= 0x11A7) or (peek() >= 0xD7B0 and peek() <= 0xD7C6)) then
			jung, s = pop()
		end
		
		-- jong in Hangul Jamo and Hangul Jamo Extended-B
		if peek() ~= nil and ((peek() >= 0x11A8 and peek() <= 0x11FF) or (peek() >= 0xD7CB and peek() <= 0xD7FB)) then
			jong, s = pop()
		end
	end
	
	return cho, jung, jong, s
end

function block_right(s)
	function peek() return us.codepoint(s, -1) end
	function pop() return us.sub(s, -1), us.sub(s, 1, -2) end
	
	local cho, jung, jong
	
	-- jong in Hangul Jamo and Hangul Jamo Extended-B
	if (peek() >= 0x11A8 and peek() <= 0x11FF) or (peek() >= 0xD7CB and peek() <= 0xD7FB) then
		jong, s = pop()
	end
		
	-- jung in Hangul Jamo and Hangul Jamo Extended-B
	if peek() ~= nil and ((peek() >= 0x1160 and peek() <= 0x11A7) or (peek() >= 0xD7B0 and peek() <= 0xD7C6)) then
		jung, s = pop()
	end
	
	-- cho in Hangul Jamo and Hangul Jamo Extended-A
	if peek() ~= nil and ((peek() >= 0x1100 and peek() <= 0x115F) or (peek() >= 0xA960 and peek() <= 0xA97C)) then
		cho, s = pop()
	end
	
	return s, cho, jung, jong
end

function is(encoded, compat)
	if encoded == nil then return false end
	local codepoint = us.codepoint(encoded, 1, 1)
	return (encoded == compat)
		or (codepoint == data.compat_to_cho)
		or (codepoint == data.compat_to_cho_loose_partial)
		or (codepoint == data.compat_to_cho_loose)
		or (codepoint == data.compat_to_jung)
		or (codepoint == data.compat_to_jung_loose)
		or (codepoint == data.compat_to_jong)
		or (codepoint == data.compat_to_jong_loose_partial)
		or (codepoint == data.compat_to_jong_loose)
end

function find(t, target)
	for k, v in pairs(t) do
	    if v == target then
	    	return k
	    end
	end
	return nil
end

function loosen(jung)
	local code = us.codepoint(jung, 1, 1)
	return find(data.compat_to_jung_loose, code) or find(data.compat_to_jung, code)
end

function tighten(loose)
	local code = data.compat_to_jung_loose or data.compat_to_jung
	if code == nil then return nil end
	return us.char(code)
end

function connectability(ajung, bjung)
	local aloose, bloose = loosen(ajung), loosen(bjung)
	if us.sub(aloose, -1) == us.sub(bloose, 1, 1) then
		return 2 -- mergeable
	elseif tighten(aloose .. bloose) then
		return 1 -- connectable
	else
		return 0
	end
end

function connect(ajung, bjung)
	-- assumes that connectability is 1
	local aloose, bloose = loosen(ajung), loosen(bjung)
	return tighten(aloose .. bloose)
end

function assemble(components)
	local result = ""
	for _, component in pairs(components) do
	    if component ~= nil then
	    	result = result .. component
	    end
	end
	return result
end

function export.conjugate(frame)
	local parent_args = frame:getParent().args
	local args = require("Module:parameters").process(parent_args, {
		 = {},
		 = {},
		 = { type = "boolean" },
		 = {},
	})

	local stem = us.toNFD(args)
	local ending = us.toNFD(args)

	local head, acho, ajung, ajong = block_right(stem)
	local bcho, bjung, bjong, tail = block_left(ending)
	
	if ajong == nil then
		if is(bcho, "ㅇ") and connectability(ajung, bjung) == 2 then
			bcho, bjung = nil, nil
		end
	end
	
	if args == "p" then
		if args then
			ajong = nil
			epenthetic = "우"
		elseif is(bcho, "ㅇ") then
			ajong = nil
			local bloose = loosen(bjung)
			if us.sub(bloose, 1, 1) ~= "ㅗ" and us.sub(bloose, 1, 1) ~= "ㅜ" then
				bjung = tighten("ㅗ" .. bloose) or tighten("ㅜ" .. bloose)
			end
		end
	elseif ajong == nil and args then
		if is(ajong, "ㅅ") or is(ajong, "ㅈ") or is(ajong, "ㅊ") then
			epenthetic = "이"
		else
			epenthetic = "으"
		end
	end
	
	local components = {head, acho, ajung, ajong, epenthetic, bcho, bjung, bjong, tail}
	local result = us.toNFC(assemble(components))
	
	-- second pass for vowel stems with connectability = 1
	stem, ending = us.toNFD(args), us.toNFD(args)
	head, acho, ajung, ajong = block_right(stem)
	bcho, bjung, bjong, tail = block_left(ending)
	
	if ajong == nil and is(bcho, "ㅇ") and connectability(ajung, bjung) == 1 then
		ajung = connect(ajung, bjung)
		bcho, bjung = nil, nil
		components = {head, acho, ajung, ajong, epenthetic, bcho, bjung, bjong, tail}
		result = result .. ", " .. us.toNFC(assemble(components))
	end
	
	return result
end

return export