local export = {}
local m_ko_utilities = require("Modül:ko-araçlar")
local m_data = require("Modül:ko-söyleniş/veri")
local gsub = mw.ustring.gsub
local match = mw.ustring.match
local sub = mw.ustring.sub
local char = mw.ustring.char
local codepoint = mw.ustring.codepoint
local PAGENAME = mw.title.getCurrentTitle().text
local system_lookup = {
= 1, = 2, = 3,
= 4, = 5, = 6,
}
local system_list = {
{
seq = 1,
abbreviation = "ph",
display = "Phonetic ]",
full = nil,
separator = "/",
},
{
seq = 2,
abbreviation = "rr",
display = "RR",
full = "Revised Romanization of Korean (transcription)",
separator = "/",
},
{
seq = 3,
abbreviation = "rrr",
display = "RR <small>(translit.)</small>",
full = "Revised Romanization of Korean (transliteration)",
separator = "/"
},
{
seq = 4,
abbreviation = "mc",
display = "MC",
full = "McCune–Reischauer",
separator = "/"
},
{
seq = 5,
abbreviation = "yr",
display = "Yale",
full = "Yale Romanization",
separator = "/"
},
{
seq = 6,
abbreviation = "ipa",
display = "]<sup>(])</sup>",
full = nil,
separator = "] ~ ["
}
}
local final_syllable_conversion = { = "Ø", = "" }
local com_mc = { = "k", = "t", = "p", = "ch", = "s", = "ss" }
local com_ph = { = "ᄁ", = "ᄄ", = "ᄈ", = "ᄊ", = "ᄍ" }
local vowel_variation = { = -56, = 112, = 0 }
local allowed_vowel_scheme = { = 1, = 1, = 1, = 1, = 1 }
local ambiguous_intersyllabic_rr = { = 1, = 1, = 1, = 1, = 1 }
local function decompose_syllable(word)
local decomposed_syllables = {}
for syllable in mw.text.gsplit(word, "") do
table.insert(decomposed_syllables, m_ko_utilities.decompose_jamo(syllable))
end
return decomposed_syllables
end
local function tidy_phonetic(original, romanised)
local j, k, w = 1, 1, {}
for i = 1, mw.ustring.len(romanised) do
local romanised_syllable = mw.ustring.sub(romanised, k, k)
local original_syllable = mw.ustring.sub(original, j, j)
if romanised_syllable ~= original_syllable then
table.insert(w, '<span style="font-size:110%; color:#BF0218"><b>'..romanised_syllable..'</b></span>')
if match(original_syllable, "") then k = k + 1 end
if match(romanised_syllable, "") then j = j + 1 end
else
table.insert(w, '<span style="font-size:110%">'..romanised_syllable..'</span>')
j, k = j + 1, k + 1
end
end
return table.concat(w)
end
local function tidy_ipa(set)
local ipa = table.concat(set, system_list.separator)
ipa = gsub(ipa, "ʌ̹ː", "ɘː")
ipa = gsub(ipa, "ɭɭ()", "ɭʎ%1")
ipa = gsub(ipa, "s(?)ʰɥi" ,"ʃ%1ʰɥi")
ipa = gsub(ipa, "s()()" ,"ɕ%1%2")
ipa = gsub(ipa, "nj", "ɲj")
ipa = gsub(ipa, "kʰ", {
= "kçi",
= "kçj",
= "kxɯ" }
)
ipa = gsub(ipa, "", {
= "çi",
= "çj",
= "xɯ",
= "ɸʷo",
= "ɸʷu",
= "ɸw",
= "ʝi",
= "ʝj",
= "ɣɯ",
= "βo",
= "βu",
= "βw" }
)
if match(ipa, "ɥi") then
local midpoint = math.floor(mw.ustring.len(ipa) / 2)
ipa = sub(ipa, 1, midpoint) .. gsub(sub(ipa, midpoint+1, -1), "ɥi", "y")
end
return ipa
end
function export.romanise(text_param, system_index, args)
local p, optional_params = {}, { "nn", "l", "com", "cap", "ni" }
for _, pm in ipairs(optional_params) do
p = { }
if args then
for pp in mw.text.gsplit(args, ",") do p = 1 end
end
end
local vowel_ui_i, vowel_ui_e, no_batchim, batchim_reduce, s_variation, iotation, yeo_reduce =
args.ui, args.uie, args.nobc, args.bcred, args.svar, args.iot, args.yeored
system_index = system_lookup or system_index
for primitive_word in mw.ustring.gmatch(text_param, "+") do
local the_original = primitive_word
primitive_word = gsub(primitive_word, "'''", "ß")
local bold_position, bold_count = {}, 0
while match(primitive_word, "ß") do
bold_position = true
primitive_word = gsub(primitive_word, "ß", "", 1)
bold_count = bold_count + 1
end
local has_vowel = {}
for ch in mw.ustring.gmatch(primitive_word, ".") do
local jungseong = math.floor(((codepoint(ch) - 0xAC00) % 588) / 28)
if ch ~= "예" and match(ch, "") then has_vowel = true end
end
local word_set = { primitive_word }
local function add_respelling(variable, modification, modification2)
modification2 = modification2 or function(x) return x end
if variable and match(system_index, "") then
variable = tonumber(variable)
local pre_length = #word_set
for i = 1, pre_length do
local item = mw.text.split(word_set, "")
item = modification(item)
item = modification2(item)
word_set = table.concat(item)
end
end
end
add_respelling(vowel_ui_i, function(x) return "이" end)
add_respelling(vowel_ui_e, function(x) return "에" end)
add_respelling(no_batchim,
function(x) return char(codepoint(x) - (codepoint(x) - 0xAC00) % 28) end,
function(y) return char(codepoint(y) + 588) end)
add_respelling(s_variation, function(x) return char(codepoint(x) - 12) end)
add_respelling(iotation, function(x) return char(codepoint(x) + 56) end)
add_respelling(yeo_reduce, function(x) return char(codepoint(x) - 56) end)
for _, vowel_id in ipairs({ 7, 11, 16 }) do
if has_vowel and allowed_vowel_scheme then
local pre_length = #word_set
for i = 1, pre_length do
local item = mw.text.split(word_set, "")
for num, it in ipairs(item) do
if math.floor(((codepoint(it) - 0xAC00) % 588) / 28) == vowel_id then
item = char(codepoint(it) + vowel_variation)
end
end
if vowel_id == 11 then
table.insert(word_set, i, table.concat(item))
else
table.insert(word_set, table.concat(item))
end
end
end
end
local word_set_romanisations = {}
for _, respelling in ipairs(word_set) do
local decomposed_syllables = decompose_syllable(respelling)
local romanisation = {}
local bold_insert_count = 0
for index = 0, #decomposed_syllables, 1 do
local this_syllable = index ~= 0 and sub(respelling, index, index) or ""
local syllable = decomposed_syllables or { initial = "Ø", vowel = "Ø", final = "X" }
local next_syllable = decomposed_syllables or { initial = "Ø", vowel = "Ø", final = "Ø" }
syllable.final = final_syllable_conversion or syllable.final
if system_index == 5 and syllable.vowel == "ᅮ" and match(syllable.initial, "") then
syllable.vowel = "ᅳ"
end
if match(system_index, "") then
if syllable.vowel == "ᅴ" and this_syllable ~= "의" then
syllable.vowel = "ᅵ"
end
if this_syllable == "넓" then
if match(next_syllable.initial, "") then
syllable.final = "ᆸ"
elseif next_syllable.initial == "ᄃ" then
if match(next_syllable.initial, "") then
syllable.final = "ᆸ"
end
end
end
end
local vowel = m_data.vowels
if p.nn then
next_syllable.initial = "ᄂ"
end
if p.com and match(system_index, "") then
next_syllable.initial = com_ph or next_syllable.initial
end
if p.ni and system_index ~= 3 then
next_syllable.initial = (system_index == 5 and syllable.final == "ᆯ") and "ᄅ" or "ᄂ"
end
if match(system_index, "") then
if tonumber(batchim_reduce or -1) == index then
syllable.final = m_data.boundary
end
if index ~= 0 and this_syllable == "밟" then
syllable.final = "ᆸ"
end
local final_next_syllable = syllable.final .. sub(respelling, index+1, index+1)
if match(final_next_syllable, "") then
syllable.final = "ᆾ"
elseif match(final_next_syllable, "ᆮ이") then
syllable.final = "ᆽ"
elseif match(final_next_syllable, "ᆮ히") then
syllable.final = "ᆾ"
elseif syllable.final .. next_syllable.initial == "ᆺᄋ" and
match(sub(respelling, index+1, index+1), "") then
syllable.final = "ᆮ"
end
end
local bound = syllable.final .. "-" .. next_syllable.initial
if not m_data.boundary then
require("Modül:debug").track("ko-söyleniş/no boundary data")
mw.log("No boundary data for " .. bound .. ".")
return nil
end
local junction = m_data.boundary
if bold_position then
junction = gsub(junction, "^(.?)(.?)$", function(a, b)
return match(syllable.final .. next_syllable.initial, "^Ø?$")
and "'''" .. a .. b
or a .. "'''" .. b end)
bold_insert_count = bold_insert_count + 1
end
if p.l or (p.l and index == 1) then
if system_index == 1 then
junction = gsub(junction, "^(.)(.?)$", function(a, b)
return match(a, "") and a .. ":" .. b or ":" .. a .. b end)
elseif system_index == 5 then
vowel = gsub(vowel, "()", "%1̄")
elseif system_index == 6 then
vowel = vowel .. "ː"
end
end
if (p.l or p.l) and index == 0 and system_index == 6 and #decomposed_syllables > 1 then
vowel = vowel .. "ˈ"
end
if p.com then
junction = gsub(junction, "(.)$", function(next_letter)
return
(system_index == 5 and "q" or "") ..
(system_index == 4
and (com_mc or "")] or com_mc or next_letter)
or next_letter) end)
end
if p.cap and index == 0 and match(system_index, "") then
junction = mw.ustring.upper(sub(junction, 1, 1)) .. sub(junction, 2, -1)
end
if p.ni and system_index == 5 then
junction = gsub(junction, "()$", "<sup>%1</sup>")
end
table.insert(romanisation, vowel .. junction)
end
local temp_romanisation = table.concat(romanisation)
if system_index == 1 then
temp_romanisation = tidy_phonetic(primitive_word, mw.ustring.toNFC(temp_romanisation))
elseif match(system_index, "") then
for i = 1, 2 do
temp_romanisation = gsub(temp_romanisation, "(.)…(.)", function(a, b)
return a .. (ambiguous_intersyllabic_rr and "-" or "") .. b end)
end
elseif system_index == 4 then
temp_romanisation = gsub(temp_romanisation, "swi", "shwi")
end
table.insert(word_set_romanisations, temp_romanisation)
end
text_param = gsub(
text_param,
the_original,
table.concat(word_set_romanisations, system_list.separator),
1
)
end
return text_param
end
function export.make(frame, scheme)
local params = {
= { default = PAGENAME, list = true },
= {},
= { alias_of = "a" },
= {},
= {},
= {},
= {},
= {},
= {},
= {},
= {},
= {},
= {},
= {},
= {},
}
local args = require("Modül:parameters").process(frame:getParent().args, params)
table.sort(system_list, function(first, second) return first.seq < second.seq end)
local results = {}
for _, text_param in ipairs(args) do
local current_word_dataset = {}
for _, system in pairs(system_list) do
local romanised = export.romanise(text_param, system.seq, args)
table.insert(current_word_dataset, romanised)
end
table.insert(results, current_word_dataset)
end
local output_result = { = {}, = {}, = {}, = {}, = {}, = {} }
for _, result in ipairs(results) do
for result_index, value in ipairs(result) do
table.insert(output_result, value)
end
end
local show_text, hide_text = {}, {}
table.insert(show_text,
"* " .. system_list.display .. ": " ..
tostring( mw.html.create( "span" )
:attr( "class", "IPA" )
:wikitext( ") .. "]" )))
local ipa_output = table.concat(output_result, system_list.separator)
local width = 15 * mw.ustring.len(ipa_output)
width = width < 400 and 400 or (width > 800 and 800 or width)
table.insert(hide_text,
'{|class="wikitable" style="width:100%; margin:0; text-align:center; border-collapse: collapse; border-style: hidden;" \n!style=\"background-color:#F6ECC0\"|' .. system_list.display .. "\n|" ..
tostring( mw.html.create( "span" )
:attr( "class", "IPA" )
:wikitext( ") .. "]" )) ..
"\n|-\n!style=\"width:160px; background-color:#F6ECC0\"| " .. system_list.display .. "\n|" ..
tostring( mw.html.create( "span" )
:attr( "class", "Kore" )
:attr( "lang", "ko" )
:wikitext( table.concat(output_result, system_list.separator) )) ..
(args.a
and "\n|-\n!style=\"background-color:#F6ECC0\"|Audio\n|" .. mw.getCurrentFrame():expandTemplate{
title = "Template:audio",
args = { args.a == "y" and "Ko-" .. PAGENAME .. ".ogg" or args.a, lang = "ko" }}
or "") ..
"\n|-\n!colspan=2|]")
for roman_index = 2, 5 do
table.insert(hide_text,
"\n|-\n!style=\"background-color:#F6ECC0\"|" ..
tostring( mw.html.create( "span" )
:css( "border-bottom", "1px dotted #000" )
:css( "cursor", "help" )
:attr( "title", system_list.full )
:wikitext( "<i>" .. system_list.display .. "</i>" )) .. "\n|" ..
table.concat(output_result, system_list.separator))
end
return
tostring( mw.html.create( "div" )
:attr( "class", "toccolours mw-collapsible mw-collapsed" )
:css( "width", width .. "px" )
:css( "background-color", "#F7FAFE" )
:css( "font-size", "100%" )
:wikitext(
"\n" ..
table.concat( show_text ) ..
"\n" ..
tostring( mw.html.create( "div")
:attr( "class", "mw-collapsible-content" )
:wikitext( "\n----\n" .. table.concat( hide_text ) .. "\n|}" ))))
end
return export