Module:lfv-IPA: Difference between revisions
Jump to navigation
Jump to search
TheNightAvl (talk | contribs) mNo edit summary |
TheNightAvl (talk | contribs) (Added phonetic transcription) |
||
Line 74: | Line 74: | ||
["ɔ"] = true, | ["ɔ"] = true, | ||
["ø"] = true, | ["ø"] = true, | ||
["u"] = | ["u"] = "u", | ||
["y"] = true, | ["y"] = true, | ||
} | |||
local consonant = { | |||
["b"] = true, | |||
["d"] = true, | |||
["ð"] = true, | |||
["f"] = true, | |||
["ɡ"] = true, | |||
["ɣ"] = true, | |||
["x"] = true, | |||
["j"] = true, | |||
["k"] = true, | |||
["l"] = true, | |||
["ʎ"] = true, | |||
["m"] = true, | |||
["n"] = true, | |||
["ɲ"] = true, | |||
["ŋ"] = true, | |||
["p"] = true, | |||
["r"] = true, | |||
["s"] = true, | |||
["ʃ"] = true, | |||
["t"] = true, | |||
["θ"] = true, | |||
["v"] = true, | |||
["w"] = true, | |||
["ɥ"] = true, | |||
["z"] = true, | |||
["ʒ"] = true, | |||
} | |||
local boundary = { | |||
[" "] = true, | |||
["|"] = true, | |||
} | } | ||
Line 87: | Line 121: | ||
} | } | ||
function generate_IPA(word) | local devoice = { | ||
["d"] = "d̥", | |||
["ð"] = "ð̥", | |||
["g"] = "g̊", | |||
["ǧ"] = "ɣ̊", | |||
["l"] = "l̥", | |||
["lj"] = "ʎ̥", | |||
["r"] = "r̥", | |||
["z"] = "z̥", | |||
["ž"] = "ʒ̊", | |||
} | |||
local voiceless = { | |||
["f"] = true, | |||
["x"] = true, | |||
["k"] = true, | |||
["p"] = true, | |||
["s"] = true, | |||
["ʃ"] = true, | |||
["t"] = true, | |||
["θ"] = true, | |||
} | |||
function generate_IPA(word, phon) | |||
local working_IPA = {} | local working_IPA = {} | ||
Line 124: | Line 181: | ||
local function p_resolve(phone) | local function p_resolve(phone) | ||
working_IPA[i] = phone | working_IPA[i] = phone | ||
p_prev = working_IPA[i-1] | |||
p_current = working_IPA[i] | |||
p_next = working_IPA[i+1] | |||
end | |||
local function remove_next(check) | |||
if check then | |||
table.remove(working_IPA, i+1) | |||
p_next = working_IPA[i+1] | |||
end | |||
end | end | ||
-- intervocalic voicing and gemination of voiceless sonorants -- | |||
if vowel[p_prev] and intervocalic_voicing[p_current] ~= nil and vowel[p_next] then | if vowel[p_prev] and intervocalic_voicing[p_current] ~= nil and vowel[p_next] then | ||
p_resolve(intervocalic_voicing[p_current]) | p_resolve(intervocalic_voicing[p_current]) | ||
end | |||
-- phonetic only -- | |||
if phon then | |||
-- l̥ → ɬ -- | |||
if p_current == "l̥" then | |||
p_resolve("ɬ") | |||
elseif p_current == "l̥l̥" then | |||
p_resolve("ɬɬ") | |||
end | |||
-- terminal devoicing -- | |||
if devoice[p_current] and (boundary[p_next] or p_next == nil) then | |||
p_resolve(devoice[p_current]) | |||
end | |||
-- regressive devoicing -- | |||
if p_current == "r" and voiceless[p_next] then | |||
p_resolve("r̥") | |||
elseif p_current == "l" and voiceless[p_next] then | |||
p_resolve("l̥") | |||
end | |||
-- /v/ -- | |||
if p_current == "v" then | |||
if consonant[p_prev] and p_prev ~= "u̯" then | |||
p_resolve("ʋ") | |||
elseif consonant[p_next] or boundary[p_next] or p_next == nil then | |||
p_resolve("u̯") | |||
end | |||
end | |||
-- /w/ -- | |||
if p_current == "w" and p_prev ~= "u̯" then | |||
p_resolve("u̯") | |||
end | |||
-- /ɥ/ -- | |||
if p_current == "ɥ" then | |||
p_resolve("y̯") | |||
end | |||
-- /j/ -- | |||
if p_current == "j" and p_prev ~= "i̯" then | |||
p_resolve("i̯") | |||
end | |||
-- /xj/ -- | |||
if p_current == "x" and p_next == "j" then | |||
p_resolve("ç") | |||
end | |||
-- V{i u} -- | |||
if vowel[p_prev] and p_current == "i" then | |||
p_resolve("i̯") | |||
elseif vowel[p_prev] and p_current == "u" then | |||
p_resolve("u̯") | |||
end | |||
end | end | ||
Line 133: | Line 263: | ||
end | end | ||
working_IPA = table.concat(working_IPA) | |||
-- /xd/ -- | |||
if mw.ustring.find(working_IPA, "(xd)") then | |||
working_IPA = mw.ustring.gsub(working_IPA, "(xd)", "hd") .. "~" .. mw.ustring.gsub(working_IPA, "(xd)", "ɦd") | |||
end | |||
return working_IPA | |||
end | end | ||
Line 152: | Line 290: | ||
outputIPA = mw.ustring.gsub(outputIPA, "(% %;)", " ") | outputIPA = mw.ustring.gsub(outputIPA, "(% %;)", " ") | ||
outputIPA = generate_IPA(outputIPA) | outputIPA = generate_IPA(outputIPA, parameters["phon"] or false) | ||
local nolarge = "" | local nolarge = "" |
Revision as of 22:03, 26 August 2023
local export = {}
local getArgs = require('Module:Arguments').getArgs
-- DATA --
local data = {
["a"] = "a",
["e"] = "e",
["ê"] = "ɛ",
["i"] = "i",
["o"] = "o",
["ô"] = "ɔ",
["ø"] = "ø",
["u"] = "u",
["y"] = "y",
["b"] = "b",
["d"] = "d",
["ð"] = "ð",
["f"] = "f",
["g"] = "ɡ",
["ǧ"] = "ɣ",
["h"] = "x",
["j"] = "j",
["k"] = "k",
["l"] = "l",
["lj"] = "ʎ",
["m"] = "m",
["n"] = "n",
["nj"] = "ɲ",
["ñ"] = "ŋ",
["p"] = "p",
["r"] = "r",
["s"] = "s",
["š"] = "ʃ",
["t"] = "t",
["þ"] = "θ",
["v"] = "v",
["w"] = "w",
["ŵ"] = "ɥ",
["z"] = "z",
["ž"] = "ʒ",
["hl"] = "l̥",
["hlj"] = "ʎ̥",
["hm"] = "m̥",
["hn"] = "n̥",
["hnj"] = "ɲ̊",
["hñ"] = "ŋ̊",
["hr"] = "r̥",
["llj"] = "ʎʎ",
["nnj"] = "ɲɲ",
["lhl"] = "l̥l̥",
["lhlj"] = "ʎʎ",
["mhm"] = "mm",
["nhn"] = "nn",
["nhnj"] = "ɲɲ",
["ñhñ"] = "ŋŋ",
["rhr"] = "rr",
[" "] = " ",
["."] = "|",
}
data[","] = data["."]
local vowel = {
["a"] = true,
["e"] = true,
["ɛ"] = true,
["i"] = true,
["o"] = true,
["ɔ"] = true,
["ø"] = true,
["u"] = "u",
["y"] = true,
}
local consonant = {
["b"] = true,
["d"] = true,
["ð"] = true,
["f"] = true,
["ɡ"] = true,
["ɣ"] = true,
["x"] = true,
["j"] = true,
["k"] = true,
["l"] = true,
["ʎ"] = true,
["m"] = true,
["n"] = true,
["ɲ"] = true,
["ŋ"] = true,
["p"] = true,
["r"] = true,
["s"] = true,
["ʃ"] = true,
["t"] = true,
["θ"] = true,
["v"] = true,
["w"] = true,
["ɥ"] = true,
["z"] = true,
["ʒ"] = true,
}
local boundary = {
[" "] = true,
["|"] = true,
}
local intervocalic_voicing = {
["ʎ̥"] = "ʎʎ",
["m̥"] = "mm",
["n̥"] = "nn",
["ɲ̊"] = "ɲɲ",
["ŋ̊"] = "ŋŋ",
["r̥"] = "rr",
}
local devoice = {
["d"] = "d̥",
["ð"] = "ð̥",
["g"] = "g̊",
["ǧ"] = "ɣ̊",
["l"] = "l̥",
["lj"] = "ʎ̥",
["r"] = "r̥",
["z"] = "z̥",
["ž"] = "ʒ̊",
}
local voiceless = {
["f"] = true,
["x"] = true,
["k"] = true,
["p"] = true,
["s"] = true,
["ʃ"] = true,
["t"] = true,
["θ"] = true,
}
function generate_IPA(word, phon)
local working_IPA = {}
-- base generation --
while #word > 0 do
if data[mw.ustring.sub(word, 1, 4)] then
table.insert(working_IPA, data[mw.ustring.sub(word, 1, 4)])
word = mw.ustring.sub(word, 5)
elseif data[mw.ustring.sub(word, 1, 3)] then
table.insert(working_IPA, data[mw.ustring.sub(word, 1, 3)])
word = mw.ustring.sub(word, 4)
elseif data[mw.ustring.sub(word, 1, 2)] then
table.insert(working_IPA, data[mw.ustring.sub(word, 1, 2)])
word = mw.ustring.sub(word, 3)
elseif data[mw.ustring.sub(word, 1, 1)] then
table.insert(working_IPA, data[mw.ustring.sub(word, 1, 1)])
word = mw.ustring.sub(word, 2)
elseif data[mw.ustring.sub(word, 1, 1)] == "·" then
word = mw.ustring.sub(word, 2)
else
error("The character '" .. mw.ustring.sub(word, 1, 1) .. "' is not recognised.")
end
end
-- resolve consonants --
local i = 1
while working_IPA[i] do
local p_prev = working_IPA[i-1]
local p_current = working_IPA[i]
local p_next = working_IPA[i+1]
local function p_resolve(phone)
working_IPA[i] = phone
p_prev = working_IPA[i-1]
p_current = working_IPA[i]
p_next = working_IPA[i+1]
end
local function remove_next(check)
if check then
table.remove(working_IPA, i+1)
p_next = working_IPA[i+1]
end
end
-- intervocalic voicing and gemination of voiceless sonorants --
if vowel[p_prev] and intervocalic_voicing[p_current] ~= nil and vowel[p_next] then
p_resolve(intervocalic_voicing[p_current])
end
-- phonetic only --
if phon then
-- l̥ → ɬ --
if p_current == "l̥" then
p_resolve("ɬ")
elseif p_current == "l̥l̥" then
p_resolve("ɬɬ")
end
-- terminal devoicing --
if devoice[p_current] and (boundary[p_next] or p_next == nil) then
p_resolve(devoice[p_current])
end
-- regressive devoicing --
if p_current == "r" and voiceless[p_next] then
p_resolve("r̥")
elseif p_current == "l" and voiceless[p_next] then
p_resolve("l̥")
end
-- /v/ --
if p_current == "v" then
if consonant[p_prev] and p_prev ~= "u̯" then
p_resolve("ʋ")
elseif consonant[p_next] or boundary[p_next] or p_next == nil then
p_resolve("u̯")
end
end
-- /w/ --
if p_current == "w" and p_prev ~= "u̯" then
p_resolve("u̯")
end
-- /ɥ/ --
if p_current == "ɥ" then
p_resolve("y̯")
end
-- /j/ --
if p_current == "j" and p_prev ~= "i̯" then
p_resolve("i̯")
end
-- /xj/ --
if p_current == "x" and p_next == "j" then
p_resolve("ç")
end
-- V{i u} --
if vowel[p_prev] and p_current == "i" then
p_resolve("i̯")
elseif vowel[p_prev] and p_current == "u" then
p_resolve("u̯")
end
end
i = i + 1
end
working_IPA = table.concat(working_IPA)
-- /xd/ --
if mw.ustring.find(working_IPA, "(xd)") then
working_IPA = mw.ustring.gsub(working_IPA, "(xd)", "hd") .. "~" .. mw.ustring.gsub(working_IPA, "(xd)", "ɦd")
end
return working_IPA
end
function export.generate(frame)
local args = getArgs(frame)
local outputIPA = args[1]
local parameters = {}
local p = 2
-- mw.log("——— Parameters ———")
while args[p] do
parameters[args[p]] = true
-- mw.log(args[p] .. " = true")
p = p + 1
end
outputIPA = mw.ustring.gsub(outputIPA, "(% %;)", " ")
outputIPA = generate_IPA(outputIPA, parameters["phon"] or false)
local nolarge = ""
if parameters["nolarge"] then
nolarge = " nolarge"
end
if parameters["phon"] and parameters["format"] then
outputIPA = "<span class=\"IPA" .. nolarge .. "\">[" .. outputIPA .. "]</span>"
elseif parameters["format"] then
outputIPA = "<span class=\"IPA" .. nolarge .. "\">/" .. outputIPA .. "/</span>"
end
-- mw.log(outputIPA)
return outputIPA
end
return export
--[[
Debug console test string:
=p.generate(mw.getCurrentFrame():newChild{title="whatever",args={"alhlen"}})
]]