10,794
edits
TheNightAvl (talk | contribs) (Added stress prediction) |
TheNightAvl (talk | contribs) (Added phonetic option) |
||
Line 130: | Line 130: | ||
} | } | ||
local valid_phone = { | local valid_phone = { | ||
["a"] = true, ["aː"] = true, ["aːː"] = true, ["æː"] = true, ["ai"] = true, | ["a"] = true, ["aː"] = true, ["aːː"] = true, ["æː"] = true, ["ai"] = true, | ||
Line 144: | Line 143: | ||
["uːː"] = true, ["uːo"] = true, ["ua"] = true, ["uo"] = true, ["v"] = true, | ["uːː"] = true, ["uːo"] = true, ["ua"] = true, ["uo"] = true, ["v"] = true, | ||
["w"] = true, ["y"] = true, ["z"] = true, ["ʒ"] = true, ["θ"] = true, | ["w"] = true, ["y"] = true, ["z"] = true, ["ʒ"] = true, ["θ"] = true, | ||
-- allophones -- | |||
["x"] = true, ["ʝ"] = true, | |||
} | } | ||
local valid_phone_temp = {"iːj", "uːj", "yːj", "ù", "ū", "ĵ"} | local valid_phone_temp = {"iːj", "uːj", "yːj", "ù", "ū", "ĵ"} | ||
Line 159: | Line 162: | ||
["t"] = true, ["ts"] = true, ["tʃ"] = true, ["v"] = true, ["w"] = true, | ["t"] = true, ["ts"] = true, ["tʃ"] = true, ["v"] = true, ["w"] = true, | ||
["z"] = true, ["ʒ"] = true, ["θ"] = true, | ["z"] = true, ["ʒ"] = true, ["θ"] = true, | ||
-- allophones -- | |||
["x"] = true, ["ʝ"] = true, | |||
} | } | ||
local consonant_temp = {"ĵ"} | local consonant_temp = {"ĵ"} | ||
Line 171: | Line 178: | ||
["t"] = true, ["ts"] = true, ["tʃ"] = true, ["v"] = true, | ["t"] = true, ["ts"] = true, ["tʃ"] = true, ["v"] = true, | ||
["z"] = true, ["ʒ"] = true, ["θ"] = true, | ["z"] = true, ["ʒ"] = true, ["θ"] = true, | ||
-- allophones -- | |||
["x"] = true, | |||
} | } | ||
Line 187: | Line 198: | ||
["t"] = "t", ["ts"] = "ts", ["tʃ"] = "tʃ", ["v"] = "f", | ["t"] = "t", ["ts"] = "ts", ["tʃ"] = "tʃ", ["v"] = "f", | ||
["z"] = "s", ["ʒ"] = "ʃ", ["θ"] = "θ", | ["z"] = "s", ["ʒ"] = "ʃ", ["θ"] = "θ", | ||
-- allophones -- | |||
["x"] = "x", | |||
} | } | ||
Line 195: | Line 210: | ||
["t"] = "d", ["ts"] = "dz", ["tʃ"] = "dʒ", ["v"] = "v", | ["t"] = "d", ["ts"] = "dz", ["tʃ"] = "dʒ", ["v"] = "v", | ||
["z"] = "z", ["ʒ"] = "ʒ", ["θ"] = "ð", | ["z"] = "z", ["ʒ"] = "ʒ", ["θ"] = "ð", | ||
-- allophones -- | |||
["x"] = "ɣ", | |||
} | } | ||
Line 272: | Line 291: | ||
["t"] = true, ["d"] = true, | ["t"] = true, ["d"] = true, | ||
-- allophones -- | |||
["x"] = true, | |||
} | } | ||
Line 283: | Line 306: | ||
["s"] = true, ["ʃ"] = true, ["z"] = true, ["ʒ"] = true, | ["s"] = true, ["ʃ"] = true, ["z"] = true, ["ʒ"] = true, | ||
-- allophones -- | |||
["x"] = true, | |||
} | } | ||
Line 291: | Line 318: | ||
["t"] = true, ["ts"] = true, ["tʃ"] = true, | ["t"] = true, ["ts"] = true, ["tʃ"] = true, | ||
["z"] = true, ["ʒ"] = true, ["θ"] = true, | ["z"] = true, ["ʒ"] = true, ["θ"] = true, | ||
-- allophones -- | |||
["x"] = true, ["ʝ"] = true, | |||
} | } | ||
Line 299: | Line 330: | ||
["v"] = true, | ["v"] = true, | ||
["z"] = true, ["ʒ"] = true, ["θ"] = true, | ["z"] = true, ["ʒ"] = true, ["θ"] = true, | ||
-- allophones -- | |||
["x"] = true, | |||
} | } | ||
local CN = continuant | local CN = continuant | ||
Line 595: | Line 630: | ||
end | end | ||
function resolve_consonants(phones, hj_dv) | function resolve_consonants(phones, hj_dv, phon) | ||
local working_phones = phones | local working_phones = phones | ||
mw.log("————— BEGINNING CONSONANT RESOLUTION —————") | mw.log("————— BEGINNING CONSONANT RESOLUTION —————") | ||
Line 644: | Line 679: | ||
-- Resolution of hjádvanþs -- | -- Resolution of hjádvanþs -- | ||
if hj_dv | if not hj_dv then | ||
if p_current == "ç" then | if p_current == "ç" then | ||
mw.log(" | mw.log("hj = false:") | ||
p_Convert("ʃ") | p_Convert("ʃ") | ||
elseif p_current == "j" and (boundary[p_prev] or p_prev == nil) and consonant[p_next] then | elseif p_current == "j" and (boundary[p_prev] or p_prev == nil) and consonant[p_next] then | ||
mw.log(" | mw.log("hj = false:") | ||
p_Convert("ʒ") | p_Convert("ʒ") | ||
end | end | ||
Line 686: | Line 721: | ||
mw.log("[d][ʃ] → [dʒ] in position " .. i .. ".") | mw.log("[d][ʃ] → [dʒ] in position " .. i .. ".") | ||
end | end | ||
end | end | ||
Line 729: | Line 765: | ||
mw.log("No cluster found.") | mw.log("No cluster found.") | ||
end | end | ||
end | |||
-- Progressive voicing assimilation of Cv -- | |||
if p_current == "v" and not obstruent_voiced[p_prev] then | |||
p_Resolve("f") | |||
mw.log("[" .. p_current .. "][v] → [" .. p_current .. "][f] in position " .. i .. ".") | |||
end | end | ||
Line 736: | Line 779: | ||
p_RemoveNext() | p_RemoveNext() | ||
mw.log("Geminate [" .. p_current .. "] removed in final position at position " .. i .. ".") | mw.log("Geminate [" .. p_current .. "] removed in final position at position " .. i .. ".") | ||
end | |||
-- PHONETIC RESOLUTION -- | |||
if phon == true then | |||
if p_current == "h" and not vowel[p_next] then | |||
mw.log("phon = true:") | |||
p_Resolve("x") | |||
elseif p_current == "h" and p_next == "j" then | |||
mw.log("phon = true:") | |||
p_Resolve("ç") | |||
p_RemoveNext() | |||
end | |||
end | end | ||
Line 868: | Line 923: | ||
elseif Cr[p_current] and p_next == "r" then -- C | *C*r … | elseif Cr[p_current] and p_next == "r" then -- C | *C*r … | ||
JV(true) -- C | *C*r(J)V | JV(true) -- C | *C*r(J)V | ||
elseif Cv[p_current] and p_next == "v" then -- C | *C*v … | elseif Cv[p_current] and (p_next == "v" or p_next == "f") then -- C | *C*v … | ||
JV(true) -- C | *C*v(J)V | JV(true) -- C | *C*v(J)V | ||
elseif CN[p_current] and nasal[p_next] then -- C | *C*N … | elseif CN[p_current] and nasal[p_next] then -- C | *C*N … | ||
Line 1,145: | Line 1,200: | ||
end | end | ||
end | end | ||
return output | return output | ||
Line 1,153: | Line 1,206: | ||
function resolve_syllables(syllables) | function resolve_syllables(syllables) | ||
mw.log("————— RESOLVING SYLLABLES —————") | |||
if #syllables > 1 then | |||
for i = 1, #syllables - 1 do | |||
for i = 1, # | |||
local onset = "" | local working_cluster = {} | ||
if (syllables[i]["coda"] or syllables[i+1]["onset"]) and syllables[i+1] and type(syllables[i]) == "table" and type(syllables[i+1]) == "table" then | |||
-- mw.log("Resolving clusters in syllables " .. i .. " and " .. i + 1 .. ".") | |||
-- get intersyllabic clusters -- | |||
if syllables[i]["coda"] then | |||
for j = 1, #syllables[i]["coda"] do | |||
table.insert(working_cluster, syllables[i]["coda"][j]) | |||
end | |||
end | |||
if syllables[i+1]["onset"] then | |||
for j = 1, #syllables[i+1]["onset"] do | |||
table.insert(working_cluster, syllables[i+1]["onset"][j]) | |||
end | |||
end | |||
-- mw.log("Cluster to be resolved: " .. table.concat(working_cluster)) | |||
local p_last = working_cluster[#working_cluster] | |||
local p_last2 = working_cluster[#working_cluster-1] | |||
local p_last3 = working_cluster[#working_cluster-2] | |||
local p_last4 = working_cluster[#working_cluster-3] | |||
local new_coda = {} | |||
local new_onset = {} | |||
-- splits the current cluster into new coda and new onset and re-assigns them to the syllables -- | |||
if | local function split(point) | ||
if point < 1 or point > 3 or point == nil then | |||
error("split() must take integer values between 1 to 4 inclusive") | |||
end | |||
for j = #working_cluster + 1 - point, #working_cluster do | |||
table.insert(new_onset, working_cluster[j]) | |||
end | |||
if #working_cluster - point > 0 then | |||
for j = 1, #working_cluster - point do | |||
table.insert(new_coda, working_cluster[j]) | |||
end | |||
end | |||
mw.log("σ" .. i .. " | σ" .. i+1 .. " : … " .. table.concat(new_coda) .. " | " .. table.concat(new_onset) .. " …") | |||
syllables[i]["coda"] = new_coda | |||
syllables[i+1]["onset"] = new_onset | |||
end | end | ||
-- determine syllable boundary -- | |||
if | if glide[p_last] and nasal[p_last2] and CN[p_last3] and p_last4 then -- C|CNJ | ||
split(3) | |||
elseif nasal[p_last] and CN[p_last2] and p_last3 then -- C|CN | |||
split(2) | |||
elseif glide[p_last] and p_last2 == "r" and Cr[p_last3] and p_last4 then -- C|CrJ | |||
split(3) | |||
elseif p_last == "r" and Cr[p_last2] and p_last3 then -- C|Cr | |||
split(2) | |||
elseif glide[p_last] and p_last2 == "l" and Cl[p_last3] and p_last4 then -- C|ClJ | |||
split(3) | |||
elseif p_last == "l" and Cl[p_last2] and p_last3 then -- C|Cl | |||
split(2) | |||
elseif glide[p_last] and (p_last2 == "v" or p_last2 == "f") and Cv[p_last3] and p_last4 then -- C|CvJ | |||
split(3) | |||
elseif (p_last == "v" or p_last == "f") and Cv[p_last2] and p_last3 then -- C|Cv | |||
split(2) | |||
elseif glide[p_last] and p_last2 then -- C|CJ | |||
split(2) | |||
else -- C|C | |||
split(1) | |||
end | end | ||
end | end | ||
end | |||
end | |||
return syllables | |||
end | |||
function syllables_to_string(syllables) | |||
local output = "" | |||
for i = 1, #syllables do | |||
local onset = "" | |||
local coda = "" | |||
local stress="" | |||
if type(syllables[i]) == "table" then | |||
if syllables[i]["onset"] then | |||
onset = table.concat(syllables[i]["onset"]) | |||
end | |||
if syllables[i]["coda"] then | |||
coda = table.concat(syllables[i]["coda"]) | |||
end | |||
if syllables[i]["stress"] then | |||
stress = "ˈ" | |||
end | |||
if syllables[i]["stress2"] then | |||
stress = "ˌ" | |||
end | |||
output = output .. stress .. onset .. syllables[i]["nucleus"] .. coda | |||
else | |||
output = output .. syllables[i] | |||
end | end | ||
end | |||
return output | |||
mw.log( | end | ||
return | |||
function export.generate(frame) | |||
local args = getArgs(frame) | |||
local outputIPA = generate_IPA(args[1]) | |||
local parameters = {} | |||
local p = 2 | |||
mw.log("——— Parameters ———") | |||
while args[p] do | |||
parameters[args[p]] = true | |||
mw.log(args[p] .. " = true") | |||
p = p + 1 | |||
end | |||
outputIPA = resolve_vowels(outputIPA) | |||
outputIPA = resolve_consonants(outputIPA, parameters["hj"], parameters["phon"]) | |||
outputIPA = get_syllables(outputIPA) | |||
outputIPA = tag_syllables(outputIPA) | |||
outputIPA = get_stress(outputIPA) | |||
outputIPA = resolve_syllables(outputIPA) | |||
outputIPA = syllables_to_string(outputIPA) | |||
mw.log(outputIPA) | |||
return outputIPA | |||
end | end |