local export = {}
local m_str_utils = require("Module:string utilities")
local codepoint = m_str_utils.codepoint
local concat = table.concat
local floor = math.floor
local gmatch = m_str_utils.gmatch
local gsplit = m_str_utils.gsplit
local gsub = m_str_utils.gsub
local insert = table.insert
local len = m_str_utils.len
local match = m_str_utils.match
local min = math.min
local remove = table.remove
local sub = m_str_utils.sub
local u = m_str_utils.char
local upper = m_str_utils.upper
local lang = require("Module:languages").getByCode("ko")
export.lang = lang
local HangChars = require("Module:scripts").getByCode("Hang"):getCharacters()
local HaniChars = require("Module:scripts").getByCode("Hani"):getCharacters()
-- makes hanjatab automatically
function export.hanjatab()
local hanja = gsub(mw.title.getCurrentTitle().text, '', '')
local table_head = '<table class="floatright wikitable" style="text-align:center; font-size:small;"><tr><th colspan="' ..
len(hanja) ..
'" style="font-weight:normal;">] in this term</th></tr><tr lang="ko" class="Kore" style="font-size:2em; background:var(--wikt-palette-white,#ffffff); color:inherit; line-height:1em;">'
return table_head ..
gsub(hanja, '(.)', '<td style="padding:0.5em;">]</td>') ..
'</tr></table>'
end
-- return only non-hangeul contained in text
function export.remove_hangeul(f)
local nonhangeul = gsub(f.args, '', '')
return nonhangeul
end
function export.boldify(f)
local pagename = mw.title.getCurrentTitle().text
hangul = f.args
if match(hangul, pagename) and not match(hangul, "'") then
hangul = gsub(hangul, pagename, "'''" .. pagename .. "'''")
end
return hangul
end
function export.usex_hangul(f)
local pagename = mw.title.getCurrentTitle().text
hangul = f.args
if match(hangul, pagename) and not match(hangul, "'") then
hangul = gsub(hangul, pagename, "'''" .. pagename .. "'''")
end
i = 1
local front, back = '<b>', '</b>'
for bold in gmatch(hangul, "'''") do
hangul = gsub(hangul, "'''", (i % 2 == 1 and front or back), 1)
i = i + 1
end
hangul = gsub(hangul, '%^', '')
return hangul
end
function export.link(arg)
local args, distances = {}, {}
local m_pron = require("Module:ko-translit")
local curr_distance, closest_match = 1000, 0
local word, translit, definition, hanja, note = false, false, false, false, false
for i = 1, 4, 1 do
if arg and arg ~= "" then
insert(args, arg)
end
end
local curr_hangul_level, closest_hangul = 0, 0
for i, parameter in ipairs(args) do
local _, tentative_hangul_level = gsub(parameter, "", "")
if tentative_hangul_level > curr_hangul_level then
curr_hangul_level = tentative_hangul_level
closest_hangul = i
end
end
if curr_hangul_level > 0 then
word = args
remove(args, closest_hangul)
end
local function compute_distance(str1, str2)
local len1, len2 = #str1, #str2
local char1, char2, distance = {}, {}, {}
str1:gsub('.', function (c)
insert(char1, c) end)
str2:gsub('.', function (c)
insert(char2, c) end)
for i = 0, len1 do
distance = {}
end
for i = 0, len1 do
distance = i
end
for i = 0, len2 do
distance = i
end
for i = 1, len1 do
for j = 1, len2 do
distance = min(
distance + 1,
distance + 1,
distance + (char1 == char2 and 0 or 1)
)
end
end
return distance
end
local m_link = require("Module:links")
local test_translit = m_pron.tr_revised(m_link.remove_links(word or arg)) or ""
if arg and arg ~= "" then
note = arg
elseif arg and arg ~= "" then
note = arg
end
if arg then
definition = arg
arg = nil
end
for i, parameter in ipairs(args) do
if not match(parameter, '') then
local tentative_distance = compute_distance(test_translit, parameter)
if tentative_distance < curr_distance then
curr_distance = tentative_distance
closest_match = i
end
end
end
if curr_distance < 3 and #args > 1 then
translit = args
remove(args, closest_match)
end
for i, parameter in ipairs(args) do
if match(parameter, "") then
hanja = parameter
remove(args, i)
end
end
if not hanja and not word then
word = args
remove(args, 1)
end
if #args > 1 then
translit = args
definition = args
elseif #args > 0 then
if definition then
translit = args
else
definition = args
end
end
if hanja and not match(hanja, "]") then
for hanja_word in gmatch(hanja, "+") do
hanja = gsub(hanja, hanja_word, "]")
end
for hangul_word in gmatch(hanja, "+") do
hanja = gsub(hanja, hangul_word, "]")
end
hanja = gsub(hanja, "%[%[%[%[", "[[")
hanja = gsub(hanja, "%]%]%]%]", "]]")
end
local tr = arg or translit or test_translit
if (translit or test_translit) and not arg then
tr = gsub(tr, "%^(%a)", upper)
end
if tr then
tr = '<span lang="ko-Latn" class="mention-tr tr Latn">' ..
tr .. "</span>"
end
if definition then
if not match(definition, "^''.+''$") then definition = "“" .. definition .. "”" end
end
if hanja then
hanja = '<span lang="ko" class="Kore">' .. m_link.language_link{lang = lang, term = hanja} .. '</span>'
end
word = gsub(word, "%^", "")
if not match(word, "]") then
if match(word, "^—.+—$") then
word = gsub(word, "—(.+)—", "]")
elseif match(word, "^—.+$") then
word = gsub(word, "—(.+)", "]")
elseif match(word, "^.+—$") then
word = gsub(word, "(.+)—", "]")
elseif match(word, "^%*") then
word = gsub(word, "%*", "")
else
word = "]"
end
end
local info = {}
insert(info, word and (hanja or nil) or nil)
insert(info, tr or nil)
insert(info, definition or nil)
local result = word
and
("<span lang=\"ko\" class=\"Kore\">" .. word .. "</span>")
or
('<span lang="ko" class="Kore">' .. m_link.language_link{lang = lang, term = hanja} .. '</span>')
if #info > 0 then
result = result .. " (" .. concat(info, ", ") .. ")"
end
if note then
result = result .. " (<i>" .. note .. "</i>)"
end
return result
end
function export.link_t(frame)
return export.link(frame:getParent().args)
end
function export.new(frame)
local title = mw.title.getCurrentTitle().text
local args = frame:getParent().args
local poses = { args or "", args or (args and "" or false), args or (args and "" or false) }
local defs = { (args ~= "" and args), (args ~= "" and args), (args ~= "" and args) }
local etym = args or false
local head = args or false
local cat = args or false
local image = args or false
local caption = args or false
local pedia = args or false
local irreg = args or false
local result = ""
local function genTitle(text)
local pos_title = {
= "Noun", = "Noun", = "Proper noun", = "Proper noun", = "Pronoun",
= "Verb", = "Adjective", = "Adjective", = "Adverb",
= "Preposition", = "Postposition", = "Conjunction",
= "Particle", = "Suffix",
= "Proverb", = "Idiom", = "Phrase", = "Interjection", = "Interjection",
= "Classifier", = "Classifier", = "Numeral", = "Abbreviation",
= "Determiner", = "Determiner", = "Root",
};
return pos_title or upper(sub(text, 1, 1)) .. sub(text, 2, -1)
end
local function genHead(text)
local pos_head = {
= "noun", = "noun", = "proper noun", = "proper noun", = "verb", = "adj", = "adv",
= "pos|post", = "pos|con", = "pos|particle", = "pos|pronoun",
= "proverb", = "pos|idiom", = "pos|phrase", = "interj",
= "pos|abbr", = "pos|cls", = "det", = "det", = "root", = "num",
};
return pos_head or "pos|" .. text
end
local function other(class, title, args, level)
local code = ""
if args then
code = code .. "\n\n" .. level .. title .. level .. "\n* {{l|ko|" .. gsub(args, ":", "|") .. "}}"
i = 2
while args do
code = code .. "\n* {{l|ko|" .. gsub(args, ":", "|") .. "}}"
i = i + 1
end
end
return code
end
if args or args or args or args or args or args or args then
multiEtym = true
end
local function iterate_param(args, genPos, etymNo)
if genPos == "proper noun" then args = "y" end
text = ""
for _, arg in ipairs( { "l", "com", "nn", "ui", "nobc", "cap", "ni", "bcred", "a", "uie" } ) do
if etymNo > 1 then arg_temp = etymNo .. arg else arg_temp = arg end
if args then text = text .. "|" .. arg .. "=" .. args end
end
return text
end
local function add_etym(args, etymNo)
etymText = ""
n = etymNo > 1 and etymNo or ""
if args then etymText = etymText .. args
elseif args then etymText = etymText .. "{{ko-etym-sino|" .. args .. (args and "|" .. args or "") .. "}}."
elseif args then etymText = etymText .. "{{ko-etym-native|" .. gsub(args, ",", "|") .. "}}"
elseif args then etymText = etymText .. "From {{bor|ko|" .. (args or "en") .. "|" .. args .. "}}."
elseif args then etymText = etymText ..
"{{compound|ko|" .. args .. (args and "(" .. args .. ")" or "") .. (args and "|t1=" .. args or "") ..
"|" .. args .. (args and "(" .. args .. ")" or "") .. (args and "|t2=" .. args or "") ..
(args and "|" .. args .. (args and "(" .. args .. ")" or "") .. (args and "|t3=" .. args or "") or "") ..
(args and "|" .. args .. (args and "(" .. args .. ")" or "") .. (args and "|t4=" .. args or "") or "") .. "}}."
elseif match(title, "다$") then
local suffix_data = {
= "|t2=to do|pos2=] deriving " .. (genHead(poses) == "adj" and "adjectives" or "active verbs"),
= "|t2=to become|pos2=] deriving " .. (genHead(poses) == "adj" and "adjectives" or "passive verbs"),
= "|pos2=suffix deriving adjectives",
}
etymText = etymText
.. "{{af|ko"
.. "|" .. sub(title, 1, -3) .. (args and "(" .. args .. ")" or "")
.. "|-" .. sub(title, -2, -1)
.. (args and "|pos1=root" or "")
.. (args and "|t1=" .. args or "")
.. suffix_data
.. "}}"
.. "."
elseif match(title, "시키다$") or match(title, "스럽다$") then
etymText = etymText
.. "{{af|ko"
.. "|" .. sub(title, 1, -4) .. (args and "(" .. args .. ")" or "")
.. "|-" .. sub(title, -3, -1)
.. (args and "|pos1=root" or "")
.. (args and "|t1=" .. args or "")
.. "}}"
.. "."
end
return etymText
end
local function add_regional(text, etymNo)
local regionalText = ""
local n = etymNo > 1 and etymNo or ""
if args then
if match(title, "다$") then
regionalText = regionalText .. "\n{{ko-regional"
.. "|" .. sub(title, 1, -3) .. (args and "(" .. args .. ")" or "") .. sub(title, -2, -1)
.. "|" .. sub(args, 1, -3) .. (args and "(" .. args .. ")" or "") .. sub(args, -2, -1)
.."}}"
elseif match(title, "시키다$") or match(title, "스럽다$") then
regionalText = regionalText .. "\n{{ko-regional"
.. "|" .. sub(title, 1, -4) .. (args and "(" .. args .. ")" or "") .. sub(title, -3, -1)
.. "|" .. sub(args, 1, -4) .. (args and "(" .. args .. ")" or "") .. sub(args, -3, -1)
.."}}"
else
regionalText = regionalText .. "\n{{ko-regional"
.. "|" .. (args and "^" or "") .. title .. (args and "(" .. args .. ")" or "")
.. "|" .. (args and "^" or "") .. args .. (args and "(" .. args .. ")" or "")
.."}}"
end
elseif args then
if match(title, "다$") then
regionalText = regionalText .. "\n{{ko-regional"
.. "|" .. sub(args, 1, -3) .. (args and "(" .. args .. ")" or "") .. sub(args, -2, -1)
.. "|" .. sub(title, 1, -3) .. (args and "(" .. args .. ")" or "") .. sub(title, -2, -1)
.."}}"
elseif match(title, "시키다$") or match(title, "스럽다$") then
regionalText = regionalText .. "\n{{ko-regional"
.. "|" .. sub(args, 1, -4) .. (args and "(" .. args .. ")" or "") .. sub(args, -3, -1)
.. "|" .. sub(title, 1, -4) .. (args and "(" .. args .. ")" or "") .. sub(title, -3, -1)
.."}}"
else
regionalText = regionalText .. "\n{{ko-regional"
.. "|" .. (args and "^" or "") .. args .. (args and "(" .. args .. ")" or "")
.. "|" .. (args and "^" or "") .. title .. (args and "(" .. args .. ")" or "")
.."}}"
end
end
return regionalText
end
-- generate {{standard form of}} if definition is not given
-- XXX: |ncap= which is set automatically by add_etym() doesn't happen yet here
-- WISHLIST: choose between {{standard spelling of}} and {{standard form of}}?
-- no difference in categorization though. really not worth it
for _, etymNo in ipairs({1, 2, 3}) do
local n = etymNo > 1 and etymNo or ""
if args then
if not defs then
if match(title, "다$") then
defs = "{{standard form of|ko"
.. "|" .. sub(args, 1, -3) .. (args and "(" .. args .. ")" or "") .. sub(args, -2, -1)
.."|from=North Korea}}"
elseif match(title, "시키다$") or match(title, "스럽다$") then
defs = "{{standard form of|ko"
.. "|" .. sub(args, 1, -4) .. (args and "(" .. args .. ")" or "") .. sub(args, -3, -1)
.."|from=North Korea}}"
else
defs = "{{standard form of|ko"
.. "|" .. (args and "^" or "") .. args .. (args and "(" .. args .. ")" or "")
.."|from=North Korea}}"
end
end
end
end
result = result .. "==Korean=="
if pedia then result = result .. "\n{{wp|lang=ko" .. (pedia ~= "y" and "|" .. pedia or "") .. "}}" end
if image then result = result .. "\n]" end
result = result .. other("alt", "Alternative forms", args, "===")
if match(title, "다$") or match(title, "시키다$") or match(title, "스럽다$") then autoEtym = true end
if args or args or args or args or args or args or args or autoEtym or multiEtym then
etym = "\n\n===Etymology" .. (multiEtym and " 1" or "") .. "===\n"
etym = etym .. add_etym(args, 1)
end
if etym then result = result .. etym end
level = multiEtym and "====" or "==="
result = result .. other("1alt", "Alternative forms", args, "====")
result = result .. "\n\n" .. level .. "Pronunciation" .. level ..
"\n{{ko-IPA" .. iterate_param(args, genHead(poses), 1) .. "}}"
if genHead(poses) == "root" then defs = "{{ko-root of|" .. defs .. "}}" end
result = result .. "\n\n" .. level .. genTitle(poses) .. level .. "\n{{ko-" .. genHead(poses) ..
(head and ("|head=" .. head) or "") .. (args and ("|hanja=" .. args) or "") ..
(irreg and "|irreg=y" or "") .. "}}" .. add_regional(args, 1) .. "\n\n# " .. (defs or "{{rfdef|ko}}")
local function add_der(args, etymNo, hanja)
n = etymNo > 1 and etymNo or ""
local translDer = { = "하다", = "되다", = "시키다" }
if args and gsub(args, "", "") == "" then
i = 1
for ch in gsplit(args, "") do
args = title .. (hanja and "(" .. hanja .. ")" or "") .. translDer
i = i + 1
end
end
return args
end
args = add_der(args, 1, args or false)
result = result .. other("syn", "=Synonyms=", args, level)
result = result .. other("ant", "=Antonyms=", args, level)
result = result .. other("der", "=Derived terms=", args, level)
result = result .. other("rel", "=Related terms=", args, level)
result = result .. other("also", "=See also=", args, level)
if genHead(poses) == "adj" or genHead(poses) == "verb" then
result = result .. "\n\n=" .. level .. "Conjugation" .. level .. "=\n{{ko-conj/" .. genHead(poses) .. (irreg and "|irreg=y" or "") .. "}}"
end
if poses then
if multiEtym then
result = result .. "\n\n===Etymology 2===\n" .. add_etym(args, 2)
level = "===="
result = result .. other("2alt", "Alternative forms", args, level)
result = result .. "\n\n" .. level .. "Pronunciation" .. level ..
"\n{{ko-IPA" .. iterate_param(args, genHead(poses), 2) .. "}}"
if genHead(poses) == "root" then defs = "{{ko-root of|" .. defs .. "}}" end
result = result .. "\n\n" .. level .. genTitle(poses) .. level .. "\n{{ko-" .. genHead(poses) ..
(head and ("|head=" .. head) or "") .. (args and ("|hanja=" .. args) or "") .. "}}" .. add_regional(args, 2) .. "\n\n# " .. (defs or "{{rfdef|ko}}")
args = add_der(args, 2, args or false)
result = result .. other("2syn", "=Synonyms=", args, level)
result = result .. other("2ant", "=Antonyms=", args, level)
result = result .. other("2der", "=Derived terms=", args, level)
result = result .. other("2rel", "=Related terms=", args, level)
result = result .. other("2also", "=See also=", args, level)
if genHead(poses) == "adj" or genHead(poses) == "verb" then
result = result .. "\n\n=" .. level .. "Conjugation" .. level .. "=\n{{ko-conj/" .. genHead(poses) .. (irreg and "|irreg=y" or "") .. "}}"
end
else
result = result .. "\n\n===" .. genTitle(poses) .. "===\n{{ko-" .. genHead(poses) ..
(head and ("|head=" .. head) or "") .. (args and ("|hanja=" .. args) or "") ..
"}}\n\n# " .. (defs or "{{rfdef|ko}}")
if genHead(poses) == "adj" or genHead(poses) == "verb" then
result = result .. "\n\n====Conjugation====\n{{ko-conj/" .. genHead(poses) .. (irreg and "|irreg=y" or "") .. "}}"
end
end
end
if poses then
if multiEtym then
result = result .. "\n\n===Etymology 3===\n" .. add_etym(args, 3)
level = "===="
result = result .. other("3alt", "Alternative forms", args, level)
result = result .. "\n\n" .. level .. "Pronunciation" .. level ..
"\n{{ko-IPA" .. iterate_param(args, genHead(poses), 3) .. "}}"
if genHead(poses) == "root" then defs = "{{ko-root of|" .. defs .. "}}" end
result = result .. "\n\n" .. level .. genTitle(poses) .. level .. "\n{{ko-" .. genHead(poses) ..
(head and ("|head=" .. head) or "") .. (args and ("|hanja=" .. args) or "") .. "}}" .. add_regional(args, 3) .. "\n\n# " .. (defs or "{{rfdef|ko}}")
args = add_der(args, 3, args or false)
result = result .. other("3syn", "=Synonyms=", args, level)
result = result .. other("3ant", "=Antonyms=", args, level)
result = result .. other("3der", "=Derived terms=", args, level)
result = result .. other("3rel", "=Related terms=", args, level)
result = result .. other("3also", "=See also=", args, level)
if genHead(poses) == "adj" or genHead(poses) == "verb" then
result = result .. "\n\n=" .. level .. "Conjugation" .. level .. "=\n{{ko-conj/" .. genHead(poses) .. (irreg and "|irreg=y" or "") .. "}}"
end
else
result = result .. "\n\n===" .. genTitle(poses) .. "===\n{{ko-" .. genHead(poses) ..
(head and ("|head=" .. head) or "") .. (args and ("|hanja=" .. args) or "") ..
"}}\n\n# " .. (defs or "{{rfdef|ko}}")
if genHead(poses) == "adj" or genHead(poses) == "verb" then
result = result .. "\n\n====Conjugation====\n{{ko-conj/" .. genHead(poses) .. (irreg and "|irreg=y" or "") .. "}}"
end
end
end
if cat then
result = result .. "\n\n{{C|ko|" .. cat .. "}}"
end
return result
end
function export.decompose_jamo(syllable)
if not match(syllable, "") then
if match(syllable, "") then return { initial = syllable, vowel = "Ø", final = "Ø" }
elseif match(syllable, "") then return { initial = "Ø", vowel = syllable, final = "Ø" }
elseif match(syllable, "") then return { initial = "Ø", vowel = "Ø", final = syllable }
elseif match(syllable, "") then return { initial = "Ø", vowel = "Ø", final = syllable }
elseif match(syllable, "") then return { initial = "Ø", vowel = syllable, final = "Ø" }
else return { initial = "Ø", vowel = " ", final = "X" } end
end
local cp = codepoint(syllable)
if not cp then return { "", "", "" } end
local relative_cp = cp - 0xAC00
local jongseong = relative_cp % 28
local jungseong = floor((relative_cp % 588) / 28)
local choseong = floor(relative_cp / 588)
choseong, jungseong, jongseong =
u(0x1100 + choseong),
u(0x1161 + jungseong),
jongseong ~= 0 and u(0x11A7 + jongseong) or ""
return { initial = choseong, vowel = jungseong, final = jongseong }
end
return export