Module:haw-IPA

local export = {}

local m_str_utils = require("Module:string utilities")

local decomp = mw.ustring.toNFD local find = m_str_utils.find local gmatch = m_str_utils.gmatch local gsub = m_str_utils.gsub local len = m_str_utils.len local lower = m_str_utils.lower local sub = m_str_utils.sub

local lang = require("Module:languages").getByCode("haw") local ipa = require("Module:IPA")

local U = require("Module:string/char") local breve = U(0x032F) local macron = U(0x0304)

local cons = "bcdfghklmnpqrstvwzʻ" local vowels = "aeiouāēīōū" local diphs = { "āi", "āe", "āo", "āu", "ēi", "ōu", "ae", "ai", "ao", "au", "ei", "eu", "iu", "ou", "oi" } local respell = { ["cdgqstz"] = "k", ["bf"] = "p", ["r"] = "l", ["v"] = "w" }

local stressed = "ˈˌ" local boundary = "%.ˈˌ%+-"

-- syllabify word local function syllabify(word) -- mark diphthongs with brackets for _, diph in ipairs(diphs) do word = gsub(word, diph, "{" .. diph .. "}") end

-- split between vowels and consonants word = gsub(word, "([" .. vowels .. "}])([{" .. cons .. vowels .. "])", "%1.%2")

-- remove diphthong brackets and any dots inside them word = gsub(word, "{[^}]*}", function(a) return gsub(a, "[%.{}]", "") end)

-- syllables that end in consonants are invalid if find(word, "[" .. cons .."]$") then error("One of the entries has an invalid Hawaiian syllable structure.") end

return word end

local function stress(word) -- decompose macrons from vowels word = decomp(word)

-- stress the last vowel if it has a macron, second last otherwise local stress_vowel_pos = len(gsub(word, "[^" .. vowels .. "]", "")) + (find(word, macron .. "$") and 1 or 0)

-- add stressed vowel at given position word = gsub(word, "([" .. vowels .. "])", function(v)		stress_vowel_pos = stress_vowel_pos - 1		return (stress_vowel_pos == 1) and 'ˈ' .. v or v	end)

-- shift stress mark before space or syllable boundary return gsub(word, "([^" .. boundary .. "]*)ˈ", "ˈ%1") end

-- generate pronunciation of words function export.toIPA(entry, is_phonetic) if type(entry) == "table" then entry = table.concat(entry) end

-- make entry lowercase entry = lower(entry)

-- validate characters if not find(entry, "[aābcdeēfghiīklmnoōpqrstuūvwzʻ %+-]") then error("Invalid characters. Only valid Hawaiian letters, spaces and symbols '+' and '-' are accepted.") end

-- syllabify entry entry = syllabify(entry)

-- syllabify and stress entry local result = "" for segment in gmatch(syllabify(entry), "[^ %+-]+[ %+-]?") do		-- apply stress to each segment segment = stress(segment)

-- convert to secondary stress if part of compound if find(segment, "[%+-]") then segment = gsub(segment, "ˈ", "ˌ"):gsub("[%+-]", ".") end

result = result .. segment end

-- remove syllable boundaries before stress result = gsub(result, "%.([" .. stressed .. "])", "%1")

-- mark long vowels result = gsub(result, macron, "ː")

-- mark diphthongised vowels result = gsub(result, "([^j])iu", "%1i" .. breve .. "u"):gsub("([^w])oi", "%1o" .. breve .. "i") result = gsub(result, "([" .. vowels .. "]ː?[" .. vowels .. "])", "%1" .. breve)

-- replace respellt consonants for k, v in pairs(respell) do result = gsub(result, "[" .. k .. "]", v)	end

-- real value of glottal stop result = gsub(result, "ʻ", "ʔ")

-- phonetic transcriptions if is_phonetic then -- allophony of /k/ before /i/ result = gsub(result, "ki", "ti")

-- real pronunciation of /w/ result = gsub(result, "w", "ʋ")

-- allophony of glides /j/, /w/ result = gsub(result, "([ei]" .. breve .. "?[" .. boundary .. "])([aou])", "%1j%2") result = gsub(result, "([ou]" .. breve .. "?[" .. boundary .. "])([aei])", "%1w%2")

-- actual pronunciation of diphthongs result = gsub(result, "i" .. breve, "j") result = gsub(result, "u" .. breve, "w")

-- allophony of /a/ result = gsub(result, "([" .. stressed .. "][^" .. vowels .. "]?)a", "%1ɐ") result = gsub(result, "a", "ə") result = gsub(result, "[ɐə]ː", "aː")

-- allophony of /e/ result = gsub(result, "([" .. stressed .. "][^" .. vowels .. "]?)e", "%1ɛ") result = gsub(result, "e([" .. boundary .. "][^" .. vowels .. "]*)ɛ", "ɛ%1ɛ") result = gsub(result, "ɛ([" .. boundary .. "][^" .. vowels .. "]*)e", "ɛ%1ɛ") result = gsub(result, "ɛː", "eː") end

return result end

-- rapid pronunciation of diphthongs function export.rapid(entry) return gsub(entry, "ɐj", "ɛj"):gsub("ɐw", "ɔw") end

-- display pronunciation function export.show(frame) local args = frame:getParent.args local pagetitle = mw.title.getCurrentTitle.text

local p, results = {}, {}

if args[1] then for _, v in ipairs(args) do			table.insert(p, (v ~= "") and v or nil) end else p = { pagetitle } end

for _, word in ipairs(p) do		local phonemic = export.toIPA(word, false) local phonetic = export.toIPA(word, true) local rapid = export.rapid(phonetic)

table.insert(results, { pron = "/" .. phonemic .. "/" }) if phonemic ~= phonetic then table.insert(results, { pron = "[" .. phonetic .. "]" }) end if phonetic ~= rapid then table.insert(results, { pron = "[" .. rapid .. "]", qq = {"rapid speech"} }) end end

return ipa.format_IPA_full { lang = lang, items = results } end

return export