Module:rad-IPA: Difference between revisions

Rejigged stress assignment and fixed bug with [v] assimilation
(Added nasalisation to phonetic realisation)
(Rejigged stress assignment and fixed bug with [v] assimilation)
Line 165: Line 165:
-- allophones --
-- allophones --
["x"] = true, ["ʝ"] = true,
["x"] = true, ["ʝ"] = true, ["ʋ"] = true,
}
}
local consonant_temp = {"ĵ"}
local consonant_temp = {"ĵ"}
Line 189: Line 189:
-- allophones --
-- allophones --
["x"] = true,
["x"] = true, ["ʋ"] = true,
}
}


Line 196: Line 196:
["dʒ"] = true, ["ɡ"] = true, ["ɣ"] = true,  
["dʒ"] = true, ["ɡ"] = true, ["ɣ"] = true,  
["v"] = true,
["v"] = true,
["z"] = true, ["ʒ"] = true,  
["z"] = true, ["ʒ"] = true,
}
}
Line 301: Line 301:
-- allophones --
-- allophones --
["x"] = true,
["x"] = true, ["ʋ"] = true,
}
}


Line 316: Line 316:
-- allophones --
-- allophones --
["x"] = true,
["x"] = true, ["ʋ"] = true,
}
}


Line 340: Line 340:
-- allophones --
-- allophones --
["x"] = true,
["x"] = true, ["ʋ"] = true,
}
}
local CN = continuant
local CN = continuant
Line 353: Line 353:
-- allophones --
-- allophones --
["x"] = true,
["x"] = true, ["ʋ"] = true,
}
}


