local export = {}
local rsubn = mw.ustring.gsub
local U = mw.ustring.char
local TIE = U(0x361)
local BREVE = U(0x306)
local DENTAL = U(0x32A)
local SYLLABIC = U(0x329)
local FRONTED = U(0x31F)
local RETRACTED = U(0x320)
local NASAL= U(0x303)
local GRAVE = U(0x300)
local D_GRAVE = U(0x30F)
local UPSTEP = "ꜛ"
local DOWNSTEP = "ꜜ"
local PALATALIZED = "ʲ"
local vowels = "ɑæɛiɪɔuʊɯy" .. FRONTED .. RETRACTED .. NASAL .. SYLLABIC .. BREVE
local vowels_c = "[" .. vowels .. "]"
local palatal_cons = "ʃʒjɲɕʑʎ" .. PALATALIZED
local cons = "bʋɡdʒzjklɫʎmnɲpɾrstfxʃɕʑ" .. TIE .. DENTAL
local accents = GRAVE .. D_GRAVE
local diacritics = "ʲ" .. TIE .. BREVE .. DENTAL .. SYLLABIC .. FRONTED .. RETRACTED .. NASAL .. GRAVE .. D_GRAVE
local tones = UPSTEP .. DOWNSTEP
-- characters that map to IPA sounds
local phonetic_chars_map = {
["а"] = "ɑ",
["б"] = "b",
["в"] = "ʋ",
["г"] = "ɡ",
["д"] = "d" .. DENTAL,
["е"] = "ɛ" .. RETRACTED,
["є"] = "ɛ" .. RETRACTED,
["ж"] = "ʒ",
["ѕ"] = "d" .. DENTAL .. TIE .. "z" .. DENTAL,
["ꙃ"] = "d" .. TIE .. "z",
["ꙁ"] = "z" .. DENTAL,
["з"] = "z" .. DENTAL,
["и"] = "i",
["й"] = "jь",
["і"] = "i",
["ї"] = "i",
["к"] = "k",
["л"] = "ɫ" .. DENTAL,
["м"] = "m",
["н"] = "n" .. DENTAL,
["о"] = "ɔ" .. FRONTED,
["п"] = "p",
["р"] = "ɾ" .. DENTAL,
["с"] = "s" .. DENTAL,
["т"] = "t" .. DENTAL,
["ꙋ"] = "u",
["ф"] = "f",
["х"] = "x",
["ѿ"] = "ɔt" .. DENTAL .. "ʊ" .. BREVE,
["ц"] = "t" .. DENTAL .. TIE .. "s" .. DENTAL,
["ч"] = "t" .. TIE .. "ʃ",
["ш"] = "ʃ",
["щ"] = "ʃt" .. PALATALIZED,
["ꙑ"] = "ɯ",
["ы"] = "ɯ",
["ѣ"] = "æ",
["ѫ"] = "ɔ" .. NASAL,
["ѧ"] = "ɛ" .. NASAL,
["я"] = "ɛ" .. NASAL,
["ю"] = "ju",
["ꙗ"] = "jɑ",
["ѥ"] = "jɛ" .. RETRACTED,
["ꙓ"] = "jæ",
["ꙙ"] = "jɛ" .. NASAL,
["ѩ"] = "jɛ" .. NASAL,
["ѭ"] = "jɔ" .. NASAL,
["ѳ"] = "t" .. DENTAL,
["ѯ"] = "kʊ" .. BREVE .. "s" .. DENTAL,
["ѱ"] = "pʊ" .. BREVE .. "s" .. DENTAL,
["ѡ"] = "ɔ",
["ꙉ"] = "ʒd" .. PALATALIZED,
["ѻ"] = "ɔ",
["ꙍ"] = "ɔ",
["ѽ"] = "ɔ",
["у"] = "y",
["ѵ"] = "y",
["҇"] = PALATALIZED,
["҄"] = PALATALIZED
}
-- version of rsubn() that discards all but the first return value
local function rsub(term, foo, bar)
local retval = rsubn(term, foo, bar)
return retval
end
function export.toIPA(term)
term = mw.ustring.toNFC(mw.ustring.lower(term))
-- Change Cyrillic glyphs to IPA symbols
term = rsub(term, ".", phonetic_chars_map)
-- Change y into its actual sound value
term = rsub(term, "ɔ" .. FRONTED .. "y", "u")
term = rsub(term, "([" .. vowels .. "][" .. diacritics .. "])y", "%1ʋ")
term = rsub(term, "([" .. vowels .. "][" .. diacritics .. "][" .. tones .. "])y", "%1ʋ")
term = rsub(term, "([" .. vowels .. "])y", "%1ʋ")
term = rsub(term, "([" .. cons .. "#])y", "%1i")
-- Change j to ʲ after consonants
term = rsub(term, "([" .. cons .. "#])j", "%1" .. PALATALIZED)
-- Palatalize dental consonants
term = rsub(term, "[ɫl]" .. DENTAL .. PALATALIZED, "ʎ")
term = rsub(term, "ɾ" .. DENTAL .. PALATALIZED, "ɾ" .. PALATALIZED)
term = rsub(term, "n" .. DENTAL .. PALATALIZED, "ɲ")
term = rsub(term, "ʒd" .. DENTAL, "ʒdʲ")
term = rsub(term, "ʃt" .. DENTAL, "ʃtʲ")
-- Palatalize vowels
term = rsub(term, "([" .. palatal_cons .. "])ɑ", "%1æ")
term = rsub(term, "([" .. palatal_cons .. "])u", "%1y")
term = rsub(term, "([" .. palatal_cons .. "])ɔ" .. NASAL, "%1ɛ" .. NASAL)
-- Handle nasal gamma in Greek loanwords
term = rsub(term, "[nɡ]" .. DENTAL .. "?([ɡk])", "n" .. DENTAL .. "ъ%1")
-- Raise tense yers
term = rsub(term, "ъj", "ɯj")
term = rsub(term, "ьj", "ij")
-- Remove yers succeeding a syllabic liquid
term = rsub(term, "([" .. cons .."])ɾ" .. DENTAL .. "[ъь]", "%1r" .. SYLLABIC)
term = rsub(term, "([" .. cons .."])ɫ" .. DENTAL .. "[ъь]", "%1ɫ" .. SYLLABIC)
-- Allophone of ɫ before front vowels
term = rsub(term, "ɫ" .. DENTAL .. "([iьɛæ])", "l" .. DENTAL .. "%1")
-- Change strong yers into IPA
term = rsub(term, "ь([" .. cons .. diacritics .. "][" .. cons .. diacritics .. "][" .. diacritics .. cons .. "][" .. cons .. diacritics .. "][" .. diacritics .. cons .. "][" .. cons .. diacritics .. "])([ъьʊɪ])", "ɪ%1%2")
term = rsub(term, "ь([" .. cons .. diacritics .. "][" .. cons .. diacritics .. "][" .. diacritics .. cons .. "][" .. cons .. diacritics .. "][" .. diacritics .. cons .. "])([ъьʊɪ])", "ɪ%1%2")
term = rsub(term, "ь([" .. cons .. diacritics .. "][" .. cons .. diacritics .. "][" .. diacritics .. cons .. "][" .. cons .. diacritics .. "])([ъьʊɪ])", "ɪ%1%2")
term = rsub(term, "ь([" .. cons .. diacritics .. "][" .. cons .. diacritics .. "][" .. diacritics .. cons .. "])([ъьʊɪ])", "ɪ%1%2")
term = rsub(term, "ь([" .. cons .. diacritics .. "][" .. cons .. diacritics .. "])([ъьʊɪ])", "ɪ%1%2")
term = rsub(term, "ь([" .. cons .. diacritics .. "])([ъьʊɪ])", "ɪ%1%2")
term = rsub(term, "ъ([" .. cons .. "][" .. diacritics .. "][" .. cons .. "][" .. diacritics .. "][" .. cons .. "][" .. diacritics .. "])([ъьʊɪ])", "ʊ%1%2")
term = rsub(term, "ъ([" .. cons .. "][" .. diacritics .. "][" .. cons .. "][" .. diacritics .. "])([" .. cons .. "])", "ʊ%1%2")
term = rsub(term, "ъ([" .. cons .. "][" .. diacritics .. "][" .. cons .. "][" .. diacritics .. "])([ъьʊɪ])", "ʊ%1%2")
term = rsub(term, "ъ([" .. cons .. "][" .. diacritics .. "][" .. cons .. "])([ъьʊɪ])", "ʊ%1%2")
term = rsub(term, "ъ([" .. cons .. "][" .. cons .. "][" .. diacritics .. "])([ъьʊɪ])", "ʊ%1%2")
term = rsub(term, "ъ([" .. cons .. "][" .. cons .. "])([ъьʊɪ])", "ʊ%1%2")
term = rsub(term, "ъ([" .. cons .."][" .. diacritics .. "])([ъьʊɪ])", "ʊ%1%2")
term = rsub(term, "ъ([" .. cons .."])([ъьʊɪ])", "ʊ%1%2")
-- Finally do the same for weak yers
term = rsub(term, "ь", "ɪ" .. BREVE)
term = rsub(term, "ъ", "ʊ" .. BREVE)
-- Iotate i, ɛ, ɛ̃, æ, and optionally a at the start of a word and after a vowel
term = rsub(term, "%f[%a%-" .. DENTAL .. FRONTED .. "]([iɛæ])", "j%1")
term = rsub(term, "([" .. vowels .. "])([iɛæ])", "j%1")
term = rsub(term, "([" .. vowels .. "][" .. diacritics .. "])([iɛæ])", "%1j%2")
term = rsub(term, "%f[%a%-" .. DENTAL .. FRONTED .. "]ɑ", "(j)ɑ")
-- Remove unnecessary characters
term = rsub(term, "%[", "")
term = rsub(term, "%]", "")
term = rsub(term, "%-", "")
term = rsub(term, PALATALIZED .. PALATALIZED, PALATALIZED)
-- Convert pitch accent
term = rsub(term, "jɪ" .. BREVE .. GRAVE .. "([sz])" .. DENTAL, "jɪ" .. BREVE .. "%1" .. DENTAL .. UPSTEP)
term = rsub(term, "jɪ" .. BREVE .. D_GRAVE .. "([sz])" .. DENTAL, "jɪ" .. BREVE .. "%1" .. DENTAL .. DOWNSTEP)
term = rsub(term, "bɛ" .. BREVE .. GRAVE .. "([sz])" .. DENTAL, "bɛ" .. BREVE .. "%1" .. DENTAL .. UPSTEP)
term = rsub(term, "bɛ" .. RETRACTED .. D_GRAVE .. "([sz])" .. DENTAL, "bɛ" .. RETRACTED .. "%1" .. DENTAL .. DOWNSTEP)
term = rsub(term, "ʋʊ" .. BREVE .. GRAVE .. "([sz])" .. DENTAL, "vʊ" .. BREVE .. "%1" .. DENTAL .. UPSTEP)
term = rsub(term, "ʋʊ" .. RETRACTED .. D_GRAVE .. "([sz])" .. DENTAL, "ʋʊ" .. RETRACTED .. "%1" .. DENTAL .. DOWNSTEP)
term = rsub(term, GRAVE, UPSTEP)
term = rsub(term, D_GRAVE, DOWNSTEP)
-- Syllabify
term = rsub(term, "([" .. tones .. "])([" .. cons .. "])", "%1.%2")
term = rsub(term, "([" .. vowels .. "])([" .. cons .. "])", "%1.%2")
return term
end
function export.show(frame)
local params = {
[1] = {}
}
local title = mw.title.getCurrentTitle()
local args = require("Module:parameters").process(frame:getParent().args, params)
local term = args[1] or title.nsText == "Template" and "примѣръ" or title.text
local ipa = export.toIPA(term)
ipa = "[" .. ipa .. "]"
ipa = require("Module:IPA").format_IPA_full(require("Module:languages").getByCode("cu"), { { pron = ipa } } )
return ipa
end
return export