10,794
edits
TheNightAvl (talk | contribs) mNo edit summary |
TheNightAvl (talk | contribs) (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) | |||
local 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 | ||
if outputIPA[i]["stress"] then | |||
stress = "ˈ" | |||
end | |||
if outputIPA[i]["stress2"] then | |||
stress = "ˌ" | |||
end | |||
output = output .. stress .. onset .. outputIPA[i]["nucleus"] .. coda | |||
else | else | ||
output = output .. outputIPA[i] | |||
end | end | ||
end | end | ||
return | mw.log(output) | ||
return output | |||
end | end | ||