This is a private module sandbox of Zhnka, for his own experimentation. Items in this module may be added and removed at Zhnka's discretion; do not rely on this module's stability.
local export = {}
local m_IPA = require("Module:IPA")
local m_table = require("Module:table")
local lang = require("Module:languages").getByCode("zlw-ocs")
local U = mw.ustring.char
local rsub = mw.ustring.gsub
local rlower = mw.ustring.lower
local rfind = mw.ustring.find
local raised = U(0x031D)
local syllabic = U(0x0329)
local consonants = "bdcɟfɡɣxjkɫlmnɲprstʋzʒʃɲʲ"
local sconsonants = "bdcɟfɡɣxjkɫmnɲpstʋzʒʃɲʲ"
local C = ""
local sC = ""
local vowels = "aɛiɨou"
local V = ""
local voiceless_consonant = "ptsʃckxf"
local voiced_consonant = "bdzʒɟɡɣʋ"
local syllabic_consonant = "" .. syllabic
local function track(page)
require("Module:debug").track("zlw-ocs-IPA/" .. page)
return true
end
local function rsub_repeatedly(term, foo, bar)
while true do
local new_term = rsub(term, foo, bar)
if new_term == term then
return term
end
term = new_term
end
end
local digraphs = {
= "x",
= "d͡ʒ",
= "i̯ɛː",
}
local devoicing = {
= "t͡s",
= "t͡ʃ",
= "p",
= "t",
= "s",
= "ʃ",
= "x",
= "k",
= "f",
= "c",
}
local voicing = {
= "d͡z",
= "d͡ʒ",
= "b",
= "d",
= "z",
= "ʒ",
= "ɣ",
= "ɡ",
= "ʋ",
= "ɟ",
}
local function voice_backward(sound, following)
return voicing .. following
end
local function devoice_backward(sound, following)
return devoicing .. following
end
local function voice_forward(preceding, sound)
return preceding .. voicing
end
local function devoice_forward(preceding, sound)
return preceding .. devoicing
end
local function final_devoicing(sound, following)
return devoicing .. following .. "#"
end
local function flatmap(items, fun)
local new = {}
for _, item in ipairs(items) do
local results = fun(item)
mw.logObject(results, "results")
for _, result in ipairs(results) do
table.insert(new, result)
end
mw.logObject(new, "new")
end
return new
end
local phon = {
= "a",
= "aː",
= "b",
= "bʲ",
= "t͡s",
= "t͡ʃ",
= "cʲ",
= "d",
= "ɟ",
= "ɛ",
= "ɛː",
= "i̯ɛ",
= "f",
= "fʲ",
= "ɡ",
= "ɣ",
= "i",
= "iː",
= "j",
= "k",
= "l",
= "ʎ",
= "ɫ",
= "m",
= "mʲ",
= "n",
= "ɲ",
= "o",
= "oː",
= "p",
= "pʲ",
= "r",
= "r"..raised,
= "s",
= "ʃ",
= "sʲ",
= "t",
= "c",
= "u",
= "uː",
= "ʋ",
= "ʋʲ",
= "ɨ",
= "ɨː",
= "z",
= "ʒ",
= "zʲ",
= "ː",
= "ʔ"
}
function export.phonemic(text, post)
text = rlower(text)
text = rsub(text, " | ", "# | #")
text = "##" .. rsub(text, " ", "# #") .. "##"
-- basic phonology
for digraph, replacement in pairs(digraphs) do
text = rsub(text, digraph, replacement)
end
text = rsub(text, ".", phon)
text = rsub(text, "l()", "ɫ%1")
text = rsub(text, "l#", "ɫ#")
text = rsub(text, "(l)(" .. C .. ")", "ɫ%2")
text = rsub(text, "ʎ", "l")
-- palatalisation
text = rsub(text, "ni", "ɲi")
text = rsub(text, "ti", "ci")
text = rsub(text, "di", "ɟi")
text = rsub(text, "(" .. C .. ")()#", "%0"..syllabic.."#")
text = rsub(text, "(" .. C .. ")()(" .. C .. ")", "%1%2"..syllabic.."%3")
text = rsub(text, "(" .. sC .. ")()#", "%0"..syllabic.."#")
text = rsub(text, "(" .. sC .. ")()(" .. sC .. ")", "%1%2"..syllabic.."%3")
text = rsub(text, "()r̝", "%1r̝̊")
text = rsub(text, "'", "ˈ")
text = rsub(text, "-", "");
-- suffixes
text = rsub(text, "^ˈ%-", "-")
if not rfind(text, " ") then
text = rsub(text, text, "ˈ" .. text)
end
local variants = {text}
local function flatmap_and_sub_pre(from, to1, to2)
variants =
flatmap(
variants,
function(item)
if rfind(item, from) then
local retval = {rsub_repeatedly(item, from, to1)}
if to2 then
m_table.insertIfNot(retval, rsub_repeatedly(item, from, to2))
end
return retval
else
return {item}
end
end
)
end
if post ~= nil then
if args.desc == "no" then
else
if args.desc ~= nil then
desc = args.desc
desc = rlower(desc)
desc = rsub(desc, " | ", "# | #")
desc = "##" .. rsub(desc, " ", "# #") .. "##"
-- basic phonology
for digraph, replacement in pairs(digraphs) do
desc = rsub(desc, digraph, replacement)
end
desc = rsub(desc, ".", phon)
desc = rsub(desc, "l()", "ɫ%1")
text = rsub(text, "l#", "ɫ#")
text = rsub(text, "(l)(" .. C .. ")", "ɫ%2")
text = rsub(text, "ʎ", "l")
-- palatalisation
desc = rsub(desc, "ni", "ɲi")
desc = rsub(desc, "ti", "ci")
desc = rsub(desc, "di", "ɟi")
desc = rsub(desc, "(" .. C .. ")()#", "%0"..syllabic.."#")
desc = rsub(desc, "(" .. sC .. ")()#", "%0"..syllabic.."#")
desc = rsub(desc, "'", "ˈ")
desc = rsub(desc, "-", "")
-- suffixes
desc = rsub(desc, "^ˈ%-", "-")
if not rfind(desc, " ") then
desc = rsub(desc, desc, "ˈ" .. desc)
end
variants = {desc}
end
text = flatmap_and_sub_pre("(" .. C .. ")()(" .. C .. ")", "%1%2"..syllabic.."%3")
text = flatmap_and_sub_pre("(" .. sC .. ")()(" .. sC .. ")", "%1%2"..syllabic.."%3")
flatmap_and_sub_pre("r̝#", "r̝̊")
text = flatmap_and_sub_pre("()(r̝̊)", devoice_backward)
text = flatmap_and_sub_pre("()(#)", final_devoicing)
text = flatmap_and_sub_pre("v()", "f%1")
text = flatmap_and_sub_pre("f()", "v%1")
text = flatmap_and_sub_pre("()()", voice_forward)
text = flatmap_and_sub_pre("()()", devoice_forward)
text = flatmap_and_sub_pre("d͡z()", "t͡s%1")
text = flatmap_and_sub_pre("t͡s()", "d͡z%1")
text = flatmap_and_sub_pre("d͡ʒ()", "t͡ʃ%1")
text = flatmap_and_sub_pre("t͡ʃ()", "d͡ʒ%1")
text = flatmap_and_sub_pre("()()", devoice_backward)
text = flatmap_and_sub_pre("()()", voice_backward)
flatmap_and_sub_pre("-", "")
flatmap_and_sub_pre("ɨː", "iː", "ɛj")
flatmap_and_sub_pre("ɨ", "i")
flatmap_and_sub_pre("lu", "li")
flatmap_and_sub_pre("ɫ", "l")
flatmap_and_sub_pre("ʲu", "i")
flatmap_and_sub_pre("()ʲ", "%1")
flatmap_and_sub_pre("ʲ", "j")
flatmap_and_sub_pre("()u", "%1i")
flatmap_and_sub_pre("t͡su", "t͡si")
flatmap_and_sub_pre("(r"..raised..")u", "%1i")
flatmap_and_sub_pre("oː", "u̯o")
flatmap_and_sub_pre("uː", "ou̯")
flatmap_and_sub_pre("ie", "iː")
flatmap_and_sub_pre("ʋ", "v")
flatmap_and_sub_pre("i̯ɛː", "iː")
flatmap_and_sub_pre("()i̯", "%1j")
flatmap_and_sub_pre("()ɛː", "%1iː")
flatmap_and_sub_pre("(r"..raised..")ɛː", "%1iː")
flatmap_and_sub_pre("ɣ", "ɦ")
flatmap_and_sub_pre("i̯", "")
flatmap_and_sub_pre("r̝()", "r̝̊%1")
end
end
flatmap_and_sub_pre("#", "")
return variants
end
function export.IPA(frame)
local terms = {}
args = frame:getParent().args
local currentTitle = mw.title.getCurrentTitle().text
for _, term in ipairs(args) do
if term == currentTitle then track("redundant") end
table.insert(terms, term)
end
if #terms == 0 then
terms = {currentTitle}
end
local results1, results2 = {}, {}
for _, term in ipairs(terms) do
local variantsPre = export.phonemic(term)
for _, variant in ipairs(variantsPre) do
table.insert(results1, {pron = "/" .. variant .. "/"})
end
local variantsPost = export.phonemic(term, true)
for _, variant in ipairs(variantsPost) do
table.insert(results2, {pron = "/" .. variant .. "/"})
end
end
if args.desc == "no" then
results1.qualifiers = {"13<sup>th</sup> CE"}
return "*" .. m_IPA.format_IPA_full { lang = lang, items = results1 }
else
results1.qualifiers = {"13<sup>th</sup> CE"}
results2.qualifiers = {"15<sup>th</sup> CE"}
return "*" .. m_IPA.format_IPA_full { lang = lang, items = results1 }
.. "\n*" .. m_IPA.format_IPA_full { lang = lang, items = results2 }
end
end
return export