Line 766: Line 766:
-- Resolution of regressive voicing assimilation --
-- Resolution of regressive voicing assimilation --
if obstruent[p_current] == true then
if obstruent[p_current] then
mw.log("Obstruent [" .. p_current .. "] found in position " .. i .. ". Searching for cluster.")
mw.log("Obstruent [" .. p_current .. "] found in position " .. i .. ". Searching for cluster.")
local final_i = i
local final_i = i
-- find voicing of final obstruent in cluster --
-- find voicing of final obstruent in cluster --
for j = i + 1, #working_phones do
for k = i + 1, #working_phones do
local check_phone = working_phones[j]
local check_phone = working_phones[k]
if obstruent[check_phone] == true and not check_phone == "v" then -- /v/ is excluded
if obstruent[check_phone] and check_phone ~= "v" then -- /v/ is excluded
final_i = j
final_i = k
else break
else
break
end
end
end
end
if final_i > i then -- if cluster recognised --
if final_i ~= i then -- if cluster recognised --
final_obs = working_phones[final_i]
final_obs = working_phones[final_i]
mw.log("Final obstruent in cluster is [" .. final_obs .. "], cluster length " .. final_i - i + 1 .. ".")
mw.log("Final obstruent in cluster is [" .. final_obs .. "], cluster length " .. final_i - i + 1 .. ".")
Line 785: Line 786:
-- assimilate --
-- assimilate --
if not obstruent_voiced[p_current] == obstruent_voiced[final_obs] then
if obstruent_voiced[p_current] ~= obstruent_voiced[final_obs] then
mw.log("Voicing mismatch found in cluster at position " .. i .. ".")
mw.log("Voicing mismatch found in cluster at position " .. i .. ".")
if obstruent_voiced[final_obs] == true then
if obstruent_voiced[final_obs] == true then
Line 798: Line 799:
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 816: Line 810:
-- PHONETIC RESOLUTION --
-- PHONETIC RESOLUTION --
if phon == true then
if phon == true then
-- Cv --
if p_current == "v" and obstruent[p_prev] then
p_Resolve("ʋ")
mw.log("[" .. p_prev .. "][ʋ] → [" .. p_prev .. "][ʋ] in position " .. i .. ".")
end
if p_current == "h" and not vowel[p_next] then -- hC
if p_current == "h" and not vowel[p_next] then -- hC
mw.log("phon = true:")
mw.log("phon = true:")
Line 974: Line 976:
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"  or p_next == "f") then -- C | *C*v …
elseif Cv[p_current] and (p_next == "v"  or p_next == "ʋ") 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,066: Line 1,068:
function get_stress(syllables)
function get_stress(syllables)
--[[
--[[
Stress in Radestrian is calculated excluding · prefixes, which are stressed as if they were standalone words but with secondary stress. Stress in Radestrian falls on either the first syllable or the second syllable. The first syllable is the default stress position. Second-syllable stress occurs in eight circumstances:
Stress in Radestrian is calculated excluding · prefixes, which are stressed as if they were standalone words but with secondary stress. Stress in Radestrian falls on either the first syllable or the second syllable. The first syllable is the default stress position. Second-syllable stress occurs in six circumstances:
1:
1:
Line 1,074: Line 1,076:
2:
2:
σₙ = 3
σₙ = 3
σ₁: short, open
σ₁: short
σ₂: long
σ₂: long
3:
3:
σₙ = 3
σₙ = 3
σ₁: short, closed
σ₁: short, open
σ₂: long, closed
σ₂: short, not weak, closed
4:
4:
σₙ = 3
σₙ = 4+
σ₁: short
σ₁: short
σ₂: short, not weak, closed
σ₂: long
5:
5:
σₙ = 4+
σₙ = 4+
σ₁: short, open
σ₁: short, open
σ₂: short, open
σ₂: short, closed
σ₃: short
6:
6:
σₙ = 4+
σₙ = 4+
σ₁: short, open
σ₁: short, closed
σ₂: short, closed
σ₂: short, closed
σ₃: short
7:
7:
σₙ = 4+
σₙ = 4+
σ₁: short, open
σ₁: short
σ₂: long
σ₂: short, open
8:
σ₃: short
σₙ = 4+
σ₁: short, closed
σ₄: short
]]
]]
Line 1,182: Line 1,181:
elseif #working_word == 3 then -- trisyllabic?
elseif #working_word == 3 then -- trisyllabic?
if not working_word[2]["weak"] and working_word[2]["checked"] then -- condition 4
if working_word[2]["long"] then -- condition 2
stress(2)
elseif not (working_word[1]["checked"] or working_word[2]["weak"]) and working_word[2]["checked"] then -- condition 3
stress(2)
stress(2)
elseif working_word[2]["long"] then
if working_word[1]["checked"] then
if working_word[2]["checked"] then -- condition 3
stress(2)
else
stress(1)
end
elseif working_word[2]["long"] then -- condition 2
stress(2)
else
stress(1)
end
else
else
stress(1)
stress(1)
Line 1,202: Line 1,191:
elseif #working_word >= 4 then -- 4+ syllables
elseif #working_word >= 4 then -- 4+ syllables
if working_word[1]["checked"] then
if working_word[2]["long"] then -- condition 4
if not working_word[3]["long"] then -- condition 8
stress(2)
elseif working_word[2]["checked"] then
if not working_word[1]["checked"] then -- condition 5
stress(2)
elseif not working_word[3]["long"] then -- condition 6
stress(2)
stress(2)
else
else
stress(1)
stress(1)
end
end
elseif not working_word[3]["long"] then -- condition 7
elseif working_word[2]["long"] then -- condition 7
stress(2)
elseif working_word[2]["checked"] then -- condition 6
stress(2)
elseif not working_word[3]["long"] then -- condition 5
stress(2)
stress(2)
else
else
Line 1,320: Line 1,306:
elseif p_last == "l" and Cl[p_last2] and p_last3 then -- C|Cl
elseif p_last == "l" and Cl[p_last2] and p_last3 then -- C|Cl
split(2)
split(2)
elseif glide[p_last] and (p_last2 == "v" or p_last2 == "f") and Cv[p_last3] and p_last4 then -- C|CvJ
elseif glide[p_last] and (p_last2 == "v" or p_last2 == "ʋ") and Cv[p_last3] and p_last4 then -- C|CvJ
split(3)
split(3)
elseif (p_last == "v" or p_last == "f") and Cv[p_last2] and p_last3 then -- C|Cv
elseif (p_last == "v" or p_last == "ʋ") and Cv[p_last2] and p_last3 then -- C|Cv
split(2)
split(2)
elseif glide[p_last] and p_last2 then -- C|CJ
elseif glide[p_last] and p_last2 then -- C|CJ
Line 1,359: Line 1,345:
-- phonetic nasalisation --
-- phonetic nasalisation --
if phon then
if phon and syllables[i]["coda"] then
local function get_nasal(check)
local function get_nasal(check)
Line 1,373: Line 1,359:
if fricative[syllables[i]["coda"][2]] then
if fricative[syllables[i]["coda"][2]] then
get_nasal(true)
get_nasal(true)
elseif syllables[i]["coda"][2] == nil and fricative[syllables[i+1]["onset"][1]] then
elseif syllables[i+1]["onset"] then
get_nasal(true)
if syllables[i]["coda"][2] == nil and fricative[syllables[i+1]["onset"][1]] then
get_nasal(true)
end
end
end
Line 1,381: Line 1,369:
if syllables[i]["coda"][2] == "h" or syllables[i]["coda"][2] == "x" or syllables[i]["coda"][2] == "ɣ" then
if syllables[i]["coda"][2] == "h" or syllables[i]["coda"][2] == "x" or syllables[i]["coda"][2] == "ɣ" then
get_nasal(true)
get_nasal(true)
elseif syllables[i]["coda"][2] == nil and (syllables[i+1]["onset"][1] == "h" or syllables[i+1]["onset"][1] == "x" or syllables[i+1]["onset"][1] == "ɣ") then
elseif syllables[i+1]["onset"] then
get_nasal(true)
if syllables[i]["coda"][2] == nil and (syllables[i+1]["onset"][1] == "h" or syllables[i+1]["onset"][1] == "x" or syllables[i+1]["onset"][1] == "ɣ") then
get_nasal(true)
end
end
end