Mòdul:la-pron
A continuació es mostra la documentació transclosa de la subpàgina /ús. [salta a la caixa de codi]
Mòdul de suport per la plantilla:la-pron. Vegeu la documentació de la plantilla.
local export = {}
local letters_ipa = {
["a"] = "a",
["e"] = "ɛ",
["i"] = "ɪ",
["o"] = "ɔ",
["u"] = "ʊ",
["y"] = "ʏ",
["ā"] = "aː",
["ē"] = "eː",
["ī"] = "iː",
["ō"] = "oː",
["ū"] = "uː",
["ȳ"] = "yː",
['ae']='aj',
['oe']='oj',
['au']='aw',
['ei']='ej',
['eu']='ew',
["b"] = "b",
["d"] = "d",
["f"] = "f",
["c"] = "k",
["g"] = "ɡ",
["v"] = "w",
["x"] = "ks",
["ph"] = "f",
["th"] = "tʰ",
["ch"] = "k",
["qv"] = "kw",
["gv"] = "ɡw",
}
local vowels = {
"a", "ɪ", "ʊ", "ʏ",
"ɛ", "ɔ",
"aː", "eː", "iː", "oː", "uː", "yː",
"aj", "oj", "ej", "aw", "ew",
}
local onsets = {
"b", "p", "pʰ", "d", "t", "tʰ", "ɡ", "k", "kʰ", "kʷ", "ɡʷ", "kw", "gw",
"f", "s", "h", "z",
"l", "m", "n", "r", "j", "w",
"bl", "pl", "pʰl", "br", "pr", "pʰr",
"dr", "tr", "tʰr",
"ɡl", "kl", "kʰl", "ɡr", "kr", "kʰr", "ɡn",
"fl", "fr",
"sp", "st", "sk", "skʷ", "sl", "sm", "sn", "sw", "skw",
"spr", "str", "skr",
"spl", "skl",
}
local codas = {
"b", "p", "pʰ", "d", "t", "tʰ", "ɡ", "k", "kʰ",
"f", "s",
"l", "m", "n", "r",
"sp", "st", "sk",
"spʰ", "stʰ", "skʰ", "sf",
"lp", "lt", "lk",
"lb", "ld", "lɡ",
"lpʰ", "ltʰ", "lkʰ",
"lf",
"rp", "rt", "rk",
"rb", "rd", "rɡ",
"rpʰ", "rtʰ", "rkʰ",
"rf",
"mp", "nt", "nk",
"mb", "nd", "nɡ",
"mpʰ", "ntʰ", "nkʰ",
"lm", "rl", "rm", "rn",
"ps", "ts", "ks", "ls", "ns", "rs",
"lks", "nks", "rks",
"lms", "rls", "rms", "rns",
}
local breves = {
["ă"] = "a",
["ĕ"] = "e",
["ĭ"] = "i",
["ŏ"] = "o",
["ŭ"] = "u",
["æ"] = "ae",
["œ"] = "oe",
}
for i, val in ipairs(vowels) do
vowels[val] = true
end
for i, val in ipairs(onsets) do
onsets[val] = true
end
for i, val in ipairs(codas) do
codas[val] = true
end
local function letters_to_ipa(word)
local phonemes = {}
while mw.ustring.len(word) > 0 do
local longestmatch = ""
for letter, ipa in pairs(letters_ipa) do
if mw.ustring.len(letter) > mw.ustring.len(longestmatch) and mw.ustring.sub(word, 1, mw.ustring.len(letter)) == letter then
longestmatch = letter
end
end
if mw.ustring.len(longestmatch) > 0 then
table.insert(phonemes, letters_ipa[longestmatch])
word = mw.ustring.sub(word, mw.ustring.len(longestmatch) + 1)
else
table.insert(phonemes, mw.ustring.sub(word, 1, 1))
word = mw.ustring.sub(word, 2)
end
end
return phonemes
end
local function get_onset(syll)
local consonants = {}
for i = 1, #syll do
if vowels[syll[i]] then
break
end
table.insert(consonants, syll[i])
end
return table.concat(consonants)
end
local function get_coda(syll)
local consonants = {}
for i = #syll, 1, -1 do
if vowels[syll[i]] then
break
end
table.insert(consonants, 1, syll[i])
end
return table.concat(consonants)
end
-- Split the word into syllables of CV shape
local function split_syllables(remainder)
local syllables = {}
local syll = {}
while #remainder > 0 do
local phoneme = table.remove(remainder, 1)
if phoneme == "." then
if #syll > 0 then
table.insert(syllables, syll)
syll = {}
end
elseif vowels[phoneme] then
table.insert(syll, phoneme)
table.insert(syllables, syll)
syll = {}
else
table.insert(syll, phoneme)
end
end
-- If there are phonemes left, then the word ends in a consonant
-- Add them to the last syllable
for _, phoneme in ipairs(syll) do
table.insert(syllables[#syllables], phoneme)
end
-- Split consonant clusters between syllables
for i, current in ipairs(syllables) do
if i > 1 then
local previous = syllables[i-1]
local onset = get_onset(current)
-- Shift over consonants until the syllable onset is valid
while not (onset == "" or onsets[onset]) do
table.insert(previous, table.remove(current, 1))
onset = get_onset(current)
end
-- If the preceding syllable still ends with a vowel, and the current one begins with s + another consonant, or with gn, then shift it over
if get_coda(previous) == "" and ((current[1] == "s" and not vowels[current[2]]) or (current[1] =="g" and current[2] == "n")) then
table.insert(previous, table.remove(current, 1))
end
end
end
return syllables
end
local function detect_accent(syllables)
-- Detect accent placement
if #syllables > 2 then
-- Does the penultimate syllable end in a single vowel?
local penult = syllables[#syllables-1]
if mw.ustring.find(penult[#penult], "^[aeɛiɪoɔuʊyʏ]$") then
return #syllables - 2
else
return #syllables - 1
end
elseif #syllables == 2 then
return #syllables - 1
end
end
local function convert_word(word, phonetic)
-- Normalize spelling
word = mw.ustring.gsub(word, "w", "v")
word = mw.ustring.gsub(word, "([aeiouyāēīōūȳ])v([^aeiouyāēīōūȳ])", "%1u%2")
word = mw.ustring.gsub(word, "qu", "qv")
word = mw.ustring.gsub(word, "ngu([aeiouyāēīōūȳ])", "ngv%1")
word = mw.ustring.gsub(word, "^i([aeiouyāēīōūȳ])", "j%1")
word = mw.ustring.gsub(word, "^u([aeiouyāēīōūȳ])", "v%1")
word = mw.ustring.gsub(word, "([aeiouyāēīōūȳ])i([aeiouyāēīōūȳ])", "%1j%2")
word = mw.ustring.gsub(word, "([aeiouyāēīōūȳ])u([aeiouyāēīōūȳ])", "%1v%2")
-- Vowel length before nasal + fricative is allophonic
word = mw.ustring.gsub(word, "ā([mn][fs])", "a%1")
word = mw.ustring.gsub(word, "ē([mn][fs])", "e%1")
word = mw.ustring.gsub(word, "ī([mn][fs])", "i%1")
word = mw.ustring.gsub(word, "ō([mn][fs])", "o%1")
word = mw.ustring.gsub(word, "ū([mn][fs])", "u%1")
word = mw.ustring.gsub(word, "ȳ([mn][fs])", "y%1")
-- Apply some basic phoneme-level assimilations
word = mw.ustring.gsub(word, "xs", "ks")
word = mw.ustring.gsub(word, "b([st])", "p%1")
word = mw.ustring.gsub(word, "d([st])", "t%1")
word = mw.ustring.gsub(word, "g([st])", "k%1")
word = mw.ustring.gsub(word, "n([bp])", "m%1")
-- Convert word to IPA
local phonemes = letters_to_ipa(word)
-- Split into syllables
local syllables = split_syllables(phonemes)
-- Add accent
local accent = detect_accent(syllables)
if phonetic then
for i, syll in ipairs(syllables) do
for j, phoneme in ipairs(syll) do
syll[j] = phonetic_vowels[phoneme] or phoneme
end
end
end
for i, syll in ipairs(syllables) do
syllables[i] = (i == accent and "ˈ" or "") .. table.concat(syll)
end
word = (mw.ustring.gsub(table.concat(syllables, "."), "%.ˈ", "ˈ"))
if phonetic then
word = mw.ustring.gsub(word, "ɡ([.ˈ]?)n", "ŋ%1n")
word = mw.ustring.gsub(word, "n([.ˈ]?)([kɡ])", "ŋ%1%2")
word = mw.ustring.gsub(word, "ʷ([eɛiɪyʏ])", "ᶣ%1")
-- Nasal vowels
word = mw.ustring.gsub(word, "a([nm])$", "ã")
word = mw.ustring.gsub(word, "([eɛ][nm])$", "ẽ")
word = mw.ustring.gsub(word, "([iɪ][nm])$", "ĩ")
word = mw.ustring.gsub(word, "([oɔ][nm])$", "õ")
word = mw.ustring.gsub(word, "([uʊ][nm])$", "ũ")
word = mw.ustring.gsub(word, "([yʏ][nm])$", "ỹ")
word = mw.ustring.gsub(word, "a([nm])([%.ˈ]?[sf])", "ãː%2")
word = mw.ustring.gsub(word, "([eɛ][nm])([%.ˈ]?[sf])", "ẽː%2")
word = mw.ustring.gsub(word, "([iɪ][nm])([%.ˈ]?[sf])", "ĩː%2")
word = mw.ustring.gsub(word, "([oɔ][nm])([%.ˈ]?[sf])", "õː%2")
word = mw.ustring.gsub(word, "([uʊ][nm])([%.ˈ]?[sf])", "ũː%2")
word = mw.ustring.gsub(word, "([yʏ][nm])([%.ˈ]?[sf])", "ỹː%2")
--L pinguis
word = mw.ustring.gsub(word, "l", "ɫ")
word = mw.ustring.gsub(word, "ɫ(%.?)ɫ", "l%1l")
word = mw.ustring.gsub(word, "ɫ(%.?[iɪyʏ])", "l%1")
else
-- al·lòfons normals en català
word = mw.ustring.gsub(word, "ɡ([%.ˈ]?n)", "ŋ%1")
word = mw.ustring.gsub(word, "n([%.ˈ]?[kɡ])", "ŋ%1")
word = mw.ustring.gsub(word, "l$", "ɫ")
word = mw.ustring.gsub(word, "l(%.[^l])", "ɫ%1")
end
return word
end
local function convert_words(words, phonetic)
words = mw.ustring.lower(words)
words = mw.ustring.gsub(words,'[,?!:;()\'"%-]', '')
words = mw.ustring.gsub(words,'[ăĕĭŏŭæœ]', breves)
if mw.ustring.find(words,'[^a-zA-Zāēīōūȳ,.?!:;()\'" ]') then error('no extra punctuations allowed than sentence markers') end
local result = {}
for word in mw.text.gsplit(words, " ") do
table.insert(result, convert_word(word, phonetic))
end
return table.concat(result, " ")
end
function export.show(words, phonetic)
if type(words) == "table" then -- assume a frame
words = words.args[1]:lower() or mw.title.getCurrentTitle().text:lower()
end
return convert_words(words, phonetic)
end
local unassimilated_prefixes = {
'ab','ad','circum','con','contrā','dis','ex','īn','inter','ob','per','sub','subter'
}
return export