Module:rad-IPA: Difference between revisions

Added syllabification
(Added Cv resolution)
(Added syllabification)
Line 224: Line 224:
["z"] = "ʒ",
["z"] = "ʒ",
}
}
local nasal = {
["m"] = true, ["n"] = true, ["ŋ"] = true,
}
local glide = {
local glide = {
Line 244: Line 248:
}
}


local Cv_fixed = {
local Cv_fixed = { -- <Cv> combinations that uniformly pronounced without /v/ --
["b"] = true,
["b"] = true,
["f"] = true,
["f"] = true,
Line 250: Line 254:
}
}


local Cv_split = {
local Cv_split = { -- <Cv> combinations that are only pronounced with /v/ post-vocalically --
["m"] = true, ["n"] = true,  
["m"] = true, ["n"] = true,  
}
}
local Cr = { -- consonants that can precede /r/ in a medial onset --
["p"] = true, ["k"] = true, ["b"] = true, ["ɡ"] = true,
["ç"] = true, ["ð"] = true,
["f"] = true, ["ɣ"] = true, ["h"] = true,
["v"] = true,
["θ"] = true,
["t"] = true, ["d"] = true,
}
local Cl = { -- consonants that can precede /l/ in a medial onset --
["p"] = true, ["k"] = true, ["b"] = true, ["ɡ"] = true,
["ç"] = true, ["ð"] = true,
["f"] = true, ["ɣ"] = true, ["h"] = true,
["v"] = true,
["θ"] = true,
["s"] = true, ["ʃ"] = true, ["z"] = true, ["ʒ"] = true,
}
local Cv = { -- consonants that can precede /v/ in a medial onset --
["ç"] = true, ["d"] = true, ["ð"] = true, ["dz"] = true,
["dʒ"] = true, ["ɡ"] = true, ["ɣ"] = true, ["h"] = true,
["k"] = true, ["l"] = true, ["r"] = true, ["s"] = true, ["ʃ"] = true,
["t"] = true, ["ts"] = true, ["tʃ"] = true,
["z"] = true, ["ʒ"] = true, ["θ"] = true,
}
local continuant = { -- consonants that can precede nasals in a medial onset -- (non-glide continuants)
["ç"] = true, ["ð"] = true,
["f"] = true, ["ɣ"] = true, ["h"] = true,
["l"] = true, ["r"] = true, ["s"] = true, ["ʃ"] = true,
["v"] = true,
["z"] = true, ["ʒ"] = true, ["θ"] = true,
}
local CN = continuant


