Module:rad-IPA: Difference between revisions

Added stress prediction
mNo edit summary
(Added stress prediction)
Line 955: Line 955:
return syllables
return syllables
end
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:
1:
σₙ = 2
σ₁: short, open
σ₂: heavy
2:
σₙ = 3
σ₁: short, open
σ₂: long
3:
σₙ = 3
σ₁: short, closed
σ₂: long, closed
4:
σₙ = 3
σ₁: short
σ₂: short, not weak, closed
5:
σₙ = 4+
σ₁: short, open
σ₂: short, open
σ₃: short
6:
σₙ = 4+
σ₁: short, open
σ₂: short, closed
7:
σₙ = 4+
σ₁: short, open
σ₂: long
8:
σₙ = 4+
σ₁: short, closed
σ₄: short
]]
local working_word = {}
local output = {}
local test_n = #syllables
mw.log("————— BEGINNING STRESS ASSIGNMENT —————")
while #syllables > 0 do
-- basically an iteration of working words
if type(syllables[1]) == "table" then -- testing for boundary syllable
-- set up current working word by adding and removing the initial syllables from the array until a boundary is registered
for i = 1, test_n do
table.insert(working_word, syllables[1])
table.remove(syllables, 1)
mw.log("Syllable " .. i .. " registered to working word.")
if syllables[1] == nil or type(syllables[1]) == "string" then -- check next syllable is a boundary (now 1 after deletion of registered syllable)
mw.log("Boundary found: continuing to stress assignment.")
break
end -- if next syllable is a boundary, register and continue to stress assignment
end
-- INTERNAL FUNCTIONS
local function stress(syl) -- assigns primary or secondary stress to the current working word
if syl == 1 or syl == 2 then
if syllables[1] == "-" or output[#output] == "·" then -- check if following · or preceding - ; if so, assign stress regardless of monosyllabicness
working_word[syl]["stress"] = true
mw.log("Primary stress assigned to syllable " .. syl .. ".")
elseif #working_word > 1 then -- if monosyllabic, do not add a redundant stress mark
if output[#output] == "-" or syllables[1] == "·" then -- check if following - or preceding ·
working_word[syl]["stress2"] = true
mw.log("Secondary stress assigned to syllable " .. syl .. ".")
else
working_word[syl]["stress"] = true
mw.log("Primary stress assigned to syllable " .. syl .. ".")
end
else
mw.log("Implicit primary stress assigned to monosyllable.")
end
-- register the working word
if #working_word > 0 then
for j = 1, #working_word do
table.insert(output, working_word[j])
end
working_word = {}
mw.log("Word registered to output.")
else
error("An empty word cannot be registered.")
end
else
error("Empty or invalid input to stress().")
end
end
-- calculate stress on the working word
mw.log("Syllables in working word: " .. #working_word)
if #working_word == 0 or working_word == nil then
error("The working word is empty.")
elseif #working_word == 1 then -- monosyllabic?
stress(1)
elseif working_word[1]["long"] then
stress(1)
elseif #working_word == 2 then -- disyllabic?
if working_word[2]["heavy"] then -- condition 1
stress(2)
else
stress(1)
end
elseif #working_word == 3 then -- trisyllabic?
if not working_word[2]["weak"] and working_word[2]["checked"] then -- condition 4
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
stress(1)
end
elseif #working_word >= 4 then -- 4+ syllables
if working_word[1]["checked"] then
if not working_word[3]["long"] then -- condition 8
stress(2)
else
stress(1)
end
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)
else
stress(1)
end
else
error("Invalid syllable count.")
end
elseif syllables[1] == nil then
error("Empty syllable found in array. The array should contain no empty syllables.")
else -- if boundary is identified as the working word, then
mw.log ("Boundary syllable identified.")
table.insert(output, syllables[1])
mw.log("Boundary registered to output: [" .. syllables[1] .. "]")
table.remove(syllables, 1)
end
mw.log("—————")
end
mw.log("SYLLABLES EXHAUSTED\n==========\nRemoving [·] and [-] from the system.")
local screened = false
while screened == false do
for i = 1, #output do
if output[i] == "-" or output[i] == "·" then
table.remove(output, i)
break
elseif i == #output then
screened = true
end
end
end
boundary["·"] = false
return output
end
function resolve_syllables(syllables)
end
end


Line 969: Line 1,167:
outputIPA = get_syllables(outputIPA)
outputIPA = get_syllables(outputIPA)
outputIPA = tag_syllables(outputIPA)
outputIPA = tag_syllables(outputIPA)
outputIPA = get_stress(outputIPA)
-- test output only --
local output = ""
local test_output = ""
for i = 1, #outputIPA do
for i = 1, #outputIPA do
local onset = ""
local onset = ""
local coda = ""
local coda = ""
local stress=""
if type(outputIPA[i]) == "table" then
if type(outputIPA[i]) == "table" then
if outputIPA[i]["onset"] then
if outputIPA[i]["onset"] then
onset = table.concat(outputIPA[i]["onset"], " ")
onset = table.concat(outputIPA[i]["onset"])
end
end
if outputIPA[i]["coda"] then
if outputIPA[i]["coda"] then
coda = table.concat(outputIPA[i]["coda"], " ")
coda = table.concat(outputIPA[i]["coda"])
end
end
test_output = test_output .. " " .. onset .. " [ " .. outputIPA[i]["nucleus"] .. " ] " .. coda
if outputIPA[i]["stress"] then
stress = "ˈ"
end
if outputIPA[i]["stress2"] then
stress = "ˌ"
end
output = output .. stress .. onset .. outputIPA[i]["nucleus"] .. coda
else
else
test_output = test_output .. " • " .. outputIPA[i]
output = output .. outputIPA[i]
end
end
end
end
mw.log(test_output)
return test_output
mw.log(output)
return output
end
end