Difference between revisions of "Module:Hangul"

From blackwiki
Jump to navigation Jump to search
blackwiki>Erutuon
(fix joinability (or whatever the term for this is))
blackwiki>Erutuon
(failed attempt to add syllable names)
Line 70: Line 70:
 
return letter
 
return letter
 
end
 
end
 +
end
 +
 +
 +
---- From [[wikt:Module:ko-hangul]
 +
local info = {}
 +
info.initials = {
 +
KIYEOK      =  0, SSANGKIYEOK =  1, NIEUN      =  2,
 +
TIKEUT      =  3, SSANGTIKEUT =  4, RIEUL      =  5,
 +
MIEUM      =  6, PIEUP      =  7, SSANGPIEUP  =  8,
 +
SIOS        =  9, SSANGSIOS  = 10, IEUNG      = 11,
 +
CIEUC      = 12, SSANGCIEUC  = 13, CHIEUCH    = 14,
 +
KHIEUKH    = 15, THIEUTH    = 16, PHIEUPH    = 17,
 +
HIEUH      = 18
 +
}
 +
 +
info.vowels = {
 +
A  =  0, AE  =  1, YA  =  2, YAE =  3, EO  =  4,
 +
E  =  5, YEO =  6, YE  =  7, O  =  8, WA  =  9,
 +
WAE = 10, OE  = 11, YO  = 12, U  = 13, WEO = 14,
 +
WE  = 15, WI  = 16, YU  = 17, EU  = 18, YI  = 19,
 +
I  = 20
 +
}
 +
 +
info.finals = {
 +
KYEOK        =  1, SSANGKIYEOK  =  2, KYEOK_SIOS    =  3,
 +
NIEUN        =  4, NIEUN_CIEUC  =  5, NIEUN_HIEUH  =  6,
 +
TIKEUT        =  7, RIEUL        =  8, RIEUL_KIYEOK  =  9,
 +
RIEUL_MIEUM  = 10, RIEUL_PIEUP  = 11, RIEUL_SIOS    = 12,
 +
RIEUL_THIEUTH = 13, RIEUL_PHIEUPH = 14, RIEUL_HIEUH  = 15,
 +
MIEUM        = 16, PIEUP        = 17, PIEUP_SIOS    = 18,
 +
SIOS          = 19, SSANGSIOS    = 20, IEUNG        = 21,
 +
CIEUC        = 22, CHIEUCH      = 23, KHIEUKH      = 24,
 +
THIEUTH      = 25, PHIEUPH      = 26, HIEUH        = 27,
 +
KIYEOK_RIEUL  = 28
 +
}
 +
 +
-- Provided that s is a string, returns true if s consists of a single
 +
-- precomposed Hangul syllable, and false otherwise.
 +
local function isHangulSyllable(s)
 +
    if type(s) == 'number' then
 +
        return (s >= 0xAC00) and (s <= 0xD7A3)
 +
    elseif type(s) == 'string' then
 +
        return s:len() == 3 and s >= '\234\176\128' and s <= '\237\158\163'
 +
    else
 +
    return false
 +
    end
 +
end
 +
 +
-- Provided that s is a single character or code point corresponding to
 +
-- a precomposed Hangul syllable, returns its "syllable index" per
 +
-- section 3.12 of the Unicode spec, i.e., the character-code of
 +
-- the syllable minus 0xAC00, which is an integer in the range [0, 11171].
 +
local function getSyllableIndex(hangulSyllable)
 +
    if type(hangulSyllable) == 'string' then
 +
        hangulSyllable = mw.ustring.codepoint(hangulSyllable)
 +
    end
 +
    return hangulSyllable - 0xAC00
 +
end
 +
 +
-- Given the "syllable index" of a precomposed Hangul syllable (see
 +
-- above), returns "indices" representing the three constituent jamo
 +
-- ("lead", i.e. initial consonant; "vowel"; and "tail", i.e. final
 +
-- consonant, except that zero denotes the absence of a final consonant).
 +
local function syllableIndex2JamoIndices(syllableIndex)
 +
    local lIndex = math.floor(syllableIndex / 588)
 +
    local vIndex = math.floor((syllableIndex % 588) / 28)
 +
    local tIndex = syllableIndex % 28
 +
 +
    return lIndex, vIndex, tIndex
 +
end
 +
 +
-- Same as previous, but takes a string consisting of a precomposed Hangul
 +
-- syllable, instead of the "syllable index". (A convenience function.)
 +
local function syllable2JamoIndices(hangulSyllable)
 +
    return syllableIndex2JamoIndices(getSyllableIndex(hangulSyllable))
 +
end
 +
 +
-- Given a string consisting of a single precomposed hangul syllable,
 +
-- returns a string consisting of the same syllable but decomposed into
 +
-- its constituent jamo. (This function is not really expected to be
 +
-- useful, but it's here to show how the parts fit together.)
 +
local function syllable2Jamo(hangulSyllable)
 +
    local lIndex, vIndex, tIndex =
 +
        syllable2JamoIndices(hangulSyllable)
 +
    local l = mw.ustring.char(0x1100 + lIndex)
 +
    local v = mw.ustring.char(0x1161 + vIndex)
 +
    local t
 +
    if tIndex == 0 then
 +
        t = ''
 +
    else
 +
        t = mw.ustring.char(0x11A7 + tIndex)
 +
    end
 +
    return l .. v .. t
 +
end
 +
 +
----
 +
 +
-- From [[wikt:Module:Unicode data]].
 +
local function get_name(syllable)
 +
local li, vi, ti = syllableIndex2JamoIndices(tocodepoint(syllable) - 0xAC00)
 +
 +
return ("HANGUL SYLLABLE %s%s%s"):format(
 +
hangul_leads[li], hangul_vowels[vi], hangul_trails[ti])
 
end
 
end
  
Line 104: Line 207:
 
output.add('|}')
 
output.add('|}')
 
 
return table.concat(output, '\n')
+
output = table.concat(output, '\n')
 +
mw.ustring.toNFC(output) -- oops, doesn't convert jamo sequences to syllables
 +
output = mw.ustring.gsub(
 +
output,
 +
'[가-힣]',
 +
get_name)
 +
 +
return output
 
end
 
end
  
 
return p
 
return p

Revision as of 22:15, 27 April 2018

Usage

Script error: The function "syllables_by_initial" does not exist. Script error: The function "TOC" does not exist.



local p = {}

-- Put these two in data module?
local medials = {
	'ᅡ',
	'ᅢ',
	'ᅣ',
	'ᅤ',
	'ᅥ',
	'ᅦ',
	'ᅧ',
	'ᅨ',
	'ᅩ',
	'ᅪ',
	'ᅫ',
	'ᅬ',
	'ᅭ',
	'ᅮ',
	'ᅯ',
	'ᅰ',
	'ᅱ',
	'ᅲ',
	'ᅳ',
	'ᅴ',
	'ᅵ',
}

local finals = {
	'',
	'ᆨ',
	'ᆩ',
	'ᆪ',
	'ᆫ',
	'ᆬ',
	'ᆭ',
	'ᆮ',
	'ᆯ',
	'ᆰ',
	'ᆱ',
	'ᆲ',
	'ᆳ',
	'ᆴ',
	'ᆵ',
	'ᆶ',
	'ᆷ',
	'ᆸ',
	'ㅄ',
	'ㅅ',
	'ㅆ',
	'ㅇ',
	'ㅈ',
	'ᆾ',
	'ᆿ',
	'ᇀ',
	'ᇁ',
	'ᇂ',
}

local tocodepoint, tochar = mw.ustring.codepoint, mw.ustring.char
local function make_joinable(letter)
	local codepoint = tocodepoint(letter)
	
	if not codepoint then
		return ''
	
	-- Hangul Compatibility Jamo (U+3130-318F) rather than Hangul Jamo (U+1100-11FF)
	elseif 0x3130 <= codepoint and codepoint <= 0x318F then
		return tochar(codepoint - 0x1F8B)
	else
		return letter
	end
end


---- From [[wikt:Module:ko-hangul]
local info = {}
info.initials = {
	KIYEOK      =  0, SSANGKIYEOK =  1, NIEUN       =  2,
	TIKEUT      =  3, SSANGTIKEUT =  4, RIEUL       =  5,
	MIEUM       =  6, PIEUP       =  7, SSANGPIEUP  =  8,
	SIOS        =  9, SSANGSIOS   = 10, IEUNG       = 11,
	CIEUC       = 12, SSANGCIEUC  = 13, CHIEUCH     = 14,
	KHIEUKH     = 15, THIEUTH     = 16, PHIEUPH     = 17,
	HIEUH       = 18
}

info.vowels = {
	A   =  0, AE  =  1, YA  =  2, YAE =  3, EO  =  4,
	E   =  5, YEO =  6, YE  =  7, O   =  8, WA  =  9,
	WAE = 10, OE  = 11, YO  = 12, U   = 13, WEO = 14,
	WE  = 15, WI  = 16, YU  = 17, EU  = 18, YI  = 19,
	I   = 20
}

info.finals = {
	KYEOK         =  1, SSANGKIYEOK   =  2, KYEOK_SIOS    =  3,
	NIEUN         =  4, NIEUN_CIEUC   =  5, NIEUN_HIEUH   =  6,
	TIKEUT        =  7, RIEUL         =  8, RIEUL_KIYEOK  =  9,
	RIEUL_MIEUM   = 10, RIEUL_PIEUP   = 11, RIEUL_SIOS    = 12,
	RIEUL_THIEUTH = 13, RIEUL_PHIEUPH = 14, RIEUL_HIEUH   = 15,
	MIEUM         = 16, PIEUP         = 17, PIEUP_SIOS    = 18,
	SIOS          = 19, SSANGSIOS     = 20, IEUNG         = 21,
	CIEUC         = 22, CHIEUCH       = 23, KHIEUKH       = 24,
	THIEUTH       = 25, PHIEUPH       = 26, HIEUH         = 27,
	KIYEOK_RIEUL  = 28
}

-- Provided that s is a string, returns true if s consists of a single
-- precomposed Hangul syllable, and false otherwise.
local function isHangulSyllable(s)
    if type(s) == 'number' then
        return (s >= 0xAC00) and (s <= 0xD7A3)
    elseif type(s) == 'string' then
        return s:len() == 3 and s >= '\234\176\128' and s <= '\237\158\163'
    else
    	return false
    end
end
 
-- Provided that s is a single character or code point corresponding to
-- a precomposed Hangul syllable, returns its "syllable index" per
-- section 3.12 of the Unicode spec, i.e., the character-code of
-- the syllable minus 0xAC00, which is an integer in the range [0, 11171].
local function getSyllableIndex(hangulSyllable)
    if type(hangulSyllable) == 'string' then
        hangulSyllable = mw.ustring.codepoint(hangulSyllable)
    end
    return hangulSyllable - 0xAC00
end
 
-- Given the "syllable index" of a precomposed Hangul syllable (see
-- above), returns "indices" representing the three constituent jamo
-- ("lead", i.e. initial consonant; "vowel"; and "tail", i.e. final
-- consonant, except that zero denotes the absence of a final consonant).
local function syllableIndex2JamoIndices(syllableIndex)
    local lIndex = math.floor(syllableIndex / 588)
    local vIndex = math.floor((syllableIndex % 588) / 28)
    local tIndex = syllableIndex % 28
 
    return lIndex, vIndex, tIndex
end
 
-- Same as previous, but takes a string consisting of a precomposed Hangul
-- syllable, instead of the "syllable index". (A convenience function.)
local function syllable2JamoIndices(hangulSyllable)
    return syllableIndex2JamoIndices(getSyllableIndex(hangulSyllable))
end
 
-- Given a string consisting of a single precomposed hangul syllable,
-- returns a string consisting of the same syllable but decomposed into
-- its constituent jamo. (This function is not really expected to be
-- useful, but it's here to show how the parts fit together.)
local function syllable2Jamo(hangulSyllable)
    local lIndex, vIndex, tIndex =
        syllable2JamoIndices(hangulSyllable)
    local l = mw.ustring.char(0x1100 + lIndex)
    local v = mw.ustring.char(0x1161 + vIndex)
    local t
    if tIndex == 0 then
        t = ''
    else
        t = mw.ustring.char(0x11A7 + tIndex)
    end
    return l .. v .. t
end

----

-- From [[wikt:Module:Unicode data]].
local function get_name(syllable)
	local li, vi, ti = syllableIndex2JamoIndices(tocodepoint(syllable) - 0xAC00)

	return ("HANGUL SYLLABLE %s%s%s"):format(
		hangul_leads[li], hangul_vowels[vi], hangul_trails[ti])
end

function p.show(frame)
	local initial = frame.args[1] or 'ᄀ'
	local codepoint = mw.ustring.codepoint(initial)
	if not (0x1100 <= codepoint and codepoint <= 0x1112) then
		error('Incorrect initial ' .. initial .. '. Should be between U+1100 and U+1112.')
	end
	
	local output = {}
	local i = 0
	function output.add(text)
		i = i + 1
		output[i] = text
	end
	function output.row()
		output.add('|-\n')
	end
	
	output.add('{| class="wikitable"\n! Final→<br>Medial↓')
	for _, final in ipairs(finals) do
		output.add(('! %s'):format(final))
	end
	
	for _, medial in ipairs(medials) do
		output.row()
		output.add(('! %s'):format(medial))
		for _, final in ipairs(finals) do
			output.add(('| %s%s%s'):format(initial, medial, make_joinable(final)))
		end
	end
	
	output.add('|}')
	
	output = table.concat(output, '\n')
	mw.ustring.toNFC(output) -- oops, doesn't convert jamo sequences to syllables
	output = mw.ustring.gsub(
		output,
		'[가-힣]',
		get_name)
	
	return output
end

return p