-- VOWEL GROUPS --
-- VOWEL GROUPS --
Line 506: Line 549:
end
end
end
if boundary[p_current] then
mw.log("——— word boundary detected ———")
end
end
Line 679: Line 726:
end
end
mw.log("Vowel resolution result: [" .. table.concat(working_phones,"][") .. "]")
mw.log("Consonant resolution result: [" .. table.concat(working_phones,"][") .. "]")
return working_phones
return working_phones
Line 688: Line 735:
local syllables = {}
local syllables = {}
local working_syllable = {
local working_syllable = {
["onset"] = {},
["onset"] = {},
["nucleus"] = {},
["nucleus"] = "",
["coda"] = {},
["coda"] = {},
}
}
local syllable_no = 1
local syllable_no = 1
local function register_syllable()
local function logSyllable()
syllables[syllable_no] = working_syllable
local onset = ""
mw.log("Syllable " .. syllable_no .. " registered.")
local coda = ""
syllable_no = syllable_no + 1
working_syllable = {}
if working_syllable["onset"] then
onset = table.concat(working_syllable["onset"], " ")
end
if working_syllable["coda"] then
coda = table.concat(working_syllable["coda"], " ")
end
mw.log( onset .. " [ " .. working_syllable["nucleus"] .. " ] " .. coda )
end
end
local function register_boundary()
mw.log("————— BEGINNING SYLLABIFICATION —————")
register_syllable()
syllables[syllable_no] = "|"
mw.log("Boundary syllable " .. syllable_no .. " registered.")
syllable_no = syllable_no + 1
end
-- division into syllables --
-- division into syllables --
while #working_phones > 0 do
while #working_phones > 0 do
local p_check = working_phones[1]
local p_current = working_phones[1]
if consonant[p_check] or p_check == "·" or p_check == "-" then
local p_next = working_phones[2]
if working_syllable["nucleus"] == nil then
local p_next2 = working_phones[3]
table.append(working_syllable["onset"], p_check)
local p_next3 = working_phones[4]
mw.log("[" .. p_check .. "] appended to working onset.")
local function register_syllable(check)
if check == true then
syllables[syllable_no] = working_syllable
if #syllables[syllable_no]["onset"] == 0 then
syllables[syllable_no]["onset"] = nil
end
if #syllables[syllable_no]["coda"] == 0 then
syllables[syllable_no]["coda"] = nil
end
mw.log("Syllable " .. syllable_no .. " registered:")
logSyllable()
mw.log("===== NEW SYLLABLE=====")
syllable_no = syllable_no + 1
working_syllable = {
["onset"] = {},
["nucleus"] = "",
["coda"] = {},
}
end
end
local function register_boundary(check)
if check == true then
register_syllable(true)
syllables[syllable_no] = p_current
table.remove(working_phones, 1)
mw.log("Boundary syllable " .. syllable_no .. " registered: '" .. p_current .. "'.")
syllable_no = syllable_no + 1
end
end
local function register_phone(check)
if check == true then
if vowel[p_current] then
working_syllable["nucleus"] = p_current
mw.log("[" .. p_current .. "] is now the working nucleus.")
elseif consonant[p_current] then
local unit = ""
if working_syllable["nucleus"] == "" then
unit = "onset"
else
unit = "coda"
end
table.insert(working_syllable[unit], p_current)
mw.log("[" .. p_current .. "] appended to the working " .. unit .. ".")
else
error("Invalid input for function register_phone")
end
table.remove(working_phones, 1)
table.remove(working_phones, 1)
mw.log("Current test string: " .. table.concat(working_phones))
mw.log("Current working syllable:")
logSyllable()
if #working_phones == 0 then
register_syllable(true)
end
end
end
mw.log(" ========= ")
mw.log("Current test string: " .. table.concat(working_phones))
if consonant[p_current] then
if working_syllable["nucleus"] == ""  then
register_phone(true)
else
else
--add to coda until new syllable
if vowel[p_next] or (glide[p_next] and vowel[p_next2]) then -- *C*(J)V
register_syllable(true)
register_phone(true)
elseif #working_syllable["coda"] > 0 then -- C | …
local function JV(check)
if check == true then
if vowel[p_next2] or (glide[p_next2] and vowel[p_next3]) then -- C | *C*l(J)V
register_syllable(true)
register_phone(true)
else
register_phone(true)
end
end
end
if Cl[p_current] and p_next == "l" then -- C | *C*l …
JV(true) -- C | *C*l(J)V
elseif Cr[p_current] and p_next == "r" then -- C | *C*r …
JV(true) -- C | *C*r(J)V
elseif Cv[p_current] and p_next == "v" then -- C | *C*v …
JV(true) -- C | *C*v(J)V
elseif CN[p_current] and nasal[p_next] then -- C | *C*N …
JV(true) -- C | *C*N(J)V
else
register_phone(true)
end
else
register_phone(true)
end
end
end
elseif vowel[p_check] then
elseif vowel[p_current] then
if working_syllable["nucleus"] == nil then
if working_syllable["nucleus"] == "" then
working_syllable["nucleus"] = p_check
register_phone(true)
else
else
-- register syllable and begin new syllable
register_syllable(true)
register_phone(true)
end
end
elseif boundary[p_current] or p_current == "-" then
register_boundary(true)
else
else
-- register current syllable and register boundary --
error("Unrecognised phone in syllabifier: " .. p_current)
end
end
end
end
 
mw.log("——— STRING EXHAUSTED ———")
mw.log("——— STRING EXHAUSTED ———")
Line 745: Line 890:
outputIPA = resolve_vowels(outputIPA)
outputIPA = resolve_vowels(outputIPA)
outputIPA = resolve_consonants(outputIPA, hj)
outputIPA = resolve_consonants(outputIPA, hj)
outputIPA = table.concat(outputIPA,"][")
outputIPA = get_syllables(outputIPA)
return "[" .. outputIPA .. "]"
-- test output only --
for i = 1, #outputIPA do
local onset = ""
local coda = ""
if type(outputIPA[i]) == "table" then
if outputIPA[i]["onset"] then
onset = table.concat(outputIPA[i]["onset"], " ")
end
if outputIPA[i]["coda"] then
coda = table.concat(outputIPA[i]["coda"], " ")
end
mw.log("Syllable " .. i .. ": " .. onset .. " [ " .. outputIPA[i]["nucleus"] .. " ] " .. coda )
else
mw.log("Boundary syllable " .. i .. ": '" .. outputIPA[i] .. "'")
end
end
-- return outputIPA
end
end