Module:Hangul
Appearance
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]].
-- http://www.unicode.org/Public/UNIDATA/Jamo.txt
local hangul_leads = {
[0] = "G", "GG", "N", "D", "DD", "R", "M", "B", "BB", "S", "SS",
"", "J", "JJ", "C", "K", "T", "P", "H"
}
local hangul_vowels = {
[0] = "A", "AE", "YA", "YAE", "EO", "E", "YEO", "YE", "O", "WA",
"WAE", "OE", "YO", "U", "WEO", "WE", "WI", "YU", "EU", "YI",
"I"
}
local hangul_trails = {
[0] = "", "G", "GG", "GS", "N", "NJ", "NH", "D", "L", "LG", "LM", "LB",
"LS", "LT", "LP", "LH", "M", "B", "BS", "S", "SS", "NG", "J", "C", "K",
"T", "P", "H"
}
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')
output = mw.ustring.toNFC(output)
output = mw.ustring.gsub(
output,
'[가-힣]',
function (syllable)
return ('title="%s" | %s'):format(get_name(syllable), syllable)
end)
return output
end
return p